From ff2b83164daf08a960d37f74141ec2cef8d1e820 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 5 Aug 2021 13:59:25 +0200 Subject: [PATCH] Implementato metodi x update DTO al ricevimento dati + riduzione inserimento --- GWMS.Data/Controllers/GWMSController.cs | 83 +++++++++---- GWMS.Data/GWMS.Data.csproj | 4 - GWMS.UI/Controllers/IOBController.cs | 8 +- GWMS.UI/Controllers/PlantLogController.cs | 2 +- GWMS.UI/Data/GWMSDataService.cs | 138 +++++++++++++++++++++- GWMS.UI/GWMS.UI.csproj | 2 +- GWMS.UI/appsettings.json | 2 + Resources/ChangeLog.html | 2 +- Resources/VersNum.txt | 2 +- Resources/manifest.xml | 2 +- 10 files changed, 207 insertions(+), 38 deletions(-) diff --git a/GWMS.Data/Controllers/GWMSController.cs b/GWMS.Data/Controllers/GWMSController.cs index 5aad10b..858bc08 100644 --- a/GWMS.Data/Controllers/GWMSController.cs +++ b/GWMS.Data/Controllers/GWMSController.cs @@ -136,6 +136,19 @@ namespace GWMS.Data.Controllers #region Public Methods + /// + /// Calcola DataOra arrotondata per eccesso secondo intervallo minuti indicato + /// + /// + /// + /// + public DateTime DateRoundEnd(DateTime dateOrig, int minInt) + { + int minRound = (int)Math.Ceiling((double)dateOrig.Minute / minInt) * minInt; + DateTime roundDate = dateOrig.Date.AddHours(dateOrig.Hour).AddMinutes(minRound); + return roundDate; + } + public void Dispose() { // Clear database context @@ -212,14 +225,14 @@ namespace GWMS.Data.Controllers return dbResult; } - public List GetPlantsDTO() + public List GetPlantsDTO(int maxRecords) { var plantList = dbCtx .DbSetPlant .ToList(); var dbResult = plantList - .Select(x => PlantDTO(x.PlantId)) + .Select(x => PlantDTO(x.PlantId, maxRecords)) .ToList(); return dbResult; @@ -334,9 +347,10 @@ namespace GWMS.Data.Controllers /// /// Recupero info PLANT modalità DTO /// - /// + /// Impianto + /// Max numero di record da recuperare /// - public PlantDTO PlantDTO(int PlantId) + public PlantDTO PlantDTO(int PlantId, int maxRecords) { var currPlant = GetPlant(PlantId); @@ -352,30 +366,35 @@ namespace GWMS.Data.Controllers .DbSetPlantLog .Where(x => x.FluxType == "Level" && x.PlantId == PlantId) .OrderBy(x => x.DtEvent) + .Take(maxRecords) .ToList(); var rawMainPressData = dbCtx .DbSetPlantLog .Where(x => x.FluxType == "MainPress" && x.PlantId == PlantId) .OrderBy(x => x.DtEvent) + .Take(maxRecords) .ToList(); var rawBHPressData = dbCtx .DbSetPlantLog .Where(x => x.FluxType == "PressBH" && x.PlantId == PlantId) .OrderBy(x => x.DtEvent) + .Take(maxRecords) .ToList(); var rawBLPressData = dbCtx .DbSetPlantLog .Where(x => x.FluxType == "PressBL" && x.PlantId == PlantId) .OrderBy(x => x.DtEvent) + .Take(maxRecords) .ToList(); var rawOrderData = dbCtx .DbSetOrders .Where(x => x.PlantId == PlantId) .OrderBy(x => x.DtOrder) + .Take(maxRecords) .ToList(); LevelTS = rawLevelData @@ -397,6 +416,7 @@ namespace GWMS.Data.Controllers PressTS.Add("BH", PressBHTS); PressTS.Add("BL", PressBLTS); + double actLevel = LevelTS.Count > 0 ? LevelTS.OrderByDescending(x => x.DtEvent).Take(1).FirstOrDefault().ValDouble : 0; double valMain = PressMainTS.Count > 0 ? PressMainTS.OrderByDescending(x => x.DtEvent).Take(1).FirstOrDefault().ValDouble : 0; double valBH = PressBHTS.Count > 0 ? PressBHTS.OrderByDescending(x => x.DtEvent).Take(1).FirstOrDefault().ValDouble : 0; double valBL = PressBLTS.Count > 0 ? PressBLTS.OrderByDescending(x => x.DtEvent).Take(1).FirstOrDefault().ValDouble : 0; @@ -410,7 +430,7 @@ namespace GWMS.Data.Controllers PlantId = PlantId, PlantCode = currPlant.PlantCode, PlantDesc = currPlant.PlantDesc, - LevelAct = currPlant.LevelAct, + LevelAct = actLevel, LevelMax = currPlant.LevelMax, PressAct = PressAct, LevelTS = LevelTS, @@ -421,36 +441,55 @@ namespace GWMS.Data.Controllers } /// - /// Inserimento di un novo record x plant log + /// Recupero da DB l'ultimo record per ogni flusso + /// + /// + public List PlantLogGetLastByFlux() + { + List lastRec = dbCtx + .DbSetPlantLog + .OrderByDescending(o => o.DtEvent) + .GroupBy(g => g.FluxType) + .Select(s => s.First()) + .ToList(); + return lastRec; + } + + /// + /// Inserimento di un set di record x plant log /// /// Record da inserire (senza ID...) /// public bool PlantLogInsertNew(List newItems) { bool fatto = false; - - //List newList = new List(); - - //foreach (var item in newItems) - //{ - // newList.Add(new PlantLogModel() - // { - // DtEvent = item.DtEvent, - // FluxType = item.FluxType, - // PlantId = item.PlantId, - // ValNumber = item.ValNumber, - // ValString = item.ValString - // }); - //} try { dbCtx .DbSetPlantLog .AddRange(newItems); - //.AddRange(newList); - dbCtx.SaveChanges(); fatto = true; + +#if false + // ogni 10 insert faccio chiamata x pulizia per le ultime 3h... FARE!!!! + Dictionary flux2prox = new Dictionary(); + foreach (var item in newItems) + { + if (!flux2prox.ContainsKey(item.FluxType)) + { + flux2prox.Add(item.FluxType, item.PlantId); + } + } + // ciclo x ogni flusso + foreach (var item in flux2prox) + { + DateTime adesso = DateTime.Now; + DateTime startTime = DateTime.Today.AddHours(adesso.Hour - 2); + string sqlQuery = $"CALL DecimateLog('{startTime}', {item.Value}, 15, '{item.Key}')"; + var table = dbCtx.DbSetPlantLog.FromSqlRaw(sqlQuery); + } +#endif } catch (Exception exc) { diff --git a/GWMS.Data/GWMS.Data.csproj b/GWMS.Data/GWMS.Data.csproj index 72a0778..f3c186c 100644 --- a/GWMS.Data/GWMS.Data.csproj +++ b/GWMS.Data/GWMS.Data.csproj @@ -26,8 +26,4 @@ - - - - \ No newline at end of file diff --git a/GWMS.UI/Controllers/IOBController.cs b/GWMS.UI/Controllers/IOBController.cs index 99991ac..1e8a768 100644 --- a/GWMS.UI/Controllers/IOBController.cs +++ b/GWMS.UI/Controllers/IOBController.cs @@ -231,7 +231,9 @@ namespace GWMS.UI.Controllers if (currPlant != null && currPlant.PlantId > 0) { double valDbl = 0; - double.TryParse(valore, out valDbl); + NumberStyles style = NumberStyles.Number; + CultureInfo culture = CultureInfo.CreateSpecificCulture("it-IT"); + double.TryParse(valore.Replace(".", ","), style, culture, out valDbl); // converto in plantLogModel... PlantLogModel newItem = new PlantLogModel() { @@ -245,7 +247,7 @@ namespace GWMS.UI.Controllers List newData = new List(); newData.Add(newItem); // insert! - fatto = _DataService.PlantLogInsert(newData); + fatto = _DataService.PlantLogInsert(newData).Result; } } catch (Exception exc) @@ -283,7 +285,7 @@ namespace GWMS.UI.Controllers // conversione dati List plData = rawData.fluxData.Select(jpl => _DataService.convertFluxToPL(currPlant.PlantId, jpl)).ToList(); //insert! - fatto = _DataService.PlantLogInsert(plData); + fatto = _DataService.PlantLogInsert(plData).Result; } } if (fatto) diff --git a/GWMS.UI/Controllers/PlantLogController.cs b/GWMS.UI/Controllers/PlantLogController.cs index 5679c25..9dcdebe 100644 --- a/GWMS.UI/Controllers/PlantLogController.cs +++ b/GWMS.UI/Controllers/PlantLogController.cs @@ -76,7 +76,7 @@ namespace GWMS.UI.Controllers // verifico ci sia valore if (newItems != null) { - fatto = _DataService.PlantLogInsert(newItems); + fatto = _DataService.PlantLogInsert(newItems).Result; } if (fatto) { diff --git a/GWMS.UI/Data/GWMSDataService.cs b/GWMS.UI/Data/GWMSDataService.cs index 7bac480..c4f3268 100644 --- a/GWMS.UI/Data/GWMSDataService.cs +++ b/GWMS.UI/Data/GWMSDataService.cs @@ -15,6 +15,7 @@ using NLog; using GWMS.Data.DTO; using GWMS.Data.DatabaseModels; using static GWMS.Data.IobObjects; +using System.Globalization; namespace GWMS.UI.Data { @@ -89,6 +90,88 @@ namespace GWMS.UI.Data return new DistributedCacheEntryOptions().SetAbsoluteExpiration(DateTime.Now.AddSeconds(numSecAbsExp)).SetSlidingExpiration(TimeSpan.FromSeconds(numSecSliExp)); } + /// + /// Recupera PlantDTO e aggiorno valori attuali (se presente...) + /// ATTENZIONE: i dati sono sempre ricevuti PER SINGOLO PlantId!!! + /// + /// + private async Task updateCurrDTO(List newItems) + { + List dbResult = new List(); + int PlantId = newItems.FirstOrDefault().PlantId; + string cacheKey = "DATA:PLANTS:ListDTO"; + string rawData; + var redisDataList = await distributedCache.GetAsync(cacheKey); + if (redisDataList != null) + { + rawData = Encoding.UTF8.GetString(redisDataList); + dbResult = JsonConvert.DeserializeObject>(rawData); + + // ora ciclo x ogni flusso/macchina l'ultimo record + List lastByFlux = newItems + .OrderByDescending(x => x.DtEvent) + .GroupBy(g => g.FluxType) + .Select(s => s.First()) + .ToList(); + // aggiorno il DTO x i valori trovati... + var currDto = dbResult.Where(x => x.PlantId == PlantId).FirstOrDefault(); + + // verifico SE c'è Level + var lastLev = lastByFlux.Where(x => x.FluxType == "Level").FirstOrDefault(); + if (lastLev != null) + { + currDto.LevelAct = lastLev.ValNumber; + } + + // verifico SE c'è MainPress + var lastMain = lastByFlux.Where(x => x.FluxType == "MainPress").FirstOrDefault(); + if (lastMain != null) + { + if (currDto.PressAct.ContainsKey("Main")) + { + currDto.PressAct["Main"] = lastMain.ValNumber; + } + else + { + currDto.PressAct.Add("Main", lastMain.ValNumber); + } + } + + // verifico SE c'è PressBH + var lastBH = lastByFlux.Where(x => x.FluxType == "PressBH").FirstOrDefault(); + if (lastBH != null) + { + if (currDto.PressAct.ContainsKey("BH")) + { + currDto.PressAct["BH"] = lastBH.ValNumber; + } + else + { + currDto.PressAct.Add("BH", lastBH.ValNumber); + } + } + + // verifico SE c'è PressBL + var lastBL = lastByFlux.Where(x => x.FluxType == "PressBL").FirstOrDefault(); + if (lastBL != null) + { + if (currDto.PressAct.ContainsKey("BL")) + { + currDto.PressAct["BL"] = lastBL.ValNumber; + } + else + { + currDto.PressAct.Add("BL", lastBL.ValNumber); + } + } + + // salvo DTO! + rawData = JsonConvert.SerializeObject(dbResult); + redisDataList = Encoding.UTF8.GetBytes(rawData); + await distributedCache.SetAsync(cacheKey, redisDataList, cacheOpt(true)); + } + } + #endregion Private Methods #region Protected Methods @@ -154,7 +237,9 @@ namespace GWMS.UI.Data { // cerco di ottenere un val in cifre double valDbl = 0; - double.TryParse(origData.valore, out valDbl); + NumberStyles style = NumberStyles.Number; + CultureInfo culture = CultureInfo.CreateSpecificCulture("it-IT"); + double.TryParse(origData.valore.Replace(".", ","), style, culture, out valDbl); TimeSpan delta = origData.dtCurr.Subtract(origData.dtEve); PlantLogModel answ = new PlantLogModel() { @@ -279,9 +364,52 @@ namespace GWMS.UI.Data return await Task.FromResult(dbResult); } - public bool PlantLogInsert(List newItems) + public async Task PlantLogInsert(List newItems) { - return dbController.PlantLogInsertNew(newItems); + // aggiorno valori ACT x DTO + await updateCurrDTO(newItems); + + // inserimento su DB + int IntervalMin = 60; + int.TryParse(_configuration["IntervalMin"], out IntervalMin); + + List lastValues = dbController.PlantLogGetLastByFlux(); + + List item2insert = new List(); + // verifico i flussi presenti tra quelli ricevuti + List fluxList = newItems + .GroupBy(g => g.FluxType) + .Select(s => s.First().FluxType) + .ToList(); + foreach (var item in fluxList) + { + // cerco se c'è valore... + var lastInserted = lastValues.Where(x => x.FluxType == item).FirstOrDefault(); + DateTime dateLimit = DateTime.Today.AddDays(-1); + if (lastInserted != null) + { + // per ogni flusso calcolo il valore minimo x inserimento (arrotondando a minInt) + dateLimit = dbController.DateRoundEnd(lastInserted.DtEvent, IntervalMin); + } + + // cerco se ho record > valore minimo x ogni flusso ricevuto + List insCandidates = newItems.Where(x => x.FluxType == item && x.DtEvent >= dateLimit).ToList(); + + while (insCandidates.Count > 0) + { + var newRec = insCandidates.First(); + // il primo lo accodo da inserire + item2insert.Add(newRec); + // calcolo nuovo veto + dateLimit = dbController.DateRoundEnd(newRec.DtEvent, IntervalMin); + // ...e se ho record accodo + insCandidates = newItems.Where(x => x.FluxType == item && x.DtEvent >= dateLimit).ToList(); + } + } + + // faccio vero insert + return dbController.PlantLogInsertNew(item2insert); + //return dbController.PlantLogInsertNew(newItems); } public async Task> PlantsGetAll() @@ -299,7 +427,9 @@ namespace GWMS.UI.Data { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); - dbResult = dbController.GetPlantsDTO(); + int maxRec = 100; + int.TryParse(_configuration["MaxLogRecord"], out maxRec); + dbResult = dbController.GetPlantsDTO(maxRec); rawData = JsonConvert.SerializeObject(dbResult); redisDataList = Encoding.UTF8.GetBytes(rawData); await distributedCache.SetAsync(cacheKey, redisDataList, cacheOpt(true)); diff --git a/GWMS.UI/GWMS.UI.csproj b/GWMS.UI/GWMS.UI.csproj index 2d97a19..615258b 100644 --- a/GWMS.UI/GWMS.UI.csproj +++ b/GWMS.UI/GWMS.UI.csproj @@ -2,7 +2,7 @@ net5.0 - 1.0.2108.0413 + 1.0.2108.0512 95c9f021-52d1-4390-a670-5810b7b777b0 diff --git a/GWMS.UI/appsettings.json b/GWMS.UI/appsettings.json index edfb216..f87efe7 100644 --- a/GWMS.UI/appsettings.json +++ b/GWMS.UI/appsettings.json @@ -24,6 +24,8 @@ "nKey": "PZZFRR", "sKey": "M3T@n0" }, + "IntervalMin": 60, + "MaxLogRecord": 240, "ZCodeUrl": "https://qrcode.steamware.net/", "logo": "img/LogoPizzaferri.jpg" } \ No newline at end of file diff --git a/Resources/ChangeLog.html b/Resources/ChangeLog.html index 788540d..869cb8c 100644 --- a/Resources/ChangeLog.html +++ b/Resources/ChangeLog.html @@ -1,6 +1,6 @@ GWMS - Gas Warehouse Management System -

Versione: 1.0.2108.0413

+

Versione: 1.0.2108.0512


Note di rilascio:
  • diff --git a/Resources/VersNum.txt b/Resources/VersNum.txt index 659b999..1c41793 100644 --- a/Resources/VersNum.txt +++ b/Resources/VersNum.txt @@ -1 +1 @@ -1.0.2108.0413 +1.0.2108.0512 diff --git a/Resources/manifest.xml b/Resources/manifest.xml index 0900e68..5a8aa81 100644 --- a/Resources/manifest.xml +++ b/Resources/manifest.xml @@ -1,6 +1,6 @@ - 1.0.2108.0413 + 1.0.2108.0512 http://nexus.steamware.net/repository/SWS/GWMS/stable/0/GWMS.UI.zip http://nexus.steamware.net/repository/SWS/GWMS/stable/0/ChangeLog.html false