diff --git a/MP.MONO.Core/Constants.cs b/MP.MONO.Core/Constants.cs
index 0941556..4c2e9c6 100644
--- a/MP.MONO.Core/Constants.cs
+++ b/MP.MONO.Core/Constants.cs
@@ -74,9 +74,10 @@ namespace MP.MONO.Core
// REDIS Channels messaggi (verso DECODER)
public static readonly string ALARM_RAW_QUEUE = $"AlarmsRawVal";
+ public static readonly string COUNT_RAW_QUEUE = $"CountRawVal";
public static readonly string PARAMS_RAW_QUEUE = $"ParamsRawVal";
public static readonly string STATUS_RAW_QUEUE = $"StatusRawVal";
- public static readonly string COUNT_RAW_QUEUE = $"CountRawVal";
+ public static readonly string TOOLS_RAW_QUEUE = $"ToolsRawVal";
#endregion Public Fields
}
diff --git a/MP.MONO.DECODER/ParamsManager.cs b/MP.MONO.DECODER/ParamsManager.cs
index cf6b60b..e131fa7 100644
--- a/MP.MONO.DECODER/ParamsManager.cs
+++ b/MP.MONO.DECODER/ParamsManager.cs
@@ -133,6 +133,7 @@ namespace MP.MONO.DECODER
DtRif = adesso,
FluxType = item.Key,
MachineId = 1,
+ DataType = Enums.DataLogType.Parameter,
ValNum = calcVal,
ValStr = $"{calcVal:N3}"
diff --git a/MP.MONO.DECODER/Program.cs b/MP.MONO.DECODER/Program.cs
index 75ad3aa..88e1832 100644
--- a/MP.MONO.DECODER/Program.cs
+++ b/MP.MONO.DECODER/Program.cs
@@ -100,6 +100,7 @@ setupConf();
DateTime lastExecParams = DateTime.Now.AddHours(-1);
DateTime lastLogDetail = DateTime.Now.AddHours(-1);
int numSendParam = 1;
+int numSendTools = 1;
int numSendMStatus = 1;
/* --------------------------------
@@ -126,6 +127,19 @@ DateTime lastExecStatus = DateTime.Now.AddHours(-1);
// registro gestione eventi
mpStatusRecvPipe.EA_NewMessage += MpStatusRecvPipe_EA_NewMessage;
+
+/* --------------------------------
+ * Setup Gestione Tools
+ * --------------------------------*/
+ToolsManager toolsMan = new ToolsManager();
+// inizializzo gestione messagePipe da Redis x allarmi
+MessagePipe toolsSendPipe = new MessagePipe(redisConn, Constants.TOOLS_M_QUEUE);
+MessagePipe toolsRecvPipe = new MessagePipe(redisConn, Constants.TOOLS_RAW_QUEUE);
+// datetime dell'inizio esecuzione task... x usare un semaforo di veto doppia esecuzione entro 30 sec
+DateTime lastExecTools = DateTime.Now.AddHours(-1);
+// registro gestione eventi
+toolsRecvPipe.EA_NewMessage += ToolsRecvPipe_EA_NewMessage;
+
/* --------------------------------
* Setup Gestione Parametri
* --------------------------------*/
@@ -535,6 +549,87 @@ void AlarmsValPipe_EA_NewMessage(object? sender, EventArgs e)
}
}
+///
+/// Gestione evento ricezione messaggi tools
+///
+void ToolsRecvPipe_EA_NewMessage(object? sender, EventArgs e)
+{
+ PubSubEventArgs currArgs = (PubSubEventArgs)e;
+ // conversione on-the-fly Dictionary --> parametri valorizzati (tra quelli configurati)
+ if (!string.IsNullOrEmpty(currArgs.newMessage))
+ {
+ DateTime adesso = DateTime.Now;
+ List? redisToolsConf = new List();
+ try
+ {
+ // verifico codici ricevuti
+ var toolsList = JsonConvert.DeserializeObject>(currArgs.newMessage);
+ if (toolsList != null)
+ {
+ // recupero elenco parametri salvati in redis...
+ string rawData = redisDb.StringGet(Constants.TOOLS_CONF_KEY);
+ if (!string.IsNullOrEmpty(rawData))
+ {
+ redisToolsConf = JsonConvert.DeserializeObject>(rawData);
+ // se ho i parametri...
+ if (redisToolsConf != null)
+ {
+ // ciclo x ogni valore ricevuto da message service...
+ foreach (var item in toolsList)
+ {
+ // cerco il parametro corrispondente...
+ var currToolVal = redisToolsConf.FirstOrDefault(x => x.Title == item.Key);
+ if (currToolVal != null)
+ {
+ currToolVal.ValueNum = item.Value;
+ currToolVal.Value = $"{item.Value.ToString(currToolVal.DisplFormat)}";
+ }
+ }
+ // verifico NON ci sia veto di scrittura... DbSampleInt (60 sec...)
+ if (adesso.Subtract(lastExecTools).TotalSeconds > DbSampleInt)
+ {
+ lastExecTools = adesso;
+ if (dbController != null)
+ {
+ // verifico x ogni parametro se sia completato il periodo di campionamento...
+ var val2save = toolsMan.processData(toolsList, redisToolsConf);
+ if (val2save.Count > 0)
+ {
+ // salvo sul DB
+ _ = dbController.DataLogInsertMany(val2save).Result;
+ Log.Info($"Tools | DB | {val2save.Count} rec inserted");
+ }
+ }
+ }
+ }
+ }
+
+ // invio sulla message pipeline corretta TUTTI i parametri aggiornati serializzati
+ string updRawVal = JsonConvert.SerializeObject(redisToolsConf);
+ toolsSendPipe.saveAndSendMessage(Constants.TOOLS_CURR_KEY, updRawVal);
+ if (redisToolsConf != null)
+ {
+ if (adesso.Subtract(lastLogDetail).TotalSeconds > 5 || numSendTools > 10)
+ {
+ Log.Info($"TOOLS | {redisToolsConf.Count} data transmitted x {numSendTools}");
+ lastLogDetail = adesso;
+ numSendTools = 0;
+ }
+ else
+ {
+ numSendTools++;
+ }
+ }
+ }
+ }
+ catch (Exception exc)
+ {
+ Log.Error($"Eccezione in ToolsRecvPipe_EA_NewMessage:{Environment.NewLine}{exc}{Environment.NewLine}{currArgs.newMessage}");
+ }
+ }
+}
+
+
///
/// Gestione evento ricezione messaggi parametri
///
diff --git a/MP.MONO.DECODER/ToolsManager.cs b/MP.MONO.DECODER/ToolsManager.cs
new file mode 100644
index 0000000..9b360c6
--- /dev/null
+++ b/MP.MONO.DECODER/ToolsManager.cs
@@ -0,0 +1,155 @@
+using MP.MONO.Core;
+using MP.MONO.Core.DTO;
+using MP.MONO.Data.DbModels;
+using NLog;
+using NLua;
+
+namespace MP.MONO.DECODER
+{
+ public class ToolsManager
+ {
+ #region Private Fields
+
+ ///
+ /// Dizionario dei valori accumulati sulle variabili
+ ///
+ private Dictionary VarAccumulator = new Dictionary();
+
+ #endregion Private Fields
+
+ #region Protected Fields
+
+ protected static Logger Log = LogManager.GetCurrentClassLogger();
+ protected static string luaPath = "";
+ protected static Lua state = new Lua();
+ protected List AlarmList = new List();
+
+ #endregion Protected Fields
+
+ #region Public Fields
+
+ public static string alarmStatus = "";
+ public static bool valueChanged = false;
+
+ #endregion Public Fields
+
+ #region Public Constructors
+
+ public ToolsManager()
+ {
+ // preparo variabile x avvisare script che il modo è da NLua
+ state["callMode"] = "NLua";
+ state["vcFunct"] = "AVG";
+
+ // carico il file (derivato da quello dei parametri)
+ luaPath = Path.Combine(Directory.GetCurrentDirectory(), "lua", "ToolsDecoder.lua");
+ state.DoFile(luaPath);
+
+ Log.Info("ToolsManager OK");
+ Console.WriteLine("ToolsManager OK");
+ }
+
+ #endregion Public Constructors
+
+ #region Public Methods
+
+ ///
+ /// Funzione chiamata LUA x calcolo degli eventuali parametri con periodi "scaduti"
+ ///
+ ///
+ ///
+ ///
+ public List processData(Dictionary paramsList, List redisParamConf)
+ {
+ List answ = new List();
+ DateTime adesso = DateTime.Now;
+
+ // vado ad "accumulare i dati" a quelli presenti...
+ foreach (var item in paramsList)
+ {
+ var currParam = redisParamConf.FirstOrDefault(x => x.Title == item.Key);
+ // cerco nelle variabili accomulatori...
+ if (!VarAccumulator.ContainsKey(item.Key))
+ {
+ if (currParam != null)
+ {
+ var dataList = new List();
+ dataList.Add(item.Value);
+ VCData newSet = new VCData()
+ {
+ dataArray = dataList,
+ DTStart = adesso,
+ Funzione = currParam.VcFunc,
+ Period = currParam.SamplePeriod
+ };
+ // se non ci fosse creo
+ VarAccumulator.Add(item.Key, newSet);
+ }
+ }
+ else
+ {
+ // altrimenti aggiorno
+ VarAccumulator[item.Key].dataArray.Add(item.Value);
+ }
+
+ // effettuo verifiche scadenza
+ bool calcOk = false;
+ double calcVal = 0;
+ if (VarAccumulator.ContainsKey(item.Key))
+ {
+ if (VarAccumulator[item.Key].isElapsed)
+ {
+ string funcMode = $"{VarAccumulator[item.Key].Funzione}";
+ // se scaduto --> mando a LUA x calcolo
+ state["valList"] = VarAccumulator[item.Key].dataArray;
+ state["numRec"] = VarAccumulator[item.Key].dataArray.Count;
+ state["vcFunct"] = funcMode;
+
+ // effettuo calcolo
+ state.DoString("doProcess()");
+
+ // recupero valore calcolato
+ bool.TryParse(state.GetString("calcOk"), out calcOk);
+ if (calcOk)
+ {
+ try
+ {
+ var stringVal = state.GetString("calcVal");
+ if (!string.IsNullOrEmpty(stringVal))
+ {
+ calcVal = state.GetNumber("calcVal");
+ Log.Trace($"calcVal: {calcVal}");
+ }
+ }
+ catch (Exception exc)
+ {
+ Log.Error($"exception during processData for {item.Key}{Environment.NewLine}{exc}");
+ }
+ }
+
+ // aggiungo alla lista finale...
+ var dbRecord = new DataLogModel()
+ {
+ DtRif = adesso,
+ FluxType = item.Key,
+ MachineId = 1,
+ DataType = Enums.DataLogType.Tools,
+ ValNum = calcVal,
+ ValStr = $"{calcVal:N3}"
+
+ };
+ answ.Add(dbRecord);
+
+ // elimino dai valori accumulati...
+ VarAccumulator.Remove(item.Key);
+ }
+ }
+ }
+
+
+ return answ;
+ }
+
+ #endregion Public Methods
+ }
+}
\ No newline at end of file
diff --git a/MP.MONO.DECODER/lua/CountersDecoder.lua b/MP.MONO.DECODER/lua/CountersDecoder.lua
index b56e76c..8ce917a 100644
--- a/MP.MONO.DECODER/lua/CountersDecoder.lua
+++ b/MP.MONO.DECODER/lua/CountersDecoder.lua
@@ -1,10 +1,10 @@
--[[---------------------------------------------------
-Procedura calcolo statistiche parametri:
+Procedura calcolo statistiche counters (derivato dai parametri):
Variabili IN:
- vcFunct(string): tipo di processing da effettuare tra [POINT/AVG/MEDIAN/MIN/MAX]
- valList(): elenco VALORI double da processare
-- numRec(int): conteggio numero recorda da processare
+- numRec(int): conteggio numero record da processare
Variabili OUT:
- calcVal(double): valore calcolato finale
diff --git a/MP.MONO.DECODER/lua/ParamsDecoder.lua b/MP.MONO.DECODER/lua/ParamsDecoder.lua
index b56e76c..2b76d18 100644
--- a/MP.MONO.DECODER/lua/ParamsDecoder.lua
+++ b/MP.MONO.DECODER/lua/ParamsDecoder.lua
@@ -4,7 +4,7 @@ Procedura calcolo statistiche parametri:
Variabili IN:
- vcFunct(string): tipo di processing da effettuare tra [POINT/AVG/MEDIAN/MIN/MAX]
- valList(): elenco VALORI double da processare
-- numRec(int): conteggio numero recorda da processare
+- numRec(int): conteggio numero record da processare
Variabili OUT:
- calcVal(double): valore calcolato finale
diff --git a/MP.MONO.DECODER/lua/ToolsDecoder.lua b/MP.MONO.DECODER/lua/ToolsDecoder.lua
new file mode 100644
index 0000000..0296c8d
--- /dev/null
+++ b/MP.MONO.DECODER/lua/ToolsDecoder.lua
@@ -0,0 +1,105 @@
+--[[---------------------------------------------------
+Procedura calcolo statistiche TOOLS:
+
+Variabili IN:
+- vcFunct(string): tipo di processing da effettuare tra [POINT/AVG/MEDIAN/MIN/MAX]
+- valList(): elenco VALORI double da processare
+- numRec(int): conteggio numero record da processare
+
+Variabili OUT:
+- calcVal(double): valore calcolato finale
+-----------------------------------------------------]]
+
+
+-- Per eventuale debug
+local ZBS = "c:/ZeroBraneStudio"
+if not package.path:find(ZBS,1,true) then
+ package.path = ZBS .. "/lualibs/?/?.lua;" .. ZBS .. "/lualibs/?.lua;" .. package.path
+ package.cpath = ZBS .. "/bin/?.dll;" .. ZBS .. "/bin/clibs53/?.dll;" .. package.cpath
+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
+ 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
+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)
+ end
+ print('calcVal: ' .. calcVal)
+ print('------------------------------')
+ end
+end
+
+
+-- MAIN
+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
+ calcOk = false
+ valListTable = {}
+
+ checkInit()
+ setupTable()
+ doCalc()
+ displayTestInfo()
+end
+
+if (callMode ~= 'NLua') then
+ doProcess()
+end
diff --git a/MP.MONO.Data/Controllers/MpDbController.cs b/MP.MONO.Data/Controllers/MpDbController.cs
index eadd62a..e06bc76 100644
--- a/MP.MONO.Data/Controllers/MpDbController.cs
+++ b/MP.MONO.Data/Controllers/MpDbController.cs
@@ -495,11 +495,12 @@ namespace MP.MONO.Data.Controllers
/// Recupero record DataLog data condizione filtro
///
///
+ /// Tipologia di dato richiesto da enum
///
///
///
///
- public List DataLogGetFilt(int machineId, string fluxType, DateTime inizio, DateTime fine)
+ public List DataLogGetFilt(int machineId, DataLogType dataType, string fluxType, DateTime inizio, DateTime fine)
{
List dbResult = new List();
using (MapoMonoContext localDbCtx = new MapoMonoContext())
@@ -508,7 +509,7 @@ namespace MP.MONO.Data.Controllers
{
dbResult = localDbCtx
.DbSetDataLog
- .Where(x => x.MachineId == machineId && x.FluxType == fluxType && x.DtRif >= inizio && x.DtRif <= fine)
+ .Where(x => (x.MachineId == machineId) && (x.FluxType == fluxType) && (x.DataType == dataType || dataType == DataLogType.ND) && (x.DtRif >= inizio && x.DtRif <= fine))
.Include(m => m.MachineNav)
.OrderByDescending(x => x.DataLogId)
.ToList();
diff --git a/MP.MONO.SIM/Program.cs b/MP.MONO.SIM/Program.cs
index 97760ce..6fa510f 100644
--- a/MP.MONO.SIM/Program.cs
+++ b/MP.MONO.SIM/Program.cs
@@ -513,7 +513,8 @@ void simTools()
// recupero uno stato simulato
var newVal = currSimGen.getTools();
string rawData = JsonConvert.SerializeObject(newVal);
- saveAndSendMessage(Constants.TOOLS_CURR_KEY, Constants.TOOLS_M_QUEUE, rawData);
+ saveAndSendMessage(Constants.TOOLS_CURR_KEY, Constants.TOOLS_RAW_QUEUE, rawData);
+ //saveAndSendMessage(Constants.TOOLS_CURR_KEY, Constants.TOOLS_M_QUEUE, rawData);
// attesa random
Thread.Sleep(rand.Next(minPeriod, maxPeriod));
diff --git a/MP.MONO.UI/Data/CurrentDataService.cs b/MP.MONO.UI/Data/CurrentDataService.cs
index 4bf970c..42a20fe 100644
--- a/MP.MONO.UI/Data/CurrentDataService.cs
+++ b/MP.MONO.UI/Data/CurrentDataService.cs
@@ -235,11 +235,20 @@ namespace MP.MONO.UI.Data
return await Task.FromResult(dbResult);
}
- public async Task> DataLogGetFilt(int machineId, string fluxType, DateTime inizio, DateTime fine)
+ ///
+ /// TimeSearie in formato DataLogModel
+ ///
+ /// ID macchina
+ /// Tipologia di dato richiesto da enum
+ /// Tipo di Flusso
+ /// DT Inizio estrazione
+ /// DT Fine estrazione
+ ///
+ public async Task> DataLogGetFilt(int machineId, DataLogType dataType, string fluxType, DateTime inizio, DateTime fine)
{
string source = "DB";
List dbResult = new List();
- string currKey = $"{Constants.DATA_LOG_KEY}:{machineId}:{fluxType.Replace(" ", "_")}:{inizio:yyyyMMdd}:{fine:yyyyMMdd}";
+ string currKey = $"{Constants.DATA_LOG_KEY}:{machineId}:{dataType}:{fluxType.Replace(" ", "_")}:{inizio:yyyyMMdd}:{fine:yyyyMMdd}";
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
string rawData = await redisDb.StringGetAsync(currKey);
@@ -258,14 +267,14 @@ namespace MP.MONO.UI.Data
}
else
{
- dbResult = dbController.DataLogGetFilt(machineId, fluxType, inizio, fine);
+ dbResult = dbController.DataLogGetFilt(machineId, dataType, fluxType, inizio, fine);
// salvo per 2 min...
rawData = JsonConvert.SerializeObject(dbResult);
await redisDb.StringSetAsync(currKey, rawData, TimeSpan.FromSeconds(120));
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
- Log.Info($"DataLogGetFilt | {machineId} | {fluxType} | {inizio:yyyyMMdd}-{fine:yyyyMMdd} | {source} | {ts.TotalMilliseconds} ms | {rawData.Length / 1024} kb");
+ Log.Info($"DataLogGetFilt | {machineId} | {dataType} | {fluxType} | {inizio:yyyyMMdd}-{fine:yyyyMMdd} | {source} | {ts.TotalMilliseconds} ms | {rawData.Length / 1024} kb");
return dbResult;
}
///