using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using MP.MONO.Core.DTO; using MP.MONO.Data.DbModels; using MP.MONO.Data.DTO; using NLog; using System.Diagnostics; using static MP.MONO.Core.Enums; namespace MP.MONO.Data.Controllers { public class MpDbController : IDisposable { #region Public Constructors public MpDbController(IConfiguration currAppConf) { appConf = currAppConf; LogDurationLimitMs = appConf.GetValue("OptPar:LogDurationLimitMs"); } #endregion Public Constructors #region Public Methods /// /// Elenco records anagrafica allarmi /// /// public List AlarmListGetAll() { List? dbResult = new List(); using (MapoMonoContext localDbCtx = new MapoMonoContext()) { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); try { dbResult = localDbCtx .DbSetAlarmList .OrderBy(x => x.FullValue) .ToList(); } catch (Exception exc) { LogException("Eccezione durante AlarmListGetAll", exc); } LogDebug("AlarmListGetAll", stopWatch.Elapsed); stopWatch.Stop(); } return dbResult; } /// /// Inserimento di un record anagrafica allarmi (o se esiste restituisce quello esistente) /// /// Record da inserire (senza ID...) /// public AlarmListModel? AlarmListInsert(string alarmText) { AlarmListModel? foundRec = new AlarmListModel(); using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); // verifico che NON esista con pèari descrizione... foundRec = localDbCtx .DbSetAlarmList .FirstOrDefault(x => x.FullValue == alarmText); // se non c'è aggiungo if (foundRec == null) { foundRec = new AlarmListModel() { FullValue = alarmText }; localDbCtx .DbSetAlarmList .Add(foundRec); localDbCtx.SaveChanges(); // rifaccio search foundRec = localDbCtx .DbSetAlarmList .FirstOrDefault(x => x.FullValue == alarmText); } LogDebug("AlarmListInsert", stopWatch.Elapsed); stopWatch.Stop(); } catch (Exception exc) { LogException("Eccezione durante AlarmListInsert", exc); } } return foundRec; } /// /// Inserimento di una lista record anagrafica allarmi /// /// Lista Record da inserire (senza ID...) /// public async Task AlarmListInsertMany(List newItems) { bool fatto = false; using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); await localDbCtx .DbSetAlarmList .AddRangeAsync(newItems); await localDbCtx.SaveChangesAsync(); fatto = true; stopWatch.Stop(); LogDebug("AlarmListInsertMany", stopWatch.Elapsed); } catch (Exception exc) { LogException("Eccezione durante AlarmListInsertMany", exc); } } return fatto; } /// /// Recupero elenco allarmi (ultimi dato "skip") /// /// /// /// /// public async Task> AlarmLogGetFilt(int MachineId, int skipRec, int numRec) { List dbResult = new List(); using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = await localDbCtx .DbSetAlarmLog .AsNoTracking() .Where(x => x.MachineId == MachineId) .Include(m => m.MachineNav) .OrderByDescending(x => x.AlarmLogId) .Skip(skipRec) .Take(numRec) .ToListAsync(); LogDebug("AlarmLogGetFilt", stopWatch.Elapsed); stopWatch.Stop(); } catch (Exception exc) { LogException("Eccezione durante AlarmLogGetFilt", exc); } } //await Task.Delay(1); return dbResult; } /// Recupero elenco allarmi con data <= alla data di riferimento (ultimi dato /// "skip") public List AlarmLogGetFiltByDate(int MachineId, DateTime dtRif, int skipRec, int numRec) { List dbResult = new List(); using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = localDbCtx .DbSetAlarmLog .AsNoTracking() .Where(x => (x.MachineId == MachineId) && (x.DtRif <= dtRif)) .Include(m => m.MachineNav) .OrderByDescending(x => x.AlarmLogId) .Skip(skipRec) .Take(numRec) .ToList(); LogDebug("AlarmLogGetFiltByDate", stopWatch.Elapsed); stopWatch.Stop(); } catch (Exception exc) { LogException("Eccezione durante AlarmLogGetFiltByDate", exc); } } return dbResult; } /// /// Inserimento di un record AlarmLog /// /// Record da inserire (senza ID...) /// public async Task AlarmLogInsert(AlarmLogModel newItem) { bool fatto = false; using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); localDbCtx .DbSetAlarmLog .Add(newItem); await localDbCtx.SaveChangesAsync(); fatto = true; LogDebug("AlarmLogInsert", stopWatch.Elapsed); stopWatch.Stop(); } catch (Exception exc) { LogException("Eccezione durante AlarmLogInsert", exc); } } return fatto; } /// /// Inserimento di una lista record AlarmLog /// /// Lista Record da inserire (senza ID...) /// public async Task AlarmLogInsertMany(List newItems) { bool fatto = false; using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { if (newItems.Count > 0) { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); await localDbCtx .DbSetAlarmLog .AddRangeAsync(newItems); await localDbCtx.SaveChangesAsync(); fatto = true; LogInfo($"AlarmLogInsertMany| DB insert | {newItems.Count} rec", stopWatch.Elapsed); stopWatch.Stop(); } } catch (Exception exc) { LogException("Eccezione durante AlarmLogInsertMany", exc); } } return fatto; } /// /// Chiude ultimo record dato Id (se fossero + di 1 chiude tutti...) /// /// Id Allarme /// public async Task AlarmRecCloseActive(int AlarmId) { bool fatto = false; using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); DateTime adesso = DateTime.Now; // prendo ultimi 10000 allarmi (odierni) var lastAlarms = localDbCtx .DbSetAlarmRec .OrderByDescending(x => x.AlarmRecId) .Take(10000) .ToList(); var candList = lastAlarms .Where(x => x.AlarmId == AlarmId && x.DtStart >= x.DtEnd) .ToList(); if (candList.Count > 0) { foreach (var item in candList) { item.DtEnd = adesso; } await localDbCtx.SaveChangesAsync(); fatto = true; LogDebug($"AlarmRecCloseActive | {candList.Count} closed", stopWatch.Elapsed); } else { LogDebug($"AlarmRecCloseActive | NONE", stopWatch.Elapsed); } stopWatch.Stop(); } catch (Exception exc) { LogException("Eccezione durante AlarmRecCloseActive", exc); } } return fatto; } /// /// Chiude ultimo record di allarmi aperti (avendo verificato sia zero da un pò...) /// /// public async Task AlarmRecCloseStarving() { bool fatto = false; using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); DateTime adesso = DateTime.Now; var lastAlarms = localDbCtx .DbSetAlarmRec .OrderByDescending(x => x.AlarmRecId) .Take(100000) .ToList(); var candList = lastAlarms .Where(x => x.DtStart >= x.DtEnd) .ToList(); foreach (var item in candList) { item.DtEnd = adesso; } await localDbCtx.SaveChangesAsync(); fatto = true; stopWatch.Stop(); LogDebug($"AlarmRecCloseStarving", stopWatch.Elapsed); } catch (Exception exc) { LogException("Eccezione durante AlarmRecCloseStarving", exc); } } return fatto; } /// /// Recupero elenco allarmi Rec ATTIVI (non chiusi) /// /// public List AlarmRecGetActive() { List dbResult = new List(); using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); // recupero 10'000 allarme x limitare... int numRec = localDbCtx .DbSetAlarmRec .Count(); int numMax = 10000; int limitIdx = 0; if (numRec > numMax) { var limitRec = localDbCtx .DbSetAlarmRec .AsNoTracking() .OrderByDescending(x => x.AlarmRecId) .Skip(numMax) .Take(1) .FirstOrDefault(); limitIdx = limitRec != null ? limitRec.AlarmRecId : 0; } dbResult = localDbCtx .DbSetAlarmRec //.AsNoTracking() .Where(x => x.AlarmRecId > limitIdx && x.DtStart >= x.DtEnd) .Include(m => m.AlarmListNav) .ToList(); LogDebug("AlarmRecGetActive", stopWatch.Elapsed); stopWatch.Stop(); } catch (Exception exc) { LogException("Eccezione durante AlarmRecGetActive", exc); } } return dbResult; } /// /// Recupero elenco allarmi Rec (ultimi dato "skip") /// /// /// /// /// public async Task> AlarmRecGetFilt(int MachineId, int skipRec, int numRec) { List dbResult = new List(); using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = await localDbCtx .DbSetAlarmRec .AsNoTracking() .Where(x => x.MachineId == MachineId) .Include(m => m.MachineNav) .Include(m => m.AlarmListNav) .OrderByDescending(x => x.DtStart) .Skip(skipRec) .Take(numRec) .ToListAsync(); stopWatch.Stop(); LogDebug("AlarmRecGetFilt", stopWatch.Elapsed); } catch (Exception exc) { LogException("Eccezione durante AlarmRecGetFilt", exc); } } return dbResult; } /// Recupero elenco allarmi Rec con data <= a quella di riferimento(ultimi dato /// "skip") public List AlarmRecGetFiltByDate(int MachineId, DateTime dtRif, int skipRec, int numRec) { List dbResult = new List(); using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = localDbCtx .DbSetAlarmRec .AsNoTracking() .Where(x => (x.MachineId == MachineId) && (x.DtStart <= dtRif)) .Include(m => m.MachineNav) .Include(m => m.AlarmListNav) .OrderByDescending(x => x.DtStart) .Skip(skipRec) .Take(numRec) .ToList(); LogDebug("AlarmRecGetFiltByDate", stopWatch.Elapsed); stopWatch.Stop(); } catch (Exception exc) { LogException("Eccezione durante AlarmRecGetFiltByDate", exc); } } return dbResult; } /// /// Recupero lista sommatoria durata eventi allarme per analisi, ordinati in logica di /// pareto (Max-min) /// /// Id Macchina /// inizio analisi (evento deve iniziare/finire entro periodo) /// fine analisi (evento deve iniziare/finire entro periodo) /// durata minima evento per venire considerato, -1 = tutti /// durata massima evento per venire considerato, -1 = tutti /// public List AlarmRecGetParetoDur(int machineId, DateTime dtFrom, DateTime dtTo, int minDur = -1, int maxDur = -1) { List dbResult = new List(); using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); // effettuo il calcolo in + step... var rawData = localDbCtx .DbSetAlarmRec .AsNoTracking() .Where(x => x.MachineId == machineId && (x.DtStart >= dtFrom && x.DtStart <= dtTo) && (x.Duration >= minDur || minDur < 0) && (x.Duration <= maxDur || maxDur < 0)) .ToList(); dbResult = rawData .GroupBy(g => g.AlarmId) .Select(g => new AlarmDurationDTO() { MachineId = machineId, AlarmId = g.Key, Duration = g.Sum(x => x.Duration) }) .ToList() .Join( AlarmListGetAll(), f => f.AlarmId, l => l.AlarmId, (dur, list) => new AlarmDurationDTO() { AlarmId = dur.AlarmId, Duration = dur.Duration, MachineId = dur.MachineId, AlarmDescription = list.FullValue } ) .OrderByDescending(o => o.Duration) .ToList(); LogDebug("AlarmRecGetParetoDur", stopWatch.Elapsed); stopWatch.Stop(); } catch (Exception exc) { LogException("Eccezione durante AlarmRecGetParetoDur", exc); } } return dbResult; } /// /// Recupero lista di conteggio eventi allarme per analisi, ordinati in logica di pareto (Max-min) /// /// Id Macchina /// inizio analisi (evento deve iniziare DOPO questa data) /// fine analisi (evento deve iniziare prima di questa data) /// durata minima evento per venire considerato, -1 = tutti /// durata massima evento per venire considerato, -1 = tutti /// public List AlarmRecGetParetoFreq(int machineId, DateTime dtFrom, DateTime dtTo, int minDur = -1, int maxDur = -1) { List dbResult = new List(); using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = localDbCtx .DbSetAlarmRec .AsNoTracking() .Where(x => x.MachineId == machineId && (x.DtStart >= dtFrom && x.DtStart <= dtTo) && (x.Duration >= minDur || minDur < 0) && (x.Duration <= maxDur || maxDur < 0)) .GroupBy(g => g.AlarmId) .Select(g => new AlarmFreqDTO() { MachineId = machineId, AlarmId = g.Key, EventCount = g.Count() }) .ToList() .Join( AlarmListGetAll(), f => f.AlarmId, l => l.AlarmId, (freq, list) => new AlarmFreqDTO() { AlarmId = freq.AlarmId, EventCount = freq.EventCount, MachineId = freq.MachineId, AlarmDescription = list.FullValue } ) .OrderByDescending(o => o.EventCount) .ToList(); LogDebug("AlarmRecGetParetoFreq", stopWatch.Elapsed); stopWatch.Stop(); } catch (Exception exc) { LogException("Eccezione durante AlarmRecGetParetoFreq", exc); } } return dbResult; } /// /// Inserimento di un record AlarmRec /// /// Record da inserire (senza ID...) /// public async Task AlarmRecInsert(AlarmRecModel newItem) { bool fatto = false; using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); // verifico non sia già aperto... verifico eventuali items già aperti da NON // dover aggiungere... var stillOpenAlarms = localDbCtx .DbSetAlarmRec .Where(x => x.DtStart >= x.DtEnd && x.AlarmId == newItem.AlarmId) .Select(x => x.AlarmId) .ToList(); // se ho trovato --> salto! if (stillOpenAlarms != null && stillOpenAlarms.Count > 0) { LogError($"Errore: trovato {stillOpenAlarms.Count} istanze già attive | Id: {newItem.AlarmId}"); } else { localDbCtx .DbSetAlarmRec .Add(newItem); await localDbCtx.SaveChangesAsync(); fatto = true; } LogInfo($"AlarmRecInsert| DB insert 1 rec", stopWatch.Elapsed); stopWatch.Stop(); } catch (Exception exc) { LogException("Eccezione durante AlarmRecInsert", exc); } } return fatto; } /// /// Inserimento di una lista record AlarmRec /// /// Lista Record da inserire (senza ID...) /// public bool AlarmRecInsertMany(List newItems) { bool fatto = false; using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { if (newItems.Count > 0) { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); // aggiungo localDbCtx .DbSetAlarmRec .AddRange(newItems); // salvo! localDbCtx.SaveChanges(); fatto = true; LogInfo($"AlarmRecInsertMany | DB insert | {newItems.Count} rec", stopWatch.Elapsed); stopWatch.Stop(); } } catch (Exception exc) { LogException("Eccezione durante AlarmRecInsertMany", exc); } } return fatto; } /// /// Recupero counters da DB /// /// public List CountersGetAll() { List dbResult = new List(); using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = localDbCtx .DbSetCounter .AsNoTracking() .ToList(); LogDebug($"CountersGetAll", stopWatch.Elapsed); stopWatch.Stop(); } catch (Exception exc) { LogException("Eccezione durante CountersGetAll", exc); } } return dbResult; } /// /// Inserimento/Update di una lista counters /// /// Lista Record da inserire /// public bool CountersUpsertMany(List newItems) { bool fatto = false; using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { if (newItems.Count > 0) { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); // x ogni valore cerco... foreach (var item in newItems) { var oldRec = localDbCtx .DbSetCounter .Where(x => x.CCode == item.CCode) .FirstOrDefault(); if (oldRec == null) { localDbCtx .DbSetCounter .Add(item); } else { oldRec.ActualVal = item.ActualVal; localDbCtx.Entry(oldRec).State = EntityState.Modified; } } // salvo le modifiche localDbCtx.SaveChanges(); fatto = true; stopWatch.Stop(); LogInfo($"CountersUpsertMany | DB insert | {newItems.Count} rec", stopWatch.Elapsed); } } catch (Exception exc) { LogException("Eccezione durante CountersUpsertMany", exc); } } return fatto; } /// /// Recupero DataLogDTO data condizione filtro /// /// ID macchina /// Tipologia di dato richiesto da enum /// Tipo di Flusso /// DT Inizio estrazione /// DT Fine estrazione /// public async Task> DataLogDtoGetFilt(int machineId, DataLogType dataType, string fluxType, DateTime inizio, DateTime fine) { List dbResult = new List(); using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = await localDbCtx .DbSetDataLog .Where(x => (x.MachineId == machineId) && (x.FluxType == fluxType) && (x.DataType == dataType || dataType == DataLogType.ND) && (x.DtRif >= inizio && x.DtRif <= fine)) .Select(r => new DataLogDTO() { DataLogId = r.DataLogId, DtRif = r.DtRif, ValNum = r.ValNum }) .OrderByDescending(x => x.DataLogId) .ToListAsync(); stopWatch.Stop(); LogDebug("DataLogDtoGetFilt", stopWatch.Elapsed); } catch (Exception exc) { LogException("Eccezione durante DataLogDtoGetFilt", exc); } } return dbResult; } /// /// Recupero record DataLog data condizione filtro /// /// Tipologia di dato richiesto da enum /// /// /// /// /// public async Task> DataLogGetFilt(DataLogType dataType, DateTime inizio, DateTime fine, int machineId, string fluxType) { List dbResult = new List(); using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = await localDbCtx .DbSetDataLog .Where(x => (x.MachineId == machineId) && (x.FluxType == fluxType) && (x.DataType == dataType || dataType == DataLogType.ND) && (x.DtRif >= inizio && x.DtRif <= fine)) .Include(m => m.MachineNav) .OrderByDescending(x => x.DataLogId) .ToListAsync(); stopWatch.Stop(); LogDebug("DataLogGetFilt (5p)", stopWatch.Elapsed); } catch (Exception exc) { LogException("Eccezione durante DataLogGetFilt (5p)", exc); } } return dbResult; } /// /// Recupero record DataLog data condizione filtro (multi-flusso) /// /// Tipologia di dato richiesto da enum /// /// /// public async Task> DataLogGetFilt(DataLogType dataType, DateTime inizio, DateTime fine) { List dbResult = new List(); using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = await localDbCtx .DbSetDataLog .Where(x => (x.DataType == dataType || dataType == DataLogType.ND) && (x.DtRif >= inizio && x.DtRif <= fine)) .Include(m => m.MachineNav) .OrderByDescending(x => x.DataLogId) .ToListAsync(); stopWatch.Stop(); LogDebug("DataLogGetFilt (3p)", stopWatch.Elapsed); } catch (Exception exc) { LogException("Eccezione durante DataLogGetFilt (3p)", exc); } } return dbResult; } /// /// Inserimento di un SET di record DataLog (post aggregazione base VC) /// /// Lista Record da inserire (senza ID...) /// public async Task DataLogInsertMany(List newItems) { bool fatto = false; using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); await localDbCtx .DbSetDataLog .AddRangeAsync(newItems); await localDbCtx.SaveChangesAsync(); fatto = true; stopWatch.Stop(); LogDebug("DataLogInsertMany", stopWatch.Elapsed); } catch (Exception exc) { LogException("Eccezione durante DataLogInsertMany", exc); } } return fatto; } /// /// Recupero record DataStAg (aggregati) data condizione filtro /// /// /// /// /// /// public List DataStAgGetFilt(int MachineId, string FluxType, int skipRec, int numRec) { List dbResult = new List(); using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = localDbCtx .DbSetDataStAg .Where(x => x.MachineId == MachineId && x.FluxType == FluxType) .Include(m => m.MachineNav) .OrderByDescending(x => x.DataStAgId) .Skip(skipRec) .Take(numRec) .ToList(); stopWatch.Stop(); LogDebug("DataStAgGetFilt", stopWatch.Elapsed); } catch (Exception exc) { LogException("Eccezione durante DataStAgGetFilt", exc); } } return dbResult; } /// /// Inserimento di un record DataStAg (aggregati) - creati da ANALYZER che effettua compattazione /// /// Record da inserire (senza ID...) /// public async Task DataStAgInsert(DataStAgModel newItem) { bool fatto = false; using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); localDbCtx .DbSetDataStAg .Add(newItem); await localDbCtx.SaveChangesAsync(); fatto = true; stopWatch.Stop(); LogDebug("DataStAgInsert", stopWatch.Elapsed); } catch (Exception exc) { LogException("Eccezione durante DataStAgInsert", exc); } } return fatto; } public void Dispose() { // Clear database context Log.Info("Dispose di MpDbController"); } public ProductionDTO MachineGetProd() { // !!!FIXME TODO... è fake... Random rand = new Random(); int stdCycle = 5; ProductionDTO currMachDto = new ProductionDTO() { Order = "ODL Test", ItemCode = "ART.0000123", ProgName = "P000012", CurrQty = DateTime.Now.Minute + rand.Next(1, 40), OrderQty = 100, CycleTimeMin = rand.NextDouble() * stdCycle, Message = "...simulated data..." }; Task.Delay(400).Wait(); return currMachDto; } /// /// Recupero pareto status impianto /// /// Macchina selezionata /// inizio periodo /// fine periodo /// public List ParetoStatusMach(int MachineId, DateTime from, DateTime to) { List dbResult = new List(); using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = localDbCtx .DbSetParetoStatus .FromSqlRaw("CALL stp_paretoStatus({0},{1},{2});", MachineId, from.ToString("yyyy-MM-dd"), to.ToString("yyyy-MM-dd")) .ToList(); LogDebug("ParetoStatusMach", stopWatch.Elapsed); stopWatch.Stop(); } catch (Exception exc) { LogException("Eccezione durante ParetoStatusMach", exc); } } return dbResult; } /// /// Recupera elenco contatori ammessi /// /// public List PMCounterModelGetAll() { List dbResult = new List(); using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = localDbCtx .DbSetCounter .ToList(); LogDebug("PMCounterModelGetAll", stopWatch.Elapsed); stopWatch.Stop(); } catch (Exception exc) { LogException("Eccezione durante PMCounterModelGetAll", exc); } } return dbResult; } /// /// Recupera elenco Gruppi Macchina PM ammessi /// /// public List PMMachGroupGetAll() { List dbResult = new List(); using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = localDbCtx .DbSetPMMachGroup .ToList(); LogDebug("PMMachGroupGetAll", stopWatch.Elapsed); stopWatch.Stop(); } catch (Exception exc) { LogException("Eccezione durante PMMachGroupGetAll", exc); } } return dbResult; } /// /// Eliminazione Record /// /// /// /// public async Task PMTaskDeleteRecord(PrevMaintTaskModel currRec, bool forceDelete) { bool fatto = false; using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); var currVal = localDbCtx .DbSetPMTask .Where(x => x.PMTaskId == currRec.PMTaskId) .FirstOrDefault(); if (currVal != null) { // se effettivo delete if (forceDelete) { localDbCtx .DbSetPMTask .Remove(currVal); } else { currVal.IsDisabled = true; } await localDbCtx.SaveChangesAsync(); } fatto = true; stopWatch.Stop(); LogDebug("PMTaskDeleteRecord", stopWatch.Elapsed); } catch (Exception exc) { LogException("Eccezione durante PMTaskDeleteRecord", exc); } } return fatto; } /// /// Riabilitazione task disabilitato /// /// /// public async Task PMTaskEnableRecord(PrevMaintTaskModel currRec) { bool fatto = false; using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); var currVal = localDbCtx .DbSetPMTask .Where(x => x.PMTaskId == currRec.PMTaskId) .FirstOrDefault(); if (currVal != null) { // se effettivo delete if (currRec.IsDisabled) { currVal.IsDisabled = false; } await localDbCtx.SaveChangesAsync(); } fatto = true; LogDebug("PMTaskEnableRecord", stopWatch.Elapsed); stopWatch.Stop(); } catch (Exception exc) { LogException("Eccezione durante PMTaskEnableRecord", exc); } } return fatto; } /// /// Recupera elenco Topics PM ammessi /// /// public List PMTaskTopicGetAll() { List dbResult = new List(); using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = localDbCtx .DbSetPMTopic .ToList(); LogDebug("PMTaskTopicGetAll", stopWatch.Elapsed); stopWatch.Stop(); } catch (Exception exc) { LogException("Eccezione durante PMTaskTopicGetAll", exc); } } return dbResult; } /// /// Recupera elenco User Team PM ammessi /// /// public List PMUTeamGetAll() { List dbResult = new List(); using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = localDbCtx .DbSetUTeam .ToList(); stopWatch.Stop(); LogDebug("PMUTeamGetAll", stopWatch.Elapsed); } catch (Exception exc) { LogException("Eccezione durante PMUTeamGetAll", exc); } } return dbResult; } /// /// Recupero elenco Task Manut Prev Previsti/Configurati (ultimi dato "skip") /// /// /// /// /// public List PrevMaintTaskGetFilt(int MachineId, int skipRec, int numRec) { List dbResult = new List(); using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = localDbCtx .DbSetPMTask .Where(x => x.MachineId == MachineId) .Include(m => m.CounterNav) .Include(m => m.MachGroupNav) .Include(m => m.MachineNav) .Include(m => m.TopicNav) .Include(m => m.UserTeamNav) .OrderBy(x => x.ExtIdx) .Skip(skipRec) .Take(numRec) .ToList(); LogDebug("PrevMaintTaskGetFilt", stopWatch.Elapsed); stopWatch.Stop(); } catch (Exception exc) { LogException("Eccezione durante PrevMaintTaskGetFilt", exc); } } return dbResult; } /// /// Esegue update del record /// /// /// public async Task PrevMaintTaskUpdate(PrevMaintTaskModel editRec) { bool fatto = false; using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); var currRec = localDbCtx .DbSetPMTask .Where(x => x.PMTaskId == editRec.PMTaskId) .FirstOrDefault(); if (currRec != null) { currRec.CCode = editRec.CCode; currRec.ExpiryVal = editRec.ExpiryVal; currRec.ExtIdx = editRec.ExtIdx; currRec.PMMGCode = editRec.PMMGCode; currRec.PMTCode = editRec.PMTCode; currRec.PMUTCode = editRec.PMUTCode; currRec.JobDescription = editRec.JobDescription; localDbCtx.Entry(currRec).State = EntityState.Modified; } else { // se nuovo (user edit) --> NON protetto! editRec.Protected = false; localDbCtx .DbSetPMTask .Add(editRec); } await localDbCtx.SaveChangesAsync(); fatto = true; stopWatch.Stop(); LogDebug("PrevMaintTaskUpdate", stopWatch.Elapsed); } catch (Exception exc) { LogException("Eccezione durante PrevMaintTaskUpdate", exc); } } return fatto; } /// /// Inserimento di una lista record Production Log /// /// Lista Record da inserire (senza ID...) /// public async Task ProdLogInsertMany(List newItems) { bool fatto = false; using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); await localDbCtx .DbSetProdLog .AddRangeAsync(newItems); await localDbCtx.SaveChangesAsync(); fatto = true; stopWatch.Stop(); LogDebug("ProdLogInsertMany", stopWatch.Elapsed); } catch (Exception exc) { LogException("Eccezione durante ProdLogInsertMany", exc); } } return fatto; } /// /// Effettua chiamata stored x pulizia dati stale/vecchi /// /// /// public List RemoveOldData(int numDay2Keep) { List dbResult = new List(); using (MapoMonoContext localDbCtx = new MapoMonoContext()) { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); try { dbResult = localDbCtx .DbSetTaskExec .FromSqlRaw("CALL stp_removeOldData({0});", numDay2Keep) .ToList(); stopWatch.Stop(); LogDebug("RemoveOldData", stopWatch.Elapsed); } catch (Exception exc) { LogException("Eccezione durante RemoveOldData", exc); } } return dbResult; } /// /// genera elenco Task Schedulati missing da schema + attualmente presenti... /// /// /// public async Task SchedMaintTaskCreateMissing(int MachineId) { bool answ = false; using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); List missTask = new List(); // elenco dei task NON disattivati List? allTask = localDbCtx .DbSetPMTask .Where(x => x.MachineId == MachineId && !x.IsDisabled) .Include(i => i.CounterNav) .ToList(); // analizzo task per idx del PMTask var reqTask = allTask .Select(x => x.PMTaskId) .ToList(); var openTask = localDbCtx .DbSetSMTask .Where(x => x.DtExecution == DateTime.MinValue) .Include(m => m.PMTaskeNav) .ToList(); var currTask = openTask .Where(x => x.PMTaskeNav.MachineId == MachineId) .Select(x => x.PMTaskId) .ToList(); // elenco dei SOLI task presenti var listTaskOk = currTask.Intersect(reqTask).ToList(); // dall'elenco di quelli originali elimino presenti --> ho elenco mancanti... foreach (var iTask in allTask) { // se non nell'elenco aggiungo... if (!listTaskOk.Exists(x => x == iTask.PMTaskId)) { missTask.Add(iTask); } } var newRecs = missTask.Select(x => new PendingMaintModel() { CCode = x.CCode, DtCreation = DateTime.Now, ExpiryVal = x.ExpiryVal, PMTaskId = x.PMTaskId, CountStartVal = x.CounterNav.ActualVal }).ToList(); localDbCtx .DbSetSMTask .AddRange(newRecs); // salvo localDbCtx.SaveChanges(); answ = true; LogDebug("SchedMaintTaskCreateMissing", stopWatch.Elapsed); stopWatch.Stop(); } catch (Exception exc) { LogException("Eccezione durante SchedMaintTaskGetFilt", exc); } } await Task.Delay(1); return answ; } /// /// Recupero elenco Task Schedulati dati Macchina ed intervento "master" /// /// Macchina selezionata /// ID del PMTask parent /// Num record da saltare /// num rec da recuperare /// public List SchedMaintTaskGetByPMTask(int MachineId, int PMTaskId, int skipRec, int numRec) { List dbResult = new List(); using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = localDbCtx .DbSetSMTask .Include(i => i.CounterNav) .Where(x => x.PMTaskeNav.MachineId == MachineId && x.PMTaskId == PMTaskId && x.DtExecution > DateTime.MinValue) .Include(m => m.PMTaskeNav.MachGroupNav) .Include(m => m.CounterNav) .Include(m => m.PMTaskeNav.MachineNav) .Include(m => m.PMTaskeNav.TopicNav) .Include(m => m.PMTaskeNav.UserTeamNav) .OrderByDescending(x => x.DtCreation) .Skip(skipRec) .Take(numRec) .ToList(); LogDebug("SchedMaintTaskGetByPMTask", stopWatch.Elapsed); stopWatch.Stop(); } catch (Exception exc) { LogException("Eccezione durante SchedMaintTaskGetByPMTask", exc); } } return dbResult; } /// /// Recupero elenco Task Schedulati (ultimi dato "skip") /// /// Macchina selezionata /// Num record da saltare /// num rec da recuperare /// public List SchedMaintTaskGetFilt(int MachineId, int skipRec, int numRec) { List dbResult = new List(); using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = localDbCtx .DbSetSMTask .Include(i => i.CounterNav) .Where(x => x.PMTaskeNav.MachineId == MachineId && x.DtExecution == DateTime.MinValue) .Include(m => m.PMTaskeNav.MachGroupNav) .Include(m => m.CounterNav) .Include(m => m.PMTaskeNav.MachineNav) .Include(m => m.PMTaskeNav.TopicNav) .Include(m => m.PMTaskeNav.UserTeamNav) .OrderBy(x => x.PMTaskeNav.ExtIdx) .Skip(skipRec) .Take(numRec) .ToList(); stopWatch.Stop(); LogDebug("SchedMaintTaskGetFilt", stopWatch.Elapsed); } catch (Exception exc) { LogException("Eccezione durante SchedMaintTaskGetFilt", exc); } } return dbResult; } /// /// Registro esecuzione task schedualto /// /// /// /// /// /// public async Task SchedMaintTaskSetDone(int MachineId, int SMTaskId, DateTime ExecDT, string ExecUser) { bool answ = false; using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); // Aggiorno il task schedulato var dbResult = localDbCtx .DbSetSMTask .Include(i => i.CounterNav) .Where(x => x.PMTaskeNav.MachineId == MachineId && x.SMTaskId == SMTaskId) .FirstOrDefault(); if (dbResult != null) { // aggiorno il record dbResult.DtExecution = ExecDT; dbResult.UserCode = ExecUser; dbResult.ElapsedVal = dbResult.CounterNav.ActualVal - dbResult.CountStartVal; // aggiorno il task parent col numero di task eseguiti... int numDone = localDbCtx .DbSetSMTask .Where(x => x.PMTaskId == dbResult.PMTaskId) .Count(); var parentRecord = localDbCtx .DbSetPMTask .Where(x => x.PMTaskId == dbResult.PMTaskId) .FirstOrDefault(); if (parentRecord != null) { parentRecord.NumTaskDone = numDone; } // eseguo salvataggi! localDbCtx.SaveChanges(); // segno fatto! answ = true; } LogDebug("SchedMaintTaskSetDone", stopWatch.Elapsed); stopWatch.Stop(); } catch (Exception exc) { LogException("Eccezione durante SchedMaintTaskSetDone", exc); } } await Task.Delay(1); return answ; } /// /// Inserisce un nuovo record status log calcolando durata da rec precedente.. /// /// /// public async Task StatusLogInsert(StatusLogModel newRec) { bool answ = false; using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); TimeSpan ts; bool needInsert = false; // ultimo inserito... var lastSet = localDbCtx .DbSetStatusLog .Where(x => x.MachineId == newRec.MachineId) .OrderByDescending(x => x.EventLogId) .Take(50) .ToList(); var lastRec = lastSet .OrderByDescending(x => x.DtRif) .FirstOrDefault(); // se non trovato inserisco comunque if (lastRec == null) { needInsert = true; } // se trovato controllo variazione... else { // se cambia stato... if (lastRec.CodStatus != newRec.CodStatus) { needInsert = true; } // oppure se è passato il giorno... else if (lastRec.DtRif.Date < newRec.DtRif.Date) { needInsert = true; } // calcolo durata vecchio record... lastRec.Duration = (float)DateTime.Now.Subtract(lastRec.DtRif).TotalMinutes; } if (needInsert) { localDbCtx .DbSetStatusLog .Add(newRec); // salvo se ho NUOVO record localDbCtx.SaveChanges(); LogDebug("StatusLogInsert", stopWatch.Elapsed); stopWatch.Stop(); } answ = true; } catch (Exception exc) { LogException("Eccezione durante StatusLogInsert", exc); } } await Task.Delay(1); return answ; } /// /// Registrazione record esecuzione task x log /// /// /// public bool TaskExecInsertLog(List recList) { bool answ = false; using (MapoMonoContext localDbCtx = new MapoMonoContext()) { try { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); localDbCtx .DbSetTaskExec .AddRange(recList); localDbCtx.SaveChanges(); answ = true; stopWatch.Stop(); LogDebug("TaskExecInsertLog", stopWatch.Elapsed); } catch (Exception exc) { LogException("Eccezione durante TaskExecInsertLog", exc); } } return answ; } #endregion Public Methods #region Private Fields private static NLog.Logger Log = LogManager.GetCurrentClassLogger(); /// /// Limite durata eventi loggati x passare comunque a livello INFO... /// private int LogDurationLimitMs = 2000; #endregion Private Fields #region Private Properties /// /// Accessor configurazione /// private IConfiguration appConf { get; set; } = null!; #endregion Private Properties #region Private Methods /// /// Effettua Log tipo Debug /// /// /// private void LogDebug(string message, TimeSpan ts) { // Se superato limite --> invio a INFO if (ts.TotalMilliseconds > LogDurationLimitMs) { LogInfo($"{message} | DurationLimit Exceeded", ts); } else { Log.Debug($"{message} | {ts.TotalMilliseconds} ms"); } } /// /// Effettua Log tipo ERROR /// /// /// Eventuale exxeczione da traccaire private void LogError(string message) { Log.Error(message); } /// /// Effettua Log tipo ERROR /// /// /// Eventuale eccezione da tracciare private void LogException(string message, Exception exc) { Log.Error(exc, $"{message}{Environment.NewLine}{exc}"); } /// /// Effettua Log tipo TRACE /// /// /// private void LogInfo(string message, TimeSpan ts) { Log.Info($"{message} | {ts.TotalMilliseconds} ms"); } /// /// Effettua Log tipo TRACE /// /// /// private void LogTrace(string message, TimeSpan ts) { // Se superato limite --> invio a INFO if (ts.TotalMilliseconds > LogDurationLimitMs) { LogInfo($"{message} | DurationLimit Exceeded", ts); } else { Log.Trace($"{message} | {ts.TotalMilliseconds} ms"); } } #endregion Private Methods } }