diff --git a/MP.Data/Repository/IOC/IIocRepository.cs b/MP.Data/Repository/IOC/IIocRepository.cs
index 60537ec1..cfa5824f 100644
--- a/MP.Data/Repository/IOC/IIocRepository.cs
+++ b/MP.Data/Repository/IOC/IIocRepository.cs
@@ -1,5 +1,6 @@
using MP.Data.DbModels;
using System;
+using System.Collections.Generic;
using System.Threading.Tasks;
using static MP.Core.Objects.Enums;
@@ -26,6 +27,18 @@ namespace MP.Data.Repository.IOC
///
Task CheckCambiaStatoBatchAsync(tipoInputEvento tipoInput, string IdxMacchina, DateTime InizioStato, int IdxTipo, string CodArt, string Value, int MatrOpr, string pallet);
+ ///
+ /// Elenco da tabella Config
+ ///
+ ///
+ Task> ConfigGetAllAsync();
+
+ ///
+ /// Intera tab dati macchina
+ ///
+ ///
+ Task> DatiMacchineGetAllAsync();
+
///
/// Aggiunta record MicroStato + EventList
///
@@ -34,6 +47,41 @@ namespace MP.Data.Repository.IOC
///
Task EvListMicroStatoInsertAsync(MicroStatoMacchinaModel newRecMsm, EventListModel newRecEv);
+ ///
+ /// Upsert record keepalive
+ ///
+ ///
+ ///
+ ///
+ ///
+ Task KeepAliveUpsertAsync(string IdxMacc, DateTime OraServer, DateTime OraMacc);
+
+ ///
+ /// Intera tabella relazione master/slave in machine (gestione setup master - slave)
+ ///
+ ///
+ Task> Macchine2SlaveAsync();
+
+ ///
+ /// Recupera record macchina da Idx
+ ///
+ ///
+ ///
+ Task MacchineGetByIdxAsync(string IdxMacchina);
+
+ ///
+ /// Upsert Record Macchine ASYNC
+ ///
+ ///
+ Task MacchineUpsertAsync(MacchineModel entity);
+
+ ///
+ /// Elenco da tabella Macchine
+ ///
+ ///
+ ///
+ Task> MicroStatoMacchinaGetByIdxMaccAsync(string IdxMacc);
+
///
/// Aggiornamento record Microstato macchina
///
@@ -41,6 +89,33 @@ namespace MP.Data.Repository.IOC
///
Task MicroStatoMacchinaUpsertAsync(MicroStatoMacchinaModel newRec);
+ ///
+ /// Aggiunta record SignalLog Async
+ ///
+ ///
+ ///
+ Task SignalLogInsertAsync(SignalLogModel newRec);
+
+ ///
+ /// Intera tabella state machine ingressi 2 eventi
+ ///
+ ///
+ Task> StateMachineIngressiAsync(int idxFam);
+
+ ///
+ /// Vista v_MSFD x singola macchina (da stored) - singolo record
+ ///
+ ///
+ ///
+ Task VMSFDGetByMaccAsync(string idxMacc);
+
+ ///
+ /// Vista v_MSFD delle machine MULTI filtrato x macchina (da stored)
+ ///
+ ///
+ ///
+ Task> VMSFDGetMultiByMaccAsync(string idxMacc);
+
#endregion Public Methods
}
}
\ No newline at end of file
diff --git a/MP.Data/Repository/IOC/IocRepository.cs b/MP.Data/Repository/IOC/IocRepository.cs
index d01011c3..de11638e 100644
--- a/MP.Data/Repository/IOC/IocRepository.cs
+++ b/MP.Data/Repository/IOC/IocRepository.cs
@@ -1,8 +1,10 @@
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
+using MongoDB.Driver;
using MP.Data.DbModels;
using NLog;
using System;
+using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
@@ -99,6 +101,30 @@ namespace MP.Data.Repository.IOC
}
}
+ ///
+ public async Task> ConfigGetAllAsync()
+ {
+ await using var dbCtx = await CreateContextAsync();
+ var dbResult = await dbCtx
+ .DbSetConfig
+ .AsNoTracking()
+ .OrderBy(x => x.Chiave)
+ .ToListAsync();
+ return dbResult;
+ }
+
+ ///
+ public async Task> DatiMacchineGetAllAsync()
+ {
+ await using var dbCtx = await CreateContextAsync();
+ var dbResult = await dbCtx
+ .DbSetDatiMacchine
+ .AsNoTracking()
+ .OrderBy(x => x.IdxMacchina)
+ .ToListAsync();
+ return dbResult;
+ }
+
///
public async Task EvListMicroStatoInsertAsync(MicroStatoMacchinaModel newRecMsm, EventListModel newRecEv)
{
@@ -145,10 +171,103 @@ namespace MP.Data.Repository.IOC
}
}
+ ///
+ public async Task KeepAliveUpsertAsync(string IdxMacc, DateTime OraServer, DateTime OraMacc)
+ {
+ await using var dbCtx = await CreateContextAsync();
+ bool fatto = false;
+
+ var currRec = await dbCtx
+ .DbSetKeepAlive
+ .Where(x => x.IdxMacchina == IdxMacc)
+ .FirstOrDefaultAsync();
+ if (currRec != null)
+ {
+ currRec.DataOraServer = OraServer;
+ currRec.DataOraMacchina = OraMacc;
+ dbCtx.Entry(currRec).State = EntityState.Modified;
+ }
+ else
+ {
+ KeepAliveModel newRec = new KeepAliveModel()
+ {
+ IdxMacchina = IdxMacc,
+ DataOraMacchina = OraMacc,
+ DataOraServer = OraServer,
+ DataOraStart = DateTime.Now
+ };
+ dbCtx
+ .DbSetKeepAlive
+ .Add(newRec);
+ }
+ fatto = await dbCtx.SaveChangesAsync() > 0;
+
+ return fatto;
+ }
+
+ ///
+ public async Task> Macchine2SlaveAsync()
+ {
+ await using var dbCtx = await CreateContextAsync();
+ List dbResult = await dbCtx
+ .DbSetM2S
+ .AsNoTracking()
+ .OrderBy(x => x.IdxMacchina)
+ .ToListAsync();
+
+ return dbResult;
+ }
+
+ ///
+ public async Task MacchineGetByIdxAsync(string IdxMacchina)
+ {
+ await using var dbCtx = await CreateContextAsync();
+ MacchineModel dbResult = await dbCtx
+ .DbSetMacchine
+ .FirstOrDefaultAsync(x => x.IdxMacchina == IdxMacchina);
+ return dbResult;
+ }
+
+ ///
+ public async Task MacchineUpsertAsync(MacchineModel entity)
+ {
+ await using var dbCtx = await CreateContextAsync();
+
+ // Recuperiamo l'entità tracciata dal context
+ var trackedEntity = await dbCtx
+ .DbSetMacchine
+ .FirstOrDefaultAsync(x => x.IdxMacchina == entity.IdxMacchina);
+
+ if (trackedEntity != null)
+ {
+ // Aggiorna i valori dell'entità tracciata con quelli della nuova
+ dbCtx.Entry(trackedEntity).CurrentValues.SetValues(entity);
+ }
+ else
+ {
+ dbCtx.DbSetMacchine.Update(entity);
+ }
+ return await dbCtx.SaveChangesAsync() > 0;
+ }
+
+ ///
+ public async Task> MicroStatoMacchinaGetByIdxMaccAsync(string IdxMacc)
+ {
+ await using var dbCtx = await CreateContextAsync();
+ List dbResult = new List();
+ dbResult = await dbCtx
+ .DbSetMicroStatoMacc
+ .Where(x => x.IdxMacchina == IdxMacc)
+ .AsNoTracking()
+ .ToListAsync();
+ return dbResult;
+ }
+
+ ///
public async Task MicroStatoMacchinaUpsertAsync(MicroStatoMacchinaModel newRec)
{
- bool fatto = false;
await using var dbCtx = await CreateContextAsync();
+ bool fatto = false;
var actRec = await dbCtx
.DbSetMicroStatoMacc
@@ -174,6 +293,56 @@ namespace MP.Data.Repository.IOC
return fatto;
}
+ ///
+ public async Task SignalLogInsertAsync(SignalLogModel newRec)
+ {
+ await using var dbCtx = await CreateContextAsync();
+ var currRec = dbCtx
+ .DbSetSignalLog
+ .Add(newRec);
+ return await dbCtx.SaveChangesAsync() > 0;
+ }
+
+ ///
+ public async Task> StateMachineIngressiAsync(int idxFam)
+ {
+ await using var dbCtx = await CreateContextAsync();
+ var IdxFamIn = new SqlParameter("@IdxFamigliaIngresso", idxFam);
+ var dbResult = await dbCtx
+ .DbSetSMI
+ .FromSqlRaw("exec dbo.stp_TRI_getByIdxFamIng @IdxFamigliaIngresso", IdxFamIn)
+ .AsNoTracking()
+ .ToListAsync();
+ return dbResult;
+ }
+
+ ///
+ public async Task VMSFDGetByMaccAsync(string idxMacc)
+ {
+ await using var dbCtx = await CreateContextAsync();
+ var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacc);
+ var dbResult = (await dbCtx
+ .DbSetMSFD
+ .FromSqlRaw("exec dbo.stp_MSFD_getMacc @IdxMacchina", IdxMacchina)
+ .AsNoTracking()
+ .ToListAsync())
+ .FirstOrDefault();
+ return dbResult;
+ }
+
+ ///
+ public async Task> VMSFDGetMultiByMaccAsync(string idxMacc)
+ {
+ await using var dbCtx = await CreateContextAsync();
+ var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacc);
+ var dbResult = await dbCtx
+ .DbSetMSFD
+ .FromSqlRaw("exec dbo.stp_MSFD_getMulti @IdxMacchina", IdxMacchina)
+ .AsNoTracking()
+ .ToListAsync();
+ return dbResult;
+ }
+
#endregion Public Methods
#region Protected Fields
diff --git a/MP.Data/Services/IOC/IIocService.cs b/MP.Data/Services/IOC/IIocService.cs
index d723e812..f1376610 100644
--- a/MP.Data/Services/IOC/IIocService.cs
+++ b/MP.Data/Services/IOC/IIocService.cs
@@ -38,6 +38,17 @@ namespace MP.Data.Services.IOC
///
Task MicroStatoMacchinaUpsertAsync(MicroStatoMacchinaModel newRec);
+ ///
+ /// Processa input da IOB eventualmente registrando i segnali inviati
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ Task ProcessInputAsync(string idxMacchina, string valore, string dtEve, string dtCurr, string contatore);
+
#endregion Public Methods
}
}
\ No newline at end of file
diff --git a/MP.Data/Services/IOC/IocService.cs b/MP.Data/Services/IOC/IocService.cs
index bda957c9..cce02490 100644
--- a/MP.Data/Services/IOC/IocService.cs
+++ b/MP.Data/Services/IOC/IocService.cs
@@ -1,8 +1,15 @@
using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using MP.Core.Objects;
using MP.Data.DbModels;
using MP.Data.Repository.IOC;
+using Newtonsoft.Json;
+using NLog;
using StackExchange.Redis;
using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
using System.Threading.Tasks;
using static MP.Core.Objects.Enums;
@@ -15,10 +22,14 @@ namespace MP.Data.Services.IOC
public IocService(
IConfiguration config,
IConnectionMultiplexer redis,
- IIocRepository repo) : base(config, redis)
+ IIocRepository repo,
+ IServiceScopeFactory scopeFactory) : base(config, redis)
{
_className = "IocServ";
+ int.TryParse(config.GetValue("ServerConf:redisLongTimeCache"), out redisLongTimeCache);
+ int.TryParse(config.GetValue("ServerConf:redisShortTimeCache"), out redisShortTimeCache);
_repo = repo;
+ _scopeFactory = scopeFactory;
}
#endregion Public Constructors
@@ -32,6 +43,37 @@ namespace MP.Data.Services.IOC
return success;
}
+ ///
+ /// Elenco completo config da DB
+ ///
+ ///
+ public async Task> ConfigGetAllAsync()
+ {
+ List? result = new List();
+ // cerco in redis...
+ RedisValue rawData = await _redisDb.StringGetAsync(MP.Data.Utils.redisConfKey);
+ string source = "DB";
+ if (!string.IsNullOrEmpty($"{rawData}"))
+ {
+ result = JsonConvert.DeserializeObject>($"{rawData}");
+ source = "REDIS";
+ }
+ else
+ {
+ result = await _repo.ConfigGetAllAsync();
+ //result = await Task.FromResult(SpecDbController.ConfigGetAllAsync());
+ // serializzo e salvo...
+ rawData = JsonConvert.SerializeObject(result);
+ await _redisDb.StringSetAsync(MP.Data.Utils.redisConfKey, rawData, getRandTOut(redisLongTimeCache));
+ }
+ Log.Debug($"ConfigGetAllAsync Read from {source}");
+ if (result == null)
+ {
+ result = new List();
+ }
+ return result;
+ }
+
///
public async Task EvListMicroStatoInsertAsync(MicroStatoMacchinaModel newRecMsm, EventListModel newRecEv)
{
@@ -39,6 +81,66 @@ namespace MP.Data.Services.IOC
return success;
}
+ ///
+ /// Restituisce il valOut booleano se la macchina sia abilitata all'inserimento COMPLETO nel
+ /// Signal Log
+ ///
+ ///
+ ///
+ public async Task IobSLogEnabAsync(string idxMacchina)
+ {
+ bool answ = false;
+ // ORA recupero da memoria redis...
+ try
+ {
+ var currHash = MP.Data.Utils.RedKeyDatiMacc(idxMacchina, MpIoNS);
+ RedisValue rawData = await _redisDb.HashGetAsync(currHash, (RedisValue)"sLogEnabled");
+ // se è vuoto... leggo da DB e popolo!
+ if (!rawData.HasValue)
+ {
+ await ResetDatiMacchinaAsync(idxMacchina);
+ // riprovo
+ rawData = await _redisDb.HashGetAsync(currHash, (RedisValue)"sLogEnabled");
+ }
+
+ // provo conversione
+ bool.TryParse($"{rawData}", out answ);
+ }
+ catch (Exception exc)
+ {
+ Log.Error($"Errore IobSLogEnabAsync | idxMacchina {idxMacchina}:{Environment.NewLine}{exc}");
+ }
+ return answ;
+ }
+
+ ///
+ /// Elenco completo valori Macchine 2 Slave
+ ///
+ ///
+ public async Task> Macchine2SlaveGetAllAsync()
+ {
+ List? result = new List();
+ string currKey = $"{MP.Data.Utils.redisBaseAddr}:M2STab";
+ // cerco in redis dato valOut sel macchina...
+ RedisValue rawData = await _redisDb.StringGetAsync(currKey);
+ if (rawData.HasValue)
+ {
+ result = JsonConvert.DeserializeObject>($"{rawData}");
+ }
+ else
+ {
+ result = await _repo.Macchine2SlaveAsync();
+ // serializzo e salvo...
+ rawData = JsonConvert.SerializeObject(result);
+ await _redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache * 10));
+ }
+ if (result == null)
+ {
+ result = new List();
+ }
+ return result;
+ }
+
///
public async Task MicroStatoMacchinaUpsertAsync(MicroStatoMacchinaModel newRec)
{
@@ -46,13 +148,819 @@ namespace MP.Data.Services.IOC
return success;
}
+ ///
+ public async Task ProcessInputAsync(string idxMacchina, string valore, string dtEve, string dtCurr, string contatore)
+ {
+ string answ = "";
+ if (ValidateinputParams(idxMacchina, valore, dtEve, dtCurr))
+ {
+ DateTime dataOraEvento = ParseEventTime(dtEve, dtCurr);
+
+ // se abilitato registro evento sul DB
+ if (await IobSLogEnabAsync(idxMacchina))
+ {
+ int cntVal = 0;
+ int.TryParse(contatore, out cntVal);
+ await saveSigLogAsync(idxMacchina, valore, dataOraEvento, cntVal);
+ }
+ // continuo col resto
+ try
+ {
+ // scrivo keep alive!!! (se necessario, altrimenti è in cache...)
+ await ScriviKeepAliveAsync(idxMacchina, DateTime.Now);
+ // Cache dati macchina per evitare lookup ridondanti
+ Dictionary datiMacc = await mDatiMacchineAsync(idxMacchina);
+ // verifico se sia una macchina MULTI....
+ if (isMulti(idxMacchina, datiMacc))
+ {
+ // inizio preprocessing
+ string newVal = "";
+ // processo OGNI macchina a stati dell'impianto... (KEY:IdxMacchina / IdxMacchina#qualcosa, Val = IdxFamIn)
+ foreach (var item in await mTabMSMIAsync(idxMacchina))
+ {
+ newVal = preProcInput(item.Key, valore, datiMacc);
+ // ora processo e salvo il valOut del microstato...
+ // INTERNAMENTE gestisce i casi DB/REDIS secondo necessità
+ await CheckMicroStatoAsync(item.Key, newVal, dataOraEvento, contatore, datiMacc);
+ }
+ }
+ else
+ {
+ // ora processo e salvo il valOut del microstato... INTERNAMENTE
+ // gestisce i casi DB/REDIS secondo necessità
+ await CheckMicroStatoAsync(idxMacchina, valore, dataOraEvento, contatore, datiMacc);
+ }
+ // forzo RESET dati macchina...
+ await ResetDatiMacchinaAsync(idxMacchina);
+ // registro in risposta che è andato tutto bene...
+ answ = "OK";
+ }
+ catch (Exception exc)
+ {
+ string errore = $"Errore: {Environment.NewLine}{exc}";
+ Log.Error(errore);
+ answ = errore;
+ }
+ }
+ return answ;
+ }
+
+ ///
+ /// scrive un evento di keepalive sulla tabella
+ ///
+ ///
+ ///
+ ///
+ public async Task ScriviKeepAliveAsync(string IdxMacchina, DateTime oraMacchina)
+ {
+ // cerco se ho keep alive in redis,
+ var currKey = MP.Data.Utils.RedKeyHash($"KeepAlive:{IdxMacchina}");
+ bool keyPresent = await _redisDb.KeyExistsAsync(currKey);
+ // se NON presente salvo in REDIS con TTL 10 sec e sul DB...
+ if (!keyPresent)
+ {
+ DateTime adesso = DateTime.Now;
+ await _redisDb.StringSetAsync(currKey, adesso.ToString("s"), TimeSpan.FromSeconds(30));
+ // effettuo scrittura sul DB
+ await _repo.KeepAliveUpsertAsync(IdxMacchina, DateTime.Now, oraMacchina);
+ }
+ }
+
#endregion Public Methods
+ #region Protected Fields
+
+ protected Random rand = new Random();
+
+ #endregion Protected Fields
+
+ #region Protected Methods
+
+ ///
+ /// Restituisce un timeout dai minuti richiesti + tempo random 1..60 sec
+ ///
+ ///
+ ///
+ protected TimeSpan getRandTOut(double stdMinutes)
+ {
+ double rndValue = stdMinutes + (double)rand.Next(1, 60) / 60;
+ return TimeSpan.FromMinutes(rndValue);
+ }
+
+ #endregion Protected Methods
+
#region Private Fields
+ private static Logger Log = LogManager.GetCurrentClassLogger();
+
private readonly string _className;
+
private readonly IIocRepository _repo;
+ private readonly IServiceScopeFactory _scopeFactory;
+
+ ///
+ /// Provider CultureInfo x parse valori (es dataora)
+ ///
+ private CultureInfo ciProvider = CultureInfo.InvariantCulture;
+
+ ///
+ /// Formato dataora standard x parsing
+ ///
+ private string dtFormat = "yyyyMMddHHmmssfff";
+
+ private int redisLongTimeCache = 5;
+
+ private int redisShortTimeCache = 2;
+
#endregion Private Fields
+
+ #region Private Methods
+
+ ///
+ /// controlla se da il segnale di "microstato" deriva un evento da generare - modalità OFFLINE
+ ///
+ /// idx macchina
+ /// valOut ingresso
+ /// data-ora evento (server)
+ /// sequenza dati inviati
+ /// dati macchina in cache (opzionale, se null fa lookup)
+ ///
+ private async Task CheckMicroStatoAsync(string idxMacchina, string valore, DateTime dtEve, string contatore, Dictionary? datiMaccCache = null)
+ {
+ // recupero SE IMPIEGATO REDIS i valori del Dictionary della macchina...
+ Dictionary datiMacc = datiMaccCache ?? await mDatiMacchineAsync(idxMacchina);
+
+ // processing
+ inputComandoMapo answ = new inputComandoMapo();
+
+ // SE no trovassi verifico se esista la macchina altrimenti la creo... REDIS compliant
+ if (!datiMacc.ContainsKey(idxMacchina))
+ {
+ await verificaIdxMacchinaAsync(idxMacchina);
+ }
+
+ // continuo processing...
+ string CodArticolo = datiMacc["CodArticolo"];
+ if (string.IsNullOrEmpty(CodArticolo))
+ {
+ var allDatiMacch = await _repo.DatiMacchineGetAllAsync();
+ var recMacc = allDatiMacch.FirstOrDefault(x => x.IdxMacchina == idxMacchina);
+ if (recMacc != null)
+ {
+ CodArticolo = recMacc.CodArticoloA;
+ }
+ }
+ // preparo gestione val ingresso
+ int? valINT = 0;
+ int idxTipoEv = 0;
+ int next_idxMS = 0;
+ try
+ {
+ valINT = int.Parse(valore, NumberStyles.HexNumber);
+ int idxFamIn = Convert.ToInt32(datiMacc["IdxFamIn"]);
+ int idxMicroStato = Convert.ToInt32(datiMacc["IdxMicroStato"]);
+ int valIOB = Convert.ToInt32(valINT);
+ next_idxMS = idxMicroStato;
+ // recupero singolo valOut (stringa) x chiave
+ string todoSMI = await ValoreSmiAsync(idxFamIn, idxMicroStato, valIOB);
+ // solo se ho trovato un risultato nella tab SMI della famiglia macchina...
+ if (!string.IsNullOrEmpty(todoSMI) && todoSMI.Contains("_"))
+ {
+ // splitto e salvo valori OUT...
+ string[] valori = todoSMI.Split('_');
+ idxTipoEv = Convert.ToInt32(valori[0]);
+ next_idxMS = Convert.ToInt32(valori[1]);
+ }
+ }
+ catch (Exception exc)
+ {
+ Log.Error($"[ChkMiSt_5a] - - Eccezione in recupero riga Trans ingressi | idxMacchina {idxMacchina} | valINT {valINT}:{Environment.NewLine}{exc}", Environment.NewLine, exc, valINT, idxMacchina);
+ }
+
+ // effettuo update vari SU DB!!!
+ MicroStatoMacchinaModel newRecMsm = new MicroStatoMacchinaModel()
+ {
+ IdxMacchina = idxMacchina,
+ IdxMicroStato = next_idxMS,
+ InizioStato = dtEve,
+ Value = valore
+ };
+ if (idxTipoEv > 0)
+ {
+ // preparo record
+ string valEsteso = string.Format("[{0}] {1}", contatore.PadLeft(3, '0'), valore);
+ // creo evento
+ EventListModel newRecEv = new EventListModel()
+ {
+ CodArticolo = CodArticolo,
+ IdxMacchina = idxMacchina,
+ IdxTipo = idxTipoEv,
+ InizioStato = dtEve,
+ MatrOpr = 0,
+ pallet = "-",
+ Value = valEsteso
+ };
+ // salva e processa evento + microstato
+ answ = await scriviRigaEventoAsync(newRecMsm, newRecEv);
+ }
+ else
+ {
+ await _repo.MicroStatoMacchinaUpsertAsync(newRecMsm);
+ }
+ return answ;
+ }
+
+ ///
+ /// Helper standardizzazione valOut dataora ricevuto da IOB remoti
+ ///
+ ///
+ ///
+ private string dtFormStd(string? s)
+ {
+ return s?.Length > 17 ? s[..17] : s?.PadRight(17, '0') ?? string.Empty;
+ }
+
+ ///
+ /// Restituisce il valOut booleano se la macchina sia di tipo MULTI (con più state machine x INGRESSI)
+ /// usando dati macchina in cache per evitare lookup ridondanti
+ ///
+ ///
+ ///
+ ///
+ private bool isMulti(string idxMacchina, Dictionary datiMacc)
+ {
+ bool answ = false;
+ try
+ {
+ answ = Convert.ToBoolean(datiMacc.ContainsKey("Multi") && datiMacc["Multi"] == "1");
+ }
+ catch (Exception exc)
+ {
+ Log.Error($"Eccezione in isMulti{Environment.NewLine}{exc}");
+ }
+ return answ;
+ }
+
+ private async Task> ListMasterAsync()
+ {
+ HashSet result = new();
+ string currKey = $"{MP.Data.Utils.redisBaseAddr}:ListMaster";
+ RedisValue rawData = await _redisDb.StringGetAsync(currKey);
+ if (rawData.HasValue)
+ {
+ result = JsonConvert.DeserializeObject>($"{rawData}") ?? new();
+ }
+ else
+ {
+ var fullList = await Macchine2SlaveGetAllAsync();
+ result = fullList.Select(x => x.IdxMacchina).ToHashSet();
+ // serializzo e salvo...
+ rawData = JsonConvert.SerializeObject(result);
+ await _redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache * 10));
+ }
+ return result;
+ }
+
+ private async Task> ListSlaveAsync()
+ {
+ HashSet result = new();
+ string currKey = $"{MP.Data.Utils.redisBaseAddr}:ListSlave";
+ RedisValue rawData = await _redisDb.StringGetAsync(currKey);
+ if (rawData.HasValue)
+ {
+ result = JsonConvert.DeserializeObject>($"{rawData}") ?? new();
+ }
+ else
+ {
+ var fullList = await Macchine2SlaveGetAllAsync();
+ result = fullList.Select(x => x.IdxMacchinaSlave).Distinct().ToHashSet();
+ // serializzo e salvo...
+ rawData = JsonConvert.SerializeObject(result);
+ await _redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache * 10));
+ }
+ return result;
+ }
+
+ ///
+ /// Restitusice elenco KVP dei campi DatiMacchine + StatoMacchine per l'impianto indicato
+ ///
+ ///
+ ///
+ private async Task> mDatiMacchineAsync(string idxMacchina)
+ {
+ // hard coded dimensione vettore DatiMacchine
+ Dictionary answ = new Dictionary();
+ // ORA recupero da memoria redis...
+ try
+ {
+ var currHash = MP.Data.Utils.RedKeyDatiMacc(idxMacchina, MpIoNS);
+ answ = await RedisGetHashDictAsync(currHash);
+ // se è vuoto... leggo da DB e popolo!
+ if (answ.Count == 0)
+ {
+ answ = await ResetDatiMacchinaAsync(idxMacchina);
+ }
+ }
+ catch (Exception exc)
+ {
+ Log.Error($"Errore in compilazione dati Macchine x Redis - idxMacchina {idxMacchina}:{Environment.NewLine}{exc}");
+ }
+ return answ;
+ }
+
+ ///
+ /// Restitusice elenco KVP (async) per evitare blocchi quando chiamato da metodi asincroni
+ ///
+ ///
+ ///
+ private async Task[]> mTabMSMIAsync(string idxMacchina)
+ {
+ KeyValuePair[] answ = new KeyValuePair[1];
+ answ[0] = new KeyValuePair("0", "0");
+ try
+ {
+ var currHash = MP.Data.Utils.RedKeyMsmi(idxMacchina);
+ answ = await RedisGetHashAsync(currHash);
+ if (answ == null || answ.Length == 0)
+ {
+ answ = await resetMSMIAsync(idxMacchina);
+ }
+ }
+ catch (Exception exc)
+ {
+ Log.Error($"Errore in compilazione Tabella Multi State Machine Ingressi x Redis:{Environment.NewLine}{exc}");
+ }
+ return answ;
+ }
+
+ ///
+ /// Calcola dataora evento da info dt ricevute
+ ///
+ ///
+ ///
+ ///
+ private DateTime ParseEventTime(string dtEve, string dtCurr)
+ {
+ DateTime dataOraEvento = DateTime.Now;
+
+ // fix formato dataora in ingresso
+ string stdEve = dtFormStd(dtEve);
+ string stdCurr = dtFormStd(dtCurr);
+
+ // 2. Se le stringhe normalizzate coincidono, skip dei calcoli
+ if (stdEve != stdCurr)
+ {
+ // 3. Parsing sicuro
+ if (DateTime.TryParseExact(stdEve, dtFormat, ciProvider, DateTimeStyles.None, out DateTime dtEvento) &&
+ DateTime.TryParseExact(stdCurr, dtFormat, ciProvider, DateTimeStyles.None, out DateTime dtCorrente))
+ {
+ TimeSpan diff = dtCorrente - dtEvento;
+ double ms = Math.Abs(diff.TotalMilliseconds);
+
+ // 4. Classificazione delta con switch expression (più leggibile e performante)
+ string deltaClass = ms switch
+ {
+ <= 10 => "0-10 ms",
+ <= 100 => "10-100 ms",
+ <= 1000 => "100-1000 ms",
+ <= 10000 => "1-10 sec",
+ _ => "> 10 sec"
+ };
+
+ Log.Debug($"Correzione delta {deltaClass}");
+
+ // 5. Correzione data/ora server: sottrao lo scarto calcolato
+ dataOraEvento = dataOraEvento.Subtract(diff);
+ }
+ else
+ {
+ Log.Error($"Errore parsing date: {stdEve} | {stdCurr}");
+ }
+ }
+ return dataOraEvento;
+ }
+
+ ///
+ /// Calcola l'effettivo valOut da passare alla macchina a stati INGRESSI usando dati macchina in cache
+ ///
+ ///
+ ///
+ ///
+ ///
+ private string preProcInput(string idxMacchina, string valore, Dictionary datiMacc)
+ {
+ string newVal = "";
+ try
+ {
+ // variabili
+ int valINT = 0;
+ int BitFilt = 0;
+ int BSR = 0;
+ bool ExplodeBit = false;
+ int NumBit = 0;
+ int newValInt = 0;
+ // recupero parametri dalla cache...
+ int.TryParse(datiMacc.ContainsKey("BitFilt") ? datiMacc["BitFilt"] : "0", out BitFilt);
+ int.TryParse(datiMacc.ContainsKey("BSR") ? datiMacc["BSR"] : "0", out BSR);
+ Boolean.TryParse(datiMacc.ContainsKey("ExplodeBit") ? datiMacc["ExplodeBit"] : "false", out ExplodeBit);
+ // non usato (x ora)
+ int.TryParse(datiMacc.ContainsKey("NumBit") ? datiMacc["NumBit"] : "0", out NumBit);
+
+ // recupero valOut
+ valINT = int.Parse(valore, NumberStyles.HexNumber);
+ // filtro
+ newValInt = MP.Core.Utils.bMaskInt(valINT, BitFilt);
+ // effettuo eventuale BitShiftRight
+ if (BSR > 0)
+ {
+ newValInt = newValInt >> BSR;
+ }
+ // effettuo eventuale esplosione in BIT esclusivi
+ if (ExplodeBit)
+ {
+ newValInt = Convert.ToInt32(1 << newValInt);
+ }
+ // riconverto a STRING HEX!!!
+ newVal = newValInt.ToString("X");
+ }
+ catch
+ {
+ newVal = valore;
+ }
+
+ return newVal;
+ }
+
+ private async Task[]> RedisGetHashAsync(RedisKey redKey)
+ {
+ HashEntry[] rawData = await _redisDb.HashGetAllAsync(redKey);
+ var result = rawData.Where(x => !x.Name.IsNull).Select(x => new KeyValuePair($"{x.Name}", $"{x.Value}")).ToArray();
+ return result;
+ }
+
+ private async Task> RedisGetHashDictAsync(RedisKey hashKey)
+ {
+ HashEntry[] rawData = await _redisDb.HashGetAllAsync(hashKey);
+ var result = rawData
+ .Where(x => !x.Name.IsNull)
+ .ToDictionary(x => x.Name.ToString(), x => x.Value.ToString());
+ return result;
+ }
+
+ private async Task RedisSetHashAsync(RedisKey redKey, KeyValuePair[] valori, double expireSeconds = -1.0)
+ {
+ HashEntry[] redHash = valori.Select(x => new HashEntry(x.Key, x.Value)).ToArray();
+ await _redisDb.HashSetAsync(redKey, redHash);
+ if (expireSeconds > 0.0)
+ {
+ await _redisDb.KeyExpireAsync(redKey, DateTime.Now.AddSeconds(expireSeconds));
+ }
+ }
+
+ ///
+ /// Restitusice elenco KVP dei campi DatiMacchine + StatoMacchine per l'impianto indicato
+ ///
+ ///
+ ///
+ private async Task> ResetDatiMacchinaAsync(string idxMacc)
+ {
+ Dictionary result = new Dictionary();
+ VMSFDModel? dbResult = null;
+ dbResult = await _repo.VMSFDGetByMaccAsync(idxMacc);
+ if (dbResult == null) return new Dictionary();
+
+ double numSecCache = redisLongTimeCache;
+ // converto in formato dizionario...
+ if (dbResult != null)
+ {
+ // salvo 1:1 i valori... STATO
+ result.Add("IdxMicroStato", $"{dbResult.IdxMicroStato}");
+ result.Add("IdxStato", $"{dbResult.IdxStato}");
+ result.Add("CodArticolo", $"{dbResult.CodArticolo}");
+ result.Add("insEnabled", $"{dbResult.InsEnabled}");
+ result.Add("sLogEnabled", $"{dbResult.SLogEnabled}");
+ result.Add("pallet", $"{dbResult.Pallet}");
+ result.Add("CodArticolo_A", $"{dbResult.CodArticoloA}");
+ result.Add("CodArticolo_B", $"{dbResult.CodArticoloB}");
+ result.Add("TempoCicloBase", $"{dbResult.TempoCicloBase}");
+ result.Add("PzPalletProd", $"{dbResult.PzPalletProd}");
+ result.Add("MatrOpr", $"{dbResult.MatrOpr}");
+ result.Add("lastVal", $"{dbResult.LastVal}");
+ result.Add("TCBase", $"{dbResult.TempoCicloBase}");
+
+ //...e SETUP
+ result.Add("CodMacc", $"{dbResult.Codmacchina}");
+ result.Add("IdxFamIn", $"{dbResult.IdxFamigliaIngresso}");
+ result.Add("Multi", $"{dbResult.Multi}");
+ result.Add("BitFilt", $"{dbResult.BitFilt}");
+ result.Add("MaxVal", $"{dbResult.MaxVal}");
+ result.Add("BSR", $"{dbResult.Bsr}");
+ result.Add("ExplodeBit", $"{dbResult.ExplodeBit}");
+ result.Add("NumBit", $"{dbResult.NumBit}");
+ result.Add("IdxFamMacc", $"{dbResult.IdxFamiglia}");
+ result.Add("simplePallet", $"{dbResult.SimplePallet}");
+ result.Add("palletChange", $"{dbResult.PalletChange}");
+ // durata cache in secondi dal valOut insEnabled...
+ //double numSecCache = ((result["insEnabled"].ToLower() == "true") ? redisShortTimeCache : redisLongTimeCache);
+ numSecCache = dbResult.InsEnabled ? redisShortTimeCache : redisLongTimeCache;
+ }
+ else
+ {
+ }
+ // dati master/slave
+ string isMaster = (await ListMasterAsync()).Contains(idxMacc) ? "1" : "0";
+ string isSlave = (await ListSlaveAsync()).Contains(idxMacc) ? "1" : "0";
+ result.Add("Master", isMaster);
+ result.Add("Slave", isSlave);
+
+ // Processing redis in transazoine...
+ var redKey = MP.Data.Utils.RedKeyDatiMacc(idxMacc, MpIoNS);
+
+ // variazione con redis transaction...
+ var transaction = _redisDb.CreateTransaction();
+ // 1. Eliminiamo la chiave (rimuove i vecchi campi)
+ _ = transaction.KeyDeleteAsync(redKey);
+ // 2. Prepariamo gli HashEntry per il batch (più efficiente di un Dictionary)
+ HashEntry[] entries = result.Select(kvp => new HashEntry(kvp.Key, kvp.Value)).ToArray();
+ // 3. Inseriamo i nuovi valori
+ _ = transaction.HashSetAsync(redKey, entries);
+ // 4. Impostiamo l'expiration in un unico colpo
+ _ = transaction.KeyExpireAsync(redKey, TimeSpan.FromSeconds(numSecCache));
+ // Eseguiamo tutto in un unico viaggio verso Redis
+ bool success = await transaction.ExecuteAsync();
+
+ return result;
+ }
+
+ ///
+ /// Resetta (rileggendo) i dati della State Machine multi ingressi nel formato
+ /// currKey: IdxMacchina
+ /// value: IdxFamigliaIngresso
+ ///
+ ///
+ ///
+ private async Task[]> resetMSMIAsync(string idxMacchina)
+ {
+ var currHash = MP.Data.Utils.RedKeyMsmi(idxMacchina);
+ // recupero records
+ var tabMSMI = await _repo.VMSFDGetMultiByMaccAsync(idxMacchina);
+
+ KeyValuePair[] answ = new KeyValuePair[tabMSMI.Count];
+ // salvo tutti i valori StateMachineIngressi...
+ int i = 0;
+ foreach (var item in tabMSMI)
+ {
+ answ[i] = new KeyValuePair(item.IdxMacchina, item.IdxFamigliaIngresso.ToString());
+ i++;
+ }
+ // verifico il timeout (default 60 sec...)
+ var sTOutSmi = await tryGetConfigAsync("TmOut.MSMI");
+ int tOut = 60;
+ int.TryParse(sTOutSmi, out tOut);
+ tOut = tOut <= 60 ? 60 : tOut;
+ // salvo in redis!
+ await RedisSetHashAsync(currHash, answ, tOut);
+ return answ;
+ }
+
+ ///
+ /// Resetta (rileggendo) i dati della State Machine ingressi nel formato
+ /// currKey: cState_nVal (current MICRO-STATE + "_" + new Value)
+ /// value: iTipoEv_nState (IdxTipoEv da trasmettere + New MICRO-STATE)
+ ///
+ ///
+ ///
+ private async Task[]> resetSMIAsync(int idxFamIn)
+ {
+ var currHash = MP.Data.Utils.GetHashSMI(idxFamIn);
+ // leggo da DB...
+ var tabSMI = await _repo.StateMachineIngressiAsync(idxFamIn);
+
+ KeyValuePair[] answ = new KeyValuePair[tabSMI.Count];
+ // salvo tutti i valori StateMachineIngressi...
+ int i = 0;
+ string key = "";
+ string val = "";
+ foreach (var item in tabSMI)
+ {
+ key = string.Format("{0}_{1}", item.IdxMicroStato, item.ValoreIngresso);
+ val = string.Format("{0}_{1}", item.IdxTipoEvento, item.NextIdxMicroStato);
+ answ[i] = new KeyValuePair(key, val);
+ i++;
+ }
+ // verifico il timeout (default 60 sec...)
+ int tOut = 300;
+ var sTOutSmi = await tryGetConfigAsync("TmOut.SMI");
+ if (!string.IsNullOrEmpty(sTOutSmi))
+ {
+ int.TryParse(sTOutSmi, out tOut);
+ }
+ // salvo in redis!
+ await RedisSetHashAsync(currHash, answ, tOut);
+ return answ;
+ }
+
+ ///
+ /// salva il segnale di "microstato" (segnale) ASYNC
+ ///
+ /// idx macchina
+ /// valOut ingresso
+ /// data-ora evento (server)
+ /// contatore sequenza dati inviati
+ ///
+ private async Task saveSigLogAsync(string idxMacchina, string valore, DateTime dtEve, int contatore)
+ {
+ SignalLogModel newRec = new SignalLogModel()
+ {
+ IdxMacchina = idxMacchina,
+ DtCurr = DateTime.Now,
+ DtEve = dtEve,
+ Contatore = contatore,
+ Valore = valore
+ };
+ return await _repo.SignalLogInsertAsync(newRec);
+ }
+
+ ///
+ /// Scrive una riga evento + una riga microstato insieme, ed effettua verifica necessità cambio stato
+ ///
+ /// Record MicroStatoMacchina
+ /// record EventList
+ ///
+ private async Task scriviRigaEventoAsync(MicroStatoMacchinaModel newRecMsm, EventListModel newRecEv)
+ {
+ bool inserito = false;
+
+ // inserisco evento
+ inserito = await _repo.EvListMicroStatoInsertAsync(newRecMsm, newRecEv);
+ // faccio controllo per eventuale cambio stato da tab transizioni...
+
+ await _repo.CheckCambiaStatoBatchAsync(tipoInputEvento.hw, newRecEv.IdxMacchina, newRecEv.InizioStato ?? DateTime.Now, newRecEv.IdxTipo, newRecEv.CodArticolo, newRecEv.Value, newRecEv.MatrOpr, newRecEv.pallet);
+
+ // formatto output
+ inputComandoMapo answ = new inputComandoMapo();
+ answ.outValue = inserito.ToString();
+ answ.needStatusRefresh = true;
+ return answ;
+ }
+
+ ///
+ /// Restitusice elenco KVP dei campi della State Machine ingressi nel formato
+ /// currKey: cState_nVal (current MICRO-STATE + "_" + new Value)
+ /// value: iTipoEv_nState (IdxTipoEv da trasmettere + New MICRO-STATE
+ ///
+ ///
+ ///
+ private async Task[]> StateMachInByKeyAsync(int idxFamIn)
+ {
+ // hard coded dimensione vettore DatiMacchine
+ KeyValuePair[] answ = new KeyValuePair[1];
+ // iniziualizzo con un valOut... 0/0
+ answ[0] = new KeyValuePair("0", "0");
+ // ORA recupero da memoria redis...
+ try
+ {
+ var currHash = MP.Data.Utils.GetHashSMI(idxFamIn);
+ answ = await RedisGetHashAsync(currHash);
+ // se è vuoto... leggo da DB e popolo!
+ if (answ.Length == 0)
+ {
+ answ = await resetSMIAsync(idxFamIn);
+ }
+ }
+ catch (Exception exc)
+ {
+ Log.Error($"Errore in compilazione State Machine Ingressi x Redis:{Environment.NewLine}{exc}");
+ }
+ return answ;
+ }
+
+ ///
+ /// Restituisce valOut della stringa (SE disponibile)
+ ///
+ ///
+ ///
+ private async Task tryGetConfigAsync(string keyName)
+ {
+ string answ = "";
+ // preselezione valori
+ var configData = await ConfigGetAllAsync();
+ var currRec = configData.FirstOrDefault(x => x.Chiave == keyName);
+ if (currRec != null)
+ {
+ answ = currRec.Valore;
+ }
+ return answ;
+ }
+
+ ///
+ /// Validazione preliminare valori input
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private bool ValidateinputParams(string idxMacchina, string valore, string dtEve, string dtCurr)
+ {
+ bool isValid = false;
+ // preparo stringa valori correnti
+ string currVals = $"idxMacchina: {idxMacchina} | valOut: {valore} | dtEve: {dtEve} | dtCurr:{dtCurr}";
+ if (dtEve == null || dtCurr == null)
+ {
+ Log.Warn($"procInput: null found | {currVals}");
+ }
+ else if (dtEve.Length < 17 || dtCurr.Length < 17)
+ {
+ Log.Info($"procInput: invalid data | {currVals}");
+ }
+ else if (string.IsNullOrEmpty(idxMacchina))
+ {
+ Log.Info($"procInput: missing IdxMacchina | {currVals}");
+ }
+ else if (string.IsNullOrEmpty(valore))
+ {
+ Log.Info($"procInput: missing valOut | {currVals}");
+ }
+ else
+ {
+ isValid = true;
+ }
+ return isValid;
+ }
+
+ ///
+ /// Restituisce il valore SPECIFICATO per la state machine ingressi
+ /// value: iTipoEv_nState (IdxTipoEv da trasmettere + New MICRO-STATE)
+ ///
+ ///
+ ///
+ ///
+ ///
+ private async Task ValoreSmiAsync(int idxFamIn, int idxMicroStato, int valoreIn)
+ {
+ string valOut = "";
+ var currHash = MP.Data.Utils.GetHashSMI(idxFamIn);
+ string field = $"{idxMicroStato}_{valoreIn}";
+ var searchVal = await _redisDb.HashGetAsync(currHash, field);
+ if (!searchVal.HasValue)
+ {
+ // ricarico tabella (salvando in redis x ricerca successiva)!
+ var valori = await StateMachInByKeyAsync(idxFamIn);
+ if (valori.Any(x => x.Key == field))
+ {
+ searchVal = valori.FirstOrDefault(x => x.Key == field).Value;
+ }
+ }
+ valOut = $"{searchVal}";
+ return valOut;
+ }
+
+ ///
+ /// cerca codice in anagrafica macchine ed eventualmente inserisce nuova macchina
+ ///
+ ///
+ private async Task verificaIdxMacchinaAsync(string IdxMacchina)
+ {
+ // esecuzione in REDIS...cerco status macchina...
+ if ((await mDatiMacchineAsync(IdxMacchina)).Count == 0)
+ {
+ // verifico se esiste su DB
+ var dbRec = await _repo.MacchineGetByIdxAsync(IdxMacchina);
+ if (dbRec == null)
+ {
+ MacchineModel newRec = new MacchineModel()
+ {
+ IdxMacchina = IdxMacchina,
+ CodMacchina = "0000",
+ Nome = IdxMacchina,
+ Descrizione = "Macchina non codificata",
+ Note = "-",
+ locazione = "",
+ RecipeArchivePath = "",
+ RecipePath = ""
+ };
+ await _repo.MacchineUpsertAsync(newRec);
+
+ // verifico ci sia un microstato macchina...
+ var recMSM = await _repo.MicroStatoMacchinaGetByIdxMaccAsync(IdxMacchina);
+ if (recMSM.Count == 0)
+ {
+ // inserisco nuovo stato...
+ MicroStatoMacchinaModel msRec = new MicroStatoMacchinaModel()
+ {
+ IdxMacchina = IdxMacchina,
+ IdxMicroStato = 0,
+ InizioStato = DateTime.Now,
+ Value = "00"
+ };
+ await _repo.MicroStatoMacchinaUpsertAsync(msRec);
+ }
+ }
+ }
+ }
+
+ #endregion Private Methods
}
}
\ No newline at end of file
diff --git a/MP.IOC/Controllers/IOBController.cs b/MP.IOC/Controllers/IOBController.cs
index 21ef2c34..563f5cca 100644
--- a/MP.IOC/Controllers/IOBController.cs
+++ b/MP.IOC/Controllers/IOBController.cs
@@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Mvc;
using MP.Core.DTO;
using MP.Core.Objects;
using MP.Data.DbModels;
+using MP.Data.Services.IOC;
using MP.IOC.Data;
using Newtonsoft.Json;
using NLog;
@@ -16,17 +17,18 @@ namespace MP.IOC.Controllers
{
#region Public Constructors
- public IOBController(IConfiguration configuration, MpDataService DataService)
+ public IOBController(IConfiguration configuration, MpDataService DataService, IIocService IService)
{
_configuration = configuration;
DService = DataService;
+ IOCService = IService;
}
#endregion Public Constructors
#region Public Methods
- ///
+ ///
/// SALVA x macchina KVP parametro/valore:
/// GET: api/IOB/addOptPar/SIMUL_03?pName=PZREQ&pValue=1000
///
@@ -327,15 +329,6 @@ namespace MP.IOC.Controllers
}
}
- ///
- /// Chiude ODL precedente ed avvia uno nuovo (duplicandolo e sitemando quantità RIMANENTE),
- /// e CONFERMA produzione...
- ///
- /// GET: IOB/forceSplitOdl/SIMUL_03
- ///
- ///
- /// Esito chiamata (OK/vuoto)
-
[HttpGet("forceSplitOdl/{id}")]
public async Task ForceSplitOdl(string id)
{
@@ -358,6 +351,14 @@ namespace MP.IOC.Controllers
return Ok(answ);
}
+ ///
+ /// Chiude ODL precedente ed avvia uno nuovo (duplicandolo e sitemando quantità RIMANENTE),
+ /// e CONFERMA produzione...
+ ///
+ /// GET: IOB/forceSplitOdl/SIMUL_03
+ ///
+ ///
+ /// Esito chiamata (OK/vuoto)
///
/// Recupera ArtNum dato CodXdl (per impianti che accettano solo INT in scrittura):
/// GET: IOB/getArtNum/SIMUL_03?CodXdl=ABC123
@@ -880,7 +881,8 @@ namespace MP.IOC.Controllers
DateTime dataOraEvento = DateTime.Now;
try
{
- answ = await DService.ProcessInputAsync(id, valore, dtEve, dtCurr, cnt);
+ answ = await IOCService.ProcessInputAsync(id, valore, dtEve, dtCurr, cnt);
+ //answ = await DService.ProcessInputAsync(id, valore, dtEve, dtCurr, cnt);
return Ok(answ);
}
catch (Exception exc)
@@ -1447,8 +1449,8 @@ namespace MP.IOC.Controllers
#region Private Fields
private static IConfiguration _configuration = null!;
-
private static Logger Log = LogManager.GetCurrentClassLogger();
+ private IIocService IOCService;
#endregion Private Fields
diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj
index f5d79982..0d8916eb 100644
--- a/MP.IOC/MP.IOC.csproj
+++ b/MP.IOC/MP.IOC.csproj
@@ -4,7 +4,7 @@
net8.0
enable
enable
- 8.16.2604.3016
+ 8.16.2604.3017
diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html
index 8babd7b3..d84fdcbc 100644
--- a/MP.IOC/Resources/ChangeLog.html
+++ b/MP.IOC/Resources/ChangeLog.html
@@ -1,6 +1,6 @@
Modulo MP-IOC
- Versione: 8.16.2604.3016
+ Versione: 8.16.2604.3017
Note di rilascio:
-
diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt
index ba173677..291a80f5 100644
--- a/MP.IOC/Resources/VersNum.txt
+++ b/MP.IOC/Resources/VersNum.txt
@@ -1 +1 @@
-8.16.2604.3016
+8.16.2604.3017
diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml
index ced1d562..e80112ee 100644
--- a/MP.IOC/Resources/manifest.xml
+++ b/MP.IOC/Resources/manifest.xml
@@ -1,6 +1,6 @@
-
- 8.16.2604.3016
+ 8.16.2604.3017
https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip
https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html
false