diff --git a/MP-TAB-SERV/Components/CardTest.razor b/MP-TAB-SERV/Components/CardTest.razor new file mode 100644 index 00000000..908afa56 --- /dev/null +++ b/MP-TAB-SERV/Components/CardTest.razor @@ -0,0 +1,62 @@ +
+
+

+ @if (DoPlaceholder) + { +
+ +
+ } + else + { + @Title + } +

+
+
+ @if (DoPlaceholder) + { +
+ + + + +
+ } + else + { +

@ChildContent

+ } +
+ +
+ +@code { + [Parameter] + public RenderFragment? ChildContent { get; set; } + + [Parameter] + public string? Title { get; set; } + + [Parameter] + public string CardCss { get; set; } = ""; + + [Parameter] + public bool DoPlaceholder { get; set; } = false; + + private void OnYes() + { + Console.WriteLine($"{Title} | 'Yes' button selected."); + } +} \ No newline at end of file diff --git a/MP-TAB-SERV/Components/MachineBlock.razor b/MP-TAB-SERV/Components/MachineBlock.razor new file mode 100644 index 00000000..9d1d4c05 --- /dev/null +++ b/MP-TAB-SERV/Components/MachineBlock.razor @@ -0,0 +1,304 @@ +@if (RecMSE == null) +{ +
+
+
+ + + + +
+
+
+} +else +{ + @if (FullMode) + { +
+ @RecMSE.CodMacchina +
+
+
+
+
+ Art +
+
+ @RecMSE.CodArticolo +
+
+
+
+ @($"PODL{RecMSE.IdxPOdl:00000000}") +
+
+ @($"ODL{RecMSE.IdxOdl:00000000}") +
+
+
+
+
+
+
+

+ @RecMSE.Nome +

+
+
+
+
+ @RecMSE.DescrizioneStato +
+
+ @(formatDurata(RecMSE.Durata)) +
+
+
+
+
+
+ Confermati +
+
+ Prodotti +
+
+ Ordinati +
+
+
+
+ @($"{RecMSE.PezziConf:N0}") +
+
+ @($"{RecMSE.PezziProd:N0}") +
+
+ @($"{RecMSE.NumPezzi:N0}") +
+
+
+
+ +
+
+
+
+
+
+
+ } + else + { +
+
+
+
+
+
+ Art +
+
+ @RecMSE.CodArticolo +
+
+
+
+ @($"PODL{RecMSE.IdxPOdl:00000000}") +
+
+ @($"ODL{RecMSE.IdxOdl:00000000}") +
+
+
+
+
+
+
+

+ @RecMSE.Nome +

+
+
+
+
+ @RecMSE.DescrizioneStato +
+
+ @(formatDurata(RecMSE.Durata)) +
+
+
+
+
+
+ Confermati +
+
+ Prodotti +
+
+ Ordinati +
+
+
+
+ @($"{RecMSE.PezziConf:N0}") +
+
+ @($"{RecMSE.PezziProd:N0}") +
+
+ @($"{RecMSE.NumPezzi:N0}") +
+
+
+
+ +
+
+
+
+
+
+
+ } +} + +@code { + + [Parameter] + public MappaStatoExpl? RecMSE { get; set; } = null; + + + [Parameter] + public int keepAliveMin { get; set; } = 5; + + + [Parameter] + public bool FullMode { get; set; } = true; + + [Inject] + protected NavigationManager NavMan { get; set; } = null!; + + + protected int kaFactor = 60 / 2; + + protected override void OnInitialized() + { + // se configurata uso cartella virtuale... altrimenti cartella processo + imgBasePath = Environment.CurrentDirectory;// @"C:\Steamware\macchine"; + } + + private string imgBasePath = ""; + + protected ProdAdvDispl.ProdCounter CurrCount + { + get + { + ProdAdvDispl.ProdCounter answ = new ProdAdvDispl.ProdCounter() + { + numPzConf = (int)RecMSE.PezziConf, + numPzOrd= (int)RecMSE.NumPezzi, + numPzProd= (int)RecMSE.PezziProd + }; + return answ; + } + } + + protected async Task ShowDetail() + { + NavMan.NavigateTo($"machine-detail/?IdxMacc={RecMSE!.IdxMacchina}"); + } + + /// + /// url completo immagine + /// + /// + /// + public string ImgUrlMacc(string url) + { + string answ = ""; + if (string.IsNullOrEmpty(url.ToString())) + { + url = "Steamware.png"; + } + // verifico esistenza macchina SMALL... + answ = $"images/macchine/small/{url}"; + string fullPath = Path.Combine(imgBasePath, "wwwroot", answ); + if (!File.Exists(fullPath)) + { + // se non ci fosse cerco immagine fullsize + answ = $"images/macchine/{url}"; + fullPath = Path.Combine(imgBasePath, "wwwroot", answ); + } + // altrimenti metto default Steamware + if (!File.Exists(fullPath)) + { + answ = "images/macchine/Steamware.png"; + } + return answ; + } + + /// + /// formatta la durata in minuti in un modo "human readable" gg/ore/min + /// + /// minuti + /// + public static string formatDurata(double? minuti) + { + string answ = "??"; + if (minuti != null) + { + DateTime tempo = new DateTime(); + tempo = tempo.AddMinutes((double)minuti); + + if (minuti < 60) + { + answ = $"{tempo.Minute:00}:{tempo.Second:00}"; + } + else if (minuti < 1440) + { + answ = $"{tempo.Hour}h {tempo.Minute}m"; + } + else + { + answ = $"{tempo.DayOfYear}g {tempo.Hour}h"; + } + } + return answ; + } + + private string cssComStatus(string semaforo, DateTime? lastUpdateN) + { + DateTime lastUpdate = lastUpdateN.HasValue ? (DateTime)lastUpdateN : DateTime.Now.AddHours(-1); + string answ = cssStatus(semaforo); + if (DateTime.Now.Subtract(lastUpdate).TotalSeconds > (keepAliveMin * kaFactor)) + { + answ = $"{baseCss}Ro"; + // blink se secondo pari... + DateTime adesso = DateTime.Now; + int resto = 0; + Math.DivRem(adesso.Second, 2, out resto); + if (resto == 0) + { + answ += "_b"; + } + } + return answ; + } + + private string cssStatus(string codSemaforo) + { + // se vuoto --> mostra nero! + if (string.IsNullOrEmpty(codSemaforo)) + { + codSemaforo = "sNe"; + } + string codColore = codSemaforo.Substring(1, 2); + string answ = $"{baseCss}{codColore}"; + return answ; + } + protected string baseCss = "sem"; +} diff --git a/MP-TAB-SERV/Components/ProdAdvDispl.razor b/MP-TAB-SERV/Components/ProdAdvDispl.razor new file mode 100644 index 00000000..fd61c443 --- /dev/null +++ b/MP-TAB-SERV/Components/ProdAdvDispl.razor @@ -0,0 +1,121 @@ +
+
+ @($"{NumGreen}%") +
+
+ @($"{NumYellow}%") +
+
+ @($"{NumGray}%") +
+
+ @($"{NumBlue}%") +
+
+ + +@code { + /// + /// Conteggio dati produzione da mostrare + /// + [Parameter] + public ProdCounter CountData { get; set; } = null!; + + /// + /// Numero pezzi CONFERMATI + /// + protected int NumPzConf { get; set; } = 0; + + /// + /// Numero pezzi ORDINATI + /// + protected int NumPzOrd { get; set; } = 0; + + /// + /// Numero pezzi PRODOTTI + /// + protected int NumPzProd { get; set; } = 0; + + + /// + /// Numero pezzi per display BLU + /// + protected int NumBlue { get; set; } = 0; + + /// + /// Numero pezzi per display GRIGIO + /// + protected int NumGray { get; set; } = 40; + + /// + /// Numero pezzi per display VERDE + /// + protected int NumGreen { get; set; } = 20; + + /// + /// Numero pezzi per display GIALLO + /// + protected int NumYellow { get; set; } = 30; + + protected override void OnParametersSet() + { + decimal denom = CountData.numPzProd > CountData.numPzOrd ? (decimal)CountData.numPzProd / 100 : (decimal)CountData.numPzOrd / 100; + denom = denom == 0 ? 1 : denom; + // calcolo se sono nel caso prod < ordinati o se sono andato OVER + if (CountData.numPzProd < CountData.numPzOrd) + { + nGreen = (int)Math.Floor((decimal)CountData.numPzConf / denom); + nYellow = (int)Math.Floor((decimal)(CountData.numPzProd - CountData.numPzConf) / denom); + nGray = 100 - (nGreen + nYellow); + nBlue = 0; + } + else + { + // devo verificare SE ne ho confermati meno che ordinati o meno... + if (CountData.numPzConf < CountData.numPzOrd) + { + nGreen = (int)Math.Floor((decimal)CountData.numPzConf / denom); + } + else + { + nGreen = (int)Math.Floor((decimal)CountData.numPzOrd / denom); + } + nBlue = 100 - nGreen; + nYellow = 0; + nGray = 0; + } + // disegno! + NumGreen = nGreen; + NumYellow = nYellow; + NumGray = nGray; + NumBlue = nBlue; + // base.OnParametersSet(); + } + + protected int nBlue = 0; + protected int nGray = 0; + protected int nGreen = 0; + protected int nYellow = 0; + + /// + /// Classe gesitone conteggi produzione + /// + public class ProdCounter + { + + /// + /// NUmero pezzi CONFERMATI + /// + public int numPzConf { get; set; } = 0; + + /// + /// Numero pezzi ORDINATI + /// + public int numPzOrd { get; set; } = 0; + + /// + /// Numero pezzi PRODOTTI + /// + public int numPzProd { get; set; } = 0; + } +} diff --git a/MP-TAB-SERV/Pages/CardDemo.razor b/MP-TAB-SERV/Pages/CardDemo.razor new file mode 100644 index 00000000..8581926d --- /dev/null +++ b/MP-TAB-SERV/Pages/CardDemo.razor @@ -0,0 +1,58 @@ +@page "/CardDemo" + +@if (CardTitles == null || CardTitles.Count == 0) +{ +
+
+ waiting on browser +
+ @for (int i = 0; i < 9; i++) + { +
+ + +
+ } +
+} +else +{ + +
+
+ loaded on browser +
+ @foreach (var item in CardTitles) + { +
+ +
+ Demo content page for @item +
+
+ This is an example Blazor component! +
+
+
+ } +
+} + +@code { + + protected List? CardTitles { get; set; } + + protected override async Task OnInitializedAsync() + { + CardTitles = null; + await Task.Delay(300); + CardTitles = new List(); + await InvokeAsync(StateHasChanged); + await Task.Delay(300); + for (int i = 0; i < 9; i++) + { + CardTitles.Add($"Card {i + 1:00}"); + } + await Task.Delay(10); + } +} \ No newline at end of file diff --git a/MP-TAB-SERV/Pages/HwSwInfo.razor b/MP-TAB-SERV/Pages/HwSwInfo.razor new file mode 100644 index 00000000..0a1e680d --- /dev/null +++ b/MP-TAB-SERV/Pages/HwSwInfo.razor @@ -0,0 +1,7 @@ +@page "/hw-sw-info" + +

HwSwInfo

+ +@code { + +} diff --git a/MP-TAB-SERV/Pages/Logout.razor b/MP-TAB-SERV/Pages/Logout.razor new file mode 100644 index 00000000..a881db05 --- /dev/null +++ b/MP-TAB-SERV/Pages/Logout.razor @@ -0,0 +1,8 @@ +@page "/logout" + +

logout

+ + +@code { + +} diff --git a/MP-TAB-SERV/Pages/MachineDetail.razor b/MP-TAB-SERV/Pages/MachineDetail.razor new file mode 100644 index 00000000..66b50e9c --- /dev/null +++ b/MP-TAB-SERV/Pages/MachineDetail.razor @@ -0,0 +1,34 @@ +@page "/machine-detail" + +@using MP.Data.Services; +@inject MessageService MsgServ + +

Machine Detail

+

@IdxMacc

+@if (CurrMSE == null) +{ + +} +else +{ + +} + +@code { + + [Parameter] + [SupplyParameterFromQuery(Name = "IdxMacc")] + public string? IdxMacc { get; set; } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + // recupero MSE macchina.... + if (!string.IsNullOrEmpty(IdxMacc)) + { + CurrMSE = await MsgServ.GetMachineMse(IdxMacc); + } + //await InvokeAsync(StateHasChanged); + // return base.OnAfterRenderAsync(firstRender); + } + protected MappaStatoExpl? CurrMSE { get; set; } = null; +} diff --git a/MP-TAB-SERV/Pages/StatusMap.razor b/MP-TAB-SERV/Pages/StatusMap.razor new file mode 100644 index 00000000..cd5bea4b --- /dev/null +++ b/MP-TAB-SERV/Pages/StatusMap.razor @@ -0,0 +1,25 @@ +@page "/" +@page "/home" +@page "/status-map" + + +
+ @if (ListMSE == null || ListMSE.Count == 0) + { + @for (int i = 0; i < 10; i++) + { +
+ +
+ } + } + else + { + @foreach (var item in ListMSE) + { +
+ +
+ } + } +
diff --git a/MP-TAB-SERV/Pages/StatusMap.razor.cs b/MP-TAB-SERV/Pages/StatusMap.razor.cs new file mode 100644 index 00000000..161957ad --- /dev/null +++ b/MP-TAB-SERV/Pages/StatusMap.razor.cs @@ -0,0 +1,197 @@ +using global::Microsoft.AspNetCore.Components; +using MP.Data.Conf; +using MP.Data.DatabaseModels; +using MP.Data.Services; +using NLog; + +namespace MP_TAB_SERV.Pages +{ + public partial class StatusMap + { + #region Protected Fields + + protected bool doAnimate = true; + protected int keepAliveMin = 1; + protected int maxCol = 6; + protected string showArt = ""; + protected int slowRefreshSec = 300; + + #endregion Protected Fields + + #region Protected Properties + + [Inject] + protected StatusData MDataService { get; set; } = null!; + + [Inject] + protected MessageService MsgServ { get; set; } = null!; + + protected int slowRefreshMs + { + get + { + // tempo variabile tra +/- 10% del target + int answ = rnd.Next(900, 1100) * slowRefreshSec; + return answ; + } + } + + #endregion Protected Properties + + #region Protected Methods + + /// + /// Recupera il valore e se trovato aggiorna + /// + /// Valore da cercare + /// String in cui salvare il valore se trovato + /// + protected bool getConfVal(string chiave, ref string varObj) + { + bool answ = false; + if (CurrConfig != null && CurrConfig.Count > 0) + { + // sistemo i parametri opzionali... + ConfigModel? risultato = CurrConfig.FirstOrDefault(x => x.Chiave == chiave); + if (risultato != null) + { + varObj = risultato.Valore; + answ = !string.IsNullOrEmpty(risultato.Valore); + } + } + return answ; + } + + /// + /// Recupera il valore e se trovato aggiorna + /// + /// Valore da cercare + /// Int in cui salvare il valore se trovato + /// + protected bool getConfValInt(string chiave, ref int varObj) + { + bool answ = false; + if (CurrConfig != null && CurrConfig.Count > 0) + { + // sistemo i parametri opzionali... + ConfigModel? risultato = CurrConfig.FirstOrDefault(x => x.Chiave == chiave); + if (risultato != null) + { + answ = int.TryParse(risultato.Valore, out varObj); + } + } + return answ; + } + + /// + /// Recupera da conf eventuale setup tag dell'IOB indicato + /// + /// + /// + protected List? getIobTag(string codIob) + { + List? answ = null; + if (MDataService.currTagConf != null) + { + // cerco x chiave IOB... + if (MDataService.currTagConf.ContainsKey(codIob)) + { + answ = MDataService.currTagConf[codIob]; + } + } + return answ; + } + + /// + /// Recupera da redis (in una chiamata soltanto) tutti i valori richiesti e compone un + /// dizionario x ottimizzare visualizzazione + /// + /// + /// + protected Dictionary getTagVal(string codIob) + { + Dictionary answ = new Dictionary(); + // recupero conf tags... + var currTags = getIobTag(codIob); + if (currTags != null && currTags.Count > 0) + { + // FIXME TODO !!!! FARE !!!! - da verificare + answ = currTags.ToDictionary(x => x.TagLocation, x => MDataService.getTagConf(x.TagLocation)); + } + return answ; + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (ListMSE != null) + { + // salvo in LocalStorage... + await MsgServ.SaveMse(ListMSE); + } + } + + protected override async Task OnInitializedAsync() + { + ListMSE = null; + await setupConf(); + //await InvokeAsync(StateHasChanged); + //await Task.Delay(500); + await ReloadData(); + } + + #endregion Protected Methods + + #region Private Fields + + private static NLog.Logger Log = LogManager.GetCurrentClassLogger(); + + private static System.Timers.Timer slowTimer = new System.Timers.Timer(300000); + + private List? CurrConfig = null; + + private Random rnd = new Random(); + + #endregion Private Fields + + #region Private Properties + + private List? ListMSE { get; set; } = null; + + #endregion Private Properties + + #region Private Methods + + private async Task ReloadData() + { + ListMSE = await MDataService.MseGetAll(); + //try + //{ + // // salvo in LocalStorage... + // await MsgServ.SaveMse(CurrListMSE); + //} + //catch (Exception exc) + //{ + // Log.Error($"Eccezione in ReloadData{Environment.NewLine}{exc}"); + //} + } + + private async Task setupConf() + { + CurrConfig = await MDataService.ConfigGetAll(); + if (CurrConfig != null && CurrConfig.Count > 0) + { + // sistemo i parametri opzionali... + getConfValInt("keepAliveMin", ref keepAliveMin); + getConfValInt("MON_maxCol", ref maxCol); + int intDoAnim = 0; + getConfValInt("doAnimate", ref intDoAnim); + doAnimate = intDoAnim == 1; + getConfValInt("pageRefreshSec", ref slowRefreshSec); + getConfVal("sART", ref showArt); + Log.Info($"setupConf | Effettuato setup parametri | keepAlive: {keepAliveMin} | MaxCol: {maxCol} | doAnimate: {doAnimate} | slowRefreshSec: {slowRefreshSec}"); + } + } + + #endregion Private Methods + } +} \ No newline at end of file