From 695b46bb49c6888902b0fd7d692b6d6f768e0620 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Fri, 6 Oct 2023 15:43:44 +0200 Subject: [PATCH] TAB3: - Gestione fermate RT - fix lettura h2IOB --- MP-TAB-SERV/Components/IobInfoMan.razor.cs | 5 +- MP-TAB-SERV/Components/ProdStopMan.razor | 2 +- MP-TAB-SERV/Components/ProdStopMan.razor.cs | 21 + MP-TAB-SERV/MP-TAB-SERV.csproj | 2 +- MP-TAB-SERV/Pages/ProdStop.razor | 15 +- MP-TAB-SERV/Pages/ProdStop.razor.cs | 148 +++++- MP-TAB-SERV/Resources/ChangeLog.html | 2 +- MP-TAB-SERV/Resources/VersNum.txt | 2 +- MP-TAB-SERV/Resources/manifest.xml | 2 +- MP-TAB-SERV/Shared/MainLayout.razor | 106 ---- MP-TAB-SERV/Shared/MainLayout.razor.cs | 159 ++++++ MP-TAB-SERV/appsettings.json | 3 +- MP.Data/Controllers/MpTabController.cs | 112 ++++- MP.Data/DTO/IobInfoDTO.cs | 15 - MP.Data/DatabaseModels/AnagStatiModel.cs | 26 + .../DatabaseModels/MicroStatoMacchinaModel.cs | 21 + MP.Data/DatabaseModels/StatoMacchineModel.cs | 26 + MP.Data/MoonProContext.cs | 3 + MP.Data/Objects/Enums.cs | 459 ++++++++++++++++++ MP.Data/Objects/IOB_data.cs | 25 + MP.Data/Objects/InputComandoMapo.cs | 103 ++++ MP.Data/Services/SharedMemService.cs | 148 ++++-- MP.Data/Services/TabDataService.cs | 418 +++++++++++++++- 23 files changed, 1636 insertions(+), 187 deletions(-) create mode 100644 MP-TAB-SERV/Shared/MainLayout.razor.cs delete mode 100644 MP.Data/DTO/IobInfoDTO.cs create mode 100644 MP.Data/DatabaseModels/AnagStatiModel.cs create mode 100644 MP.Data/DatabaseModels/MicroStatoMacchinaModel.cs create mode 100644 MP.Data/DatabaseModels/StatoMacchineModel.cs create mode 100644 MP.Data/Objects/Enums.cs create mode 100644 MP.Data/Objects/IOB_data.cs create mode 100644 MP.Data/Objects/InputComandoMapo.cs diff --git a/MP-TAB-SERV/Components/IobInfoMan.razor.cs b/MP-TAB-SERV/Components/IobInfoMan.razor.cs index 663f2789..baef2d6e 100644 --- a/MP-TAB-SERV/Components/IobInfoMan.razor.cs +++ b/MP-TAB-SERV/Components/IobInfoMan.razor.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Components; using MP.Data.DTO; +using MP.Data.Objects; using MP.Data.Services; namespace MP_TAB_SERV.Components @@ -12,12 +13,14 @@ namespace MP_TAB_SERV.Components [Inject] protected TabDataService TabSrv { get; set; } = null!; - protected IobInfoDTO infosIob { get; set; } = new IobInfoDTO(); + protected IOB_data infosIob { get; set; } = new IOB_data(); protected override async Task OnInitializedAsync() { infosIob = await TabSrv.IobInfo(idxMacch); } + + } } \ No newline at end of file diff --git a/MP-TAB-SERV/Components/ProdStopMan.razor b/MP-TAB-SERV/Components/ProdStopMan.razor index 5ab071fd..a81d28df 100644 --- a/MP-TAB-SERV/Components/ProdStopMan.razor +++ b/MP-TAB-SERV/Components/ProdStopMan.razor @@ -1,5 +1,5 @@ 
-
+
diff --git a/MP-TAB-SERV/Components/ProdStopMan.razor.cs b/MP-TAB-SERV/Components/ProdStopMan.razor.cs index c4a43b13..b0415cda 100644 --- a/MP-TAB-SERV/Components/ProdStopMan.razor.cs +++ b/MP-TAB-SERV/Components/ProdStopMan.razor.cs @@ -4,11 +4,32 @@ namespace MP_TAB_SERV.Components { public partial class ProdStopMan { + #region Public Properties + + [Parameter] + public EventCallback E_EventSelected { get; set; } + + [Parameter] + public int IdxEvento { get; set; } = 0; + [Parameter] public string objCss { get; set; } = ""; + [Parameter] public string objIcon { get; set; } = ""; + [Parameter] public string objTxt { get; set; } = ""; + + #endregion Public Properties + + #region Protected Methods + + protected async Task ReportSelected() + { + await E_EventSelected.InvokeAsync(IdxEvento); + } + + #endregion Protected Methods } } \ No newline at end of file diff --git a/MP-TAB-SERV/MP-TAB-SERV.csproj b/MP-TAB-SERV/MP-TAB-SERV.csproj index c829ab60..b7b22d09 100644 --- a/MP-TAB-SERV/MP-TAB-SERV.csproj +++ b/MP-TAB-SERV/MP-TAB-SERV.csproj @@ -3,7 +3,7 @@ net6.0 enable - 6.16.2310.519 + 6.16.2310.615 enable MP_TAB_SERV diff --git a/MP-TAB-SERV/Pages/ProdStop.razor b/MP-TAB-SERV/Pages/ProdStop.razor index c91e88af..0970245c 100644 --- a/MP-TAB-SERV/Pages/ProdStop.razor +++ b/MP-TAB-SERV/Pages/ProdStop.razor @@ -18,10 +18,15 @@ else
- @foreach(var item in events2show) - { - - } + @if (!string.IsNullOrEmpty(lblOut)) + { +
+ @lblOut +
+ } + @foreach (var item in events2show) + { + + }
} - \ No newline at end of file diff --git a/MP-TAB-SERV/Pages/ProdStop.razor.cs b/MP-TAB-SERV/Pages/ProdStop.razor.cs index c8695340..3b2dca5b 100644 --- a/MP-TAB-SERV/Pages/ProdStop.razor.cs +++ b/MP-TAB-SERV/Pages/ProdStop.razor.cs @@ -1,11 +1,155 @@ using global::Microsoft.AspNetCore.Components; using MP.Data.DatabaseModels; using MP.Data.Services; +using NLog.Layouts; namespace MP_TAB_SERV.Pages { public partial class ProdStop { + [Inject] + protected SharedMemService MStor { get; set; } = null!; + [Inject] + protected TabDataService TabServ { get; set; } = null!; + + protected string lblOut { get; set; } = ""; + + + /// + /// Determina se insert sia Realtime o batch con DataOra (in base a diff tra DataOra selezionata e realtime, se superiore ad X minuti NON è realtime) + /// + public bool insRealtime + { + get + { + bool answ = true; +#if false + try + { + if (Math.Abs(dataOraEv.Subtract(DateTime.Now).TotalMinutes) > memLayer.ML.CRI("dltMinRealtime")) + { + answ = false; + } + } + catch + { } +#endif + return answ; + } + } + + /// + /// Processo registrazione eventi + /// + /// + /// + protected async Task EventRecord(int IdxEv) + { + await Task.Delay(1); + // salvo evento e processo... + + if (IdxEv > 0) + { + var rigaEvento = MStor.GetEventRow(IdxEv); + if (rigaEvento != null) + { + var rigaStato = await TabServ.StatoMacchina(IdxMacc); + // processo evento... + if (insRealtime) + { + // se realtime + TabServ.scriviRigaEventoBarcode(IdxMacc, IdxEv, rigaStato.CodArticolo, "DRT", MatrOpr, rigaStato.pallet); + // resetta il microstato in modo da ricevere successive info HW + TabServ.resetMicrostatoMacchina(IdxMacc); + } + else + { +#if false + // in primis disabilito insert... + DataLayerObj.taStatoMacchine.setInsEnabled(idxMacchina, false); + // calcolo evento + string evento = IdxEv.ToString(); + string commento = ""; + try + { + evento = DataLayerObj.taAnagEventi.GetByIdx(IdxEv)[0].Nome.Replace("Barcode - ", ""); + } + catch + { } + // genero stringa pseudo-univoca + string codRich = string.Format("{0:yyMMddHHmmss}-{1}", DateTime.Now, IdxEv); + // x prima cosa scrivo un evento tipo "1" x chiudere la durata appena prima dell'evento successivo + try + { + // cerco da 1 sec DOPO evento... + DS_applicazione.DiarioDiBordoDataTable tabNext = controllerMapo.nextEventoImpiantoFrom(idxMacchina, dataOraEv.AddSeconds(1)); + + DateTime nextEvDT = DateTime.Now; + if (tabNext.Rows.Count > 0) + { + nextEvDT = tabNext[0].InizioStato; + } + // se non trovo chiusura evento inserisco a 1 minuto prima di adesso la chiusura... + else + { + nextEvDT = DateTime.Now.AddMinutes(-1); + } + // fix salvo la dichiarazione di chiusura + commento = string.Format("999 - M.Lav EndEvt: {0} [{1}]", evento, codRich); + DataLayerObj.scriviRigaEventoBarcode(idxMacchina, 1, rigaStato.CodArticolo, commento, DataLayerObj.MatrOpr, rigaStato.pallet, nextEvDT.AddSeconds(-1), DateTime.Now); // 1 hard-coded x resettare + } + catch + { } + // update commento! + commento = string.Format("999 - Dich StartEvt: {0} [{1}]", evento, codRich); + // recupero data/ora evento da inserire (quella selezionata) ed AGGIUNGO 1 sec!!! così rimane traccia + DataLayerObj.scriviRigaEventoBarcode(idxMacchina, IdxEv, rigaStato.CodArticolo, commento, DataLayerObj.MatrOpr, rigaStato.pallet, dataOraEv.AddSeconds(1), DateTime.Now); + // eseguo ricalcolo! + DateTime startRicalcolo = dataOraEv.AddMinutes(memLayer.ML.CRI("minAnticipoRicalcolo")); + + // leggo parametri x esecuzione... + int rdm_nEvStep = memLayer.ML.CRI("rdm_nEvStep"); + int rdm_nEvCheck = memLayer.ML.CRI("rdm_nEvCheck"); + bool rdm_ChkOnly = memLayer.ML.CRB("rdm_ChkOnly"); + DataLayerObj.taComm.stp_ricalcolaDatiMacchinaFromDate(idxMacchina, startRicalcolo, 1, rdm_nEvStep, rdm_nEvCheck, rdm_ChkOnly); // nella stored imposto macchina OFFline e poi ONline, parto da "minAnticipoRicalcolo" minuti prima... + // aggiorno data evento x insert eventuale commento (5 sec...) + dataOraEv = dataOraEv.AddSeconds(5); + // riabilito insert... anche se non dovrebbe servire x stored ricalcolo precedente... + DataLayerObj.taStatoMacchine.setInsEnabled(idxMacchina, true); +#endif + } + // mostro esito + alertCss = "alert-succes"; + lblOut = "Registrata dichiarazione fermata"; + } + else + { + alertCss = "alert-danger"; + lblOut = $"Codice evento non valido! {IdxEv}"; + } + } +#if false + // refresh fermate + repLI.DataBind(); + // faccio refresh x singola macchina 2019.03.26 + DataLayerObj.taMSE.forceRecalc(0, idxMacchina); + // sollevo evento! + if (eh_newVal != null) + { + eh_newVal(this, new EventArgs()); + } +#endif + } + private int MatrOpr + { + get => MServ.MatrOpr; + } + + [Inject] + protected MessageService MServ { get; set; } = null!; + + protected string alertCss { get; set; } = "alert-danger"; + #region Protected Properties protected MappaStatoExpl? CurrMSE { get; set; } = null; @@ -43,9 +187,9 @@ namespace MP_TAB_SERV.Pages } var eventsAll = await TabSrv.AnagEventiGetAll(); - if(eventsAll != null) + if (eventsAll != null) { - events2show = eventsAll.Where(x => x.EventoTablet).OrderBy(x=>x.Nome).ToList(); + events2show = eventsAll.Where(x => x.EventoTablet).OrderBy(x => x.Nome).ToList(); } } diff --git a/MP-TAB-SERV/Resources/ChangeLog.html b/MP-TAB-SERV/Resources/ChangeLog.html index d8c36b01..3d18e7ef 100644 --- a/MP-TAB-SERV/Resources/ChangeLog.html +++ b/MP-TAB-SERV/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

Versione: 6.16.2310.519

+

Versione: 6.16.2310.615


Note di rilascio:
  • diff --git a/MP-TAB-SERV/Resources/VersNum.txt b/MP-TAB-SERV/Resources/VersNum.txt index d492269e..b1409f9e 100644 --- a/MP-TAB-SERV/Resources/VersNum.txt +++ b/MP-TAB-SERV/Resources/VersNum.txt @@ -1 +1 @@ -6.16.2310.519 +6.16.2310.615 diff --git a/MP-TAB-SERV/Resources/manifest.xml b/MP-TAB-SERV/Resources/manifest.xml index e62fd14e..0ef7c5c3 100644 --- a/MP-TAB-SERV/Resources/manifest.xml +++ b/MP-TAB-SERV/Resources/manifest.xml @@ -1,6 +1,6 @@ - 6.16.2310.519 + 6.16.2310.615 https://nexus.steamware.net/repository/SWS/MP-TAB-SERV/stable/LAST/MP-TAB-SERV.zip https://nexus.steamware.net/repository/SWS/MP-TAB-SERV/stable/LAST/ChangeLog.html false diff --git a/MP-TAB-SERV/Shared/MainLayout.razor b/MP-TAB-SERV/Shared/MainLayout.razor index 57835be6..f80be328 100644 --- a/MP-TAB-SERV/Shared/MainLayout.razor +++ b/MP-TAB-SERV/Shared/MainLayout.razor @@ -1,12 +1,6 @@ @using System.Diagnostics; @inherits LayoutComponentBase -@implements IDisposable -@inject NavigationManager NavMan -@inject ListSelectDataSrv MDataService -@inject TabDataService TDataService -@inject SharedMemService MStor -@inject MessageService MServ MP-TAB-SERV @@ -52,103 +46,3 @@
    -@code { - /// - /// Elenco items da menù per pagina corrente... - /// - protected List CurrMenuItems { get; set; } = new List(); - - /// - /// Livello corrente del menu - /// - protected string CurrLevel { get; set; } = ""; - - protected string ResetClass = "btn-primary"; - - private void HandleLocationChanged(object? sender, LocationChangedEventArgs e) - { - // Logger.LogInformation("URL of new location: {Location}", e.Location); - CurrLevel = MStor.PageLevel(NavMan.Uri); - // recupero menù - if (MStor.DictMenu.ContainsKey(CurrLevel)) - { - CurrMenuItems = MStor.DictMenu[CurrLevel]; - InvokeAsync(StateHasChanged).ConfigureAwait(false); - } - } - - public void Dispose() - { - NavMan.LocationChanged -= HandleLocationChanged; - } - /// - /// Init struttura dati - /// - /// - protected override async Task OnInitializedAsync() - { - NavMan.LocationChanged += HandleLocationChanged; - // verifica preliminare setup mdati - if (!MStor.MenuOk) - { - var allData = await MDataService.ListLinkAll(); - MStor.SetupMenu(allData); - - // fix config... - var allConf = await MDataService.ConfigGetAll(); - MStor.SetConfig(allConf); - - // fix MSFD... - var allMSFD = await TDataService.VMSFDGetAll(); - MStor.SetMsfd(allMSFD); - - // non da farsi globalmente - // // fix macchine - // var allMach = await MDataService.MacchineByMatrOper(0); - // MStor.DictMacchine = allMach.ToDictionary(x => x.IdxMacchina, x => $"{x.IdxMacchina} | {x.Nome}"); - } - CurrLevel = MStor.PageLevel(NavMan.Uri); - // recupero menù - if (MStor.DictMenu.ContainsKey(CurrLevel)) - { - CurrMenuItems = MStor.DictMenu[CurrLevel]; - } - await Task.Delay(1); - } - - private static Logger Log = LogManager.GetCurrentClassLogger(); - - protected async Task ForceReload() - { - Stopwatch sw = new Stopwatch(); - sw.Start(); - Log.Info("Start ForceReload"); - ResetClass = "btn-warning"; - await InvokeAsync(StateHasChanged); - await MServ.ClearLocalStor(); - await MServ.ClearSessionStor(); - MStor.ClearCache(); - await MDataService.FlushCache(); - var allData = await MDataService.ListLinkAll(); - MStor.SetupMenu(allData); - var allConf = await MDataService.ConfigGetAll(); - MStor.SetConfig(allConf); - sw.Stop(); - int delta = 400 - (int)sw.ElapsedMilliseconds; - if (delta > 0) - { - await Task.Delay(delta); - } - ResetClass = "btn-primary"; - // await InvokeAsync(StateHasChanged); - Log.Info($"ForceReload completed in {sw.ElapsedMilliseconds}ms"); - // ricarica pagina! - NavMan.NavigateTo("/", true); - } - - - private void OnYes() - { - Console.WriteLine($"{DateTime.Now} | 'Yes' button selected."); - } -} \ No newline at end of file diff --git a/MP-TAB-SERV/Shared/MainLayout.razor.cs b/MP-TAB-SERV/Shared/MainLayout.razor.cs new file mode 100644 index 00000000..bf283356 --- /dev/null +++ b/MP-TAB-SERV/Shared/MainLayout.razor.cs @@ -0,0 +1,159 @@ +using global::Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Routing; +using MP.Data.DatabaseModels; +using MP.Data.Services; +using NLog; +using System.Diagnostics; + +namespace MP_TAB_SERV.Shared +{ + public partial class MainLayout : IDisposable + { + #region Public Methods + + public void Dispose() + { + NavMan.LocationChanged -= HandleLocationChanged; + } + + #endregion Public Methods + + #region Protected Fields + + protected string ResetClass = "btn-primary"; + + #endregion Protected Fields + + #region Protected Properties + + /// + /// Livello corrente del menu + /// + protected string CurrLevel { get; set; } = ""; + + /// + /// Elenco items da menù per pagina corrente... + /// + protected List CurrMenuItems { get; set; } = new List(); + + [Inject] + protected ListSelectDataSrv MDataService { get; set; } = null!; + + [Inject] + protected MessageService MServ { get; set; } = null!; + + [Inject] + protected SharedMemService MStor { get; set; } = null!; + + [Inject] + protected NavigationManager NavMan { get; set; } = null!; + + [Inject] + protected TabDataService TDataService { get; set; } = null!; + + #endregion Protected Properties + + #region Protected Methods + + protected async Task ForceReload() + { + Stopwatch sw = new Stopwatch(); + sw.Start(); + Log.Info("Start ForceReload"); + ResetClass = "btn-warning"; + await InvokeAsync(StateHasChanged); + // reset cache varie + await MServ.ClearLocalStor(); + await MServ.ClearSessionStor(); + await MDataService.FlushCache(); + // reload MStor + await ReloadMemStor(); + // calcolo tempo esecuzione + sw.Stop(); + int delta = 500 - (int)sw.ElapsedMilliseconds; + delta = delta > 0 ? delta : 50; + await Task.Delay(delta); + ResetClass = "btn-primary"; + // await InvokeAsync(StateHasChanged); + Log.Info($"ForceReload completed in {sw.ElapsedMilliseconds}ms"); + // ricarica pagina! + NavMan.NavigateTo("/", true); + } + + /// + /// Init struttura dati + /// + /// + protected override async Task OnInitializedAsync() + { + NavMan.LocationChanged += HandleLocationChanged; + // verifica preliminare setup mdati + if (!MStor.MenuOk) + { + await ReloadMemStor(); + } + + CurrLevel = MStor.PageLevel(NavMan.Uri); + // recupero menù + if (MStor.DictMenu.ContainsKey(CurrLevel)) + { + CurrMenuItems = MStor.DictMenu[CurrLevel]; + } + + await Task.Delay(1); + } + + protected async Task ReloadMemStor() + { + // in primis svuoto... + MStor.ClearCache(); + // rileggo link + var allData = await MDataService.ListLinkAll(); + MStor.SetupMenu(allData); + // fix config... + var allConf = await MDataService.ConfigGetAll(); + MStor.SetConfig(allConf); + // fix MSFD... + var allMSFD = await TDataService.VMSFDGetAll(); + MStor.SetMsfd(allMSFD); + // fix elenco eventi + var allEvents = await TDataService.AnagEventiGetAll(); + MStor.SetEventi(allEvents); + // fix elenco stati + var allStati = await TDataService.AnaStatiGetAll(); + MStor.SetStati(allStati); + // non da farsi globalmente // fix macchine var allMach = await + // MDataService.MacchineByMatrOper(0); MStor.DictMacchine = allMach.ToDictionary(x => + // x.IdxMacchina, x => $"{x.IdxMacchina} | {x.Nome}"); + } + + #endregion Protected Methods + + #region Private Fields + + private static Logger Log = LogManager.GetCurrentClassLogger(); + + #endregion Private Fields + + #region Private Methods + + private void HandleLocationChanged(object? sender, LocationChangedEventArgs e) + { + // Logger.LogInformation("URL of new location: {Location}", e.Location); + CurrLevel = MStor.PageLevel(NavMan.Uri); + // recupero menù + if (MStor.DictMenu.ContainsKey(CurrLevel)) + { + CurrMenuItems = MStor.DictMenu[CurrLevel]; + InvokeAsync(StateHasChanged).ConfigureAwait(false); + } + } + + private void OnYes() + { + Console.WriteLine($"{DateTime.Now} | 'Yes' button selected."); + } + + #endregion Private Methods + } +} \ No newline at end of file diff --git a/MP-TAB-SERV/appsettings.json b/MP-TAB-SERV/appsettings.json index d158c405..8996b6b1 100644 --- a/MP-TAB-SERV/appsettings.json +++ b/MP-TAB-SERV/appsettings.json @@ -19,6 +19,7 @@ "OptConf": { "BaseAddr": "https://localhost:7295/MP/TAB3/", "BaseUrl": "/MP/TAB3", - "ImgBasePath": "C:\\Steamware\\macchine" + "ImgBasePath": "C:\\Steamware\\macchine", + "CodModulo": "MoonPro" } } diff --git a/MP.Data/Controllers/MpTabController.cs b/MP.Data/Controllers/MpTabController.cs index 94cf865e..f4b9f048 100644 --- a/MP.Data/Controllers/MpTabController.cs +++ b/MP.Data/Controllers/MpTabController.cs @@ -24,7 +24,7 @@ namespace MP.Data.Controllers #region Public Methods /// - /// Restituisce l'anagrafica eventi per intero + /// Restituisce l'anagrafica EVENTI per intero /// /// public List AnagEventiGetAll() @@ -33,9 +33,25 @@ namespace MP.Data.Controllers using (var dbCtx = new MoonProContext(_configuration)) { dbResult = dbCtx - .DbSetAnagEventi - .AsNoTracking() - .ToList(); + .DbSetAnagEventi + .AsNoTracking() + .ToList(); + } + return dbResult; + } + /// + /// Restituisce l'anagrafica STATI per intero + /// + /// + public List AnagStatiGetAll() + { + List dbResult = new List(); + using (var dbCtx = new MoonProContext(_configuration)) + { + dbResult = dbCtx + .DbSetAnagStati + .AsNoTracking() + .ToList(); } return dbResult; } @@ -138,6 +154,94 @@ namespace MP.Data.Controllers return dbResult; } + /// + /// Stato macchina (da key) + /// + /// + /// + public StatoMacchineModel StatoMacchina(string idxMacchina) + { + StatoMacchineModel dbResult = new StatoMacchineModel(); + using (var dbCtx = new MoonProContext(_configuration)) + { + dbResult = dbCtx + .DbSetStatoMacc + .Where(x => x.IdxMacchina == idxMacchina) + .AsNoTracking() + .FirstOrDefault(); + } + return dbResult; + } + /// + /// MicroStato macchina (da key) + /// + /// + /// + public MicroStatoMacchinaModel MicroStatoMacchina(string idxMacchina) + { + MicroStatoMacchinaModel dbResult = new MicroStatoMacchinaModel(); + using (var dbCtx = new MoonProContext(_configuration)) + { + dbResult = dbCtx + .DbSetMicroStatoMacc + .Where(x => x.IdxMacchina == idxMacchina) + .AsNoTracking() + .FirstOrDefault(); + } + return dbResult; + } + /// + /// Stato macchina - tutte + /// + /// + /// + public List MicroStatoMacchinaGetAll() + { + List dbResult = new List(); + using (var dbCtx = new MoonProContext(_configuration)) + { + dbResult = dbCtx + .DbSetMicroStatoMacc + .AsNoTracking() + .ToList(); + } + return dbResult; + } + /// + /// Aggiornamento record Microstato macchina + /// + /// + /// + public bool MicroStatoMacchinaUpsert(MicroStatoMacchinaModel newRec) + { + bool fatto = false; + using (var dbCtx = new MoonProContext(_configuration)) + { + var actRec = dbCtx + .DbSetMicroStatoMacc + .Where(x => x.IdxMacchina == newRec.IdxMacchina) + .AsNoTracking() + .FirstOrDefault(); + if(actRec==null) + { + dbCtx + .DbSetMicroStatoMacc + .Add(newRec); + } + else + { + actRec.IdxMicroStato = newRec.IdxMicroStato; + actRec.InizioStato = newRec.InizioStato; + actRec.Value = newRec.Value; + + dbCtx.Entry(actRec).State = EntityState.Modified; + } + dbCtx.SaveChanges(); + fatto = true; + } + return fatto; + } + /// /// Effettua conferma prod macchina dell'intero periodo da confermare (ultima conferma /// --> dtEvent) diff --git a/MP.Data/DTO/IobInfoDTO.cs b/MP.Data/DTO/IobInfoDTO.cs deleted file mode 100644 index a0fd39ec..00000000 --- a/MP.Data/DTO/IobInfoDTO.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace MP.Data.DTO -{ - public class IobInfoDTO - { - public string name { get; set; } = "ND"; - public string IP { get; set; } = "::1"; - public string iType { get; set; } = "Win"; - } -} diff --git a/MP.Data/DatabaseModels/AnagStatiModel.cs b/MP.Data/DatabaseModels/AnagStatiModel.cs new file mode 100644 index 00000000..f2222adf --- /dev/null +++ b/MP.Data/DatabaseModels/AnagStatiModel.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MP.Data.DatabaseModels +{ + [Table("AnagraficaStati")] + public class AnagStatiModel + { + [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int IdxStato { get; set; } = 0; + public string Descrizione { get; set; } = ""; + public string Semaforo { get; set; } = ""; + public int Priorita { get; set; } = 0; + public string ClasseTempo { get; set; } = ""; + public bool ShowArticolo { get; set; } = true; + public string KeyStato { get; set; } = ""; + public string NoteStato { get; set; } = ""; + //public string CssClass { get; set; } = ""; + //public string Icon { get; set; } = ""; + } +} diff --git a/MP.Data/DatabaseModels/MicroStatoMacchinaModel.cs b/MP.Data/DatabaseModels/MicroStatoMacchinaModel.cs new file mode 100644 index 00000000..223e5dab --- /dev/null +++ b/MP.Data/DatabaseModels/MicroStatoMacchinaModel.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +#nullable disable +// +// This is here so CodeMaid doesn't reorganize this document +// +namespace MP.Data.DatabaseModels +{ + [Table("MicroStatoMacchina")] + public partial class MicroStatoMacchinaModel + { + [Key] + public string IdxMacchina { get; set; } = "NA"; + public int IdxMicroStato { get; set; } = 0; + public DateTime InizioStato { get; set; } = DateTime.Now; + public string Value { get; set; } = ""; + } +} diff --git a/MP.Data/DatabaseModels/StatoMacchineModel.cs b/MP.Data/DatabaseModels/StatoMacchineModel.cs new file mode 100644 index 00000000..3ce3410b --- /dev/null +++ b/MP.Data/DatabaseModels/StatoMacchineModel.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +#nullable disable +// +// This is here so CodeMaid doesn't reorganize this document +// +namespace MP.Data.DatabaseModels +{ + [Table("StatoMacchine")] + public partial class StatoMacchineModel + { + [Key] + public string IdxMacchina { get; set; } = "NA"; + public int IdxStato { get; set; } = 0; + public DateTime InizioStato { get; set; } = DateTime.Now; + public string Value { get; set; } = ""; + public string CodArticolo { get; set; } = ""; + public float TempoCicloBase { get; set; } = 0; + public int PzPalletProd { get; set; } = 0; + public int MatrOpr { get; set; } = 0; + public string pallet { get; set; } = ""; + } +} diff --git a/MP.Data/MoonProContext.cs b/MP.Data/MoonProContext.cs index 76b41cff..4355ea4e 100644 --- a/MP.Data/MoonProContext.cs +++ b/MP.Data/MoonProContext.cs @@ -39,6 +39,7 @@ namespace MP.Data public virtual DbSet DbSetStatArticoli { get; set; } public virtual DbSet DbSetArticoli { get; set; } public virtual DbSet DbSetAnagEventi { get; set; } + public virtual DbSet DbSetAnagStati { get; set; } public virtual DbSet DbSetMacchine { get; set; } public virtual DbSet DbSetMSE { get; set; } public virtual DbSet DbSetConfig { get; set; } @@ -63,6 +64,8 @@ namespace MP.Data public virtual DbSet DbSetM2S { get; set; } public virtual DbSet DbSetSMI { get; set; } public virtual DbSet DbSetKeepAlive { get; set; } + public virtual DbSet DbSetMicroStatoMacc { get; set; } + public virtual DbSet DbSetStatoMacc { get; set; } public virtual DbSet DbSetStatoProd { get; set; } public virtual DbSet DbSetStAct { get; set; } diff --git a/MP.Data/Objects/Enums.cs b/MP.Data/Objects/Enums.cs new file mode 100644 index 00000000..ee7d02aa --- /dev/null +++ b/MP.Data/Objects/Enums.cs @@ -0,0 +1,459 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MP.Data.Objects +{ + public class Enums + { + public enum DataItemCategory + { + CONDITION = 0, + EVENT = 1, + SAMPLE = 2 + } + + /// + /// Tipo di esito (generico) + /// + public enum esitoExec + { + undone, + ok, + error + } + + /// + /// Tipo di IOB + /// + public enum IobType + { + /// + /// Non definito + /// + ND, + + /// + /// IOB rPI + /// + rPi, + + /// + /// IOB Windows + /// + WIN + } + + public enum modBusAddrType + { + /// + /// ModBus Coil 0xxxxx (booleano) - OUT R/W + /// + Coil = 0, + + /// + /// ModBus Input discreto 1xxxxx (booleano) - IN R + /// + DiscreteInput = 1, + + /// + /// ModBus Input Register 3xxxxx (int[] convertibile a vari int/real) - IN R + /// + InputRegister = 3, + + /// + /// ModBus Holding Register 4xxxxx (int[] convertibile a vari int/real) - OUT R/W + /// + HoldingRegister = 4 + } + + /// + /// Elenco dei tipi di valore gestiti da PLC (inizialmente SIEMENS) + /// + public enum plcDataType + { + /// + /// Tipo boolean + /// + Boolean, + + /// + /// Tipo Int16 intero 16bit + /// + Int, + + /// + /// Tipo UInt16 reversed LowHigh + /// + IntLH, + + /// + /// Tipo Int32 intero 32bit + /// + DInt, + + /// + /// Tipo UInt32 reversed LowHigh + /// + DIntLH, + + /// + /// Tipo UInt16, intero 16bit + /// + Word, + + /// + /// Tipo UInt32, intero Unsigned 32bit + /// + DWord, + + /// + /// Tipo REAL 32 bit + /// + Real, + + /// + /// Tipo REAL 32 bit standard (HighLow) - sinonimo di Real, creato x simmetria con caso LH + /// + RealHL, + + /// + /// Tipo REAL 32 bit con swap byte (LowHigh) al posto del normale caso HL (HighLow) + /// + RealLH, + + /// + /// Tipo stringa + /// + String, + + /// + /// Timpo intero da High/Low Bit positivo (high bit va moltiplicato x 32768 = Uint16Max/2) + /// + HLPInt, + + /// + /// Tipo FLOAT 32 bit con endiannes standard (es modbus) + /// https://www.scadacore.com/tools/programming-calculators/online-hex-converter/ Float - + /// Big Endian (ABCD) + /// + FloatABCD, + + /// + /// Tipo FLOAT 32 bit con endiannes NON standard (es modbus) + /// https://www.scadacore.com/tools/programming-calculators/online-hex-converter/ Float - + /// Mid-Big Endian (BADC) + /// + FloatBADC, + + /// + /// Tipo FLOAT 32 bit con endiannes NON standard (es modbus) + /// https://www.scadacore.com/tools/programming-calculators/online-hex-converter/ Float - + /// Mid-Little Endian (CDAB) + /// + FloatCDAB, + + /// + /// Tipo FLOAT 32 bit con endiannes NON standard (es modbus) + /// https://www.scadacore.com/tools/programming-calculators/online-hex-converter/ Float - + /// Little Endian (DCBA) + /// + FloatDCBA, + + /// + /// Valore bitmap, inteso come array di bit ognuno da trattare come uno stato on/off + /// indipendente e sommabile (es allarmi) + /// + BitMap, + + /// + /// Tipo Byte 8 bit equivalente a BitMap + /// + Byte, + + /// + /// Tipo UInt16 intero senza segno 16bit + /// + UInt, + + /// + /// Tipo UInt32 intero senza segno 32bit + /// + UDInt + } + + /// + /// Tipologia dato Raw Transfer + /// + /// serializzazione Native [JsonConverter(typeof(JsonStringEnumConverter))] serializzazione + /// Newtonsoft json [JsonConverter(typeof(StringEnumConverter))] + [JsonConverter(typeof(StringEnumConverter))] + public enum rawTransfType + { + ND = 0, + + /// + /// Icoel: Batch info + /// + IcoelBatch, + + /// + /// Icoel: Variety + layout info relative + /// + IcoelVarInfo, + + /// + /// Info tipo tabella RegGiacenze (MAG) + /// + RegGiacenze + } + + /// + /// Enumerazione tipi di semaforo + /// + public enum Semaforo + { + /// + /// Stato non definito + /// + ND, + + /// + /// Verde + /// + SV, + + /// + /// Giallo + /// + SG, + + /// + /// Rosso + /// + SR, + + /// + /// Grigio/Spento + /// + SS + } + + /// + /// Elenco task ammessi (x IOB-WIN da eseguire...) + /// + public enum taskType + { + /// + /// Task nullo / fake + /// + nihil, + + /// + /// Rimanda a PLC eventuale segnale NON in setup (MA NON RESETTA) + /// + fixStopSetup, + + /// + /// Indica al PLC di forzare il reset del contapezzi + /// + forceResetPzCount, + + /// + /// Indica al PLC di forzare il NUOVO valore di contapezzi (impostato come value) + /// + forceSetPzCount, + + /// + /// Imposta Articolo su PLC + /// + setArt, + + /// + /// Imposta Commessa su PLC + /// + setComm, + + /// + /// Set di un PARAMETRO su PLC (in value avremo un JSON object) + /// + setParameter, + + /// + /// Set Programma CNC su PLC + /// + setProg, + + /// + /// Indica al PLC di impostare il numero di pezzi da produrre per la commessa (impostato + /// come value) + /// + setPzComm, + + /// + /// Indica al PLC iniziato setup (e secondo casi ferma contapezzi /resetta) + /// + startSetup, + + /// + /// Indica al PLC finito setup (e secondo casi ferma contapezzi /resetta) + /// + stopSetup, + + /// + /// Richiesta invio watchdog a PLC + /// + sendWatchDogMes2Plc, + + /// + /// Indica che è FINITA la produzione (e quindi cancello dati backup) + /// + endProd, + + /// + /// Richiesta esecuzione di un sync dei dati DB di frontiera + /// + syncDbData, + + /// + /// Imposta Fornitore (es grower x ICOEL) + /// + setSupplier, + + /// + /// Effettua processing other info (es ritorno consumi x ricette FIMAT) + /// + processOtherInfo + } + + /// + /// Finestra temporale di aggregazione dati VC + /// + public enum timeWindow + { + free, + hour, + day, + week, + month + } + + public enum tipoBarcode + { + /// + /// tipo non riconosciuto + /// + nd, + + /// + /// identifica una matricola operatore nel formato OPxxxxx (xxxxx è un intero che + /// rappresenta la matricola, std fino a 8 cifre) + /// + matrOperatore, + + /// + /// identifica un cartellino di tipo CodArticolo + /// + codArticolo, + + /// + /// identifica un codice per le attività di inizio/fine attrezzaggio e inizio/fine produzione + /// + attrezzaggio, + + /// + /// identifica un codice per le attività di conferma produzione/fermi + /// + confermaProduzione, + + /// + /// identifica un cartellino di dichiarazione fermata nel formato FExxxx dove xxxx è + /// idxEvento dichiarato... + /// + dichiaraFermata, + + /// + /// indentifica un codice di modifica turno + /// + modificaTurno + } + + /// + /// tipologia di evento (generico) segnalato + /// + public enum tipoEvento + { + /// + /// evento di reset + /// + reset, + + /// + /// richiesta editing + /// + edit, + + /// + /// nuova selezione + /// + selection, + + /// + /// eliminazione record(s) + /// + delete + } + + /// + /// tipologia evento inviato + /// + public enum tipoInputEvento + { + barcode, + hw + } + + /// + /// Tipologia di selettore + /// + public enum tipoSelettore + { + articoli + } + + /// + /// Tipologia di elaborazione/funzione da applicare a VC + /// + public enum VC_func + { + /// + /// Valore puntuale + /// + POINT = 0, + + /// + /// Valore medio del periodo + /// + AVG, + + /// + /// Valore massimo del periodo + /// + MAX, + + /// + /// Valore minimo del periodo + /// + MIN, + + /// + /// Calcolo della mediana del periodo + /// + MEDIAN + } + } +} diff --git a/MP.Data/Objects/IOB_data.cs b/MP.Data/Objects/IOB_data.cs new file mode 100644 index 00000000..3c05c8bb --- /dev/null +++ b/MP.Data/Objects/IOB_data.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static MP.Data.Objects.Enums; + +namespace MP.Data.Objects +{ + /// + /// Dati resoconto IOB + /// + public class IOB_data + { + #region Public Fields + + public bool CNC_Counter { get; set; }=false; + public string IP { get; set; } =""; + public IobType iType { get; set; } = IobType.ND; + public string name { get; set; } ="ND"; + public string typeCss { get; set; } = "fa fa-question-circle-o"; + + #endregion Public Fields + } +} diff --git a/MP.Data/Objects/InputComandoMapo.cs b/MP.Data/Objects/InputComandoMapo.cs new file mode 100644 index 00000000..206d920b --- /dev/null +++ b/MP.Data/Objects/InputComandoMapo.cs @@ -0,0 +1,103 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MP.Data.Objects +{ + /// + /// Struttura gestione comandi di input + /// + public struct inputComandoMapo + { + #region Public Fields + + /// + /// descrizione comando + /// + public string descrComando; + + /// + /// idx evento associato al comando + /// + public int idxTipoEvento; + + /// + /// input comando valido si/no + /// + public bool isValid; + + /// + /// refresh stato macchina encessario si/no + /// + public bool needStatusRefresh; + + /// + /// valore di output dal comando + /// + public string outValue; + + /// + /// input precedente + /// + public string precInput; + + /// + /// testo da mostrare all'utente + /// + public string text2show; + + /// + /// lista del nome dei WebBrowserBox e delle relative url, nel formato {0}##{1} {0}=nome + /// WebBrowserBox (es. box01), {1}=url relativo (es. http://server/MoonPro/Produzione.aspx?idxMacchina=99) + /// + public string[] wBrowsBoxUrls; + + #endregion Public Fields + + #region Public Methods + + public static bool operator !=(inputComandoMapo left, inputComandoMapo right) + { + return !(left == right); + } + + public static bool operator ==(inputComandoMapo left, inputComandoMapo right) + { + return left.Equals(right); + } + + public override bool Equals(object obj) + { + if (!(obj is inputComandoMapo item)) + return false; + + if (descrComando != item.descrComando) + return false; + if (idxTipoEvento != item.idxTipoEvento) + return false; + if (isValid != item.isValid) + return false; + if (needStatusRefresh != item.needStatusRefresh) + return false; + if (outValue != item.outValue) + return false; + if (precInput != item.precInput) + return false; + if (text2show != item.text2show) + return false; + if (wBrowsBoxUrls != item.wBrowsBoxUrls) + return false; + + return true; + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } + + #endregion Public Methods + } +} diff --git a/MP.Data/Services/SharedMemService.cs b/MP.Data/Services/SharedMemService.cs index 442b12f5..b0cece8a 100644 --- a/MP.Data/Services/SharedMemService.cs +++ b/MP.Data/Services/SharedMemService.cs @@ -20,6 +20,11 @@ namespace MP.Data.Services /// public Dictionary DictConfig { get; set; } = new Dictionary(); + /// + /// Dizionario Eventi (codice, record completo) + /// + public Dictionary DictEventi { get; set; } = new Dictionary(); + /// /// Dizionario macchine (shared) /// @@ -30,6 +35,20 @@ namespace MP.Data.Services /// public Dictionary DictMacchMulti { get; set; } = new Dictionary(); + /// + /// Dizionario Menu + /// + public Dictionary> DictMenu { get; set; } = new Dictionary>(); + + /// + /// Dizionario Stati (codice, record completo) + /// + public Dictionary DictStati { get; set; } = new Dictionary(); + + /// + /// Lista completa eventi + /// + public List ListEventi { get; set; } = new List(); /// /// List configurazione attiva da tab DB @@ -37,9 +56,9 @@ namespace MP.Data.Services public List ListMSFD { get; set; } = new List(); /// - /// Dizionario Menu + /// Lista completa stati /// - public Dictionary> DictMenu { get; set; } = new Dictionary>(); + public List ListStati { get; set; } = new List(); public bool MenuOk { @@ -50,6 +69,75 @@ namespace MP.Data.Services #region Public Methods + /// + /// Reset cache memory + /// + public void ClearCache() + { + DictMacchine = new Dictionary(); + DictMacchMulti = new Dictionary(); + DictMenu = new Dictionary>(); + DbConfig = new List(); + DictConfig = new Dictionary(); + DictEventi = new Dictionary(); + DictStati = new Dictionary(); + Log.Info("SharedMemService | Cache resetted!"); + } + + public string GetConf(string chiave) + { + string answ = ""; + if (DictConfig.ContainsKey(chiave)) + { + answ = DictConfig[chiave]; + } + return answ; + } + + public bool GetConfBool(string chiave) + { + bool answ = false; + bool.TryParse(GetConf(chiave), out answ); + return answ; + } + + public int GetConfInt(string chiave) + { + int answ = 0; + int.TryParse(GetConf(chiave), out answ); + return answ; + } + + /// + /// Recupero riga evento da dizionario + /// + /// + /// + public AnagEventiModel GetEventRow(int IdxTipo) + { + AnagEventiModel answ = new AnagEventiModel(); + if (DictEventi.ContainsKey(IdxTipo)) + { + answ = DictEventi[IdxTipo]; + } + return answ; + } + + /// + /// Recupero riga stato da dizionario + /// + /// + /// + public AnagStatiModel GetStateRow(int IdxStato) + { + AnagStatiModel answ = new AnagStatiModel(); + if (DictStati.ContainsKey(IdxStato)) + { + answ = DictStati[IdxStato]; + } + return answ; + } + /// /// Restituisce il livello pagina dato URL /// - se contiene ?IdxMacc --> T2D (detail) @@ -76,26 +164,22 @@ namespace MP.Data.Services return answ; } - /// - /// Reset cache memory - /// - public void ClearCache() + public void SetConfig(List? allConf) { - DictMacchine = new Dictionary(); - DictMenu = new Dictionary>(); - DbConfig = new List(); - DictConfig = new Dictionary(); - Log.Info("SharedMemService | Cache resetted!"); - } - - public void SetConfig(List? newConfList) - { - DbConfig = newConfList ?? new List(); + DbConfig = allConf ?? new List(); // salvo dizionario DictConfig = DbConfig.ToDictionary(x => x.Chiave, x => x.Valore); Log.Info("SharedMemService | SetConfig executed!"); } + public void SetEventi(List allEvents) + { + ListEventi = allEvents ?? new List(); + // salvo dizionario + DictEventi = ListEventi.ToDictionary(x => x.IdxTipo, x => x); + Log.Info("SharedMemService | SetEventi executed!"); + } + public void SetMsfd(List newList) { ListMSFD = newList ?? new List(); @@ -104,6 +188,14 @@ namespace MP.Data.Services Log.Info("SharedMemService | SetMsfd executed!"); } + public void SetStati(List allStati) + { + ListStati = allStati ?? new List(); + // salvo dizionario + DictStati = ListStati.ToDictionary(x => x.IdxStato, x => x); + Log.Info("SharedMemService | SetStati executed!"); + } + /// /// Effettua setup memorie menu recuperando dati dal DB + popolando dizionario x livelli /// @@ -132,30 +224,6 @@ namespace MP.Data.Services Log.Info("SharedMemService | SetupMenu executed!"); } - public string GetConf(string chiave) - { - string answ = ""; - if (DictConfig.ContainsKey(chiave)) - { - answ = DictConfig[chiave]; - } - return answ; - } - public int GetConfInt(string chiave) - { - int answ = 0; - int.TryParse(GetConf(chiave), out answ); - return answ; - } - public bool GetConfBool(string chiave) - { - bool answ = false; - bool.TryParse(GetConf(chiave), out answ); - return answ; - } - - - #endregion Public Methods #region Private Fields diff --git a/MP.Data/Services/TabDataService.cs b/MP.Data/Services/TabDataService.cs index 2e0a3dc4..40cbca19 100644 --- a/MP.Data/Services/TabDataService.cs +++ b/MP.Data/Services/TabDataService.cs @@ -1,6 +1,7 @@ using Microsoft.Extensions.Configuration; using MP.Data.DatabaseModels; using MP.Data.DTO; +using MP.Data.Objects; using Newtonsoft.Json; using NLog; using StackExchange.Redis; @@ -9,6 +10,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Text; using System.Threading.Tasks; +using static MP.Data.Objects.Enums; namespace MP.Data.Services { @@ -25,8 +27,8 @@ namespace MP.Data.Services redisDb = redisConn.GetDatabase(); // conf DB - string connStr = _configuration.GetConnectionString("Mp.All"); - if (string.IsNullOrEmpty(connStr)) + ConnStr = _configuration.GetConnectionString("Mp.All"); + if (string.IsNullOrEmpty(ConnStr)) { Log.Error("ConnString empty!"); } @@ -38,9 +40,47 @@ namespace MP.Data.Services dbIocController = new Controllers.MpIocController(configuration); sb.AppendLine($"TabDataService | MpIocController OK"); Log.Info(sb.ToString()); + // sistemo i parametri x redHas... + CodModulo = _configuration.GetValue("OptConf:CodModulo"); + var cstringArray = ConnStr.Split(";"); + foreach (var item in cstringArray) + { + var cData = item.Trim().Split("="); + if (cData.Length == 2) + { + if (!connStrParams.ContainsKey(cData[0])) + { + connStrParams.Add(cData[0], cData[1]); + } + } + } + // sistemo + DataSource = connStrParams["Server"]; + DataBase = connStrParams["Database"]; } } + private Dictionary connStrParams = new Dictionary(); + private string ConnStr = ""; + private string CodModulo = ""; + private string DataSource = ""; + private string DataBase = ""; + + private string redHash(string keyName) + { + string result = keyName; + try + { + result = $"{CodModulo}:{DataSource}:{DataBase}:{keyName}".Replace("\\", "_"); + } + catch (Exception exc) + { + Log.Error($"Errore in redHash{Environment.NewLine}{exc}"); + } + + return result; + } + #endregion Public Constructors #region Public Properties @@ -52,6 +92,10 @@ namespace MP.Data.Services #region Public Methods + /// + /// Elenco completo EVENTI + /// + /// public async Task> AnagEventiGetAll() { // setup parametri costanti @@ -85,6 +129,43 @@ namespace MP.Data.Services return result; } + /// + /// Elenco completo STATI + /// + /// + public async Task> AnaStatiGetAll() + { + // setup parametri costanti + DateTime startDate = new DateTime(2000, 1, 1); + DateTime endDate = DateTime.Today.AddDays(1); + string source = "DB"; + Stopwatch sw = new Stopwatch(); + sw.Start(); + List? result = new List(); + // cerco in redis... + string currKey = $"{redisBaseKey}:AnagStati"; + RedisValue rawData = await redisDb.StringGetAsync(currKey); + if (!string.IsNullOrEmpty($"{rawData}")) + { + result = JsonConvert.DeserializeObject>($"{rawData}"); + source = "REDIS"; + } + else + { + result = dbTabController.AnagStatiGetAll(); + // serializzp e salvo... + rawData = JsonConvert.SerializeObject(result); + await redisDb.StringSetAsync(currKey, rawData, LongCache); + } + if (result == null) + { + result = new List(); + } + sw.Stop(); + Log.Debug($"AnaStatiGetAll | {source} | {sw.Elapsed.TotalMilliseconds}ms"); + return result; + } + /// /// Effettua conferma prod macchina dell'intero periodo da confermare (ultima conferma /// --> dtEvent) @@ -160,24 +241,23 @@ namespace MP.Data.Services - - public async Task IobInfo(string IdxMacchina) + public async Task IobInfo(string IdxMacchina) { string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); - IobInfoDTO? result = new IobInfoDTO(); + IOB_data? result = new IOB_data(); // cerco in redis... - string currKey = $"{moonProRedisBaseKey}:{IdxMacchina}"; + string currKey = redHash($"hM2IOB:{IdxMacchina}"); RedisValue rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty($"{rawData}")) { - result = JsonConvert.DeserializeObject($"{rawData}"); + result = JsonConvert.DeserializeObject($"{rawData}"); source = "REDIS"; } if (result == null) { - result = new IobInfoDTO(); + result = new IOB_data(); } sw.Stop(); Log.Debug($"IobInfo | {source} | {sw.Elapsed.TotalMilliseconds}ms"); @@ -314,6 +394,41 @@ namespace MP.Data.Services Log.Debug($"StatoProdMacchina | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } + /// + /// Stato macchina + /// + /// + /// + public async Task StatoMacchina(string idxMacchina) + { + // setup parametri costanti + string source = "DB"; + Stopwatch sw = new Stopwatch(); + sw.Start(); + StatoMacchineModel? result = new StatoMacchineModel(); + // cerco in redis... + string currKey = $"{redisBaseKey}:StatoMacc:{idxMacchina}"; + RedisValue rawData = await redisDb.StringGetAsync(currKey); + if (!string.IsNullOrEmpty($"{rawData}")) + { + result = JsonConvert.DeserializeObject($"{rawData}"); + source = "REDIS"; + } + else + { + result = dbTabController.StatoMacchina(idxMacchina); + // serializzp e salvo... + rawData = JsonConvert.SerializeObject(result); + await redisDb.StringSetAsync(currKey, rawData, TimeSpan.FromSeconds(2)); + } + if (result == null) + { + result = new StatoMacchineModel(); + } + sw.Stop(); + Log.Debug($"StatoMacchina | {source} | {sw.Elapsed.TotalMilliseconds}ms"); + return result; + } /// /// Intera vista v_MSFD @@ -444,5 +559,292 @@ namespace MP.Data.Services private string moonProRedisBaseKey = "MoonPro:SQL2016DEV:MoonPro:hM2IOB"; #endregion Private Fields + /// + /// Aggiunta record EventList + /// + /// + /// + public async Task EvListInsert(EventListModel newRec) + { + bool fatto = false; + using (var dbCtx = new MoonProContext(_configuration)) + { + try + { + var currRec = dbCtx + .DbSetEvList + .Add(newRec); + await dbCtx.SaveChangesAsync(); + } + catch (Exception exc) + { + Log.Error($"Eccezione durante EvListInsert{Environment.NewLine}{exc}"); + } + } + await Task.Delay(1); + return fatto; + } + + /// + /// scrive una riga di evento inviato da Barcode nel db + /// + /// codice macchina + /// idx evento + /// Codice Articolo + /// valore + /// matricola operatore + /// pallet (vuoto se nd) + /// + public async Task scriviRigaEventoBarcode(string idxMacchina, int idxTipo, string codArticolo, string value, int matrOpr, string pallet) + { + bool inserito = false; + DateTime adesso = DateTime.Now; + EventListModel newRec = new EventListModel() + { + IdxMacchina = idxMacchina, + InizioStato = adesso, + IdxTipo = idxTipo, + CodArticolo = codArticolo, + Value = value, + MatrOpr = matrOpr, + pallet = pallet + }; + try + { + // inserisco evento + inserito = await EvListInsert(newRec); + } + catch (Exception exc) + { + string logMsg = $"Eccezione in fase di scrittura evento con i seguenti dati | macchina: {idxMacchina} | IdxTipo: {idxTipo} | CodArticolo: {codArticolo} | Value {value} | MatrOpr {matrOpr} | Pallet {pallet}{Environment.NewLine}{exc}"; + Log.Error(logMsg); + } + try + { + // faccio controllo per eventuale cambio stato da tab transizioni... + checkCambiaStatoBatch(tipoInputEvento.barcode, idxMacchina, adesso, idxTipo, codArticolo, value, matrOpr, pallet); + } + catch (Exception exc) + { + string logMsg = $"Eccezione in checkCambiaStatoBatch(6) | tipoInputEvento: {tipoInputEvento.barcode} | macchina: {idxMacchina} | dataOra: {adesso} | IdxTipo: {idxTipo} | CodArticolo: {codArticolo} | Value {value} | MatrOpr {matrOpr} | Pallet {pallet}{Environment.NewLine}{exc}"; + Log.Error(logMsg); + } + // formatto output + inputComandoMapo answ = new inputComandoMapo(); + answ.outValue = inserito.ToString(); + answ.needStatusRefresh = true; + return answ; + } + /// + /// Verifica se sia necessario inserire un cambio di stato impianto in modalità batch + /// + /// + /// + /// + /// + /// + /// + /// + /// + private void checkCambiaStatoBatch(tipoInputEvento tipoInput, string IdxMacchina, DateTime InizioStato, int IdxTipo, string CodArt, string Value, int MatrOpr, string pallet) + { +#if false + DS_applicazione.TransizioneStatiDataTable tabTransStati; + DS_applicazione.TransizioneStatiRow rigaTransStati; + switch (tipoInput) + { + case tipoInputEvento.barcode: + // effettuo cambio stato INDIPENDENTEMENTE da stato precedente + try + { + tabTransStati = MapoDbObj.taTranSt.GetUserForcedTransitions(IdxMacchina, IdxTipo); + if (tabTransStati != null) + { + if (tabTransStati.Count > 0) + { + rigaTransStati = tabTransStati[0]; + // solo se cambia stato... + if (rigaTransStati.IdxStato != rigaTransStati.next_IdxStato) + { + MapoDbObj.taDiario.InsStatoBatch(IdxMacchina, InizioStato, rigaTransStati.next_IdxStato, CodArt, Value, MatrOpr, pallet); + // aggiorno MSE + taMSE.forceRecalc(0, IdxMacchina); + } + } + else + { + if (_logLevel > 6) + { + Log.Info($"Non trovata riga per: BARCODE | IdxMacchina: {IdxMacchina} | IdxTipo: {IdxTipo} | CodArt: {CodArt} | Value: {Value} | MatrOpr: {MatrOpr} | pallet: {pallet}", tipoLog.INFO); + } + } + } + } + catch (Exception exc) + { + // non dovrebbe succedere... input utente da barcode dovrebbero TUTTI essere + // inseriti in tab transizione con famiglia 1... + Log.Info($"Errore controllo transizione stato x evento barcode: BARCODE | IdxMacchina: {IdxMacchina} | IdxTipo: {IdxTipo} | CodArt: {CodArt} | Value: {Value} | MatrOpr: {MatrOpr} | pallet: {pallet}{Environment.NewLine}{exc}", tipoLog.EXCEPTION); + } + break; + + case tipoInputEvento.hw: + // verifico se ci sia necessità di cambio stato + try + { + tabTransStati = MapoDbObj.taTranSt.GetHwTransitions(IdxMacchina, IdxTipo); + if (tabTransStati != null) + { + if (tabTransStati.Count > 0) + { + rigaTransStati = tabTransStati[0]; + if (rigaTransStati != null) + { + // solo se cambia stato... + if (rigaTransStati.IdxStato != rigaTransStati.next_IdxStato) + { + MapoDbObj.taDiario.InsStatoBatch(IdxMacchina, InizioStato, rigaTransStati.next_IdxStato, CodArt, Value, MatrOpr, pallet); + } + } + } + else + { + if (_logLevel > 6) + { + Log.Info($"Non trovata riga per: HW | IdxMacchina: {IdxMacchina} | IdxTipo: {IdxTipo} | CodArt: {CodArt} | Value: {Value} | MatrOpr: {MatrOpr} | pallet: {pallet}", tipoLog.INFO); + } + } + } + } + catch (Exception exc) + { + // non trovo riga [0]... NON scrivo! + Log.Info($"Errore controllo transizione stato x evento barcode: HW | IdxMacchina: {IdxMacchina} | IdxTipo: {IdxTipo} | CodArt: {CodArt} | Value: {Value} | MatrOpr: {MatrOpr} | pallet: {pallet}{Environment.NewLine}{exc}", tipoLog.EXCEPTION); + } + break; + } +#endif + } + + /// + /// Effettua reset microstato macchina + /// + /// + public void resetMicrostatoMacchina(string idxMacchina) + { + // salvo microstato 0... + MicroStatoMacchinaModel newRecMS = new MicroStatoMacchinaModel() + { + IdxMacchina = idxMacchina, + InizioStato = DateTime.Now, + IdxMicroStato = 0, + Value = "FER" + }; + var result = dbTabController.MicroStatoMacchinaUpsert(newRecMS); + // reset in redis + resetDatiMacchina(idxMacchina); + } + + /// + /// Resetta (rileggendo) i dati della macchina + /// + /// + /// + public Dictionary resetDatiMacchina(string idxMacchina) + { + Dictionary answ = new Dictionary(); +#if false + string currHash = dtMaccHash(idxMacchina); + // inizio con un bel reset... + memLayer.ML.redFlushKey(currHash); + DS_applicazione.MSFDDataTable tabMSFD = new DS_applicazione.MSFDDataTable(); + // 2018.01.08 SEMPRE senza singleton: instanzio un nuovo oggetto MapoDb + MapoDb connDb = new MapoDb(); + tabMSFD = connDb.taMSFD.getByIdxMacc(idxMacchina); + bool trovato = false; + // se ho righe... + DS_applicazione.MSFDDataTable tab = new DS_applicazione.MSFDDataTable(); + DS_applicazione.MSFDRow rigaMSFD; + if (tabMSFD.Rows.Count > 0) + { + try + { + rigaMSFD = tabMSFD[0]; + trovato = true; + } + catch + { + rigaMSFD = tab.NewMSFDRow(); + } + } + else + { + rigaMSFD = tab.NewMSFDRow(); + } + if (trovato) + { + // ora provo a compilare... + try + { + // salvo 1:1 i valori... STATO + answ.Add("IdxMicroStato", rigaMSFD.IdxMicroStato.ToString()); + answ.Add("IdxStato", rigaMSFD.IdxStato.ToString()); + answ.Add("CodArticolo", rigaMSFD.CodArticolo); + answ.Add("insEnabled", rigaMSFD.insEnabled.ToString()); + answ.Add("sLogEnabled", rigaMSFD.sLogEnabled.ToString()); + answ.Add("pallet", rigaMSFD.pallet); + answ.Add("CodArticolo_A", rigaMSFD.CodArticolo_A); + answ.Add("CodArticolo_B", rigaMSFD.CodArticolo_B); + answ.Add("TempoCicloBase", rigaMSFD.TempoCicloBase.ToString()); + answ.Add("PzPalletProd", rigaMSFD.PzPalletProd.ToString()); + answ.Add("MatrOpr", rigaMSFD.MatrOpr.ToString()); + answ.Add("lastVal", rigaMSFD.lastVal); + answ.Add("TCBase", rigaMSFD.TempoCicloBase.ToString()); + + //...e SETUP + answ.Add("CodMacc", rigaMSFD.codmacchina); + answ.Add("IdxFamIn", rigaMSFD.IdxFamigliaIngresso.ToString()); + answ.Add("Multi", rigaMSFD.Multi.ToString()); + answ.Add("BitFilt", rigaMSFD.BitFilt.ToString()); + answ.Add("MaxVal", rigaMSFD.MaxVal.ToString()); + answ.Add("BSR", rigaMSFD.BSR.ToString()); + answ.Add("ExplodeBit", rigaMSFD.ExplodeBit.ToString()); + answ.Add("NumBit", rigaMSFD.NumBit.ToString()); + answ.Add("IdxFamMacc", rigaMSFD.IdxFamiglia.ToString()); + answ.Add("simplePallet", rigaMSFD.simplePallet.ToString()); + answ.Add("palletChange", rigaMSFD.palletChange.ToString()); + } + catch (Exception exc) + { + Log.Info(string.Format("Errore in compilazione dati MSFD:{0}{1}", Environment.NewLine, exc), tipoLog.EXCEPTION); + } + // cerco dati master/slave... + string isMaster = connDb.taM2S.getByMaster(idxMacchina).Count > 0 ? "1" : "0"; + string isSlave = connDb.taM2S.getBySlave(idxMacchina).Count > 0 ? "1" : "0"; + answ.Add("Master", isMaster); + answ.Add("Slave", isSlave); + + // verifico il timeout che cambia a seconda che sia vero o falso insEnabled... + int tOutShort = memLayer.ML.cdvi("TmOut.MS.S"); + int tOutLong = memLayer.ML.cdvi("TmOut.MS.L"); + int redDtMacTOut = tOutLong; + try + { + redDtMacTOut = (answ["insEnabled"].ToLower() == "true") ? tOutShort : tOutLong; + } + catch (Exception exc) + { + Log.Info($"Eccezione in calcolo timeout dati macchina: idxMacchina{idxMacchina} | TShort: {tOutShort} | TLong {tOutLong}{Environment.NewLine}{exc}"); + } + // salvo in redis! + memLayer.ML.redSaveHashDict(currHash, answ, redDtMacTOut); + } + else + { + Log.Info("Errore in chiamata stp_MSFD_getMacc (connDb.taMSFD.getByIdxMacc(idxMacchina))"); + } +#endif + return answ; + } } } \ No newline at end of file