This commit is contained in:
zaccaria.majid
2023-06-22 11:44:26 +02:00
93 changed files with 7717 additions and 1013 deletions
+3 -3
View File
@@ -158,10 +158,10 @@ UI:deploy:
- main
needs: ["UI:build"]
script:
# IIS 02
# IIS02
- dotnet publish -p:PublishProfile=IIS02.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true $env:APP_NAME/$env:APP_NAME.csproj
# IIS DEV
- dotnet publish -p:PublishProfile=IIS03.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true $env:APP_NAME/$env:APP_NAME.csproj
# IIS04
- dotnet publish -p:PublishProfile=IIS04.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true $env:APP_NAME/$env:APP_NAME.csproj
ADAPTER:packDebug:
+13 -1
View File
@@ -45,7 +45,7 @@
"MinVal": 0,
"MaxVal": 10,
"DisplFormat": "N0",
"IsNumeric": true
"IsNumeric": false
},
{
"Order": 5,
@@ -94,5 +94,17 @@
"MaxVal": 10,
"DisplFormat": "N0",
"IsNumeric": true
},
{
"Order": 9,
"ExtCode": "ns=1;s=504_PROC 1 P.P. ORDER",
"Type": "ORDER",
"Title": "CURR ORDER",
"Value": "",
"ValueNum": 0,
"MinVal": 0,
"MaxVal": 10,
"DisplFormat": "N0",
"IsNumeric": false
}
]
+6 -2
View File
@@ -8,7 +8,7 @@
"BrowseValue": 0,
"keyPartCount": "1:507_2_WORKPIECE QTY",
"keyPartReq": "",
"keyPartId": "",
"keyPartId": "1:504_PROC 1 P.P. ORDER",
"keyProgName": "1:502_1_RECIPE NAME",
"keyRunMode": "",
"pingAsPowerOn": true,
@@ -166,6 +166,10 @@
"ns=1;s=502_1_RECIPE NAME",
"ns=1;s=507_1_WORKPIECE TIME",
"ns=1;s=507_2_WORKPIECE QTY",
"ns=1;s=507_3_CYCLE TIME"
"ns=1;s=507_3_CYCLE TIME",
"ns=1;s=504_PROC 1 P.P. ORDER",
"ns=1;s=505_PROC 1 P.P. PROCESSING",
"ns=1;s=506_PROC 1 P.P. PROCESSING PHASE",
"ns=1;s=503_PROC 1 P.P. EXECUTION TIME [HH:MM:SS]"
]
}
+15 -6
View File
@@ -45,6 +45,7 @@ namespace MP.MONO.ADAPTER.OPC
msVetoRedCache = config.GetValue<int>("OptPar:VetoSendCache");
MinWait = config.GetValue<int>("OptPar:MinWait");
MaxWait = config.GetValue<int>("OptPar:MaxWait");
DataStaleSec = config.GetValue<int>("OptPar:DataStaleSec");
AlarmCleanPre = config.GetValue<string>("OptPar:AlarmCleanPre");
AlarmCleanPost = config.GetValue<string>("OptPar:AlarmCleanPost");
AlarmTrimWSpace = config.GetValue<bool>("OptPar:AlarmTrimWSpace");
@@ -229,7 +230,20 @@ namespace MP.MONO.ADAPTER.OPC
/// <summary>
/// dataOra ultima verifica CNC disconnesso...
/// </summary>
internal DateTime lastDisconnCheck;
protected DateTime lastDisconnCheck;
/// <summary>
/// Valore soglia in secondi x indicare che i dati sono stale = bloccati/non aggiornati
/// </summary>
protected int DataStaleSec = 120;
/// <summary>
/// Verifica se i dati siano stale = incastrati (ultimo dato letto oltre 2 minuti fa) e quindi sia encessario effettuare disconnect/reconnect
/// </summary>
public bool dataIsStale
{
get => DateTime.Now.Subtract(lastCurrent).TotalSeconds > DataStaleSec;
}
/// <summary>
/// Dizionario della DataOra ultimo invio x ogni valore
@@ -895,11 +909,6 @@ namespace MP.MONO.ADAPTER.OPC
// invio
saveAndSendMessage(Constants.COUNT_CURR_KEY, Constants.COUNT_RAW_QUEUE, payloadParams);
}
#if false
// invio COMUNQUE negli eventi?!?
saveAndSendMessage("", Constants.RAW_EVENT_LOG_M_QUEUE, payload);
#endif
}
#endregion Protected Methods
+12 -4
View File
@@ -29,6 +29,7 @@ namespace MP.MONO.ADAPTER.OPC
/// </summary>
public static async Task Main(string[] args)
{
await Task.Delay(1);
TextWriter output = Console.Out;
output.WriteLine(lineSep);
output.WriteLine("Egalware | MP.MONO.ADAPTER | OPC UA Console Client");
@@ -89,13 +90,20 @@ namespace MP.MONO.ADAPTER.OPC
do
{
// se non fosse connesso... riprovo la connessione...
if (!currIob.connectionOk)
{
currIob.tryConnect();
}
currIob.tryConnect();
// attesa...
Thread.Sleep(100);
// aggiunta condizioni check dati "recenti" x ri-connessione: se NON si fosse
// aggiornato entro limite indicato --> disconnect/reconnect
if (currIob.dataIsStale)
{
currIob.tryDisconnect();
Thread.Sleep(500);
currIob.tryConnect();
}
// verifico se c'è evento quit
quit = quitEvent.WaitOne(Math.Min(1_000, waitTime));
} while (!quit);
-10
View File
@@ -199,17 +199,7 @@ namespace MP.MONO.ADAPTER.OPC
browser.NodeClassMask = (int)NodeClass.Object | (int)NodeClass.Variable;
browser.ReferenceTypeId = ReferenceTypeIds.HierarchicalReferences;
//NodeId nodeToBrowse = ObjectIds.Server;
//NodeId nodeToBrowse = new NodeId("ns=4;i=5001");
NodeId nodeToBrowse = new NodeId(browsePath);
//nodeToBrowse = ObjectIds.Server;
//nodeToBrowse = new NodeId("Calibratrice_L1", 4);
//nodeToBrowse = new NodeId("Dati_Mes", 4);
//nodeToBrowse = new NodeId(5001, 2);
//nodeToBrowse = new NodeId("ns=4;s=NxController");
//nodeToBrowse = new NodeId("ns=4;s=Dati_Mes");
//nodeToBrowse = new NodeId("NxController.GlobalVars", 4);
//nodeToBrowse = new NodeId("Dati_Mes", 4);
// Call Browse service
lg.Trace($"Browsing {nodeToBrowse} node...");
+3 -2
View File
@@ -9,7 +9,7 @@
"Redis": "nkcredis.steamware.net:6379,DefaultDatabase=7,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false,password=BtN9Py1wtLfLRvmzWnOPJ7RytDM+CLiVsJ/16zduNTlV8IOPGNrtzJSXPUnImA5PqmUMhKaUqo9NdHIG",
"AuthConnection": "Server=localhost;port=3306;database=GWMS;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
"DefaultConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
"AdminConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=root;pwd=Egalware_24068!;sslmode=None;",
"AdminConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=root;pwd=Seriate_24068!;sslmode=None;",
"MP.MONO.Data": "Server=localhost;port=3306;database=MAPO.MONO;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;"
},
"DbConfig": {
@@ -53,7 +53,8 @@
"Log2File": true,
"MinWait": 50,
"MaxWait": 150,
"VetoSendCache": 50
"VetoSendCache": 50,
"DataStaleSec": 60
},
"Machine": {
"Manufacturer": "Multiax",
+1 -1
View File
@@ -9,7 +9,7 @@
"Redis": "localhost:6379,DefaultDatabase=7,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false",
"AuthConnection": "Server=localhost;port=3306;database=GWMS;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
"DefaultConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
"AdminConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=root;pwd=Egalware_24068!;sslmode=None;",
"AdminConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=root;pwd=Seriate_24068!;sslmode=None;",
"MP.MONO.Data": "Server=localhost;port=3306;database=MAPO.MONO;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;"
},
"DbConfig": {
+1 -1
View File
@@ -9,7 +9,7 @@
"Redis": "nkcredis.steamware.net:6379,DefaultDatabase=7,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false,password=BtN9Py1wtLfLRvmzWnOPJ7RytDM+CLiVsJ/16zduNTlV8IOPGNrtzJSXPUnImA5PqmUMhKaUqo9NdHIG",
"AuthConnection": "Server=localhost;port=3306;database=GWMS;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
"DefaultConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
"AdminConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=root;pwd=Egalware_24068!;sslmode=None;",
"AdminConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=root;pwd=Seriate_24068!;sslmode=None;",
"MP.MONO.Data": "Server=localhost;port=3306;database=MAPO.MONO;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;"
},
"DbConfig": {
+1 -1
View File
@@ -6,7 +6,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Platforms>AnyCPU;x86;x64</Platforms>
<Version>1.2.2302.312</Version>
<Version>1.2.2304.1318</Version>
</PropertyGroup>
<ItemGroup>
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>MAPO-MONO</i>
<h4>Version: 1.2.2302.312</h4>
<h4>Version: 1.2.2304.1318</h4>
<br /> Release Note:
<ul>
<li>
+1 -1
View File
@@ -1 +1 @@
1.2.2302.312
1.2.2304.1318
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>1.2.2302.312</version>
<version>1.2.2304.1318</version>
<url>http://nexus.steamware.net/repository/SWS/MP.MONO.ANALYZER/stable/LAST/MP.Mon.zip</url>
<changelog>http://nexus.steamware.net/repository/SWS/MP.MONO.ANALYZER/stable/LAST/ChangeLog.html</changelog>
<mandatory>false</mandatory>
+6 -1
View File
@@ -51,12 +51,15 @@ namespace MP.MONO.Core
public static readonly string ALARM_RECEIV_KEY = $"{BASE_HASH}:Current:AlarmsReceived";
public static readonly string ALARM_PEND_KEY = $"{BASE_HASH}:Current:AlarmsPendingClose";
public static readonly string EVENT_LOG_CURR_KEY = $"{BASE_HASH}:Current:EventsLog";
public static readonly string MACH_DAY_DUR_CURR_KEY = $"{BASE_HASH}:Current:MachDayDur";
public static readonly string MACH_STATS_CURR_KEY = $"{BASE_HASH}:Current:MachStats";
public static readonly string MAINT_STATS_CURR_KEY = $"{BASE_HASH}:Current:Maintenance";
public static readonly string PARAMS_ACT_KEY = $"{BASE_HASH}:Current:ParamsVal";
public static readonly string PARAMS_CURR_KEY = $"{BASE_HASH}:Current:Params";
public static readonly string PROD_CURR_KEY = $"{BASE_HASH}:Current:Production";
public static readonly string STATUS_ACT_KEY = $"{BASE_HASH}:Current:StatusVal";
public static readonly string STATUS_LAST_KEY = $"{BASE_HASH}:Current:StatusLastVal";
public static readonly string STATUS_PARETO_KEY = $"{BASE_HASH}:Current:StatusPareto";
public static readonly string STATUS_CURR_KEY = $"{BASE_HASH}:Current:Status";
public static readonly string TOOLS_ACT_KEY = $"{BASE_HASH}:Current:ToolsVal";
public static readonly string TOOLS_CURR_KEY = $"{BASE_HASH}:Current:Tools";
@@ -70,12 +73,14 @@ namespace MP.MONO.Core
// REDIS Channels messaggi (verso UI)
public static readonly string ACT_LOG_M_QUEUE = $"ActivityLog";
public static readonly string ALARM_M_QUEUE = $"Alarms";
public static readonly string EVENT_LOG_M_QUEUE = $"EventsLog";
public static readonly string EVENT_LOG_M_QUEUE = $"EventsLog";
public static readonly string MACH_DAY_DUR_M_QUEUE = $"MachDayDur";
public static readonly string MACH_STATS_M_QUEUE = $"MachStats";
public static readonly string MAINT_STATS_M_QUEUE = $"Maintenance";
public static readonly string PARAMS_M_QUEUE = $"Params";
public static readonly string PROD_M_QUEUE = $"Production";
public static readonly string STATUS_M_QUEUE = $"Status";
public static readonly string STATUS_PAR_QUEUE = $"StatusPareto";
public static readonly string COUNT_M_QUEUE = $"Count";
public static readonly string TOOLS_M_QUEUE = $"Tools";
+4
View File
@@ -77,6 +77,10 @@ namespace MP.MONO.Core.DTO
/// </summary>
public string CssIcon { get; set; } = "";
/// <summary>
/// CSS Style
/// </summary>
public string CssClass { get; set; } = "";
/// <summary>
/// Sample period for DB recording of min/Avg/MAX data (seconds)
/// </summary>
public double SamplePeriod { get; set; } = 60 * 3;
+3 -3
View File
@@ -121,8 +121,8 @@ namespace MP.MONO.DECODER
{
// incremento contatore
ticketNum++;
// faccio coda 0...999
ticketNum = ticketNum > 999 ? 1 : ticketNum;
// faccio coda 0...9999
ticketNum = ticketNum > 9999 ? 1 : ticketNum;
// accodo...
reqList.Enqueue(ticketNum);
// rendo ticket
@@ -147,7 +147,7 @@ namespace MP.MONO.DECODER
/// </summary>
/// <param name="ticket"></param>
/// <returns></returns>
public static bool checklTicket(int ticket)
public static bool checkTicket(int ticket)
{
bool fatto = false;
if (!isProcessing)
+137 -97
View File
@@ -1,31 +1,23 @@
using MP.MONO.Core;
using MP.MONO.Core.DTO;
using MP.MONO.Data.DbModels;
using NLog;
using NLog;
using NLua;
using System.Diagnostics;
namespace MP.MONO.DECODER
{
public class CounterManager
{
#region Public Fields
public static string alarmStatus = "";
public static bool valueChanged = false;
#endregion Public Fields
#region Public Constructors
/// <summary>
/// Getione contatori x check variazioni e accumulazione conteggi
/// </summary>
public CounterManager()
{
// preparo variabile x avvisare script che il modo è da NLua
state["callMode"] = "NLua";
state["vcFunct"] = "AVG";
// carico il file
luaPath = Path.Combine(Directory.GetCurrentDirectory(), "lua", "ParamsDecoder.lua");
luaPath = Path.Combine(Directory.GetCurrentDirectory(), "lua", "CountersDecoder.lua");
state.DoFile(luaPath);
Log.Info("CounterManager OK");
@@ -37,120 +29,168 @@ namespace MP.MONO.DECODER
#region Public Methods
/// <summary>
/// Funzione chiamata LUA x calcolo degli eventuali parametri con periodi "scaduti"
/// Funzione chiamata (LUA) x controllo contatori + update in oggetto counter da persistere
/// </summary>
/// <param name="paramsList"></param>
/// <param name="redisParamConf"></param>
/// <returns></returns>
public List<DataLogModel> processData(Dictionary<string, double> paramsList, List<DisplayDataDTO> redisParamConf)
/// <param name="newStatusList">Situazione valori attuale</param>
/// <returns>Dizionario valori da salvare...</returns>
public Dictionary<string, double> processData(Dictionary<string, string> newStatusList)
{
List<DataLogModel> answ = new List<DataLogModel>();
DateTime adesso = DateTime.Now;
// vado ad "accumulare i dati" a quelli presenti...
foreach (var item in paramsList)
double delta = 0;
// accumulo frazioni di minuto solo se ho un dato temporale precedente
if (dtLastCheck != null)
{
var currParam = redisParamConf.FirstOrDefault(x => x.Title == item.Key);
// cerco nelle variabili accomulatori...
if (!ParamsAccumulator.ContainsKey(item.Key))
delta = adesso.Subtract((DateTime)dtLastCheck).TotalMinutes;
}
// preparo esecuzione
bool calcOk = false;
if (lastStatusList != null && lastStatusList.Count > 0)
{
state["delta"] = delta;
// tab dataList
state.NewTable("dataList");
var currTabData = state.GetTable("dataList");
foreach (var item in lastStatusList)
{
if (currParam != null)
{
var dataList = new List<double>();
dataList.Add(item.Value);
VCData newSet = new VCData()
{
dataArray = dataList,
DTStart = adesso,
Funzione = currParam.VcFunc,
Period = currParam.SamplePeriod
};
// se non ci fosse creo
ParamsAccumulator.Add(item.Key, newSet);
}
currTabData[item.Key] = item.Value;
}
else
state["dataList"] = currTabData;
// tab countAcc
state.NewTable("countAcc");
var currTabCount = state.GetTable("countAcc");
foreach (var item in countAccum)
{
// altrimenti aggiungo
ParamsAccumulator[item.Key].dataArray.Add(item.Value);
currTabCount[item.Key] = item.Value;
}
state["countAcc"] = currTabCount;
// call!
try
{
// effettuo calcolo
state.DoString("doProcess()");
}
catch (Exception exc)
{
Log.Error($"exception during doProcess{Environment.NewLine}{exc}");
}
// effettuo verifiche scadenza
bool calcOk = false;
double calcVal = 0;
if (ParamsAccumulator.ContainsKey(item.Key))
// recupero valore calcolato
bool.TryParse(state.GetString("calcOk"), out calcOk);
if (calcOk)
{
if (ParamsAccumulator[item.Key].isElapsed)
try
{
string funcMode = $"{ParamsAccumulator[item.Key].Funzione}";
// se scaduto --> mando a LUA x calcolo
state["valList"] = ParamsAccumulator[item.Key].dataArray;
state["numRec"] = ParamsAccumulator[item.Key].dataArray.Count;
state["vcFunct"] = funcMode;
// effettuo calcolo
state.DoString("doProcess()");
// recupero valore calcolato
bool.TryParse(state.GetString("calcOk"), out calcOk);
if (calcOk)
// leggo nuovi valori accumulati..
var tabAccum = state.GetTable("countAcc");
//var dictAccum = state.GetTableDict(tabAccum);
var dictAccum = state["countAcc"];
// vado a fare upgrade...
string sKey = "";
string sVal = "";
double dVal = 0;
foreach (var item in tabAccum.Keys)
{
try
sKey = $"{item}";
sVal = $"{tabAccum[item]}";
dVal = 0;
double.TryParse(sVal, out dVal);
if (countAccum.ContainsKey(sKey))
{
var stringVal = state.GetString("calcVal");
if (!string.IsNullOrEmpty(stringVal))
{
calcVal = state.GetNumber("calcVal");
Log.Trace($"calcVal: {calcVal}");
}
countAccum[sKey] = dVal;
}
catch (Exception exc)
else
{
Log.Error($"exception during processData for {item.Key}{Environment.NewLine}{exc}");
countAccum.Add(sKey, dVal);
}
}
// trace... stampo counters...
foreach (var cItem in countAccum.OrderBy(x => x.Key))
{
Log.Trace($"COUNTERS | {cItem.Key} | {cItem.Value}");
}
// aggiungo alla lista finale...
var dbRecord = new DataLogModel()
{
DtRif = adesso,
FluxType = item.Key,
MachineId = 1,
ValNum = calcVal,
ValStr = $"{calcVal:N3}"
};
answ.Add(dbRecord);
// elimino dai valori accumulati...
ParamsAccumulator.Remove(item.Key);
}
catch (Exception exc)
{
Log.Error($"exception during LUA processData{Environment.NewLine}{exc}");
}
}
}
return answ;
// salvo lastCheck
dtLastCheck = adesso;
// salvo ultimo stato da merge con precedente...
foreach (var item in newStatusList)
{
if (lastStatusList == null)
{
lastStatusList = new Dictionary<string, string>();
}
if (lastStatusList.ContainsKey(item.Key))
{
lastStatusList[item.Key] = item.Value;
}
else
{
lastStatusList.Add(item.Key, item.Value);
}
}
// ritorno
return countAccum;
}
/// <summary>
/// Resetta l'accumulatore indicato
/// </summary>
/// <param name="accKey"></param>
/// <returns></returns>
public bool resetAccum(string accKey)
{
bool fatto = false;
if (countAccum.ContainsKey(accKey))
{
countAccum[accKey] = 0;
}
return fatto;
}
#endregion Public Methods
#region Protected Fields
protected static Logger Log = LogManager.GetCurrentClassLogger();
protected static string luaPath = "";
protected static Lua state = new Lua();
protected List<string> AlarmList = new List<string>();
#endregion Protected Fields
#region Private Fields
/// <summary>
/// Accumulatore valori counter
/// </summary>
protected static Dictionary<string, double> countAccum = new Dictionary<string, double>();
/// <summary>
/// Dizionario dei valori accumulati sulle variabili
/// Elenco ultimi valori ricevuti x confronto
/// </summary>
private Dictionary<string, VCData> ParamsAccumulator = new Dictionary<string, VCData>();
protected static Dictionary<string, string> lastStatusList = new Dictionary<string, string>();
#endregion Private Fields
/// <summary>
/// Log instance
/// </summary>
protected static Logger Log = LogManager.GetCurrentClassLogger();
/// <summary>
/// Path script LUA
/// </summary>
protected static string luaPath = "";
/// <summary>
/// OBJ state da scambiare
/// </summary>
protected static Lua state = new Lua();
/// <summary>
/// DataOra ultimo check x confronto
/// </summary>
protected DateTime? dtLastCheck = null;
#endregion Protected Fields
}
}
+1 -1
View File
@@ -6,7 +6,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Platforms>AnyCPU;x86;x64</Platforms>
<Version>1.2.2302.312</Version>
<Version>1.2.2304.1318</Version>
</PropertyGroup>
<ItemGroup>
+12 -7
View File
@@ -37,13 +37,18 @@ namespace MP.MONO.DECODER
/// <param name="paramsList"></param>
/// <param name="MachinePlate"></param>
/// <returns></returns>
public bool processData(Dictionary<string, int> paramsList, ref MachineDTO? MachinePlate)
public MachineDTO processData(Dictionary<string, int> paramsList, MachineDTO MachinePlate)
{
bool calcOk = false;
if (MachinePlate == null)
MachineDTO plateOut = new MachineDTO()
{
MachinePlate = new MachineDTO();
}
Manufacturer = MachinePlate.Manufacturer,
ModeId = MachinePlate.ModeId,
Model = MachinePlate.Model,
Name = MachinePlate.Name,
SerNumber = MachinePlate.SerNumber,
StatusId = MachinePlate.StatusId
};
DateTime adesso = DateTime.Now;
state.NewTable("dataList");
@@ -75,12 +80,12 @@ namespace MP.MONO.DECODER
var stringVal = state.GetString("statusId");
if (!string.IsNullOrEmpty(stringVal))
{
MachinePlate.StatusId = state.GetInteger("statusId");
plateOut.StatusId = state.GetInteger("statusId");
}
stringVal = state.GetString("modeId");
if (!string.IsNullOrEmpty(stringVal))
{
MachinePlate.ModeId = state.GetInteger("modeId");
plateOut.ModeId = state.GetInteger("modeId");
}
}
catch (Exception exc)
@@ -91,7 +96,7 @@ namespace MP.MONO.DECODER
else
{ }
return calcOk;
return plateOut;
}
#endregion Public Methods
+1
View File
@@ -52,6 +52,7 @@
-->
<!--<logger name="Microsoft.*" maxlevel="Info" final="true" />-->
<!--<logger name="*" minlevel="Debug" writeTo="consoleTarget" />-->
<logger name="*" minlevel="Info" writeTo="consoleTarget" />
<logger name="*" minlevel="Info" writeTo="fileTarget" />
</rules>
</nlog>
+494 -247
View File
@@ -1,16 +1,19 @@
using Microsoft.Extensions.Configuration;
using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage;
using Microsoft.Extensions.Configuration;
using MP.MONO.Core;
using MP.MONO.Core.CONF;
using MP.MONO.Core.DTO;
using MP.MONO.Data;
using MP.MONO.Data.Controllers;
using MP.MONO.Data.DbModels;
using MP.MONO.Data.DTO;
using MP.MONO.DECODER;
using Newtonsoft.Json;
using NLog;
using Org.BouncyCastle.Asn1.Pkcs;
using Pomelo.EntityFrameworkCore.MySql.Query.Internal;
using StackExchange.Redis;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Reflection;
using static MP.MONO.Core.Enums;
@@ -85,6 +88,7 @@ List<BaseAlarmRawConf>? alarmsRListConf = new List<BaseAlarmRawConf>();
List<AlarmListModel>? alarmsRecorded = new List<AlarmListModel>();
List<MachineMode>? machineModeConf = new List<MachineMode>();
List<MachineStatus>? machineStatusConf = new List<MachineStatus>();
List<CounterModel>? countStatus = new List<CounterModel>();
MachineDTO machinePlate = new MachineDTO();
// gestione configurazioni da redis
@@ -95,6 +99,7 @@ string AlarmCleanPost = "";
int DbSampleInt = 60;
int BlinkPeriodMSec = 1000;
bool AlarmLogActive = false;
int NumDay2Keep = 180;
setupConf();
// datetime dell'inizio esecuzione task... x usare un semaforo di veto doppia esecuzione entro 30 sec
@@ -103,6 +108,20 @@ DateTime lastLogDetail = DateTime.Now.AddHours(-1);
int numSendParam = 1;
int numSendTools = 1;
int numSendMStatus = 1;
Random rand = new Random();
/* ----------------------------------------------------------------
* Setup Thread periodici (es calcolo pareto stati)
* ----------------------------------------------------------------*/
MessagePipe mpStatusParetoSendPipe = new MessagePipe(redisConn, Constants.STATUS_PAR_QUEUE);
MessagePipe mpStatsSendPipe = new MessagePipe(redisConn, Constants.MACH_STATS_M_QUEUE);
MessagePipe mpDayDurSendPipe = new MessagePipe(redisConn, Constants.MACH_DAY_DUR_M_QUEUE);
Thread threadStatus = new Thread(calcParetoStatus);
threadStatus.Start();
Thread threadDbMaint = new Thread(dbMaintenance);
threadDbMaint.Start();
Thread threadPersistCount = new Thread(persistCount);
threadPersistCount.Start();
/* --------------------------------
* Setup Gestione Counters
@@ -111,8 +130,6 @@ CounterManager counterMan = new CounterManager();
// inizializzo gestione messagePipe da Redis x allarmi
MessagePipe counterSendPipe = new MessagePipe(redisConn, Constants.COUNT_M_QUEUE);
MessagePipe counterRecvPipe = new MessagePipe(redisConn, Constants.COUNT_RAW_QUEUE);
// datetime dell'inizio esecuzione task... x usare un semaforo di veto doppia esecuzione entro 30 sec
DateTime lastExecCounters = DateTime.Now.AddHours(-1);
// registro gestione eventi
counterRecvPipe.EA_NewMessage += CounterRecvPipe_EA_NewMessage;
@@ -122,9 +139,12 @@ counterRecvPipe.EA_NewMessage += CounterRecvPipe_EA_NewMessage;
MPStatusManager mpStatusMan = new MPStatusManager();
// inizializzo gestione messagePipe da Redis x allarmi
MessagePipe mpStatusSendPipe = new MessagePipe(redisConn, Constants.STATUS_M_QUEUE);
MessagePipe mpProdSendPipe = new MessagePipe(redisConn, Constants.PROD_M_QUEUE);
MessagePipe mpStatusRecvPipe = new MessagePipe(redisConn, Constants.STATUS_RAW_QUEUE);
// datetime dell'inizio esecuzione task... x usare un semaforo di veto doppia esecuzione entro 30 sec
DateTime lastExecStatus = DateTime.Now.AddHours(-1);
// ultimi parametri stato x check variazione..
Dictionary<string, int> parListLast = new Dictionary<string, int>();
// registro gestione eventi
mpStatusRecvPipe.EA_NewMessage += MpStatusRecvPipe_EA_NewMessage;
@@ -393,6 +413,279 @@ void setupConf()
}
}
/// <summary>
/// Test di uguaglianza tra 2 dizionari...
/// </summary>
bool testEqual(Dictionary<string, string> dict1, Dictionary<string, string> dict2)
{
// se nulli inizializzo...
if (dict1 == null)
{
dict1 = new Dictionary<string, string>();
}
if (dict2 == null)
{
dict2 = new Dictionary<string, string>();
}
// in primis testo num elementi
int num1 = dict1.Count;
int num2 = dict2.Count;
if (num1 != num2)
{
return false;
}
else
{
// comparazione sequenze ordinate...
return dict1.OrderBy(x => x.Key).SequenceEqual(dict2.OrderBy(x => x.Key));
}
}
/// <summary>
/// Ultimo Plate machine salvato
/// </summary>
MachineDTO getLastMachinePlate()
{
MachineDTO? currMPlate = new MachineDTO();
string rawData = redisDb.StringGet(Constants.STATUS_CURR_KEY);
if (string.IsNullOrEmpty(rawData))
{
rawData = redisDb.StringGet(Constants.MACHINE_CONF_PLATE);
}
if (!string.IsNullOrEmpty(rawData))
{
currMPlate = JsonConvert.DeserializeObject<MachineDTO>(rawData);
}
if (currMPlate == null)
{
currMPlate = new MachineDTO();
}
return currMPlate;
}
/// <summary>
/// Ultimo ProdDTO salvato
/// </summary>
ProductionDTO getCurrProdData()
{
ProductionDTO? currProdData = new ProductionDTO();
string rawData = redisDb.StringGet(Constants.PROD_CURR_KEY);
if (!string.IsNullOrEmpty(rawData))
{
currProdData = JsonConvert.DeserializeObject<ProductionDTO>(rawData);
}
if (currProdData == null)
{
currProdData = new ProductionDTO();
}
return currProdData;
}
/// <summary>
/// Stato precedentemente salvato su REDIS x calcolo variazioni
/// </summary>
Dictionary<string, string> getLastStatusVal()
{
Dictionary<string, string> answ = new Dictionary<string, string>();
if (redisDb != null)
{
string rawData = redisDb.StringGet(Constants.STATUS_LAST_KEY);
if (!string.IsNullOrEmpty(rawData))
{
try
{
var rawDict = JsonConvert.DeserializeObject<Dictionary<string, string>>(rawData);
answ = rawDict != null ? rawDict : new Dictionary<string, string>();
}
catch
{ }
}
}
return answ;
}
/// <summary>
/// Salva su redis il set di valori ricevuti
/// </summary>
bool setLastStatusVal(Dictionary<string, string> dataList)
{
bool answ = false;
if (redisDb != null)
{
string rawData = JsonConvert.SerializeObject(dataList);
if (!string.IsNullOrEmpty(rawData))
{
answ = redisDb.StringSet(Constants.STATUS_LAST_KEY, rawData);
}
}
return answ;
}
void calcParetoStatus()
{
// ricalcolo ogni 30" +/- 2sec
int minPeriod = 28000;
int maxPeriod = 32000;
do
{
// periodo riferimento sempre ricalcolato...
DateTime inizio = DateTime.Today;
DateTime fine = DateTime.Today.AddDays(1);
// recupero pareto da DB
var newStatus = dbController.ParetoStatusMach(MachineId, inizio, fine);
// riordino e aggiungo i dati di status...
var statusAllDTO = machineStatusConf
.Select(x => new ParetoStatusDTO()
{
CodStatus = $"MS_{x.MStatusID:000}",
CssClass = x.Css,
Description = x.Description,
Group = x.Group,
Prior = x.Priority
})
.ToList();
// ora ciclo tra i valori trovati...
foreach (var item in newStatus)
{
var recStatus = statusAllDTO.Where(x => x.CodStatus == item.CodStatus).FirstOrDefault();
if (recStatus != null)
{
recStatus.TotDuration = item.TotDuration;
}
}
// salvo i dati insieme alla traduzione degli stati relativa...
var statusActDTO = statusAllDTO
.Where(x => x.TotDuration > 0)
.OrderByDescending(x => x.TotDuration).ToList();
// serializzo e salvo i valori x pareto
string rawData = JsonConvert.SerializeObject(statusActDTO);
mpStatusParetoSendPipe.saveAndSendMessage(Constants.STATUS_PARETO_KEY, rawData);
// calcolo le daily duration e invio
List<DisplayDataDTO> currMDayDurDTO = getMachDayDurDTO(statusAllDTO);
if (currMDayDurDTO.Count > 0)
{
// serializzo e salvo
rawData = JsonConvert.SerializeObject(currMDayDurDTO);
mpDayDurSendPipe.saveAndSendMessage(Constants.MACH_DAY_DUR_CURR_KEY, rawData);
}
// calcolo Current:MachStats (pareto status macchina...)
List<DisplayDataDTO> currMStatDTO = getMachStatDTO(statusActDTO);
if (currMStatDTO.Count > 0)
{
// serializzo e salvo
rawData = JsonConvert.SerializeObject(currMStatDTO);
mpStatsSendPipe.saveAndSendMessage(Constants.MACH_STATS_CURR_KEY, rawData);
}
// attesa random di circa 1 minuti x calcolare...
Thread.Sleep(rand.Next(minPeriod, maxPeriod));
} while (true);
}
void dbMaintenance()
{
// ricalcolo ogni 120 min CIRCA +/- 2%
int msecOra = 1000 * 60 * 120;
int minPeriod = msecOra * 98 / 100;
int maxPeriod = msecOra * 102 / 100;
// leggo conf x giorni da tenere...
int.TryParse(config.GetValue<string>("OptPar:NumDay2Keep"), out NumDay2Keep);
do
{
// effettuo su DB chiamata stored x pulizia dati vecchi
var cleanupResult = dbController.RemoveOldData(NumDay2Keep);
// loggo esito cleanup eseguito
foreach (var item in cleanupResult)
{
Log.Info($"DB Cleanup: {item.CodTask} | {item.Result}");
}
// attesa random da periodo...
Thread.Sleep(rand.Next(minPeriod, maxPeriod));
} while (true);
}
void persistCount()
{
// eseguo ogni 1 min CIRCA +/- 2%
int msecOra = 1000 * 60 * 1;
int minPeriod = msecOra * 98 / 100;
int maxPeriod = msecOra * 102 / 100;
// per prima cosa leggo i counters attuali...
countStatus = dbController.CountersGetAll();
do
{
// salvo su DB valori counters
_ = dbController.CountersUpsertMany(countStatus);
Log.Debug($"Counters: {countStatus.Count} saved");
// attesa random da periodo...
Thread.Sleep(rand.Next(minPeriod, maxPeriod));
} while (true);
}
List<DisplayDataDTO> getMachDayDurDTO(List<ParetoStatusDTO> currStatus)
{
List<DisplayDataDTO> dayDurList = new List<DisplayDataDTO>();
// calcolo in minuti assoluti
int i = 0;
dayDurList = currStatus
.Select(x => new DisplayDataDTO()
{
Order = i++,
Type = "TIME",
Title = $"{x.Group} | {x.Description}",
ValueNum = x.TotDuration,
Value = $"{x.TotDuration:N2}",
DisplFormat = "N0",
MinVal = 0,
MaxVal = 1,
IsNumeric = true,
EnablePlot = true,
ShowBar = true,
HLShow = x.TotDuration > 5,
CssClass = x.CssClass
})
.ToList();
return dayDurList;
}
List<DisplayDataDTO> getMachStatDTO(List<ParetoStatusDTO> currStatus)
{
List<DisplayDataDTO> machStatList = new List<DisplayDataDTO>();
// calcolo come % tempo RUN sul totale...
float globDur = currStatus.Sum(x => x.TotDuration);
int i = 0;
machStatList = currStatus
.Select(x => new DisplayDataDTO()
{
Order = i++,
Type = "PERC",
Title = $"{x.Group} | {x.Description}",
ValueNum = x.TotDuration / globDur,
Value = $"{x.TotDuration / globDur:P1}",
DisplFormat = "P1",
MinVal = 0,
MaxVal = 1,
IsNumeric = true,
EnablePlot = true,
ShowBar = true,
HLShow = x.TotDuration > (globDur * 0.01),
CssClass = x.CssClass
})
.ToList();
return machStatList;
}
/// <summary>
/// Gestione evento ricezione messaggi allarmi secondo tipologia attiva...
/// </summary>
@@ -658,13 +951,13 @@ async void AlarmsValPipe_EA_NewMessage(object? sender, EventArgs e)
{
myTicket = AlarmsBlinkManager.getTicket();
// attendo che NON ci siano altri processi in coda...
while (!AlarmsBlinkManager.checklTicket(myTicket))
while (!AlarmsBlinkManager.checkTicket(myTicket))
{
await Task.Delay(rand.Next(10, 30));
await Task.Delay(rand.Next(100, 130));
if (numTry % 2 == 0)
{
TimeSpan ts = DateTime.Now.Subtract(adesso);
Log.Info($"Ticket {myTicket} | total wait {ts.TotalMilliseconds:N3}ms");
Log.Debug($"Ticket {myTicket} | total wait {ts.TotalMilliseconds:N3}ms");
}
numTry++;
}
@@ -758,6 +1051,8 @@ async void AlarmsValPipe_EA_NewMessage(object? sender, EventArgs e)
{
checkCeasedAlarm(item);
});
//await Task.Run(() => checkCeasedAlarm(item));
//await checkCeasedAlarm(item);
}
// Loggo quanto fatto
Log.Debug($"Chiamato controllo differito per {ceasedAlarms.Count} allarmi cessati");
@@ -767,6 +1062,7 @@ async void AlarmsValPipe_EA_NewMessage(object? sender, EventArgs e)
{
Log.Error($"Eccezione:{Environment.NewLine}{exc}");
}
// tolgo semaforo processing
AlarmsBlinkManager.isProcessing = false;
stopWatch.Stop();
@@ -1070,14 +1366,11 @@ void MpStatusRecvPipe_EA_NewMessage(object? sender, EventArgs e)
*************************************************************************/
// recupero elenco parametri salvati in redis...
MachineDTO? machinePlate = new MachineDTO();
Dictionary<string, int> parList = new Dictionary<string, int>();
// recupero status precedente...
MachineDTO lastMachinePlate = getLastMachinePlate();
MachineDTO nextMachinePlate = new MachineDTO();
string rawData = redisDb.StringGet(Constants.MACHINE_CONF_PLATE);
if (!string.IsNullOrEmpty(rawData))
{
machinePlate = JsonConvert.DeserializeObject<MachineDTO>(rawData);
}
int machStatus = 0;
int procStatus = 0;
int procMode = 0;
@@ -1103,100 +1396,21 @@ void MpStatusRecvPipe_EA_NewMessage(object? sender, EventArgs e)
parList.Add(currKey, procMode);
}
// fix me todo inserire gestione program name!!!
// effettuo verifica valori production e relativo invio
checkProduction(dataList);
// fix me todo inserire gestione program name!!!
Stopwatch sw = new Stopwatch();
sw.Start();
#if false
// calcolo status
if (machStatus == 0)
{
machinePlate.StatusId = 7;
}
else
{
switch (procMode)
{
case 1:
machinePlate.StatusId = 8;
break;
case 2:
machinePlate.StatusId = 2;
break;
case 3:
machinePlate.StatusId = 9;
break;
case 4:
machinePlate.StatusId = 5;
break;
case 5:
machinePlate.StatusId = 10;
break;
case 6:
machinePlate.StatusId = 11;
break;
case 7:
machinePlate.StatusId = 12;
break;
case 8:
machinePlate.StatusId = 13;
break;
default:
break;
}
}
// eseguo cablata la gestione x ora... rispetto a MachineStatus + MachineMode
// invierò un machineDTO
switch (procStatus)
{
case 1:
machinePlate.ModeId = 2;
break;
case 2:
machinePlate.ModeId = 1;
break;
case 3:
machinePlate.ModeId = 3;
break;
case 6:
machinePlate.ModeId = 8;
break;
case 8:
machinePlate.ModeId = 9;
break;
case 11:
machinePlate.ModeId = 10;
break;
default:
break;
}
sw.Stop();
Log.Info($"Calcolo C# | {sw.ElapsedTicks} ticks | {sw.ElapsedMilliseconds} ms | {JsonConvert.SerializeObject(machinePlate)}");
Log.Info("-------------");
#endif
// calcolo con LUA e vedo se cambia...
// calcolo con LUA...
sw.Restart();
bool done = mpStatusMan.processData(parList, ref machinePlate);
nextMachinePlate = mpStatusMan.processData(parList, lastMachinePlate);
sw.Stop();
if (adesso.Subtract(lastLogDetail).TotalSeconds > 5 || numSendMStatus > 10)
{
Log.Info($"Calcolo LUA | {sw.ElapsedTicks} ticks | {sw.ElapsedMilliseconds} ms | {JsonConvert.SerializeObject(machinePlate)} | x {numSendMStatus}");
Log.Info($"Calcolo LUA | {sw.ElapsedTicks} ticks | {sw.ElapsedMilliseconds} ms | {JsonConvert.SerializeObject(nextMachinePlate)} | x {numSendMStatus}");
lastLogDetail = adesso;
numSendMStatus = 0;
}
@@ -1204,9 +1418,144 @@ void MpStatusRecvPipe_EA_NewMessage(object? sender, EventArgs e)
{
numSendMStatus++;
}
#if false
else
{
// calcolo status
if (machStatus == 0)
{
nextMachinePlate.StatusId = 7;
}
else
{
switch (procMode)
{
case 1:
nextMachinePlate.StatusId = 8;
break;
case 2:
nextMachinePlate.StatusId = 2;
break;
case 3:
nextMachinePlate.StatusId = 9;
break;
case 4:
nextMachinePlate.StatusId = 5;
break;
case 5:
nextMachinePlate.StatusId = 10;
break;
case 6:
nextMachinePlate.StatusId = 11;
break;
case 7:
nextMachinePlate.StatusId = 12;
break;
case 8:
nextMachinePlate.StatusId = 13;
break;
default:
break;
}
}
// eseguo cablata la gestione x ora... rispetto a MachineStatus + MachineMode
// invierò un machineDTO
switch (procStatus)
{
case 1:
lastMachinePlate.ModeId = 2;
break;
case 2:
lastMachinePlate.ModeId = 1;
break;
case 3:
lastMachinePlate.ModeId = 3;
break;
case 6:
lastMachinePlate.ModeId = 8;
break;
case 8:
lastMachinePlate.ModeId = 9;
break;
case 11:
lastMachinePlate.ModeId = 10;
break;
default:
break;
}
sw.Stop();
Log.Info($"Calcolo C# | {sw.ElapsedTicks} ticks | {sw.ElapsedMilliseconds} ms | {JsonConvert.SerializeObject(nextMachinePlate)}");
Log.Info("-------------");
}
#endif
// recupero elenco valori...
var lastStatusParams = getLastStatusVal();
// verifico parametri state se modificati da ultimo invio --> salvo su DB
bool isEqual = testEqual(dataList, lastStatusParams);
if (!isEqual)
{
// calcolo differenze e salvo...
var diffVal = dataList.Where(entry => !lastStatusParams.ContainsKey(entry.Key) || lastStatusParams[entry.Key] != entry.Value)
.ToDictionary(entry => entry.Key, entry => entry.Value);
// salvo ultimo blocco valori last status...
setLastStatusVal(dataList);
// salvo i valori modificati...
List<ProdLogModel> newProdRecords = diffVal
.Select(x => new ProdLogModel()
{
DtRif = adesso,
EvType = x.Key,
ValStr = x.Value,
MachineId = MachineId
})
.ToList();
// per ogni valore cerca di effettuare conversione a double...
double testVal = 0;
foreach (var item in newProdRecords)
{
testVal = 0;
double.TryParse(item.ValStr, out testVal);
item.ValNum = testVal;
}
// salvo su DB x log produzione
_ = dbController.ProdLogInsertMany(newProdRecords);
}
// confronto variazioni x "MACHINE STATUS"
if (nextMachinePlate.StatusId != lastMachinePlate.StatusId)
{
//string codStatus = $"MS_{diffVal[keyStatus]:000}";
string codStatus = $"MS_{nextMachinePlate.StatusId:000}";
// chiamo registrazione sul DB dello stato...
var newRecStatus = new StatusLogModel()
{
MachineId = MachineId,
DtRif = adesso,
Duration = 0,
CodStatus = codStatus
};
_ = dbController.StatusLogInsert(newRecStatus);
}
// invio sulla message pipeline corretta TUTTI i parametri aggiornati serializzati
string updRawVal = JsonConvert.SerializeObject(machinePlate);
string updRawVal = JsonConvert.SerializeObject(nextMachinePlate);
mpStatusSendPipe.saveAndSendMessage(Constants.STATUS_CURR_KEY, updRawVal);
}
}
@@ -1217,8 +1566,35 @@ void MpStatusRecvPipe_EA_NewMessage(object? sender, EventArgs e)
}
};
void checkProduction(Dictionary<string, string> dataList)
{
if (dataList.Count > 0)
{
var currProdDTO = getCurrProdData();
string currKey = "RECIPE NAME";
if (dataList.ContainsKey(currKey))
{
currProdDTO.ProgName = dataList[currKey];
}
currKey = "PART COUNT";
if (dataList.ContainsKey(currKey))
{
int numPz = 0;
int.TryParse(dataList[currKey], out numPz);
currProdDTO.CurrQty = numPz;
}
currKey = "CURR ORDER";
if (dataList.ContainsKey(currKey))
{
currProdDTO.Order = dataList[currKey];
}
string rawData = JsonConvert.SerializeObject(currProdDTO);
mpProdSendPipe.saveAndSendMessage(Constants.PROD_CURR_KEY, rawData);
}
}
/// <summary>
/// Gestione evento ricezione messaggi status
/// Gestione evento ricezione messaggi status x conteggi...
/// </summary>
void CounterRecvPipe_EA_NewMessage(object? sender, EventArgs e)
{
@@ -1226,169 +1602,40 @@ void CounterRecvPipe_EA_NewMessage(object? sender, EventArgs e)
// conversione on-the-fly Dictionary<string,int> --> parametri valorizzati (tra quelli configurati)
if (!string.IsNullOrEmpty(currArgs.newMessage))
{
#if false
DateTime adesso = DateTime.Now;
try
{
// verifico codici ricevuti
var dataList = JsonConvert.DeserializeObject<Dictionary<string, string>>(currArgs.newMessage);
//int valInt = 0;
if (dataList != null)
{
/************************************************************************
*
* <BROADCAST_EVENT DESCRIPTION = "MACHINE STATUS" IDENTIFIER = "1" >
* <!--
* DESCRIPTION:
* 0: MACHINE OFF
* 1: MACHINE ON
* -->
*
* <BROADCAST_EVENT DESCRIPTION = "PROC 1 STATUS" IDENTIFIER = "500" >
* <!--
* DESCRIPTION:
* 1: IDLE
* 2: CYCLE (RUN)
* 3: HOLD (HOLD, RUNH, HRUN)
* 6: ERROR
* 8: RESET
* 11: PAUSE (WAIT, INPUT)
* -->
*
* <BROADCAST_EVENT DESCRIPTION = "PROC 1 MODE" IDENTIFIER = "501" >
* <!--
* DESCRIPTION:
* 1: MDI
* 2: AUTO
* 3: STEP (BLK-BLK)
* 4: MANU (MANJOG)
* 5: MANJ (INCJOG)
* 6: RETPROF (PROFILE)
* 7: HOME
* 8: HPG (HANDWHEEL)
* -->
*
*
*************************************************************************/
// recupero elenco parametri salvati in redis...
MachineDTO? machinePlate = new MachineDTO();
string rawData = redisDb.StringGet(Constants.MACHINE_CONF_PLATE);
if (!string.IsNullOrEmpty(rawData))
// chiamo metodo CounterManager... incrementi in MINUTI!!!
var incrSet = counterMan.processData(dataList);
if (incrSet != null)
{
machinePlate = JsonConvert.DeserializeObject<MachineDTO>(rawData);
}
int machStatus = 0;
int procStatus = 0;
int procMode = 0;
string currKey = "";
// ora processo il messaggio ricevuto x stati e modi vari
currKey = "MACHINE STATUS";
if (dataList.ContainsKey(currKey))
{
int.TryParse(dataList[currKey], out machStatus);
}
currKey = "PROCESS STATUS";
if (dataList.ContainsKey(currKey))
{
int.TryParse(dataList[currKey], out procStatus);
}
currKey = "PROCESS MODE";
if (dataList.ContainsKey(currKey))
{
int.TryParse(dataList[currKey], out procMode);
}
// fix me todo inserire gestione program name!!!
if (machStatus == 0)
{
machinePlate.StatusId = 7;
}
else
{
switch (procMode)
foreach (var item in incrSet)
{
case 1:
machinePlate.StatusId = 8;
break;
case 2:
machinePlate.StatusId = 2;
break;
case 3:
machinePlate.StatusId = 9;
break;
case 4:
machinePlate.StatusId = 5;
break;
case 5:
machinePlate.StatusId = 10;
break;
case 6:
machinePlate.StatusId = 11;
break;
case 7:
machinePlate.StatusId = 12;
break;
case 8:
machinePlate.StatusId = 13;
break;
default:
break;
// verifico i valori > soglia 5 minuti...
if (item.Value > 5)
{
// salvo
var countRec = countStatus.Where(x => x.CCode == item.Key || x.CodAlias == item.Key).FirstOrDefault();
if (countRec != null)
{
// attenzione valori in ore, incrementi in minuti!
countRec.ActualVal = Math.Round(countRec.ActualVal + item.Value / 60, 6);
// resetto
counterMan.resetAccum(item.Key);
}
}
}
}
// eseguo cablata la gestione x ora... rispetto a MachineStatus + MachineMode
// invierò un machineDTO
switch (procStatus)
{
case 1:
machinePlate.ModeId = 2;
break;
case 2:
machinePlate.ModeId = 1;
break;
case 3:
machinePlate.ModeId = 3;
break;
case 6:
machinePlate.ModeId = 8;
break;
case 8:
machinePlate.ModeId = 9;
break;
case 11:
machinePlate.ModeId = 10;
break;
default:
break;
}
// invio sulla message pipeline corretta TUTTI i parametri aggiornati serializzati
string updRawVal = JsonConvert.SerializeObject(machinePlate);
paramsSendPipe.saveAndSendMessage(Constants.STATUS_CURR_KEY, updRawVal);
}
}
catch (Exception exc)
{
Log.Error($"Eccezione in MpStatusRecvPipe_EA_NewMessage:{Environment.NewLine}{exc}");
Log.Error($"Eccezione in CounterRecvPipe_EA_NewMessage:{Environment.NewLine}{exc}");
}
#endif
}
}
@@ -13,5 +13,6 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<PublishSingleFile>true</PublishSingleFile>
<PublishReadyToRun>true</PublishReadyToRun>
<OutputType>Exe</OutputType>
</PropertyGroup>
</Project>
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project>
<PropertyGroup>
<Configuration>Debug</Configuration>
<Platform>Any CPU</Platform>
<PublishDir>bin\Debug\net6.0-publish\</PublishDir>
<PublishProtocol>FileSystem</PublishProtocol>
<TargetFramework>net6.0</TargetFramework>
<SelfContained>false</SelfContained>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<PublishSingleFile>true</PublishSingleFile>
<PublishReadyToRun>true</PublishReadyToRun>
</PropertyGroup>
</Project>
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>MAPO-MONO</i>
<h4>Version: 1.2.2302.312</h4>
<h4>Version: 1.2.2304.1318</h4>
<br /> Release Note:
<ul>
<li>
+1 -1
View File
@@ -1 +1 @@
1.2.2302.312
1.2.2304.1318
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>1.2.2302.312</version>
<version>1.2.2304.1318</version>
<url>http://nexus.steamware.net/repository/SWS/MP.MONO.DECODER/stable/LAST/MP.Mon.zip</url>
<changelog>http://nexus.steamware.net/repository/SWS/MP.MONO.DECODER/stable/LAST/ChangeLog.html</changelog>
<mandatory>false</mandatory>
+3 -2
View File
@@ -10,7 +10,7 @@
"Redis": "nkcredis.steamware.net:6379,DefaultDatabase=7,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false,password=BtN9Py1wtLfLRvmzWnOPJ7RytDM+CLiVsJ/16zduNTlV8IOPGNrtzJSXPUnImA5PqmUMhKaUqo9NdHIG",
"AuthConnection": "Server=localhost;port=3306;database=GWMS;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
"DefaultConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
"AdminConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=root;pwd=Egalware_24068!;sslmode=None;",
"AdminConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=root;pwd=Seriate_24068!;sslmode=None;",
"MP.MONO.Data": "Server=localhost;port=3306;database=MAPO.MONO;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;"
},
"DbConfig": {
@@ -42,6 +42,7 @@
//"AlarmRegexp": "^{.*}",
"BlinkCount": 3,
"DbSampleInt": 60,
"BlinkPeriodMSec": 2000
"BlinkPeriodMSec": 3000,
"NumDay2Keep": 365
}
}
+4 -1
View File
@@ -39,6 +39,9 @@
"AlarmMode": "RawList",
"AlarmRegexp": "^{[\\d\\w\\:\\ \\.\\/\\(\\)]*}",
"BlinkCount": 10,
"DbSampleInt": 60
"DbSampleInt": 60,
//"AlarmLogActive": false,
"BlinkPeriodMSec": 3000,
"NumDay2Keep": 365
}
}
+12 -2
View File
@@ -10,7 +10,7 @@
"Redis": "nkcredis.steamware.net:6379,DefaultDatabase=7,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false,password=BtN9Py1wtLfLRvmzWnOPJ7RytDM+CLiVsJ/16zduNTlV8IOPGNrtzJSXPUnImA5PqmUMhKaUqo9NdHIG",
"AuthConnection": "Server=localhost;port=3306;database=GWMS;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
"DefaultConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
"AdminConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=root;pwd=Egalware_24068!;sslmode=None;",
"AdminConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=root;pwd=Seriate_24068!;sslmode=None;",
"MP.MONO.Data": "Server=localhost;port=3306;database=MAPO.MONO;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;"
},
"DbConfig": {
@@ -33,6 +33,16 @@
}
},
"OptPar": {
"AlarmMode": "RawList"
"AlarmLogActive": false,
"AlarmCleanPre": "",
"AlarmCleanPost": "",
"AlarmIgnoreEmpty": true,
"AlarmMode": "RawList",
"AlarmRegexp": "^{[\\d\\w\\:\\ \\.\\/\\(\\)]*}",
//"AlarmRegexp": "^{.*}",
"BlinkCount": 3,
"DbSampleInt": 60,
"BlinkPeriodMSec": 2000,
"NumDay2Keep": 365
}
}
+4 -4
View File
@@ -110,10 +110,10 @@ local function displayTestInfo()
if (callMode ~= 'NLua') then
print('muteMask: ' .. muteMask .. ' | disableMask: ' .. disableMask)
print(alarmStatus)
-- print('------------------------------')
-- for i,val in pairs(alarmListTable) do
-- print("AL"..i.." | "..val)
-- end
print('------------------------------')
for i,val in pairs(alarmListActive) do
print("AL"..i.." | "..val)
end
end
end
+103 -63
View File
@@ -1,13 +1,13 @@
--[[---------------------------------------------------
Procedura calcolo statistiche counters (derivato dai parametri):
Procedura calcolo CONTATORI:
Variabili IN:
- vcFunct(string): tipo di processing da effettuare tra [POINT/AVG/MEDIAN/MIN/MAX]
- valList(<double>): elenco VALORI double da processare
- numRec(int): conteggio numero record da processare
- delta(double): delta-time (minuti)
- dataList(string,string): tab stati (previus)
- countAcc(string,double): tab accumulatori
Variabili OUT:
- calcVal(double): valore calcolato finale
- countAcc(string,double): tab accumulatori
-----------------------------------------------------]]
@@ -18,88 +18,128 @@ if not package.path:find(ZBS,1,true) then
package.cpath = ZBS .. "/bin/?.dll;" .. ZBS .. "/bin/clibs53/?.dll;" .. package.cpath
end
local function addDelta(key, value)
if(value == nil) then
return
end
-- controllo esistenza
if(countAcc[key] ~= nil) then
countAcc[key] = countAcc[key] + value
else
countAcc[key] = value
end
end
local function tablelength(T)
local count = 0
for _ in pairs(T) do count = count + 1 end
return count
end
-- se non è da NLua inizializzo variabili accessorie
local function checkInit()
if (callMode ~= 'NLua') then
-- imposto valori test
valList = { 4467, 4468, 4467, 4467, 4467, 4467 }
numRec = #valList
--valList = { 4.0, 5.0, 3.0, 6.0, 1.0, 2.0 }
vcFunct = 'AVG'
--POINT AVG MEDIAN MIN MAX
-- imposto valore delta
delta = 0.5
-- imposto valori (precedenti allo stato attuale)
dataList = {}
dataList["MACHINE STATUS"] = "1"
dataList["PROCESS STATUS"] = "2"
dataList["SPINDLE 1 LOAD"] = "1"
dataList["SPINDLE 2 LOAD"] = "0"
dataList["SPINDLE 3 LOAD"] = "3"
dataList["SPINDLE 4 LOAD"] = "0"
end
end
local function setupTable()
if numRec > 0 and valList[0] ~= nil then
for i = numRec, 1, -1 do
valListTable[i] = valList[i-1]
end
else
valListTable = valList
end
end
local function doCalc()
if(numRec > 0) then
-- verifica il tipo di richiesta
if(vcFunct == 'AVG') then
s = 0
for i,v in ipairs(valListTable) do
s = s + v
end
calcVal = s / numRec
elseif(vcFunct == 'POINT') then
calcVal = valListTable[numRec]
elseif(vcFunct == 'MEDIAN') then
table.sort(valListTable)
calcVal = valListTable[numRec/2]
elseif(vcFunct == 'MIN') then
table.sort(valListTable)
calcVal = valListTable[1]
elseif(vcFunct == 'MAX') then
table.sort(valListTable)
calcVal = valListTable[numRec]
end
calcOk = true
else
calcVal = -999999
numRec = 1
calcOk = false
end
-- init variabili contatori (just in case)
addDelta("MacPowerOn",0)
addDelta("CycleProc01",0)
addDelta("SpindleTorque01",0)
addDelta("SpindleTorque02",0)
addDelta("SpindleTorque03",0)
addDelta("SpindleTorque04",0)
-- verifico di avere record x processare
numRec = tablelength(dataList)
end
local function displayTestInfo()
if (callMode ~= 'NLua') then
print('------------------------------')
print('calcOk: ' .. tostring(calcOk) .. ' | vcFunct: ' .. vcFunct)
for i,val in pairs(valList) do
print("v_"..i.." | "..val)
print('calcOk: ' .. tostring(calcOk))
print('------------------------------')
print('countAcc:')
print('---------')
for i,val in pairs(countAcc) do
print(""..i.." | "..val)
end
print('calcVal: ' .. calcVal)
print('------------------------------')
end
end
-- Main function: effettua calcolo stato secondo i parametri ricevuti
local function doCalc()
-- se ho dati processo
if(numRec > 0) then
-- se era poweron --> controllo ed eventualmente conto!
if(dataList["MACHINE STATUS"] ~= nil and dataList["MACHINE STATUS"] == "1" ) then
addDelta("MacPowerOn",delta)
-- se era ANCHE AUTO --> conto
if(dataList["PROCESS STATUS"] ~= nil and dataList["PROCESS STATUS"] == "2") then
addDelta("CycleProc01",delta)
end
-- se erano spindle > 0 --> conto
if(dataList["SPINDLE 1 LOAD"] ~= nil and dataList["SPINDLE 1 LOAD"] ~= "0" ) then
addDelta("SpindleTorque01",delta)
end
if(dataList["SPINDLE 2 LOAD"] ~= nil and dataList["SPINDLE 2 LOAD"] ~= "0" ) then
addDelta("SpindleTorque02",delta)
end
if(dataList["SPINDLE 3 LOAD"] ~= nil and dataList["SPINDLE 3 LOAD"] ~= "0" ) then
addDelta("SpindleTorque03",delta)
end
if(dataList["SPINDLE 4 LOAD"] ~= nil and dataList["SPINDLE 4 LOAD"] ~= "0" ) then
addDelta("SpindleTorque04",delta)
end
end
-- salvo calcolo eseguito
calcOk = true
-- altrimenti errore
else
numRec = 1
calcOk = false
end
end
-- MAIN
-- Funct da chiamare da ext
function doProcess()
-- variabile semaforo callMode (locali o remote da NLua)
callMode = callMode or ''
calcVal = -999
vcFunct = vcFunct or ''
valList = valList or {}
numRec = numRec or 1
dataList = dataList or {}
countAcc = countAcc or {}
calcOk = false
valListTable = {}
numRec = 0
--vero task da eseguire
checkInit()
setupTable()
doCalc()
displayTestInfo()
end
-- MAIN
if (callMode ~= 'NLua') then
doProcess()
end
+6 -2
View File
@@ -1,5 +1,5 @@
--[[---------------------------------------------------
Procedura calcolo statistiche parametri:
Procedura calcolo statistiche STATUS:
Variabili IN:
- lastMode
@@ -80,7 +80,7 @@ local function doCalc()
-- calcolo dello statusId
if(dataList["MACHINE STATUS"] == 0) then
statusId = 7
statusId = 1
else
if(dataList["PROCESS MODE"] == 1) then
statusId = 8
@@ -128,9 +128,13 @@ local function displayTestInfo()
if (callMode ~= 'NLua') then
print('------------------------------')
print('calcOk: ' .. tostring(calcOk))
print('------------------------------')
print('dataList:')
print('---------')
for i,val in pairs(dataList) do
print(""..i.." | "..val)
end
print('------------------------------')
print('statusId: ' .. statusId)
print('modeId: ' .. modeId)
print('------------------------------')
+252 -97
View File
@@ -10,12 +10,6 @@ namespace MP.MONO.Data.Controllers
{
public class MpDbController : IDisposable
{
#region Private Fields
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
#endregion Private Fields
#region Public Constructors
public MpDbController()
@@ -510,12 +504,12 @@ namespace MP.MONO.Data.Controllers
stopWatch.Start();
try
{
// verifico non sia già aperto...
// verifico eventuali items già aperti da NON dover aggiungere...
// verifico non sia già aperto... verifico eventuali items già aperti da NON
// dover aggiungere...
var stillOpenAlarms = localDbCtx
.DbSetAlarmRec
.Where(x => x.DtStart >= x.DtEnd && x.AlarmId == newItem.AlarmId)
.Select(x=> x.AlarmId)
.Select(x => x.AlarmId)
.ToList();
// se ho trovato --> salto!
@@ -586,7 +580,7 @@ namespace MP.MONO.Data.Controllers
newItems.Remove(singleItem);
}
}
}
}
#endif
if (newItems.Count > 0)
@@ -618,6 +612,81 @@ namespace MP.MONO.Data.Controllers
return fatto;
}
/// <summary>
/// Recupero counters da DB
/// </summary>
/// <returns></returns>
public List<CounterModel> CountersGetAll()
{
List<CounterModel> dbResult = new List<CounterModel>();
using (MapoMonoContext localDbCtx = new MapoMonoContext())
{
try
{
dbResult = localDbCtx
.DbSetCounter
.AsNoTracking()
.ToList();
}
catch (Exception exc)
{
Log.Error($"Eccezione durante CountersGetAll{Environment.NewLine}{exc}");
}
}
return dbResult;
}
/// <summary>
/// Inserimento/Update di una lista counters
/// </summary>
/// <param name="newItems">Lista Record da inserire</param>
/// <returns></returns>
public bool CountersUpsertMany(List<CounterModel> newItems)
{
bool fatto = false;
using (MapoMonoContext localDbCtx = new MapoMonoContext())
{
try
{
if (newItems.Count > 0)
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
// x ogni valore cerco...
foreach (var item in newItems)
{
var oldRec = localDbCtx
.DbSetCounter
.Where(x => x.CCode == item.CCode)
.FirstOrDefault();
if (oldRec == null)
{
localDbCtx
.DbSetCounter
.Add(item);
}
else
{
oldRec.ActualVal = item.ActualVal;
localDbCtx.Entry(oldRec).State = EntityState.Modified;
}
}
// salvo le modifiche
localDbCtx.SaveChanges();
fatto = true;
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Info($"CountersUpsertMany| DB upsert | {newItems.Count} rec | {ts.TotalMilliseconds} ms");
}
}
catch (Exception exc)
{
Log.Error($"Eccezione durante CountersUpsertMany{Environment.NewLine}{exc}");
}
}
return fatto;
}
/// <summary>
/// Recupero DataLogDTO data condizione filtro
/// </summary>
@@ -798,93 +867,7 @@ namespace MP.MONO.Data.Controllers
// Clear database context
//Log.Info("Dispose di GWMSController");
}
public List<DisplayDataDTO> MachineGetDisplay()
{
List<DisplayDataDTO> answ = new List<DisplayDataDTO>();
// !!!FIXME TODO... è fake...
Random rand = new Random();
double currVal = 0;
currVal = rand.Next(10, 120) * 100;
DisplayDataDTO displ01 = new DisplayDataDTO()
{
Order = 0,
Title = "SPEED",
ValueNum = currVal,
IsNumeric = true,
Value = currVal.ToString("N0"),
Type = "SPEED-5000-10000"
};
answ.Add(displ01);
currVal = rand.Next(10, 100) * 100;
DisplayDataDTO displ02 = new DisplayDataDTO()
{
Order = 0,
Title = "FEED",
ValueNum = currVal,
IsNumeric = true,
Value = currVal.ToString("N0"),
Type = "FEED-3000-5000"
};
answ.Add(displ02);
currVal = rand.NextDouble() * 1.2;
DisplayDataDTO displ03 = new DisplayDataDTO()
{
Order = 0,
Title = "SPINDLE LOAD",
ValueNum = currVal,
IsNumeric = true,
Value = currVal.ToString("P0"),
Type = "ORDER"
};
answ.Add(displ03);
currVal = rand.NextDouble() * 5000;
DisplayDataDTO displ04 = new DisplayDataDTO()
{
Order = 0,
Title = "X POS",
ValueNum = currVal,
IsNumeric = true,
Value = currVal.ToString("N1"),
Type = "POS"
};
answ.Add(displ04);
currVal = rand.NextDouble() * 10000;
DisplayDataDTO displ05 = new DisplayDataDTO()
{
Order = 0,
Title = "Y POS",
ValueNum = currVal,
IsNumeric = true,
Value = currVal.ToString("N1"),
Type = "POS"
};
answ.Add(displ05);
currVal = rand.NextDouble() * -3000;
DisplayDataDTO displ06 = new DisplayDataDTO()
{
Order = 0,
Title = "Z POS",
ValueNum = currVal,
IsNumeric = true,
Value = currVal.ToString("N1"),
Type = "POS"
};
answ.Add(displ06);
Task.Delay(200).Wait();
return answ;
}
public ProductionDTO MachineGetProd()
public ProductionDTO MachineGetProd()
{
// !!!FIXME TODO... è fake...
@@ -907,6 +890,33 @@ namespace MP.MONO.Data.Controllers
return currMachDto;
}
/// <summary>
/// Recupero pareto status impianto
/// </summary>
/// <param name="MachineId">Macchina selezionata</param>
/// <param name="from">inizio periodo</param>
/// <param name="to">fine periodo</param>
/// <returns></returns>
public List<ParetoStatusModel> ParetoStatusMach(int MachineId, DateTime from, DateTime to)
{
List<ParetoStatusModel> dbResult = new List<ParetoStatusModel>();
using (MapoMonoContext localDbCtx = new MapoMonoContext())
{
try
{
dbResult = localDbCtx
.DbSetParetoStatus
.FromSqlRaw<ParetoStatusModel>("CALL stp_paretoStatus({0},{1},{2});", MachineId, from.ToString("yyyy-MM-dd"), to.ToString("yyyy-MM-dd"))
.ToList();
}
catch (Exception exc)
{
Log.Error($"Eccezione durante ParetoStatusMach{Environment.NewLine}{exc}");
}
}
return dbResult;
}
/// <summary>
/// Recupera elenco contatori ammessi
/// </summary>
@@ -1158,6 +1168,57 @@ namespace MP.MONO.Data.Controllers
return fatto;
}
/// <summary>
/// Inserimento di una lista record Production Log
/// </summary>
/// <param name="newItems">Lista Record da inserire (senza ID...)</param>
/// <returns></returns>
public async Task<bool> ProdLogInsertMany(List<ProdLogModel> newItems)
{
bool fatto = false;
using (MapoMonoContext localDbCtx = new MapoMonoContext())
{
try
{
await localDbCtx
.DbSetProdLog
.AddRangeAsync(newItems);
await localDbCtx.SaveChangesAsync();
fatto = true;
}
catch (Exception exc)
{
Log.Error($"Eccezione durante ProdLogInsertMany{Environment.NewLine}{exc}");
}
}
return fatto;
}
/// <summary>
/// Effettua chiamata stored x pulizia dati stale/vecchi
/// </summary>
/// <param name="numDay2Keep"></param>
/// <returns></returns>
public List<TaskExecModel> RemoveOldData(int numDay2Keep)
{
List<TaskExecModel> dbResult = new List<TaskExecModel>();
using (MapoMonoContext localDbCtx = new MapoMonoContext())
{
try
{
dbResult = localDbCtx
.DbSetTaskExec
.FromSqlRaw<TaskExecModel>("CALL stp_removeOldData({0});", numDay2Keep)
.ToList();
}
catch (Exception exc)
{
Log.Error($"Eccezione durante RemoveOldData{Environment.NewLine}{exc}");
}
}
return dbResult;
}
/// <summary>
/// genera elenco Task Schedulati missing da schema + attualmente presenti...
/// </summary>
@@ -1364,6 +1425,100 @@ namespace MP.MONO.Data.Controllers
return answ;
}
/// <summary>
/// Inserisce un nuovo record status log calcolando durata da rec precedente..
/// </summary>
/// <param name="MachineId"></param>
/// <returns></returns>
public async Task<bool> StatusLogInsert(StatusLogModel newRec)
{
bool answ = false;
using (MapoMonoContext localDbCtx = new MapoMonoContext())
{
try
{
bool needInsert = false;
// ultimo inserito...
var lastRec = localDbCtx
.DbSetStatusLog
.Where(x => x.MachineId == newRec.MachineId)
.OrderByDescending(x => x.DtRif)
.FirstOrDefault();
// se non trovato inserisco comunque
if (lastRec == null)
{
needInsert = true;
}
// se trovato controllo variazione...
else
{
// se cambia stato...
if (lastRec.CodStatus != newRec.CodStatus)
{
needInsert = true;
}
// oppure se è passato il giorno...
else if (lastRec.DtRif.Date < newRec.DtRif.Date)
{
needInsert = true;
}
// calcolo durata vecchio record...
lastRec.Duration = (float)DateTime.Now.Subtract(lastRec.DtRif).TotalMinutes;
}
if (needInsert)
{
localDbCtx
.DbSetStatusLog
.Add(newRec);
}
// salvo
localDbCtx.SaveChanges();
answ = true;
}
catch (Exception exc)
{
Log.Error($"Eccezione durante StatusLogInsert{Environment.NewLine}{exc}");
}
}
await Task.Delay(1);
return answ;
}
/// <summary>
/// Registrazione record esecuzione task x log
/// </summary>
/// <param name="recList"></param>
/// <returns></returns>
public bool TaskExecInsertLog(List<TaskExecModel> recList)
{
bool answ = false;
using (MapoMonoContext localDbCtx = new MapoMonoContext())
{
try
{
localDbCtx
.DbSetTaskExec
.AddRange(recList);
localDbCtx.SaveChanges();
answ = true;
}
catch (Exception exc)
{
Log.Error($"Eccezione durante TaskExecInsertLog{Environment.NewLine}{exc}");
}
}
return answ;
}
#endregion Public Methods
#region Private Fields
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
#endregion Private Fields
}
}
+60
View File
@@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.MONO.Data.DTO
{
public class ParetoStatusDTO
{
/// <summary>
/// UID
/// </summary>
[Key]
public string CodStatus { get; set; } = "";
/// <summary>
/// Descrizione Stato
/// </summary>
public string Description { get; set; } = "";
/// <summary>
/// Livello di priorità (vince il maggiore)
/// </summary>
public int Prior { get; set; } = 1;
/// <summary>
/// Classe css associata (default)
/// </summary>
public string CssClass { get; set; } = "";
/// <summary>
/// Classe css associata (override): se non vuota usa questa
/// </summary>
public string CssClassOvr { get; set; } = "";
/// <summary>
/// Gruppo di classificazione (default)
/// </summary>
public string Group { get; set; } = "";
/// <summary>
/// Gruppo di classificazione (override): se non vuoto usa questo
/// </summary>
public string GroupOvr { get; set; } = "";
/// <summary>
/// Indica se mostrare dettaglio item associato
/// </summary>
public bool ShowProdItem { get; set; } = true;
/// <summary>
/// Durata totale stato
/// </summary>
public float TotDuration { get; set; } = 0;
}
}
+3 -7
View File
@@ -1,4 +1,5 @@
using Microsoft.EntityFrameworkCore;
using MP.MONO.Data.DbModels;
namespace MP.MONO.Data
{
@@ -9,7 +10,7 @@ namespace MP.MONO.Data
// Database config
public static int DATABASE_PROCESS_TIMEOUT = 5;
public static string DATABASE_SERV = "127.0.0.1";
public static string DATABASE_NAME = "MAPO.MONO";
public static string DATABASE_NAME = "MAPO_MONO";
public static string DATABASE_USER = "MAPO_MONO_User";
public static string DATABASE_PWD = "viadante16";
@@ -37,6 +38,7 @@ namespace MP.MONO.Data
return DbAdmin.checkCreateUser(DATABASE_USER, DATABASE_PWD);
}
public static bool ExecMigrationIdentity()
{
// esecuzione migrazione
@@ -53,12 +55,6 @@ namespace MP.MONO.Data
return migrateTask.Result;
}
//public DbConfig()
//{
// // stringa admin con utente root egalware...
// CONNECTION_STRING = $"server={DATABASE_SERV};port=3306;database={DATABASE_NAME};uid=root;pwd=Egalware_24068!;sslmode=None";
//}
public static void InitDb(string server, string nKey, string sKey)
{
DATABASE_SERV = server;
+6
View File
@@ -19,6 +19,12 @@ namespace MP.MONO.Data.DbModels
[Key, DatabaseGenerated(DatabaseGeneratedOption.None), MaxLength(250)]
public string CCode { get; set; } = "";
/// <summary>
/// Counter Code Alias
/// </summary>
[MaxLength(250)]
public string CodAlias { get; set; } = "";
/// <summary>
/// Descrizione
/// </summary>
@@ -0,0 +1,30 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.MONO.Data.DbModels
{
/// <summary>
/// Tabella Codifica Stati
/// </summary>
public class ParetoStatusModel
{
#region Public Properties
/// <summary>
/// UID
/// </summary>
[Key]
public string CodStatus { get; set; } = "";
/// <summary>
/// Durata totale stato
/// </summary>
public float TotDuration { get; set; } = 0;
#endregion Public Properties
}
}
+42
View File
@@ -0,0 +1,42 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.MONO.Data.DbModels
{
/// <summary>
/// Vista virtuale x esito esecuzione task (es cleanup tabelle)
/// </summary>
[Table("TaskExec")]
public class TaskExecModel
{
#region Public Properties
/// <summary>
/// ID
/// </summary>
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int TaskID { get; set; }
/// <summary>
/// DataOra evento registrato
/// </summary>
public DateTime DtRif { get; set; } = DateTime.Now;
/// <summary>
/// Cod task eseguito
/// </summary>
public string CodTask { get; set; } = "";
/// <summary>
/// Esito esecuzione registrato
/// </summary>
public string Result { get; set; } = "";
#endregion Public Properties
}
}
+12
View File
@@ -30,4 +30,16 @@
<PackageReference Include="StackExchange.Redis" Version="2.5.61" />
</ItemGroup>
<ItemGroup>
<None Update="SqlScripts\Stored\stp_paretoStatus.sql">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="SqlScripts\Stored\stp_removeOldData.sql">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="SqlScripts\View\v_ParetoStatus.sql">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
+21 -3
View File
@@ -20,7 +20,7 @@ namespace MP.MONO.Data
public MapoMonoContext()
{
//connString = "server=10.74.82.230;port=3306;database=MAPO.MONO;uid=steamware;pwd=Egalware_24068!;sslmode=None;";
//connString = "server=10.74.82.230;port=3306;database=MAPO.MONO;uid=steamware;pwd=Seriate_24068!;sslmode=None;";
}
@@ -112,7 +112,7 @@ namespace MP.MONO.Data
/// DbSet MachineGroup x Prev Maint
/// </summary>
public virtual DbSet<PMMGroupModel> DbSetPMMachGroup { get; set; } = null!;
/// <summary>
/// DbSet Task di Prev Maint definiti
/// </summary>
@@ -123,6 +123,17 @@ namespace MP.MONO.Data
/// </summary>
public virtual DbSet<PendingMaintModel> DbSetSMTask { get; set; } = null!;
/// <summary>
/// DbSet Pareto Status giornaliero
/// </summary>
///
public virtual DbSet<ParetoStatusModel> DbSetParetoStatus { get; set; } = null!;
/// <summary>
/// DbSet esecuzione task manutenzione DB
/// </summary>
public virtual DbSet<TaskExecModel> DbSetTaskExec { get; set; } = null!;
#endregion Public Properties
#region Private Methods
@@ -133,9 +144,9 @@ namespace MP.MONO.Data
#region Protected Methods
protected string connString = "";
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
string connString = "";
// tento setup da config
try
{
@@ -144,6 +155,11 @@ namespace MP.MONO.Data
}
catch
{ }
if (string.IsNullOrEmpty(connString))
{
// to fix in case of migrations
connString = "server=10.74.82.230; port=3306; database=MAPO.MONO;uid=steamware; pwd=Seriate_24068!; sslmode=None;";
}
if (!optionsBuilder.IsConfigured)
{
var serverVersion = ServerVersion.AutoDetect(connString);
@@ -158,6 +174,8 @@ namespace MP.MONO.Data
relationship.DeleteBehavior = DeleteBehavior.Restrict;
}
modelBuilder.Entity<ParetoStatusModel>().ToView("v_ParetoStatus");
//modelBuilder.Entity<ConfigModel>(entity =>
//{
// entity.Property(e => e.ValStd)
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,120 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace MP.MONO.Data.Migrations
{
public partial class UpdateConfStatus : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.UpdateData(
table: "Machine",
keyColumn: "MachineId",
keyValue: 1,
column: "BuildYear",
value: 2023);
migrationBuilder.InsertData(
table: "Status",
columns: new[] { "CodStatus", "CssClass", "CssClassOvr", "Description", "Group", "GroupOvr", "Prior", "ShowProdItem" },
values: new object[,]
{
{ "MS_000", "secondary", "", "UNDEFINED", "Gray", "", 1, true },
{ "MS_001", "secondary", "", "POWEROFF", "Gray", "", 1, true },
{ "MS_002", "success", "", "AUTOMATIC", "Green", "", 1, true },
{ "MS_003", "warning", "", "EDIT", "ManYellow", "", 1, true },
{ "MS_004", "warning", "", "SEMIAUTOMATIC", "ManYellow", "", 1, true },
{ "MS_005", "warning", "", "MANUAL_JOG", "ManYellow", "", 1, true },
{ "MS_006", "danger", "", "ALARM", "StopRed", "", 1, true },
{ "MS_007", "danger", "", "ESTOP", "StopRed", "", 1, true },
{ "MS_008", "warning", "", "MDI", "ManYellow", "", 1, true },
{ "MS_009", "warning", "", "STEP", "ManYellow", "", 1, true },
{ "MS_010", "warning", "", "INC_JOG", "ManYellow", "", 1, true },
{ "MS_011", "warning", "", "PROFILE", "ManYellow", "", 1, true },
{ "MS_012", "warning", "", "HOME", "ManYellow", "", 1, true },
{ "MS_013", "warning", "", "HANDWHEEL", "ManYellow", "", 1, true }
});
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DeleteData(
table: "Status",
keyColumn: "CodStatus",
keyValue: "MS_000");
migrationBuilder.DeleteData(
table: "Status",
keyColumn: "CodStatus",
keyValue: "MS_001");
migrationBuilder.DeleteData(
table: "Status",
keyColumn: "CodStatus",
keyValue: "MS_002");
migrationBuilder.DeleteData(
table: "Status",
keyColumn: "CodStatus",
keyValue: "MS_003");
migrationBuilder.DeleteData(
table: "Status",
keyColumn: "CodStatus",
keyValue: "MS_004");
migrationBuilder.DeleteData(
table: "Status",
keyColumn: "CodStatus",
keyValue: "MS_005");
migrationBuilder.DeleteData(
table: "Status",
keyColumn: "CodStatus",
keyValue: "MS_006");
migrationBuilder.DeleteData(
table: "Status",
keyColumn: "CodStatus",
keyValue: "MS_007");
migrationBuilder.DeleteData(
table: "Status",
keyColumn: "CodStatus",
keyValue: "MS_008");
migrationBuilder.DeleteData(
table: "Status",
keyColumn: "CodStatus",
keyValue: "MS_009");
migrationBuilder.DeleteData(
table: "Status",
keyColumn: "CodStatus",
keyValue: "MS_010");
migrationBuilder.DeleteData(
table: "Status",
keyColumn: "CodStatus",
keyValue: "MS_011");
migrationBuilder.DeleteData(
table: "Status",
keyColumn: "CodStatus",
keyValue: "MS_012");
migrationBuilder.DeleteData(
table: "Status",
keyColumn: "CodStatus",
keyValue: "MS_013");
migrationBuilder.UpdateData(
table: "Machine",
keyColumn: "MachineId",
keyValue: 1,
column: "BuildYear",
value: 2022);
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,72 @@
using System;
using System.Reflection;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace MP.MONO.Data.Migrations
{
public partial class TaskExecTable : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "TaskExec",
columns: table => new
{
TaskID = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
DtRif = table.Column<DateTime>(type: "datetime(6)", nullable: false),
CodTask = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Result = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_TaskExec", x => x.TaskID);
})
.Annotation("MySql:CharSet", "utf8mb4");
// aggiunta view
addView(migrationBuilder, "v_ParetoStatus");
// aggiunta stored
addStored(migrationBuilder, "stp_paretoStatus");
addStored(migrationBuilder, "stp_removeOldData");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "TaskExec");
// rimozione view
remView(migrationBuilder, "v_ParetoStatus");
// rimozione stored
remStored(migrationBuilder, "stp_paretoStatus");
remStored(migrationBuilder, "stp_removeOldData");
}
private void addView(MigrationBuilder migrationBuilder, string objName)
{
string path = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "SqlScripts", "View", $"{objName}.sql");
string viewBody = File.ReadAllText(path);
migrationBuilder.Sql(viewBody);
}
private void addStored(MigrationBuilder migrationBuilder, string objName)
{
string path = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "SqlScripts", "Stored", $"{objName}.sql");
string viewBody = File.ReadAllText(path);
migrationBuilder.Sql(viewBody);
}
private void remView(MigrationBuilder migrationBuilder, string objName)
{
migrationBuilder.Sql($"DROP VIEW IF EXISTS {objName};");
}
private void remStored(MigrationBuilder migrationBuilder, string objName)
{
migrationBuilder.Sql($"DROP PROCEDURE IF EXISTS {objName};");
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,77 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace MP.MONO.Data.Migrations
{
public partial class CounterAlias : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "CodAlias",
table: "Counter",
type: "varchar(250)",
maxLength: 250,
nullable: false,
defaultValue: "")
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.UpdateData(
table: "Counter",
keyColumn: "CCode",
keyValue: "CycleProc01",
column: "CodAlias",
value: "PROCESS STATUS");
migrationBuilder.UpdateData(
table: "Counter",
keyColumn: "CCode",
keyValue: "LMCheckElapsed",
column: "CodAlias",
value: "");
migrationBuilder.UpdateData(
table: "Counter",
keyColumn: "CCode",
keyValue: "MacPowerOn",
column: "CodAlias",
value: "MACHINE STATUS");
migrationBuilder.UpdateData(
table: "Counter",
keyColumn: "CCode",
keyValue: "SpindleTorque01",
column: "CodAlias",
value: "SPINDLE 1 LOAD");
migrationBuilder.UpdateData(
table: "Counter",
keyColumn: "CCode",
keyValue: "SpindleTorque02",
column: "CodAlias",
value: "SPINDLE 2 LOAD");
migrationBuilder.UpdateData(
table: "Counter",
keyColumn: "CCode",
keyValue: "SpindleTorque03",
column: "CodAlias",
value: "SPINDLE 3 LOAD");
migrationBuilder.UpdateData(
table: "Counter",
keyColumn: "CCode",
keyValue: "SpindleTorque04",
column: "CodAlias",
value: "SPINDLE 4 LOAD");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "CodAlias",
table: "Counter");
}
}
}
@@ -157,6 +157,11 @@ namespace MP.MONO.Data.Migrations
b.Property<double>("ActualVal")
.HasColumnType("double");
b.Property<string>("CodAlias")
.IsRequired()
.HasMaxLength(250)
.HasColumnType("varchar(250)");
b.Property<string>("Description")
.IsRequired()
.HasMaxLength(500)
@@ -174,6 +179,7 @@ namespace MP.MONO.Data.Migrations
{
CCode = "MacPowerOn",
ActualVal = 0.0,
CodAlias = "",
Description = "Machine Power On",
LastReset = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)
},
@@ -181,6 +187,7 @@ namespace MP.MONO.Data.Migrations
{
CCode = "CycleProc01",
ActualVal = 0.0,
CodAlias = "",
Description = "Process 1 on Cycle state",
LastReset = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)
},
@@ -188,6 +195,7 @@ namespace MP.MONO.Data.Migrations
{
CCode = "SpindleTorque01",
ActualVal = 0.0,
CodAlias = "",
Description = "Spindle 01 Torque % > 0",
LastReset = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)
},
@@ -195,6 +203,7 @@ namespace MP.MONO.Data.Migrations
{
CCode = "SpindleTorque02",
ActualVal = 0.0,
CodAlias = "",
Description = "Spindle 02 Torque % > 0",
LastReset = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)
},
@@ -202,6 +211,7 @@ namespace MP.MONO.Data.Migrations
{
CCode = "SpindleTorque03",
ActualVal = 0.0,
CodAlias = "",
Description = "Spindle 03 Torque % > 0",
LastReset = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)
},
@@ -209,6 +219,7 @@ namespace MP.MONO.Data.Migrations
{
CCode = "SpindleTorque04",
ActualVal = 0.0,
CodAlias = "",
Description = "Spindle 04 Torque % > 0",
LastReset = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)
},
@@ -216,6 +227,7 @@ namespace MP.MONO.Data.Migrations
{
CCode = "LMCheckElapsed",
ActualVal = 0.0,
CodAlias = "",
Description = "Time Elapsed from last full Manufacturer Check",
LastReset = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)
});
@@ -644,7 +656,7 @@ namespace MP.MONO.Data.Migrations
new
{
MachineId = 1,
BuildYear = 2022,
BuildYear = 2023,
Code = "",
Description = "Default SIM Machine",
Model = "Egalware SIM",
@@ -653,6 +665,19 @@ namespace MP.MONO.Data.Migrations
});
});
modelBuilder.Entity("MP.MONO.Data.DbModels.ParetoStatusModel", b =>
{
b.Property<string>("CodStatus")
.HasColumnType("varchar(255)");
b.Property<float>("TotDuration")
.HasColumnType("float");
b.HasKey("CodStatus");
b.ToView("v_ParetoStatus");
});
modelBuilder.Entity("MP.MONO.Data.DbModels.PendingMaintModel", b =>
{
b.Property<int>("SMTaskId")
@@ -1359,6 +1384,160 @@ namespace MP.MONO.Data.Migrations
GroupOvr = "",
Prior = 1,
ShowProdItem = true
},
new
{
CodStatus = "MS_000",
CssClass = "secondary",
CssClassOvr = "",
Description = "UNDEFINED",
Group = "Gray",
GroupOvr = "",
Prior = 1,
ShowProdItem = true
},
new
{
CodStatus = "MS_001",
CssClass = "secondary",
CssClassOvr = "",
Description = "POWEROFF",
Group = "Gray",
GroupOvr = "",
Prior = 1,
ShowProdItem = true
},
new
{
CodStatus = "MS_002",
CssClass = "success",
CssClassOvr = "",
Description = "AUTOMATIC",
Group = "Green",
GroupOvr = "",
Prior = 1,
ShowProdItem = true
},
new
{
CodStatus = "MS_003",
CssClass = "warning",
CssClassOvr = "",
Description = "EDIT",
Group = "ManYellow",
GroupOvr = "",
Prior = 1,
ShowProdItem = true
},
new
{
CodStatus = "MS_004",
CssClass = "warning",
CssClassOvr = "",
Description = "SEMIAUTOMATIC",
Group = "ManYellow",
GroupOvr = "",
Prior = 1,
ShowProdItem = true
},
new
{
CodStatus = "MS_005",
CssClass = "warning",
CssClassOvr = "",
Description = "MANUAL_JOG",
Group = "ManYellow",
GroupOvr = "",
Prior = 1,
ShowProdItem = true
},
new
{
CodStatus = "MS_006",
CssClass = "danger",
CssClassOvr = "",
Description = "ALARM",
Group = "StopRed",
GroupOvr = "",
Prior = 1,
ShowProdItem = true
},
new
{
CodStatus = "MS_007",
CssClass = "danger",
CssClassOvr = "",
Description = "ESTOP",
Group = "StopRed",
GroupOvr = "",
Prior = 1,
ShowProdItem = true
},
new
{
CodStatus = "MS_008",
CssClass = "warning",
CssClassOvr = "",
Description = "MDI",
Group = "ManYellow",
GroupOvr = "",
Prior = 1,
ShowProdItem = true
},
new
{
CodStatus = "MS_009",
CssClass = "warning",
CssClassOvr = "",
Description = "STEP",
Group = "ManYellow",
GroupOvr = "",
Prior = 1,
ShowProdItem = true
},
new
{
CodStatus = "MS_010",
CssClass = "warning",
CssClassOvr = "",
Description = "INC_JOG",
Group = "ManYellow",
GroupOvr = "",
Prior = 1,
ShowProdItem = true
},
new
{
CodStatus = "MS_011",
CssClass = "warning",
CssClassOvr = "",
Description = "PROFILE",
Group = "ManYellow",
GroupOvr = "",
Prior = 1,
ShowProdItem = true
},
new
{
CodStatus = "MS_012",
CssClass = "warning",
CssClassOvr = "",
Description = "HOME",
Group = "ManYellow",
GroupOvr = "",
Prior = 1,
ShowProdItem = true
},
new
{
CodStatus = "MS_013",
CssClass = "warning",
CssClassOvr = "",
Description = "HANDWHEEL",
Group = "ManYellow",
GroupOvr = "",
Prior = 1,
ShowProdItem = true
});
});
@@ -1395,6 +1574,28 @@ namespace MP.MONO.Data.Migrations
b.ToTable("StatusStAg");
});
modelBuilder.Entity("MP.MONO.Data.DbModels.TaskExecModel", b =>
{
b.Property<int>("TaskID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("CodTask")
.IsRequired()
.HasColumnType("longtext");
b.Property<DateTime>("DtRif")
.HasColumnType("datetime(6)");
b.Property<string>("Result")
.IsRequired()
.HasColumnType("longtext");
b.HasKey("TaskID");
b.ToTable("TaskExec");
});
modelBuilder.Entity("MP.MONO.Data.DbModels.AlarmLogModel", b =>
{
b.HasOne("MP.MONO.Data.DbModels.MachineModel", "MachineNav")
+27 -67
View File
@@ -85,7 +85,7 @@ namespace MP.MONO.Data
, new StatusModel { Prior = 1, CodStatus = "PowerOn", Description = "Power ON", CssClass = "primary", Group = "WaitBlue" }
, new StatusModel { Prior = 1, CodStatus = "TimeoutCycle", Description = "Timeout Std CycleTime", CssClass = "primary", Group = "WaitBlue" }
, new StatusModel { Prior = 1, CodStatus = "Waiting", Description = "Waiting State", CssClass = "primary", Group = "WaitBlue" }
// fermo giallo manuale
, new StatusModel { Prior = 1, CodStatus = "ProgEdit", Description = "Program Editing", CssClass = "warning", Group = "ManYellow" }
, new StatusModel { Prior = 1, CodStatus = "Setup", Description = "Machine Setup", CssClass = "warning", Group = "ManYellow" }
@@ -96,22 +96,39 @@ namespace MP.MONO.Data
// macchina spenta
, new StatusModel { Prior = 1, CodStatus = "PowerOff", Description = "Power OFF", CssClass = "secondary", Group = "Gray" }
// produzione
, new StatusModel { Prior = 1, CodStatus = "Run", Description = "Running", CssClass = "success", Group = "Green" }
, new StatusModel { Prior = 1, CodStatus = "Cycle", Description = "Machining", CssClass = "success", Group = "Green" }
// eventi cablati da status macchina...
, new StatusModel { Prior = 1, CodStatus = "MS_000", Description = "UNDEFINED", CssClass = "secondary", Group = "Gray" }
, new StatusModel { Prior = 1, CodStatus = "MS_001", Description = "POWEROFF", CssClass = "secondary", Group = "Gray" }
, new StatusModel { Prior = 1, CodStatus = "MS_002", Description = "AUTOMATIC", CssClass = "success", Group = "Green" }
, new StatusModel { Prior = 1, CodStatus = "MS_003", Description = "EDIT", CssClass = "warning", Group = "ManYellow" }
, new StatusModel { Prior = 1, CodStatus = "MS_004", Description = "SEMIAUTOMATIC", CssClass = "warning", Group = "ManYellow" }
, new StatusModel { Prior = 1, CodStatus = "MS_005", Description = "MANUAL_JOG", CssClass = "warning", Group = "ManYellow" }
, new StatusModel { Prior = 1, CodStatus = "MS_006", Description = "ALARM", CssClass = "danger", Group = "StopRed" }
, new StatusModel { Prior = 1, CodStatus = "MS_007", Description = "ESTOP", CssClass = "danger", Group = "StopRed" }
, new StatusModel { Prior = 1, CodStatus = "MS_008", Description = "MDI", CssClass = "warning", Group = "ManYellow" }
, new StatusModel { Prior = 1, CodStatus = "MS_009", Description = "STEP", CssClass = "warning", Group = "ManYellow" }
, new StatusModel { Prior = 1, CodStatus = "MS_010", Description = "INC_JOG", CssClass = "warning", Group = "ManYellow" }
, new StatusModel { Prior = 1, CodStatus = "MS_011", Description = "PROFILE", CssClass = "warning", Group = "ManYellow" }
, new StatusModel { Prior = 1, CodStatus = "MS_012", Description = "HOME", CssClass = "warning", Group = "ManYellow" }
, new StatusModel { Prior = 1, CodStatus = "MS_013", Description = "HANDWHEEL", CssClass = "warning", Group = "ManYellow" }
);
// inizializzazione dei valori di default x Tipologia counters
modelBuilder.Entity<CounterModel>().HasData(
new CounterModel { CCode = "MacPowerOn", Description = "Machine Power On" },
new CounterModel { CCode = "CycleProc01", Description = "Process 1 on Cycle state" },
new CounterModel { CCode = "SpindleTorque01", Description = "Spindle 01 Torque % > 0" },
new CounterModel { CCode = "SpindleTorque02", Description = "Spindle 02 Torque % > 0" },
new CounterModel { CCode = "SpindleTorque03", Description = "Spindle 03 Torque % > 0" },
new CounterModel { CCode = "SpindleTorque04", Description = "Spindle 04 Torque % > 0" },
new CounterModel { CCode = "LMCheckElapsed", Description = "Time Elapsed from last full Manufacturer Check" }
new CounterModel { CCode = "MacPowerOn", Description = "Machine Power On", CodAlias = "MACHINE STATUS" },
new CounterModel { CCode = "CycleProc01", Description = "Process 1 on Cycle state", CodAlias = "PROCESS STATUS" },
new CounterModel { CCode = "SpindleTorque01", Description = "Spindle 01 Torque % > 0", CodAlias = "SPINDLE 1 LOAD" },
new CounterModel { CCode = "SpindleTorque02", Description = "Spindle 02 Torque % > 0", CodAlias = "SPINDLE 2 LOAD" },
new CounterModel { CCode = "SpindleTorque03", Description = "Spindle 03 Torque % > 0", CodAlias = "SPINDLE 3 LOAD" },
new CounterModel { CCode = "SpindleTorque04", Description = "Spindle 04 Torque % > 0", CodAlias = "SPINDLE 4 LOAD" },
new CounterModel { CCode = "LMCheckElapsed", Description = "Time Elapsed from last full Manufacturer Check", CodAlias = "Manual Fix" }
);
// inizializzazione dei valori di default x Tipologia UserTeam
@@ -151,63 +168,6 @@ namespace MP.MONO.Data
new PMMGroupModel { PMMGCode = "Access", Description = "Accessories" }
);
#if false
// inizializzazione dei valori di default x USER
modelBuilder.Entity<UserModel>().HasData(
new UserModel { UserId = 1, AuthKey = "th1sIsTh3R1vrOfThNgt98", Livello = UserLevel.SuperAdmin, MaskPlantId = 0, MaskSupplierId = 0, MaskTranspId = 0, UserName = "samuele.locatelli", Email = "samuele@steamware.net", Firstname = "Samuele", Lastname = "Locatelli" },
new UserModel { UserId = 2, AuthKey = "th1sIsTh3R1vrOfThNgt91", Livello = UserLevel.SuperAdmin, MaskPlantId = 0, MaskSupplierId = 0, MaskTranspId = 0, UserName = "giancarlo.rottoli", Email = "giancarlo@steamware.net", Firstname = "Giancarlo", Lastname = "Rottoli" },
new UserModel { UserId = 3, AuthKey = "th1sIsTh3R1vrOfThNgt93", Livello = UserLevel.SuperAdmin, MaskPlantId = 0, MaskSupplierId = 0, MaskTranspId = 0, UserName = "steamw.admin", Email = "info@steamware.net", Firstname = "Steamware", Lastname = "Admin" },
new UserModel { UserId = 4, AuthKey = "th1sIsTh3R1vrOfThNgt97", Livello = UserLevel.Admin, MaskPlantId = 0, MaskSupplierId = 0, MaskTranspId = 0, UserName = "angelo.pizzaferri", Email = "a.pizzaferri@pizzaferripetroli.it", Firstname = "Angelo", Lastname = "Pizzaferri" },
new UserModel { UserId = 5, AuthKey = "th1sIsTh3R1vrOfThNgt99", Livello = UserLevel.Admin, MaskPlantId = 0, MaskSupplierId = 0, MaskTranspId = 0, UserName = "andrei.valeanu", Email = "andrei.valeanu@winnlab.it", Firstname = "Andrei", Lastname = "Valeanu" },
new UserModel { UserId = 6, AuthKey = "th1sIsTh3R1vrOfThNgt92", Livello = UserLevel.UserExt, MaskPlantId = 0, MaskSupplierId = 1, MaskTranspId = 0, UserName = "liquigas.user01", Email = "info@steamware.net", Firstname = "User", Lastname = "LIQUIGAS" },
new UserModel { UserId = 7, AuthKey = "th1sIsTh3R1vrOfThNgt94", Livello = UserLevel.UserExt, MaskPlantId = 0, MaskSupplierId = 2, MaskTranspId = 0, UserName = "vulkangas.user01", Email = "info@steamware.net", Firstname = "User", Lastname = "VULKANGAS" },
new UserModel { UserId = 8, AuthKey = "th1sIsTh3R1vrOfThNgt95", Livello = UserLevel.UserExt, MaskPlantId = 0, MaskSupplierId = 0, MaskTranspId = 1, UserName = "levorato.user01", Email = "info@steamware.net", Firstname = "User", Lastname = "LEVORATO" },
new UserModel { UserId = 9, AuthKey = "th1sIsTh3R1vrOfThNgt96", Livello = UserLevel.UserExt, MaskPlantId = 0, MaskSupplierId = 0, MaskTranspId = 2, UserName = "traffik.user01", Email = "info@steamware.net", Firstname = "User", Lastname = "TRAFFIK" },
new UserModel { UserId = 10, AuthKey = "th1sIsTh3R1vrOfThNgt96", Livello = UserLevel.User, MaskPlantId = 1, MaskSupplierId = 0, MaskTranspId = 0, UserName = "piz03.user01", Email = "info@steamware.net", Firstname = "Stazione", Lastname = "Collecchio" },
new UserModel { UserId = 11, AuthKey = "th1sIsTh3R1vrOfThNgt96", Livello = UserLevel.User, MaskPlantId = 2, MaskSupplierId = 0, MaskTranspId = 0, UserName = "piz04.user01", Email = "info@steamware.net", Firstname = "Stazione", Lastname = "Noceto" },
new UserModel { UserId = 12, AuthKey = "th1sIsTh3R1vrOfThNgt96", Livello = UserLevel.User, MaskPlantId = 3, MaskSupplierId = 0, MaskTranspId = 0, UserName = "piz05.user01", Email = "info@steamware.net", Firstname = "Stazione", Lastname = "Baganzola" },
new UserModel { UserId = 13, AuthKey = "th1sIsTh3R1vrOfThNgt96", Livello = UserLevel.User, MaskPlantId = 4, MaskSupplierId = 0, MaskTranspId = 0, UserName = "piz08.user01", Email = "info@steamware.net", Firstname = "Stazione", Lastname = "Pilastrello" }
);
#endif
#if false
// inizializzazione dei valori di default x Plant
modelBuilder.Entity<PlantDetailModel>().HasData(
new PlantDetailModel { PlantId = 1, PlantCode = "PIZ03", PlantDesc = "Collecchio", LevelMax = 26000, LevelReorder = 15000, OrderQtyStd = 18000 },
new PlantDetailModel { PlantId = 2, PlantCode = "PIZ04", PlantDesc = "Noceto", LevelMax = 28000, LevelReorder = 15000, OrderQtyStd = 18000 },
new PlantDetailModel { PlantId = 3, PlantCode = "PIZ05", PlantDesc = "Baganzola", LevelMax = 24000, LevelReorder = 15000, OrderQtyStd = 18000 },
new PlantDetailModel { PlantId = 4, PlantCode = "PIZ08", PlantDesc = "Pilastrello", LevelMax = 26000, LevelReorder = 15000, OrderQtyStd = 18000 },
new PlantDetailModel { PlantId = 5, PlantCode = "PIZ09", PlantDesc = "Guardamiglio", LevelMax = 26000, LevelReorder = 15000, OrderQtyStd = 18000 }
// new PlantDetailModel { PlantId = 1, PlantCode = "PIZ03", PlantDesc = "Collecchio", LevelMax = 26000, PressMax = 19, PressBHMax = 270, PressBLMax = 270 },
//new PlantDetailModel { PlantId = 2, PlantCode = "PIZ04", PlantDesc = "Noceto", LevelMax = 28000, PressMax = 19, PressBHMax = 270, PressBLMax = 270 },
//new PlantDetailModel { PlantId = 3, PlantCode = "PIZ05", PlantDesc = "Baganzola", LevelMax = 24000, PressMax = 19, PressBHMax = 270, PressBLMax = 270 },
//new PlantDetailModel { PlantId = 4, PlantCode = "PIZ08", PlantDesc = "Pilastrello", LevelMax = 26000, PressMax = 19, PressBHMax = 270, PressBLMax = 270 }
);
#endif
#if false
// inizializzazione dei valori di default x Trasportatori
modelBuilder.Entity<TransporterModel>().HasData(
new TransporterModel { TransporterId = 1, TransporterCode = "LEVO", TransporterDesc = "Levorato" },
new TransporterModel { TransporterId = 2, TransporterCode = "TRAF", TransporterDesc = "Traffik" }
);
#endif
#if false
// init consegne...
modelBuilder.Entity<WeekPlanModel>().HasData(
new WeekPlanModel { WeekPlanId = 1, DayNum = DayOfWeek.Monday, DeliveryHour = 20, Note = "18K", PlantId = 2, SupplierId = 1, TransporterId = 1 },
new WeekPlanModel { WeekPlanId = 2, DayNum = DayOfWeek.Tuesday, DeliveryHour = 20, Note = "18K", PlantId = 2, SupplierId = 1, TransporterId = 1 },
new WeekPlanModel { WeekPlanId = 3, DayNum = DayOfWeek.Wednesday, DeliveryHour = 20, Note = "18K", PlantId = 2, SupplierId = 1, TransporterId = 2 },
new WeekPlanModel { WeekPlanId = 4, DayNum = DayOfWeek.Thursday, DeliveryHour = 15, Note = "9K", PlantId = 2, SupplierId = 1, TransporterId = 1 },
new WeekPlanModel { WeekPlanId = 5, DayNum = DayOfWeek.Thursday, DeliveryHour = 20, Note = "18K", PlantId = 2, SupplierId = 1, TransporterId = 1 },
new WeekPlanModel { WeekPlanId = 6, DayNum = DayOfWeek.Saturday, DeliveryHour = 20, Note = "18K", PlantId = 2, SupplierId = 1, TransporterId = 1 },
new WeekPlanModel { WeekPlanId = 7, DayNum = DayOfWeek.Tuesday, DeliveryHour = 14, Note = "3K", PlantId = 3, SupplierId = 1, TransporterId = 1 },
new WeekPlanModel { WeekPlanId = 8, DayNum = DayOfWeek.Tuesday, DeliveryHour = 15, Note = "15K", PlantId = 4, SupplierId = 1, TransporterId = 1 },
new WeekPlanModel { WeekPlanId = 9, DayNum = DayOfWeek.Tuesday, DeliveryHour = 17, Note = "18K", PlantId = 1, SupplierId = 2, TransporterId = 2 }
);
#endif
}
}
}
@@ -0,0 +1,14 @@
CREATE OR REPLACE PROCEDURE stp_paretoStatus(
IN machine_id INT,
IN dt_from DATETIME,
IN dt_to DATETIME
)
READS SQL DATA
BEGIN
SELECT CodStatus, SUM(Duration) AS TotDuration
FROM StatusLog
WHERE MachineId = machine_id
AND DtRif >= dt_from
AND DtRif <= dt_to
GROUP BY CodStatus;
END;
@@ -0,0 +1,74 @@
CREATE OR REPLACE PROCEDURE stp_removeOldData(
IN day_keep INT
)
READS SQL DATA
BEGIN
SET @adesso = ADDDATE(CURRENT_TIMESTAMP, INTERVAL -1 SECOND);
SET @dt_min = ADDDATE(CURRENT_TIMESTAMP, INTERVAL -day_keep DAY);
START TRANSACTION;
-- AlarmLog
DELETE
FROM AlarmLog
WHERE DtRif <= @dt_min;
INSERT INTO TaskExec(DtRif, CodTask, Result)
SELECT CURRENT_TIMESTAMP AS DtRif
,'Cleanup AlarmLog' AS CodTask
,CONCAT('Deleted ', CAST(ROW_COUNT() AS NCHAR), ' rows') AS Result;
-- AlarmRec
DELETE
FROM AlarmRec
WHERE DtStart <= @dt_min;
INSERT INTO TaskExec(DtRif, CodTask, Result)
SELECT CURRENT_TIMESTAMP AS DtRif
,'Cleanup AlarmRec' AS CodTask
,CONCAT('Deleted ', CAST(ROW_COUNT() AS NCHAR), ' rows') AS Result;
-- DataLog
DELETE
FROM DataLog
WHERE DtRif <= @dt_min;
INSERT INTO TaskExec(DtRif, CodTask, Result)
SELECT CURRENT_TIMESTAMP AS DtRif
,'Cleanup DataLog' AS CodTask
,CONCAT('Deleted ', CAST(ROW_COUNT() AS NCHAR), ' rows') AS Result;
-- ProdLog
DELETE
FROM ProdLog
WHERE DtRif <= @dt_min;
INSERT INTO TaskExec(DtRif, CodTask, Result)
SELECT CURRENT_TIMESTAMP AS DtRif
,'Cleanup ProdLog' AS CodTask
,CONCAT('Deleted ', CAST(ROW_COUNT() AS NCHAR), ' rows') AS Result;
-- StatusLog
DELETE
FROM StatusLog
WHERE DtRif <= @dt_min;
INSERT INTO TaskExec(DtRif, CodTask, Result)
SELECT CURRENT_TIMESTAMP AS DtRif
,'Cleanup StatusLog' AS CodTask
,CONCAT('Deleted ', CAST(ROW_COUNT() AS NCHAR), ' rows') AS Result;
-- TaskExec
DELETE
FROM TaskExec
WHERE DtRif <= @dt_min;
INSERT INTO TaskExec(DtRif, CodTask, Result)
SELECT CURRENT_TIMESTAMP AS DtRif
,'Cleanup TaskExec' AS CodTask
,CONCAT('Deleted ', CAST(ROW_COUNT() AS NCHAR), ' rows') AS Result;
COMMIT;
-- seleziono risultato
SELECT *
FROM TaskExec
WHERE DtRif > @adesso;
END
@@ -0,0 +1,7 @@
-- creazione viste
DROP VIEW IF EXISTS v_ParetoStatus;
CREATE VIEW v_ParetoStatus AS
SELECT CodStatus,SUM(Duration) AS TotDuration
FROM StatusLog
GROUP BY CodStatus;
+1 -1
View File
@@ -6,7 +6,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Platforms>AnyCPU;x86;x64</Platforms>
<Version>1.2.2302.312</Version>
<Version>1.2.2304.1318</Version>
</PropertyGroup>
<ItemGroup>
+26 -78
View File
@@ -80,8 +80,9 @@ Thread threadStatus = new Thread(simMPStatus);
Thread threadCount = new Thread(simCountersRaw);
Thread threadAlarms = new Thread(simAlarms);
Thread threadParams = new Thread(simParameters);
Thread threadProd = new Thread(simProd);
Thread threadMacStats = new Thread(simMacStats);
#if false
Thread threadProd = new Thread(simProd);
#endif
Thread threadMaint = new Thread(simMaint);
Thread threadTools = new Thread(simTools);
Thread threadEvHistory = new Thread(simEvents);
@@ -90,27 +91,14 @@ Thread threadActLog = new Thread(simActivityLog);
threadStatus.Start();
threadAlarms.Start();
threadParams.Start();
threadProd.Start();
#if false
threadProd.Start();
#endif
threadCount.Start();
threadMacStats.Start();
threadMaint.Start();
threadTools.Start();
threadEvHistory.Start();
threadActLog.Start();
#if false
/// <summary>
/// verifica esistenza file oppure lo crea...
/// </summary>
void checkFilePresent(string filePath)
{
// verific presenza file log...
if (!File.Exists(filePath))
{
File.WriteAllText(filePath, $"{filePath} created!");
}
}
#endif
/// <summary>
/// Setup e salvataggio redis delle conf (es modi/stati)
@@ -136,8 +124,6 @@ void setupConf()
alarmMode = config.GetValue<AlarmReportingMode>("OptPar:AlarmMode");
redisDb.StringSetAsync(Constants.ALARMS_MODE_KEY, JsonConvert.SerializeObject(alarmMode));
ConfigManager configManager = new ConfigManager(redisConf, confPath);
if (alarmMode == AlarmReportingMode.RawList)
{
@@ -210,9 +196,12 @@ void saveAndSendMessage(string memKey, string notifyChannel, string message)
}
if (doSave)
{
redisDb.StringSetAsync(memKey, message);
LastKeySave[memKey] = DateTime.Now;
logInfo($"Redis Cache Key: {memKey}");
if (redisDb != null)
{
redisDb.StringSetAsync(memKey, message);
LastKeySave[memKey] = DateTime.Now;
logInfo($"Redis Cache Key: {memKey}");
}
}
// invio notifica tramite il canale richiesto
@@ -300,14 +289,11 @@ void simAlarms()
{
DateTime lastOk = DateTime.Now;
DateTime lastAlarm = DateTime.Now.AddMilliseconds(-1);
#if false
int stdPeriod = 1000;
#endif
/* Modalità simulazione blink...
* - verifico da quanto non ho allarmi
* - se supero soglia minima ok --> simulo allarme o interruzione (alternati)
* - vado in simulazione inizio/fine per le interruzioni (brevi)
* - vado in simulazione inizio/fine per le interruzioni (brevi)
* - vado in simulazione inizio/fine per gli allarmi (che dovranno sparire e tornare ogni 10 sec)
*/
// Dict allarmi attivi (e da quando)
@@ -332,7 +318,8 @@ void simAlarms()
// ciclo x aggiungere il numero di allarmi indicato
for (int i = 0; i < numNew; i++)
{
// seleziono uno degli allarmi del banco.. dando + peso agli "allarmi bassi"
// seleziono uno degli allarmi del banco.. dando + peso agli
// "allarmi bassi"
int alarmIndex = 0;
int msgBlock = rand.Next(1, 5);
switch (msgBlock)
@@ -340,12 +327,15 @@ void simAlarms()
case 1:
alarmIndex = rand.Next(0, alarmGroup.messages.Count / 4);
break;
case 2:
alarmIndex = rand.Next(0, alarmGroup.messages.Count / 2);
break;
case 3:
alarmIndex = rand.Next(0, alarmGroup.messages.Count * 3 / 4);
break;
case 4:
default:
alarmIndex = rand.Next(0, alarmGroup.messages.Count);
@@ -400,8 +390,7 @@ void simAlarms()
sendActiveAlarm(currAlarm);
}
// CICLO 03: aspetto periodo blink...
// CICLO 03: aspetto periodo blink...
Thread.Sleep(rand.Next(800 * perRefresh, 1000 * perRefresh));
// tolgo tutti ed invio
currAlarm = new Dictionary<string, DateTime>();
@@ -472,7 +461,8 @@ void simAlarms()
// verifico situazione allarmi già presenti
foreach (var singleAlarm in CurrActiveAlarm)
{
// 1: seleziono allarmi se ce ne fossero e la loro durata è <= limite * rand (50-200) x rimetterli in elenco
// 1: seleziono allarmi se ce ne fossero e la loro durata è <= limite * rand
// (50-200) x rimetterli in elenco
if (adesso.Subtract(singleAlarm.Value).TotalSeconds < MaxDurationAllarmi * ((double)rand.Next(50, 200) / 100))
{
NewActiveAlarm.Add(singleAlarm.Key, singleAlarm.Value);
@@ -489,7 +479,8 @@ void simAlarms()
// ciclo x aggiungere il numero di allarmi indicato
for (int i = 0; i < numNew; i++)
{
// seleziono uno degli allarmi del banco.. dando + peso agli "allarmi bassi"
// seleziono uno degli allarmi del banco.. dando + peso agli
// "allarmi bassi"
int alarmIndex = 0;
int msgBlock = rand.Next(1, 5);
switch (msgBlock)
@@ -497,12 +488,15 @@ void simAlarms()
case 1:
alarmIndex = rand.Next(0, alarmGroup.messages.Count / 4);
break;
case 2:
alarmIndex = rand.Next(0, alarmGroup.messages.Count / 2);
break;
case 3:
alarmIndex = rand.Next(0, alarmGroup.messages.Count * 3 / 4);
break;
case 4:
default:
alarmIndex = rand.Next(0, alarmGroup.messages.Count);
@@ -620,56 +614,11 @@ void simCountersRaw()
}
}
void simProd()
{
int minPeriod = 3000;
int maxPeriod = 10000;
// controllo se devo fare (se ho valori da simulare...)
if (currSimGen.currSimProd.Count > 0)
{
do
{
// recupero uno stato simulato
var newStatus = currSimGen.getProd();
string rawData = JsonConvert.SerializeObject(newStatus);
saveAndSendMessage(Constants.PROD_CURR_KEY, Constants.PROD_M_QUEUE, rawData);
// attesa random
Thread.Sleep(rand.Next(minPeriod, maxPeriod));
} while (true);
}
}
void simMacStats()
{
int minPeriod = 3000;
int maxPeriod = 5000;
// controllo se devo fare (se ho valori da simulare...)
if (currSimGen.currSimMachStat.Count > 0)
{
do
{
// recupero uno stato simulato
var newVal = currSimGen.getMacStats();
string rawData = JsonConvert.SerializeObject(newVal);
saveAndSendMessage(Constants.MACH_STATS_CURR_KEY, Constants.MACH_STATS_M_QUEUE, rawData);
// attesa random
Thread.Sleep(rand.Next(minPeriod, maxPeriod));
} while (true);
}
}
void simMaint()
{
int minPeriod = 10000;
int maxPeriod = 20000;
// controllo se devo fare (se ho valori da simulare...)
if (currSimGen.currSimMaint.Count > 0)
{
@@ -691,7 +640,6 @@ void simTools()
int minPeriod = 30000;
int maxPeriod = 120000;
// controllo se devo fare (se ho valori da simulare...)
if (currSimGen.currSimTools.Count > 0)
{
@@ -8,6 +8,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
<Platform>Any CPU</Platform>
<PublishDir>bin\Release\net6.0\publish\win-x64\</PublishDir>
<PublishProtocol>FileSystem</PublishProtocol>
<_TargetId>Folder</_TargetId>
<TargetFramework>net6.0</TargetFramework>
<SelfContained>false</SelfContained>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project>
<PropertyGroup>
<Configuration>Release</Configuration>
<Platform>Any CPU</Platform>
<PublishDir>bin\Release\net6.0-publish\</PublishDir>
<PublishProtocol>FileSystem</PublishProtocol>
<_TargetId>Folder</_TargetId>
<TargetFramework>net6.0</TargetFramework>
<SelfContained>false</SelfContained>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<PublishSingleFile>true</PublishSingleFile>
<PublishReadyToRun>true</PublishReadyToRun>
</PropertyGroup>
</Project>
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>MAPO-MONO</i>
<h4>Version: 1.2.2302.312</h4>
<h4>Version: 1.2.2304.1318</h4>
<br /> Release Note:
<ul>
<li>
+1 -1
View File
@@ -1 +1 @@
1.2.2302.312
1.2.2304.1318
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>1.2.2302.312</version>
<version>1.2.2304.1318</version>
<url>http://nexus.steamware.net/repository/SWS/MP.MONO.SIM/stable/LAST/MP.Mon.zip</url>
<changelog>http://nexus.steamware.net/repository/SWS/MP.MONO.SIM/stable/LAST/ChangeLog.html</changelog>
<mandatory>false</mandatory>
+112 -117
View File
@@ -26,7 +26,7 @@ namespace MachineSim
#region Public Constructors
public Simulator(string _confPath, int nMode, int nStatus, IDatabase? currRedisDb, IConfigurationRoot currAppConf)
public Simulator(string _confPath, int nMode, int nStatus, IDatabase currRedisDb, IConfigurationRoot currAppConf)
{
confPath = _confPath;
numMode = nMode;
@@ -91,8 +91,8 @@ namespace MachineSim
{
Dictionary<string, string> answ = new Dictionary<string, string>();
// simulo stato macchina ad 1 nel 99.5% (0 nel 0.5% dei casi
if (rand.Next(0, 1000) < 995)
// simulo stato macchina ad 1 nel 99% (0 nel 1% dei casi
if (rand.Next(0, 1000) < 990)
{
answ.Add("MACHINE STATUS", "1");
}
@@ -275,123 +275,92 @@ namespace MachineSim
return currMachDto;
}
#if false
public List<DisplayDataDTO> getProdStats()
{
List<DisplayDataDTO> answ = new List<DisplayDataDTO>();
// genero a partire dall'elenco configurato da simulare...
answ = currSimMachStat.Select(i => new DisplayDataDTO()
{
IsNumeric = i.IsNumeric,
MaxVal = i.MaxVal,
MinVal = i.MinVal,
Order = i.Order,
Title = i.Title,
Type = i.Type,
ValueNum = simNext(i.ValueNum, i.MinVal, i.MaxVal, i.SimMean, i.SimStd),
DisplFormat = i.DisplFormat
//Value = $"{getNext(i.ValueNum, i.MinVal, i.MaxVal, i.SimMean, i.SimStd):N3}",
}).ToList();
foreach (var item in answ)
{
item.Value = $"{item.ValueNum.ToString(item.DisplFormat)}";
}
return answ;
}
#endif
/// <summary>
/// Discretizza valore sim pallet tra 0..1..2 dati valori limite
/// </summary>
/// <param name="simVal"></param>
/// <param name="lim_1"></param>
/// <param name="lim_2"></param>
/// <returns></returns>
protected int discretizePalletVal(int simVal, int lim_1, int lim_2)
{
int answ = 0;
if (simVal <= lim_1)
{
answ = 0;
}
else if (simVal <= (lim_1 + lim_2))
{
answ = 1;
}
else
{
answ = 2;
}
return answ;
}
/// <summary>
/// Restituisce elenco info stato Macchina simulato come lista da adapter
/// </summary>
/// <returns></returns>
public Dictionary<string, string> getStatus()
{
DateTime adesso = DateTime.Now;
Dictionary<string, string> answ = new Dictionary<string, string>();
// simulo stato macchina ad 1 nel 99.5% (0 nel 0.5% dei casi)
if (rand.Next(0, 1000) < 995)
// dalle 22 alle 6 --> machine OFF
if (adesso.Hour < 6 || adesso.Hour >= 22)
{
answ.Add("MACHINE STATUS", "1");
answ.Add("MACHINE STATUS", "0");
answ.Add("PART COUNT", "0");
answ.Add("RECIPE NAME", "none");
answ.Add("CURR ORDER", "NA");
answ.Add("PROCESS STATUS", "1");
answ.Add("PROCESS MODE", "1");
answ.Add("P2 PALLET STATUS", "0");
answ.Add("P3 PALLET STATUS", "0");
answ.Add("P2 EXTERNAL PALLET STATUS", "0");
answ.Add("P3 EXTERNAL PALLET STATUS", "0");
}
else
{
answ.Add("MACHINE STATUS", "0");
}
// part count sono i minuti del giorno...
int simCount = (int)DateTime.Now.Subtract(DateTime.Today).TotalMinutes;
answ.Add("PART COUNT", $"{simCount}");
// simulo stato processo in ciclo 90% dei casi, resto HOLD
if (rand.Next(0, 1000) < 900)
{
answ.Add("PROCESS STATUS", "2");
// simulo modo auto 90% dei casi
if (rand.Next(0, 1000) < 900)
// simulo stato macchina ad 1 nel 99% (0 nel 1% dei casi)
if (rand.Next(0, 1000) < 990)
{
answ.Add("PROCESS MODE", "2");
answ.Add("MACHINE STATUS", "1");
}
else
{
answ.Add("PROCESS MODE", "1");
answ.Add("MACHINE STATUS", "0");
}
// part count sono i minuti del giorno...
int simCount = (int)adesso.Subtract(DateTime.Today).TotalMinutes;
answ.Add("PART COUNT", $"{simCount}");
// simulo stato processo in ciclo 90% dei casi, resto HOLD
if (rand.Next(0, 1000) < 900)
{
answ.Add("PROCESS STATUS", "2");
// simulo modo auto 85% dei casi
if (rand.Next(0, 1000) < 850)
{
answ.Add("PROCESS MODE", "2");
}
else
{
answ.Add("PROCESS MODE", "1");
}
}
else
{
answ.Add("PROCESS STATUS", "3");
answ.Add("PROCESS MODE", "7");
}
// simulo status pallets...
// Primo: 8% assente = 0, 90% presente=1, restante 2% error/hold=2
int pVal = discretizePalletVal(rand.Next(0, 1000), 80, 900);
answ.Add("P2 PALLET STATUS", $"{pVal}");
// secondo: 7% assente = 0, 91% presente=1, restante 2% error/hold=2
pVal = discretizePalletVal(rand.Next(0, 1000), 70, 910);
answ.Add("P3 PALLET STATUS", $"{pVal}");
// terzo: 6% assente = 0, 91% presente=1, restante 3% error/hold=2
pVal = discretizePalletVal(rand.Next(0, 1000), 60, 910);
answ.Add("P2 EXTERNAL PALLET STATUS", $"{pVal}");
// quarto: 8% assente = 0, 89% presente=1, restante 3% error/hold=2
pVal = discretizePalletVal(rand.Next(0, 1000), 80, 890);
answ.Add("P3 EXTERNAL PALLET STATUS", $"{pVal}");
// aggiunta part program che cambia ogni 10 minuti...
int minRound = (adesso.Minute / 10) * 10;
answ.Add("RECIPE NAME", $"{adesso:yyMMdd-HH}{minRound:00}.prg");
// aggiunta ordine... orario
answ.Add("CURR ORDER", $"ODL000{adesso:MMddHH}");
}
else
{
answ.Add("PROCESS STATUS", "3");
answ.Add("PROCESS MODE", "7");
}
// simulo status pallets...
// Primo: 8% assente = 0, 90% presente=1, restante 2% error/hold=2
int pVal = discretizePalletVal(rand.Next(0, 1000), 80, 900);
answ.Add("P2 PALLET STATUS", $"{pVal}");
// secondo: 7% assente = 0, 91% presente=1, restante 2% error/hold=2
pVal = discretizePalletVal(rand.Next(0, 1000), 70, 910);
answ.Add("P3 PALLET STATUS", $"{pVal}");
// terzo: 6% assente = 0, 91% presente=1, restante 3% error/hold=2
pVal = discretizePalletVal(rand.Next(0, 1000), 60, 910);
answ.Add("P2 EXTERNAL PALLET STATUS", $"{pVal}");
// quarto: 8% assente = 0, 89% presente=1, restante 3% error/hold=2
pVal = discretizePalletVal(rand.Next(0, 1000), 80, 890);
answ.Add("P3 EXTERNAL PALLET STATUS", $"{pVal}");
// aggiunta part program che cambia ogni minuto...
answ.Add("RECIPE NAME", $"{DateTime.Now:yyMMdd-HHmm}.prg");
return answ;
}
/// <summary>
/// Simulo dati in formato DTO (già finale)
/// </summary>
@@ -431,6 +400,7 @@ namespace MachineSim
return answ;
}
/// <summary>
/// Mostro un valore in formato chiave/valore (stringa/double)
/// </summary>
@@ -445,27 +415,17 @@ namespace MachineSim
return answ;
}
/// <summary>
/// Calcola prox valore simulato dati i parametri rand configurati, con innovazione
/// stocastica + deterministica:
/// <summary> Calcola prox valore simulato dati i parametri rand configurati, con
/// innovazione stocastica + deterministica:
/// - ciclo ogni 4 minuti - con operazione modulo (4)
/// * 0 fermo
/// * 1 --&gt; sale
/// * 2 fermo
/// * 3 --&gt; scende
/// </summary>
/// <param name="CurrVal"></param>
/// <param name="MinVal"></param>
/// <param name="MaxVal"></param>
/// <param name="sMean"></param>
/// <param name="sStd"></param>
/// <param name="simMode">Modalità simulazione (1-3)
/// 1 = std, RandomWalk + trend periodico con memoria
/// 2 = boolean
/// 3 = trend secondo valore mean (crescente se >0, decrescente se <0)
/// </param>
/// <param name="trueRatio"></param>
/// <returns></returns>
/// * 3 --&gt; scende </summary> <param name="CurrVal"></param> <param
/// name="MinVal"></param> <param name="MaxVal"></param> <param name="sMean"></param> <param
/// name="sStd"></param> <param name="simMode">Modalità simulazione (1-3) 1 = std,
/// RandomWalk + trend periodico con memoria 2 = boolean 3 = trend secondo valore mean
/// (crescente se >0, decrescente se <0) </param> <param name="trueRatio"></param> <returns></returns>
public double simNext(double CurrVal, double MinVal, double MaxVal, double sMean, double sStd, int simMode = 1, double trueRatio = 0.5)
{
double innov = 0;
@@ -476,6 +436,7 @@ namespace MachineSim
case 2:
CurrVal = rand.Next(10000) <= trueRatio * 10000 ? 1 : 0;
break;
case 3:
innov = Normal.Sample(sMean, sStd);
trend = rand.NextDouble() * 2 * sMean;
@@ -490,6 +451,7 @@ namespace MachineSim
CurrVal = CurrVal > MaxVal ? MinVal : CurrVal;
CurrVal = CurrVal < MinVal ? MaxVal : CurrVal;
break;
case 1:
default:
// innovazione stocastica di base
@@ -529,6 +491,7 @@ namespace MachineSim
#region Protected Fields
protected string confPath = "";
protected Random rand = new Random();
#endregion Protected Fields
@@ -536,12 +499,44 @@ namespace MachineSim
#region Protected Properties
protected IConfigurationRoot appConf { get; set; } = null!;
protected int numMode { get; set; } = 1;
protected int numStatus { get; set; } = 1;
protected IDatabase redisDb { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
/// <summary>
/// Discretizza valore sim pallet tra 0..1..2 dati valori limite
/// </summary>
/// <param name="simVal"></param>
/// <param name="lim_1"></param>
/// <param name="lim_2"></param>
/// <returns></returns>
protected int discretizePalletVal(int simVal, int lim_1, int lim_2)
{
int answ = 0;
if (simVal <= lim_1)
{
answ = 0;
}
else if (simVal <= (lim_1 + lim_2))
{
answ = 1;
}
else
{
answ = 2;
}
return answ;
}
#endregion Protected Methods
#region Private Methods
private void setupConfDTO(string paramFileName, ref List<SimDisplayDataDTO> localObj)
+1 -1
View File
@@ -10,7 +10,7 @@
"Redis": "nkcredis.steamware.net:6379,DefaultDatabase=7,connectTimeout=30000,syncTimeout=30000,asyncTimeout=30000,abortConnect=false,ssl=false,password=BtN9Py1wtLfLRvmzWnOPJ7RytDM+CLiVsJ/16zduNTlV8IOPGNrtzJSXPUnImA5PqmUMhKaUqo9NdHIG",
"AuthConnection": "Server=localhost;port=3306;database=GWMS;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
"DefaultConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
"AdminConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=root;pwd=Egalware_24068!;sslmode=None;",
"AdminConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=root;pwd=Seriate_24068!;sslmode=None;",
"MP.MONO.Data": "Server=localhost;port=3306;database=MAPO.MONO;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;"
},
"DbConfig": {
+13 -1
View File
@@ -45,7 +45,7 @@
"MinVal": 0,
"MaxVal": 10,
"DisplFormat": "N0",
"IsNumeric": true
"IsNumeric": false
},
{
"Order": 5,
@@ -94,5 +94,17 @@
"MaxVal": 10,
"DisplFormat": "N0",
"IsNumeric": true
},
{
"Order": 9,
"ExtCode": "ns=1;s=504_PROC 1 P.P. ORDER",
"Type": "ORDER",
"Title": "CURR ORDER",
"Value": "",
"ValueNum": 0,
"MinVal": 0,
"MaxVal": 10,
"DisplFormat": "N0",
"IsNumeric": false
}
]
+1
View File
@@ -4,6 +4,7 @@
"PROCESS STATUS",
"PROCESS MODE",
"RECIPE NAME",
"CURR ORDER",
"P2 PALLET STATUS",
"P3 PALLET STATUS",
"P2 EXTERNAL PALLET STATUS",
@@ -112,7 +112,7 @@ namespace MP.MONO.UI.Components
}).ToList();
messageReceived.InvokeAsync(alarmList.Count);
}
if (ListRecords.Count != 0 || ListRecords == null)
if (ListRecords == null || ListRecords.Count != 0)
{
compMode = false;
trigger.show = false;
@@ -130,6 +130,12 @@ namespace MP.MONO.UI.Components
{
StateHasChanged();
});
if (ListRecords == null)
{
ListRecords = new List<DisplayDataDTO>();
}
numAlarm = ListRecords.Count;
-6
View File
@@ -7,9 +7,3 @@
</div>
</div>
@code {
protected DateTime adesso = DateTime.Now;
Version version = typeof(Program).Assembly.GetName().Version;
}
+26
View File
@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using System.Net.Http;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Components.Routing;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.Web.Virtualization;
using Microsoft.JSInterop;
using MP.MONO.UI;
using MP.MONO.UI.Shared;
using MP.MONO.UI.Components;
using EgwCoreLib.Razor;
namespace MP.MONO.UI.Components
{
public partial class CmpFooter
{
protected DateTime adesso = DateTime.Now;
Version? version = typeof(Program).Assembly.GetName().Version;
}
}
@@ -22,7 +22,7 @@ namespace MP.MONO.UI.Components
string answ = "width: 0%;";
double den = (maxVal - minVal) != 0 ? (maxVal - minVal) : 1;
double ratio = ((double)num) / den;
answ = $"width: {ratio:P0};";
answ = $"width: {ratio:P0};";
return answ;
}
protected string cssLast(string toolName)
@@ -31,7 +31,8 @@ namespace MP.MONO.UI.Components
// se è ultima testo giallo...
if (SelVal != null && SelVal.Count > 0)
{
if (SelVal.LastOrDefault().Equals(toolName))
var ultimo = SelVal.LastOrDefault();
if (ultimo != null && ultimo.Equals(toolName))
{
answ = "bg-dark text-warning";
}
+6 -6
View File
@@ -9,10 +9,10 @@ namespace MP.MONO.UI.Components
{
#region Private Fields
private List<CounterModel> ListCounters;
private List<PMTaskTopicModel> ListTopics;
private List<PMMGroupModel> ListMachGroup;
private List<PMUTModel> ListUserTeam;
private List<CounterModel>? ListCounters { get; set; } = null;
private List<PMTaskTopicModel>? ListTopics { get; set; } = null;
private List<PMMGroupModel>? ListMachGroup { get; set; } = null;
private List<PMUTModel>? ListUserTeam { get; set; } = null;
#endregion Private Fields
@@ -108,8 +108,8 @@ namespace MP.MONO.UI.Components
{
Console.WriteLine("Record null!");
}
// delay x display
await DataUpdated.InvokeAsync(0);
// delay x display
await DataUpdated.InvokeAsync(0);
}
#endregion Private Methods
+33 -2
View File
@@ -11,10 +11,41 @@
{
<li class="list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-between" title="order">
<div>@item.Title</div>
<div>
<h5> <b>@item.Value</b></h5>
@if (!string.IsNullOrEmpty(item.CssIcon))
{
<div class="d-flex flex-column">
<div class="small"><b>@item.Title</b></div>
</div>
}
else
{
<div>@item.Title</div>
}
</div>
<div class="float-end">
<div class="d-flex flex-column">
<div class="d-flex flex-row-reverse">
<div>
<span class="@item.CssIcon"></span>
</div>
&nbsp;
<div>
<span class="float-end"><b>@item.Value</b></span>
</div>
</div>
</div>
</div>
</div>
<div class="d-flex">
@if (item.ShowBar)
{
<div class="w-100">
<div class="progress" style="height: 0.3rem;">
<div class="progress-bar @cssBar(item.CssClass)" role="progressbar" style="@percProgress(item.ValueNum, item.MinVal, item.MaxVal)" aria-valuenow="@item.ValueNum" aria-valuemin="@item.MinVal" aria-valuemax="@item.MaxVal"></div>
</div>
</div>
}
</div>
</li>
}
@@ -1,3 +1,4 @@
using Microsoft.AspNetCore.Components;
using MP.MONO.Core.DTO;
using MP.MONO.Data;
using Newtonsoft.Json;
@@ -6,6 +7,9 @@ namespace MP.MONO.UI.Components
{
public partial class MachStatsOverview : IDisposable
{
[Parameter]
public bool ShowAll { get; set; } = false;
#region Public Methods
public void Dispose()
@@ -17,15 +21,30 @@ namespace MP.MONO.UI.Components
#region Protected Methods
protected string cssBar(string cssClass)
{
return cssClass;
}
protected override async Task OnInitializedAsync()
{
await ReloadData();
MMDataService.machStatsPipe.EA_NewMessage += MachStatsPipe_EA_NewMessage;
}
protected string percProgress(double num, double minVal, double maxVal)
{
string answ = "width: 0%;";
double den = (maxVal - minVal) != 0 ? (maxVal - minVal) : 1;
double ratio = ((double)num) / den;
answ = $"width: {ratio:P0};";
return answ;
}
protected async Task ReloadData()
{
ListRecords = await MMDataService.getStats();
var rawData = await MMDataService.getStats();
ListRecords = rawData.Where(x => x.HLShow || ShowAll).ToList();
}
#endregion Protected Methods
@@ -45,7 +64,11 @@ namespace MP.MONO.UI.Components
{
try
{
ListRecords = JsonConvert.DeserializeObject<List<DisplayDataDTO>>(currArgs.newMessage);
var rawData = JsonConvert.DeserializeObject<List<DisplayDataDTO>>(currArgs.newMessage);
if (rawData != null)
{
ListRecords = rawData.Where(x => x.HLShow || ShowAll).ToList();
}
}
catch
{ }
@@ -39,7 +39,7 @@ namespace MP.MONO.UI.Components
public EventCallback<bool> reqClose { get; set; }
[Parameter]
public PrevMaintTaskModel currParentRec { get; set; }
public PrevMaintTaskModel currParentRec { get; set; } = null!;
#endregion Public Properties
+74 -72
View File
@@ -2,25 +2,66 @@ using Microsoft.AspNetCore.Components;
using MP.MONO.Core;
using MP.MONO.Data;
using MP.MONO.Data.DbModels;
using Newtonsoft.Json;
using System.IO;
using System.Web;
using IHostingEnvironment = Microsoft.AspNetCore.Hosting.IWebHostEnvironment;
namespace MP.MONO.UI.Components
{
public partial class MaintTaskPending
{
//private readonly IWebHostEnvironment _environment;
#region Public Fields
public string dir = "";
#endregion Public Fields
#region Public Properties
/// <summary>
/// Abilita modalità compatta (solo x home)
/// </summary>
[Parameter]
public bool compMode { get; set; } = false;
/// <summary>
/// Gestione evento x cambio modalità (pending/schedulati
/// </summary>
[Parameter]
public EventCallback<bool> reqChangeMode { get; set; }
#endregion Public Properties
#region Protected Properties
protected string bodyCss
{
get => compMode ? "p-1" : "";
}
protected string currMode
{
get => doSetup ? "Pending" : "Scheduled";
}
#endregion Protected Properties
#region Protected Methods
//private readonly IWebHostEnvironment _HostEnvironment;
protected override async Task OnInitializedAsync()
{
//dir = _HostEnvironment.WebRootPath;
await ReloadData();
MaintPendingRefreshVetoMin = Configuration.GetValue<int>("OptPar:MaintPendingRefreshVetoMin");
PercLim = Configuration.GetValue<int>("OptPar:MaintLimitPerc");
MMDataService.maintPipe.EA_NewMessage += MaintPipe_EA_NewMessage;
}
#endregion Protected Methods
//public MaintTaskPending(IWebHostEnvironment environment)
//{
// _environment = environment;
//}
#region Private Fields
private int _MaxRecord = 1000;
private bool doSetup = true;
private DateTime LastUpdate = DateTime.Now.AddHours(-12);
private List<PendingMaintModel>? ListRecords = null;
@@ -49,35 +90,6 @@ namespace MP.MONO.UI.Components
#endregion Private Fields
#region Public Properties
/// <summary>
/// Abilita modalità compatta (solo x home)
/// </summary>
[Parameter]
public bool compMode { get; set; } = false;
/// <summary>
/// Gestione evento x cambio modalità (pending/schedulati
/// </summary>
[Parameter]
public EventCallback<bool> reqChangeMode { get; set; }
private bool doSetup = true;
protected string currMode
{
get => doSetup ? "Pending" : "Scheduled";
}
protected string bodyCss
{
get => compMode ? "p-1" : "";
}
public string dir = "";
#endregion Public Properties
#region Private Properties
private int _currPage { get; set; } = 1;
@@ -181,19 +193,6 @@ namespace MP.MONO.UI.Components
#endregion Private Properties
#region Protected Methods
//private readonly IWebHostEnvironment _HostEnvironment;
protected override async Task OnInitializedAsync()
{
//dir = _HostEnvironment.WebRootPath;
await ReloadData();
MaintPendingRefreshVetoMin = Configuration.GetValue<int>("OptPar:MaintPendingRefreshVetoMin");
PercLim = Configuration.GetValue<int>("OptPar:MaintLimitPerc");
MMDataService.maintPipe.EA_NewMessage += MaintPipe_EA_NewMessage;
}
#endregion Protected Methods
#region Private Methods
/// <summary>
@@ -219,29 +218,11 @@ namespace MP.MONO.UI.Components
ShowConfirm(0);
}
}
#if false
string wwwroot = "";
string file = "";
string file = "";
#endif
private string pathFinder(int id)
{
//wwwroot = _environment.WebRootPath;
#if false
file = Path.Combine(wwwroot, id + ".pdf");
#endif
string answ = "";
string path = "Docs/Maint/" + id + ".pdf";
if (File.Exists("wwwroot/" + path))
{
answ = path;
}
else
{
path = "Docs/Maint/empty.pdf";
answ = path;
}
return answ;
}
private void ForceReload(int newNum)
{
@@ -271,6 +252,26 @@ namespace MP.MONO.UI.Components
}
}
private string pathFinder(int id)
{
//wwwroot = _environment.WebRootPath;
#if false
file = Path.Combine(wwwroot, id + ".pdf");
#endif
string answ = "";
string path = "Docs/Maint/" + id + ".pdf";
if (File.Exists("wwwroot/" + path))
{
answ = path;
}
else
{
path = "Docs/Maint/empty.pdf";
answ = path;
}
return answ;
}
private async Task RegenTask()
{
await MMDataService.SchedMaintTaskCreateMissing(MachineId);
@@ -296,13 +297,14 @@ namespace MP.MONO.UI.Components
}
#endregion Private Methods
#if false
private bool showParams = false;
private void toggleShowParams()
{
showParams = !showParams;
}
}
#endif
}
}
+16 -12
View File
@@ -53,7 +53,8 @@ namespace MP.MONO.UI.Components
// se è ultima testo giallo...
if (SelVal != null && SelVal.Count > 0)
{
if (SelVal.LastOrDefault().Equals(ParamName))
var ultimo = SelVal.LastOrDefault();
if (ultimo != null && ultimo.Equals(ParamName))
{
answ = "bg-dark text-warning";
}
@@ -147,18 +148,21 @@ namespace MP.MONO.UI.Components
try
{
var allData = JsonConvert.DeserializeObject<List<DisplayDataDTO>>(currArgs.newMessage);
if (ShowReduced)
if (allData != null)
{
ListRecords = allData
.Where(x => x.HLShow)
.OrderBy(x => x.Order)
.ToList();
}
else
{
ListRecords = allData
.OrderBy(x => x.Order)
.ToList();
if (ShowReduced)
{
ListRecords = allData
.Where(x => x.HLShow)
.OrderBy(x => x.Order)
.ToList();
}
else
{
ListRecords = allData
.OrderBy(x => x.Order)
.ToList();
}
}
}
catch
+36 -27
View File
@@ -27,36 +27,45 @@
</div>
</div>
</li>
<li class="list-group-item">
<div class="d-flex w-100 justify-content-between" title="Article">
<div>
<i class="fa-solid fa-receipt fa-2x"></i>
@if (!string.IsNullOrEmpty(@currProd.ItemCode))
{
<li class="list-group-item">
<div class="d-flex w-100 justify-content-between" title="Article">
<div>
<i class="fa-solid fa-receipt fa-2x"></i>
</div>
<div>
<h5><b>@currProd.ItemCode</b></h5>
</div>
</div>
<div>
<h5><b>@currProd.ItemCode</b></h5>
</li>
}
@if (@currProd.CycleTime.TotalMinutes > 0)
{
<li class="list-group-item">
<div class="d-flex w-100 justify-content-between" title="Current Cycle Time">
<div><i class="fa-solid fa-stopwatch fa-2x"></i></div>
<div class="h3" title="">
<b>@($"{currProd.CycleTime.Hours:00}:{currProd.CycleTime.Minutes:00}:{currProd.CycleTime.Seconds:00}")</b>
</div>
</div>
</div>
</li>
<li class="list-group-item">
<div class="d-flex w-100 justify-content-between" title="Current Cycle Time">
<div><i class="fa-solid fa-stopwatch fa-2x"></i></div>
<div class="h3" title="">
<b>@($"{currProd.CycleTime.Hours:00}:{currProd.CycleTime.Minutes:00}:{currProd.CycleTime.Seconds:00}")</b>
</li>
}
@if (!string.IsNullOrEmpty(@currProd.ProgName))
{
<li class="list-group-item">
<div class="d-flex w-100 justify-content-between" title="Program">
<div><i class="fa-solid fa-terminal"></i></div>
<div>@currProd.ProgName</div>
</div>
</div>
</li>
<li class="list-group-item">
<div class="d-flex w-100 justify-content-between small" title="Program">
<div><i class="fa-solid fa-terminal"></i></div>
<div>@currProd.ProgName</div>
</div>
@if (!string.IsNullOrEmpty(currProd.Message))
{
<div class="d-flex w-100 justify-content-end">
<small><i>@currProd.Message</i></small>
</div>
}
</li>
@if (!string.IsNullOrEmpty(currProd.Message))
{
<div class="d-flex w-100 justify-content-end">
<small><i>@currProd.Message</i></small>
</div>
}
</li>
}
</ul>
}
+13 -6
View File
@@ -1,17 +1,24 @@
@if (singleLine)
{
<div class="progress">
<div class="progress-bar @bgStyle" style="width:@(percWidth)%">@($"{currVal:N0} h | {percWidth}%")</div>
<div class="progress-bar @bgStyle" style="width:@(percWidthNum)%">@($"{currVal:N0} h | {percWidthNum}%")</div>
</div>
}
else
{
<div class="text-center @textStyle">
<span class="@warnClass"><i class="bi bi-exclamation-triangle-fill"></i></span> <b>@currVal.ToString("N0")</b> <span class="@warnClass"><i class="bi bi-exclamation-triangle-fill"></i></span>
<span class="@warnClass px-1"><i class="bi bi-exclamation-triangle-fill"></i></span> <b>@currVal.ToString("N0")</b> <sup>(@($"{maxVal:N0}"))</sup><span class="@warnClass px-1"><i class="bi bi-exclamation-triangle-fill"></i></span>
</div>
<div class="progress">
<div class="progress-bar @bgStyle" style="width:@(percWidth)%">@(percWidth)%</div>
<div class="progress-bar @bgStyle" style="width:@(percWidh)%;">
@if (percWidthNum > yelLim || percWidthNum <= 0)
{
<div>@(percWidthNum)%</div>
}
</div>
@if (percWidthNum <= yelLim && percWidthNum > 0)
{
<div>@(percWidthNum)%</div>
}
</div>
}
}
+17 -1
View File
@@ -53,7 +53,23 @@ namespace MP.MONO.UI.Components
}
}
private int percWidth { get => (int)(100 * currVal / maxVal); }
private int percWidthNum { get => (int)(100 * currVal / maxVal); }
private int percWidh
{
get
{
int answ = percWidthNum;
if (answ <= 0)
{
answ = 100;
}
//else if (answ <= redLim)
//{
// answ = redLim;
//}
return answ;
}
}
private string textStyle
{
+2 -1
View File
@@ -52,7 +52,8 @@ namespace MP.MONO.UI.Components
// se è ultima testo giallo...
if (SelVal != null && SelVal.Count > 0)
{
if (SelVal.LastOrDefault().Equals(toolName))
var ultimo = SelVal.LastOrDefault();
if (ultimo != null && ultimo.Equals(toolName))
{
answ = "bg-dark text-warning";
}
+1 -1
View File
@@ -1 +1 @@
7846c819c695edbad32f74f84430d98a82e57cc6a99ec55a4dce6c9c5eb62bec560dbfe8feca34eef826fadb81c4884b9b215fda89cf4dcee5eb46f52287e722
77b916d9f6d6157678a62fb9654d26346719ab9e4609be9b53e130f2395ee7a7273d2269e1843349fe6c081608221dc47e6ef76018e6039ea6c2910211f734ba
+1 -1
View File
@@ -1 +1 @@
467e4b24bc3fe9d237169aa274ae589b64f072fb1cd91f4d79aaee76c64afbfced7fb51536b62cf612dedfb304202a1e653778b7cc8c758f83bb058984460301
31e9cc1c2e8f30a1b4098cb157d712f11f3f2e60fb74169a354c3fa646d6d0e28518b4e3139f844b25824fbcc4340051fc507d22c1c2d2786d3786c777c31cc3
+1 -1
View File
@@ -507,7 +507,7 @@ namespace MP.MONO.UI.Data
/// <returns></returns>
public async Task<List<AlarmListModel>> getAlarmRawSetup()
{
List<AlarmListModel> mutedList = new List<AlarmListModel>();
List<AlarmListModel>? mutedList = new List<AlarmListModel>();
string rawData = await redisDb.StringGetAsync(Constants.ALARMS_SETT_RLIST_KEY);
// ora provo a deserializzare
if (!string.IsNullOrEmpty(rawData))
+1 -1
View File
@@ -6,7 +6,7 @@
public DateTime DtStart { get; set; } = DateTime.Today.AddDays(-3);
public DateTime DtEnd { get; set; } = DateTime.Today.AddDays(3);
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
if (!(obj is DataLogFilter item))
return false;
+1 -6
View File
@@ -4,7 +4,7 @@
{
#region Public Events
public event Action EA_PageUpdated;
public event Action EA_PageUpdated = null!;
#endregion Public Events
@@ -56,11 +56,6 @@
#endregion Protected Methods
#region Private Fields
#endregion Private Fields
#region Private Properties
private int _currPage { get; set; } = 1;
+1 -1
View File
@@ -41,7 +41,7 @@
#region Public Methods
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
if (!(obj is selectChartParams item))
return false;
+1 -1
View File
@@ -53,7 +53,7 @@ namespace MP.MONO.UI.Data
#region Public Methods
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
if (!(obj is selectGlobalToggle item))
return false;
+5 -1
View File
@@ -25,6 +25,10 @@
<Content Remove="NLog.config" />
</ItemGroup>
<ItemGroup>
<_WebToolingArtifacts Remove="Properties\PublishProfiles\IIS04.pubxml" />
</ItemGroup>
<ItemGroup>
<None Include="compilerconfig.json" />
<None Include="NLog.config">
@@ -33,7 +37,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="EgwCoreLib.Razor" Version="1.3.2302-beta.312" />
<PackageReference Include="EgwCoreLib.Razor" Version="1.4.2303.215" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Negotiate" Version="6.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.2">
<PrivateAssets>all</PrivateAssets>
+1
View File
@@ -24,6 +24,7 @@
<h5 class="card-header text-center fw-bold"><i class="fa-solid fa-gears"></i> PRODUCTION</h5>
<div class="card-body bg-light text-dark p-1">
<MachStatsOverview></MachStatsOverview>
<hr />
<ProdOverview></ProdOverview>
</div>
</div>
+11 -3
View File
@@ -1,6 +1,16 @@
@page "/Production"
<div class="row">
<div class="col-4">
<div class="card">
<div class="card-header">
<h5 class="pt-1"><i class="bi bi-gear pe-2" aria-hidden="true"></i><b> Machine State</b></h5>
</div>
<div class="card-body">
<MachStatsOverview ShowAll="true"></MachStatsOverview>
</div>
</div>
</div>
<div class="col-4">
<div class="card">
<div class="card-header">
@@ -11,10 +21,8 @@
</div>
</div>
</div>
<div class="col-8">
<div class="col-4">
</div>
</div>
@code {
}
+24
View File
@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using System.Net.Http;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Components.Routing;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.Web.Virtualization;
using Microsoft.JSInterop;
using MP.MONO.UI;
using MP.MONO.UI.Shared;
using MP.MONO.UI.Components;
using EgwCoreLib.Razor;
namespace MP.MONO.UI.Pages
{
public partial class Production
{
}
}
@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project>
<PropertyGroup>
<TimeStampOfAssociatedLegacyPublishXmlFile />
<EncryptedPassword>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAARwa+h3SucUCk0+IZCHMQsgAAAAACAAAAAAADZgAAwAAAABAAAADOPMd3758qI/y/dA1hJlk6AAAAAASAAACgAAAAEAAAALjI1Q4A+Na1SHTbn2iY4kQYAAAA+8wgMcZ+vEOXhrpk/ei4H4gSz/lppCy4FAAAADEgX6TTl06NoYYCkrCN2gRN2gDO</EncryptedPassword>
<History>True|2022-03-18T07:13:40.4364579Z;True|2022-03-10T18:22:15.7066492+01:00;</History>
</PropertyGroup>
</Project>
@@ -14,7 +14,7 @@ by editing this MSBuild file. In order to learn more about this please visit htt
<ExcludeApp_Data>false</ExcludeApp_Data>
<ProjectGuid>6fb65850-c023-4986-9dff-770c4e582d60</ProjectGuid>
<SelfContained>false</SelfContained>
<MSDeployServiceURL>https://iis03.egalware.com:8172/MsDeploy.axd</MSDeployServiceURL>
<MSDeployServiceURL>https://iis04.egalware.com:8172/MsDeploy.axd</MSDeployServiceURL>
<DeployIisAppPath>Default Web Site/MP/MONO</DeployIisAppPath>
<RemoteSitePhysicalPath />
<SkipExtraFilesOnServer>true</SkipExtraFilesOnServer>
+1 -1
View File
@@ -10,7 +10,7 @@
"Redis": "nkcredis.steamware.net:6379,DefaultDatabase=7,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false,password=BtN9Py1wtLfLRvmzWnOPJ7RytDM+CLiVsJ/16zduNTlV8IOPGNrtzJSXPUnImA5PqmUMhKaUqo9NdHIG",
"AuthConnection": "Server=localhost;port=3306;database=GWMS;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
"DefaultConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
"AdminConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=root;pwd=Egalware_24068!;sslmode=None;",
"AdminConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=root;pwd=Seriate_24068!;sslmode=None;",
"MP.MONO.Data": "Server=localhost;port=3306;database=MAPO.MONO;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;"
},
"DbConfig": {
+1 -1
View File
@@ -10,7 +10,7 @@
"Redis": "nkcredis.steamware.net:6379,DefaultDatabase=7,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false,password=BtN9Py1wtLfLRvmzWnOPJ7RytDM+CLiVsJ/16zduNTlV8IOPGNrtzJSXPUnImA5PqmUMhKaUqo9NdHIG",
"AuthConnection": "Server=localhost;port=3306;database=GWMS;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
"DefaultConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
"AdminConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=root;pwd=Egalware_24068!;sslmode=None;",
"AdminConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=root;pwd=Seriate_24068!;sslmode=None;",
"MP.MONO.Data": "Server=localhost;port=3306;database=MAPO.MONO;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;"
},
"DbConfig": {
+47
View File
@@ -0,0 +1,47 @@
#-----------------------------------------
# MySql script converter
#
# convertitore script mysql da Windows a linux (fix x maiuscole nei nomi...)
#
#-----------------------------------------
# leggo ogni file *.sql nella folder in cui mi trovo
$fileList = Get-Childitem 'MAPO_MONO_DB.sql' #*.sql
foreach($file in $fileList)
{
## nome ricetta (senza xml...
#$fileName=$file | Select-Object Name
#$recName = $fileName.Name.Replace('.xml','')
#$recName
# leggo tutto il file
$contenuto = Get-Content $file -Raw
# effettuo 1:1 le sostituzioni
$newContenuto = $contenuto -replace 'alarmlist','AlarmList'
$newContenuto = $newContenuto -replace 'alarmlog','AlarmLog'
$newContenuto = $newContenuto -replace 'alarmrec','AlarmRec'
$newContenuto = $newContenuto -replace 'ankeyval','AnKeyVal'
$newContenuto = $newContenuto -replace 'config','Config'
$newContenuto = $newContenuto -replace 'counter','Counter'
$newContenuto = $newContenuto -replace 'datalog','DataLog'
$newContenuto = $newContenuto -replace 'datastag','DataStAg'
$newContenuto = $newContenuto -replace 'event','Event'
$newContenuto = $newContenuto -replace 'eventlog','EventLog'
$newContenuto = $newContenuto -replace 'machine','Machine'
$newContenuto = $newContenuto -replace 'machinegroup','MachineGroup'
$newContenuto = $newContenuto -replace 'pendingmainttask','PendingMaintTask'
$newContenuto = $newContenuto -replace 'prevmainttask','PrevMaintTask'
$newContenuto = $newContenuto -replace 'prodlog','ProdLog'
$newContenuto = $newContenuto -replace 'status','Status'
$newContenuto = $newContenuto -replace 'statuslog','StatusLog'
$newContenuto = $newContenuto -replace 'statusstag','StatusStAg'
$newContenuto = $newContenuto -replace 'tasktopic','TaskTopic'
$newContenuto = $newContenuto -replace 'userteam','UserTeam'
$newContenuto = $newContenuto -replace '__efmigrationshistory','__EFMigrationsHistory'
$newContenuto = $newContenuto.Trim()
# salvataggio file elaborato
Set-Content -Path $file -Value $newContenuto
}