diff --git a/Jenkinsfile b/Jenkinsfile index decc111a..f47464dd 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -12,7 +12,7 @@ pipeline { steps { /* calcolo numero versione... diverso x branch MASTER/DEVELOP */ script { - withEnv(['NEXT_BUILD_NUMBER=1299']) { + withEnv(['NEXT_BUILD_NUMBER=1300']) { // env.versionNumber = VersionNumber(versionNumberString : '6.10.${BUILD_DATE_FORMATTED, "yyMM"}.${BUILDS_ALL_TIME}', projectStartDate : '2006-01-01', skipFailedBuilds: true) env.versionNumber = VersionNumber(versionNumberString : '6.10.${BUILD_DATE_FORMATTED, "yyMM"}.${BUILDS_ALL_TIME}', projectStartDate : '2006-01-01', skipFailedBuilds: true, overrideBuildsAllTime: '${NEXT_BUILD_NUMBER}') env.APP_NAME = 'MAPO' diff --git a/MP-IO/Web.config b/MP-IO/Web.config index efb39002..7601366c 100644 --- a/MP-IO/Web.config +++ b/MP-IO/Web.config @@ -24,8 +24,8 @@ - - + + diff --git a/MapoDb/DataLayer.cs b/MapoDb/DataLayer.cs index 07107e8c..42d8fef3 100644 --- a/MapoDb/DataLayer.cs +++ b/MapoDb/DataLayer.cs @@ -11,3216 +11,3292 @@ using SteamWare; namespace MapoDb { - /// - /// classe gestione operazioni su DB tramite MapoDb - /// - public class DataLayer - { - #region area table adapters - - // Table adapter x DS_Applicazione - public DS_applicazioneTableAdapters.AnagraficaGruppiTableAdapter taAG; - public DS_applicazioneTableAdapters.MacchineTableAdapter taMacchine; - public DS_applicazioneTableAdapters.StatoMacchineTableAdapter taStatoMacchine; - public DS_applicazioneTableAdapters.AnagraficaEventiTableAdapter taAnagEventi; - public DS_applicazioneTableAdapters.AnagraficaStatiTableAdapter taAnagStati; - public DS_applicazioneTableAdapters.KeepAliveTableAdapter taKeepAlive; - public DS_applicazioneTableAdapters.DiarioDiBordoTableAdapter taStati; - public DS_applicazioneTableAdapters.EventListTableAdapter taEventi; - public DS_applicazioneTableAdapters.AnagraficaOperatoriTableAdapter taOp; - public DS_applicazioneTableAdapters.AnagraficaOperatori2insTableAdapter taOp2ins; - public DS_applicazioneTableAdapters.TransizioneIngressiTableAdapter taTranIngr; - public DS_applicazioneTableAdapters.RemoteRebootLogTableAdapter taRemReb; - public DS_applicazioneTableAdapters.SignalLogTableAdapter taSigLog; - public DS_applicazioneTableAdapters.FluxLogTableAdapter taFL; - // Table adapter x DS_ProdTempi - public DS_ProdTempiTableAdapters.AnagArticoliTableAdapter taAnagArt; - public DS_ProdTempiTableAdapters.ODLTableAdapter taODL; - public DS_ProdTempiTableAdapters.DatiMacchineTableAdapter taDatiMacchine; - public DS_ProdTempiTableAdapters.stp_repDonati_getDatiProdMacchinaTableAdapter taDatiProdMacch; - public DS_ProdTempiTableAdapters.stp_repDonati_getDatiProdMacchinaPeriodoTableAdapter taDatiProdMacchPer; - public DS_ProdTempiTableAdapters.stp_repDonati_getLastStatoDurataMacchinaTableAdapter taDatiStatoMacch; - public DS_ProdTempiTableAdapters.PostazioniMapoTableAdapter taPostazioni; - public DS_ProdTempiTableAdapters.stp_PzProd_getByMacchinaTableAdapter taPzProd2conf; - public DS_ProdTempiTableAdapters.TempiCicloRilevatiTableAdapter taTempiCicloRilevati; - public DS_ProdTempiTableAdapters.DatiProduzioneTableAdapter taDatiProd; - public DS_ProdTempiTableAdapters.stp_TempoByIdxMaccPeriodClassTableAdapter taTempoByClass; - public DS_ProdTempiTableAdapters.TurniMacchinaTableAdapter taTurniMacc; - public DS_ProdTempiTableAdapters.CalendFesteFerieTableAdapter taCalFF; - public DS_ProdTempiTableAdapters.MappaStatoExplTableAdapter taMSE; - public DS_ProdTempiTableAdapters.PromesseODLTableAdapter taPODL; - public DS_ProdTempiTableAdapters.RegistroControlliTableAdapter taRC; - public DS_ProdTempiTableAdapters.RegistroScartiTableAdapter taRS; - public DS_ProdTempiTableAdapters.StatoProdTableAdapter taStatoProd; - // table adapter x utility - public DS_UtilityTableAdapters.v_selArticoliTableAdapter taSelArt; - public DS_UtilityTableAdapters.v_selMacchineTableAdapter taSelMacc; - public DS_UtilityTableAdapters.v_selODLTableAdapter taSelOdlFree; - public DS_UtilityTableAdapters.CommentiTableAdapter taComm; - - // table adapter x planner - public DS_PlanTableAdapters.MachineParamsTableAdapter taMacParams; - public DS_PlanTableAdapters.CalStopTableAdapter taPlanCalStop; - public DS_PlanTableAdapters.CalDispTableAdapter taPlanCalDisp; - public DS_PlanTableAdapters.RichiesteTableAdapter taPlanRichieste; - public DS_PlanTableAdapters.PromesseOUTTableAdapter taPromOut; - - // tablet adapter x IS - public DS_IntServTableAdapters.IstanzeKITTableAdapter taIstK; - public DS_IntServTableAdapters.ProduzioneAs400TableAdapter taAs400; - public DS_IntServTableAdapters.TKS_SearchTableAdapter taTKS; - public DS_IntServTableAdapters.TransitoDatiTableAdapter taIS_TrDati; - public DS_IntServTableAdapters.WipSetupKitTableAdapter taWKS; - /// - /// init dei table adapters + /// classe gestione operazioni su DB tramite MapoDb /// - protected void initTA() + public class DataLayer { - // istanzio oggetto - taAG = new DS_applicazioneTableAdapters.AnagraficaGruppiTableAdapter(); - taMacchine = new DS_applicazioneTableAdapters.MacchineTableAdapter(); - taStatoMacchine = new DS_applicazioneTableAdapters.StatoMacchineTableAdapter(); - taAnagEventi = new DS_applicazioneTableAdapters.AnagraficaEventiTableAdapter(); - taAnagStati = new DS_applicazioneTableAdapters.AnagraficaStatiTableAdapter(); - taKeepAlive = new DS_applicazioneTableAdapters.KeepAliveTableAdapter(); - taStati = new DS_applicazioneTableAdapters.DiarioDiBordoTableAdapter(); - taEventi = new DS_applicazioneTableAdapters.EventListTableAdapter(); - taOp = new DS_applicazioneTableAdapters.AnagraficaOperatoriTableAdapter(); - taOp2ins = new DS_applicazioneTableAdapters.AnagraficaOperatori2insTableAdapter(); - taTranIngr = new DS_applicazioneTableAdapters.TransizioneIngressiTableAdapter(); - taRemReb = new DS_applicazioneTableAdapters.RemoteRebootLogTableAdapter(); - taSigLog = new DS_applicazioneTableAdapters.SignalLogTableAdapter(); - taFL = new DS_applicazioneTableAdapters.FluxLogTableAdapter(); - taAnagArt = new DS_ProdTempiTableAdapters.AnagArticoliTableAdapter(); - taODL = new DS_ProdTempiTableAdapters.ODLTableAdapter(); - taDatiMacchine = new DS_ProdTempiTableAdapters.DatiMacchineTableAdapter(); - taDatiProdMacch = new DS_ProdTempiTableAdapters.stp_repDonati_getDatiProdMacchinaTableAdapter(); - taDatiProdMacchPer = new DS_ProdTempiTableAdapters.stp_repDonati_getDatiProdMacchinaPeriodoTableAdapter(); - taDatiStatoMacch = new DS_ProdTempiTableAdapters.stp_repDonati_getLastStatoDurataMacchinaTableAdapter(); - taPostazioni = new DS_ProdTempiTableAdapters.PostazioniMapoTableAdapter(); - taTurniMacc = new DS_ProdTempiTableAdapters.TurniMacchinaTableAdapter(); - taPzProd2conf = new DS_ProdTempiTableAdapters.stp_PzProd_getByMacchinaTableAdapter(); - taTempiCicloRilevati = new DS_ProdTempiTableAdapters.TempiCicloRilevatiTableAdapter(); - taDatiProd = new DS_ProdTempiTableAdapters.DatiProduzioneTableAdapter(); - taTempoByClass = new DS_ProdTempiTableAdapters.stp_TempoByIdxMaccPeriodClassTableAdapter(); - taCalFF = new DS_ProdTempiTableAdapters.CalendFesteFerieTableAdapter(); - taMSE = new DS_ProdTempiTableAdapters.MappaStatoExplTableAdapter(); - taPODL = new DS_ProdTempiTableAdapters.PromesseODLTableAdapter(); - taRC = new DS_ProdTempiTableAdapters.RegistroControlliTableAdapter(); - taRS = new DS_ProdTempiTableAdapters.RegistroScartiTableAdapter(); - taStatoProd = new DS_ProdTempiTableAdapters.StatoProdTableAdapter(); + #region area table adapters - taSelArt = new DS_UtilityTableAdapters.v_selArticoliTableAdapter(); - taSelMacc = new DS_UtilityTableAdapters.v_selMacchineTableAdapter(); - taSelOdlFree = new DS_UtilityTableAdapters.v_selODLTableAdapter(); - taComm = new DS_UtilityTableAdapters.CommentiTableAdapter(); + // Table adapter x DS_Applicazione + public DS_applicazioneTableAdapters.AnagraficaGruppiTableAdapter taAG; - taMacParams = new DS_PlanTableAdapters.MachineParamsTableAdapter(); - taPlanCalStop = new DS_PlanTableAdapters.CalStopTableAdapter(); - taPlanCalDisp = new DS_PlanTableAdapters.CalDispTableAdapter(); - taPlanRichieste = new DS_PlanTableAdapters.RichiesteTableAdapter(); - taPromOut = new DS_PlanTableAdapters.PromesseOUTTableAdapter(); + // Table adapter x DS_ProdTempi + public DS_ProdTempiTableAdapters.AnagArticoliTableAdapter taAnagArt; - taIstK = new DS_IntServTableAdapters.IstanzeKITTableAdapter(); - taAs400 = new DS_IntServTableAdapters.ProduzioneAs400TableAdapter(); - taTKS = new DS_IntServTableAdapters.TKS_SearchTableAdapter(); - taIS_TrDati = new DS_IntServTableAdapters.TransitoDatiTableAdapter(); - taWKS = new DS_IntServTableAdapters.WipSetupKitTableAdapter(); - } - /// - /// effettua setup dei connection strings da web.config delal singola applicazione - /// - protected virtual void setupConnectionStringBase() - { - string connectionString = memLayer.ML.confReadString("MoonProConnectionString"); - string connectionStringIS = memLayer.ML.confReadString("MoonProConnectionStringIS"); - string connectionStringES3 = memLayer.ML.confReadString("MoonProConnectionStringES3"); - // connections del db - taAG.Connection.ConnectionString = connectionString; - taMacchine.Connection.ConnectionString = connectionString; - taStatoMacchine.Connection.ConnectionString = connectionString; - taAnagEventi.Connection.ConnectionString = connectionString; - taAnagStati.Connection.ConnectionString = connectionString; - taKeepAlive.Connection.ConnectionString = connectionString; - taStati.Connection.ConnectionString = connectionString; - taEventi.Connection.ConnectionString = connectionString; - taOp.Connection.ConnectionString = connectionString; - taOp2ins.Connection.ConnectionString = connectionString; - taTranIngr.Connection.ConnectionString = connectionString; - taRemReb.Connection.ConnectionString = connectionString; - taSigLog.Connection.ConnectionString = connectionString; - taFL.Connection.ConnectionString = connectionString; - taAnagArt.Connection.ConnectionString = connectionString; - taODL.Connection.ConnectionString = connectionString; - taDatiMacchine.Connection.ConnectionString = connectionString; - taDatiProdMacch.Connection.ConnectionString = connectionString; - taDatiProdMacchPer.Connection.ConnectionString = connectionString; - taDatiStatoMacch.Connection.ConnectionString = connectionString; - taPostazioni.Connection.ConnectionString = connectionString; - taTurniMacc.Connection.ConnectionString = connectionString; - taPzProd2conf.Connection.ConnectionString = connectionString; - taTempiCicloRilevati.Connection.ConnectionString = connectionString; - taDatiProd.Connection.ConnectionString = connectionString; - taTempoByClass.Connection.ConnectionString = connectionString; - taCalFF.Connection.ConnectionString = connectionString; - taMSE.Connection.ConnectionString = connectionString; - taPODL.Connection.ConnectionString = connectionString; - taRC.Connection.ConnectionString = connectionString; - taRS.Connection.ConnectionString = connectionString; - taStatoProd.Connection.ConnectionString = connectionString; - taSelArt.Connection.ConnectionString = connectionString; - taSelMacc.Connection.ConnectionString = connectionString; - taSelOdlFree.Connection.ConnectionString = connectionString; - taComm.Connection.ConnectionString = connectionString; - // area planner - taMacParams.Connection.ConnectionString = connectionStringES3; - taPlanCalStop.Connection.ConnectionString = connectionStringES3; - taPlanCalDisp.Connection.ConnectionString = connectionStringES3; - taPlanRichieste.Connection.ConnectionString = connectionStringES3; - taPromOut.Connection.ConnectionString = connectionStringES3; - // area IS - taIS_TrDati.Connection.ConnectionString = connectionStringIS; - taIstK.Connection.ConnectionString = connectionStringIS; - taAs400.Connection.ConnectionString = connectionStringIS; - taWKS.Connection.ConnectionString = connectionStringIS; - taTKS.Connection.ConnectionString = connectionStringIS; - } + public DS_applicazioneTableAdapters.AnagraficaEventiTableAdapter taAnagEventi; + public DS_applicazioneTableAdapters.AnagraficaStatiTableAdapter taAnagStati; + public DS_IntServTableAdapters.ProduzioneAs400TableAdapter taAs400; + public DS_ProdTempiTableAdapters.CalendFesteFerieTableAdapter taCalFF; + public DS_UtilityTableAdapters.CommentiTableAdapter taComm; + public DS_ProdTempiTableAdapters.DatiMacchineTableAdapter taDatiMacchine; + public DS_ProdTempiTableAdapters.DatiProduzioneTableAdapter taDatiProd; + public DS_ProdTempiTableAdapters.stp_repDonati_getDatiProdMacchinaTableAdapter taDatiProdMacch; + public DS_ProdTempiTableAdapters.stp_repDonati_getDatiProdMacchinaPeriodoTableAdapter taDatiProdMacchPer; + public DS_ProdTempiTableAdapters.stp_repDonati_getLastStatoDurataMacchinaTableAdapter taDatiStatoMacch; + public DS_applicazioneTableAdapters.EventListTableAdapter taEventi; + public DS_applicazioneTableAdapters.FluxLogTableAdapter taFL; + public DS_IntServTableAdapters.TransitoDatiTableAdapter taIS_TrDati; - #endregion + // tablet adapter x IS + public DS_IntServTableAdapters.IstanzeKITTableAdapter taIstK; - #region Inizializzazione + public DS_applicazioneTableAdapters.KeepAliveTableAdapter taKeepAlive; + public DS_applicazioneTableAdapters.MacchineTableAdapter taMacchine; - /// - /// Oggetto MapoDb impiegato da DataLayer x i suoi accessi ai dati - /// - public MapoDb MapoDbObj = new MapoDb(); + // table adapter x planner + public DS_PlanTableAdapters.MachineParamsTableAdapter taMacParams; - /// - /// Init classe - /// - public DataLayer() - { - initTA(); - setupConnectionStringBase(); + public DS_ProdTempiTableAdapters.MappaStatoExplTableAdapter taMSE; + public DS_ProdTempiTableAdapters.ODLTableAdapter taODL; + public DS_applicazioneTableAdapters.AnagraficaOperatoriTableAdapter taOp; + public DS_applicazioneTableAdapters.AnagraficaOperatori2insTableAdapter taOp2ins; + public DS_PlanTableAdapters.CalDispTableAdapter taPlanCalDisp; + public DS_PlanTableAdapters.CalStopTableAdapter taPlanCalStop; + public DS_PlanTableAdapters.RichiesteTableAdapter taPlanRichieste; + public DS_ProdTempiTableAdapters.PromesseODLTableAdapter taPODL; + public DS_ProdTempiTableAdapters.PostazioniMapoTableAdapter taPostazioni; + public DS_PlanTableAdapters.PromesseOUTTableAdapter taPromOut; + public DS_ProdTempiTableAdapters.stp_PzProd_getByMacchinaTableAdapter taPzProd2conf; + public DS_ProdTempiTableAdapters.RegistroControlliTableAdapter taRC; + public DS_applicazioneTableAdapters.RemoteRebootLogTableAdapter taRemReb; + public DS_ProdTempiTableAdapters.RegistroScartiTableAdapter taRS; - // aggiunta x gestione timeout esteso (ove necessario)! - fixCommandTimeout(); + // table adapter x utility + public DS_UtilityTableAdapters.v_selArticoliTableAdapter taSelArt; - // init oggetto MapoDb - MapoDbObj = new MapoDb(); - } + public DS_UtilityTableAdapters.v_selMacchineTableAdapter taSelMacc; + public DS_UtilityTableAdapters.v_selODLTableAdapter taSelOdlFree; + public DS_applicazioneTableAdapters.SignalLogTableAdapter taSigLog; + public DS_applicazioneTableAdapters.DiarioDiBordoTableAdapter taStati; + public DS_applicazioneTableAdapters.StatoMacchineTableAdapter taStatoMacchine; + public DS_ProdTempiTableAdapters.StatoProdTableAdapter taStatoProd; + public DS_ProdTempiTableAdapters.TempiCicloRilevatiTableAdapter taTempiCicloRilevati; + public DS_ProdTempiTableAdapters.stp_TempoByIdxMaccPeriodClassTableAdapter taTempoByClass; + public DS_IntServTableAdapters.TKS_SearchTableAdapter taTKS; + public DS_applicazioneTableAdapters.TransizioneIngressiTableAdapter taTranIngr; + public DS_ProdTempiTableAdapters.TurniMacchinaTableAdapter taTurniMacc; + public DS_IntServTableAdapters.WipSetupKitTableAdapter taWKS; - /// - /// sistemazione timeout comandi nei tableadapter - /// - private void fixCommandTimeout() - { - SetAllCommandTimeouts(taComm, memLayer.ML.CRI("sqlLongCommandTimeout")); - } - void SetAllCommandTimeouts(object adapter, int timeout) - { - var commands = adapter.GetType().InvokeMember( - "CommandCollection", - BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.NonPublic, - null, adapter, new object[0]); - var sqlCommand = (SqlCommand[])commands; - foreach (var cmd in sqlCommand) - { - cmd.CommandTimeout = timeout; - } - } - - #endregion - - #region utility interne - - /// - /// registra su REDIS eventuale superamento numero limite di call x il metodo in oggetto - /// - /// - private static void saveCallRec(string callCountKey) - { - // conto la richiesta nel contatore REDIS - long nCall = memLayer.ML.setRCntI(mHash($"COUNT:pCall:{callCountKey}")); - //... se == nCall2Log scrivo su log e resetto - long nCall2Log = memLayer.ML.cdvi("nCall2Log"); - if (nCall >= nCall2Log) - { - // loggo - logger.lg.scriviLog($"{callCountKey}: {nCall} call received", tipoLog.INFO); - // resetto! - memLayer.ML.resetRCnt(mHash($"COUNT:pCall:{callCountKey}")); - } - } - - public static List DataTableToList(DataTable dt) where T : class, new() - { - List lstItems = new List(); - if (dt != null && dt.Rows.Count > 0) - foreach (DataRow row in dt.Rows) - lstItems.Add(ConvertDataRowToGenericType(row)); - else - lstItems = null; - return lstItems; - } - - private static T ConvertDataRowToGenericType(DataRow row) where T : class, new() - { - Type entityType = typeof(T); - T objEntity = new T(); - foreach (DataColumn column in row.Table.Columns) - { - object value = row[column.ColumnName]; - if (value == DBNull.Value) value = null; - PropertyInfo property = entityType.GetProperty(column.ColumnName, BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.Public); - try + /// + /// init dei table adapters + /// + protected void initTA() { - if (property != null && property.CanWrite) - property.SetValue(objEntity, value, null); + // istanzio oggetto + taAG = new DS_applicazioneTableAdapters.AnagraficaGruppiTableAdapter(); + taMacchine = new DS_applicazioneTableAdapters.MacchineTableAdapter(); + taStatoMacchine = new DS_applicazioneTableAdapters.StatoMacchineTableAdapter(); + taAnagEventi = new DS_applicazioneTableAdapters.AnagraficaEventiTableAdapter(); + taAnagStati = new DS_applicazioneTableAdapters.AnagraficaStatiTableAdapter(); + taKeepAlive = new DS_applicazioneTableAdapters.KeepAliveTableAdapter(); + taStati = new DS_applicazioneTableAdapters.DiarioDiBordoTableAdapter(); + taEventi = new DS_applicazioneTableAdapters.EventListTableAdapter(); + taOp = new DS_applicazioneTableAdapters.AnagraficaOperatoriTableAdapter(); + taOp2ins = new DS_applicazioneTableAdapters.AnagraficaOperatori2insTableAdapter(); + taTranIngr = new DS_applicazioneTableAdapters.TransizioneIngressiTableAdapter(); + taRemReb = new DS_applicazioneTableAdapters.RemoteRebootLogTableAdapter(); + taSigLog = new DS_applicazioneTableAdapters.SignalLogTableAdapter(); + taFL = new DS_applicazioneTableAdapters.FluxLogTableAdapter(); + taAnagArt = new DS_ProdTempiTableAdapters.AnagArticoliTableAdapter(); + taODL = new DS_ProdTempiTableAdapters.ODLTableAdapter(); + taDatiMacchine = new DS_ProdTempiTableAdapters.DatiMacchineTableAdapter(); + taDatiProdMacch = new DS_ProdTempiTableAdapters.stp_repDonati_getDatiProdMacchinaTableAdapter(); + taDatiProdMacchPer = new DS_ProdTempiTableAdapters.stp_repDonati_getDatiProdMacchinaPeriodoTableAdapter(); + taDatiStatoMacch = new DS_ProdTempiTableAdapters.stp_repDonati_getLastStatoDurataMacchinaTableAdapter(); + taPostazioni = new DS_ProdTempiTableAdapters.PostazioniMapoTableAdapter(); + taTurniMacc = new DS_ProdTempiTableAdapters.TurniMacchinaTableAdapter(); + taPzProd2conf = new DS_ProdTempiTableAdapters.stp_PzProd_getByMacchinaTableAdapter(); + taTempiCicloRilevati = new DS_ProdTempiTableAdapters.TempiCicloRilevatiTableAdapter(); + taDatiProd = new DS_ProdTempiTableAdapters.DatiProduzioneTableAdapter(); + taTempoByClass = new DS_ProdTempiTableAdapters.stp_TempoByIdxMaccPeriodClassTableAdapter(); + taCalFF = new DS_ProdTempiTableAdapters.CalendFesteFerieTableAdapter(); + taMSE = new DS_ProdTempiTableAdapters.MappaStatoExplTableAdapter(); + taPODL = new DS_ProdTempiTableAdapters.PromesseODLTableAdapter(); + taRC = new DS_ProdTempiTableAdapters.RegistroControlliTableAdapter(); + taRS = new DS_ProdTempiTableAdapters.RegistroScartiTableAdapter(); + taStatoProd = new DS_ProdTempiTableAdapters.StatoProdTableAdapter(); + taSelArt = new DS_UtilityTableAdapters.v_selArticoliTableAdapter(); + taSelMacc = new DS_UtilityTableAdapters.v_selMacchineTableAdapter(); + taSelOdlFree = new DS_UtilityTableAdapters.v_selODLTableAdapter(); + taComm = new DS_UtilityTableAdapters.CommentiTableAdapter(); + + taMacParams = new DS_PlanTableAdapters.MachineParamsTableAdapter(); + taPlanCalStop = new DS_PlanTableAdapters.CalStopTableAdapter(); + taPlanCalDisp = new DS_PlanTableAdapters.CalDispTableAdapter(); + taPlanRichieste = new DS_PlanTableAdapters.RichiesteTableAdapter(); + taPromOut = new DS_PlanTableAdapters.PromesseOUTTableAdapter(); + + taIstK = new DS_IntServTableAdapters.IstanzeKITTableAdapter(); + taAs400 = new DS_IntServTableAdapters.ProduzioneAs400TableAdapter(); + taTKS = new DS_IntServTableAdapters.TKS_SearchTableAdapter(); + taIS_TrDati = new DS_IntServTableAdapters.TransitoDatiTableAdapter(); + taWKS = new DS_IntServTableAdapters.WipSetupKitTableAdapter(); } - catch (Exception ex) - { - throw ex; - } - } - return objEntity; - } - #endregion + /// + /// effettua setup dei connection strings da web.config delal singola applicazione + /// + protected virtual void setupConnectionStringBase() + { + string connectionString = memLayer.ML.confReadString("MoonProConnectionString"); + string connectionStringIS = memLayer.ML.confReadString("MoonProConnectionStringIS"); + string connectionStringES3 = memLayer.ML.confReadString("MoonProConnectionStringES3"); + // connections del db + taAG.Connection.ConnectionString = connectionString; + taMacchine.Connection.ConnectionString = connectionString; + taStatoMacchine.Connection.ConnectionString = connectionString; + taAnagEventi.Connection.ConnectionString = connectionString; + taAnagStati.Connection.ConnectionString = connectionString; + taKeepAlive.Connection.ConnectionString = connectionString; + taStati.Connection.ConnectionString = connectionString; + taEventi.Connection.ConnectionString = connectionString; + taOp.Connection.ConnectionString = connectionString; + taOp2ins.Connection.ConnectionString = connectionString; + taTranIngr.Connection.ConnectionString = connectionString; + taRemReb.Connection.ConnectionString = connectionString; + taSigLog.Connection.ConnectionString = connectionString; + taFL.Connection.ConnectionString = connectionString; + taAnagArt.Connection.ConnectionString = connectionString; + taODL.Connection.ConnectionString = connectionString; + taDatiMacchine.Connection.ConnectionString = connectionString; + taDatiProdMacch.Connection.ConnectionString = connectionString; + taDatiProdMacchPer.Connection.ConnectionString = connectionString; + taDatiStatoMacch.Connection.ConnectionString = connectionString; + taPostazioni.Connection.ConnectionString = connectionString; + taTurniMacc.Connection.ConnectionString = connectionString; + taPzProd2conf.Connection.ConnectionString = connectionString; + taTempiCicloRilevati.Connection.ConnectionString = connectionString; + taDatiProd.Connection.ConnectionString = connectionString; + taTempoByClass.Connection.ConnectionString = connectionString; + taCalFF.Connection.ConnectionString = connectionString; + taMSE.Connection.ConnectionString = connectionString; + taPODL.Connection.ConnectionString = connectionString; + taRC.Connection.ConnectionString = connectionString; + taRS.Connection.ConnectionString = connectionString; + taStatoProd.Connection.ConnectionString = connectionString; + taSelArt.Connection.ConnectionString = connectionString; + taSelMacc.Connection.ConnectionString = connectionString; + taSelOdlFree.Connection.ConnectionString = connectionString; + taComm.Connection.ConnectionString = connectionString; + // area planner + taMacParams.Connection.ConnectionString = connectionStringES3; + taPlanCalStop.Connection.ConnectionString = connectionStringES3; + taPlanCalDisp.Connection.ConnectionString = connectionStringES3; + taPlanRichieste.Connection.ConnectionString = connectionStringES3; + taPromOut.Connection.ConnectionString = connectionStringES3; + // area IS + taIS_TrDati.Connection.ConnectionString = connectionStringIS; + taIstK.Connection.ConnectionString = connectionStringIS; + taAs400.Connection.ConnectionString = connectionStringIS; + taWKS.Connection.ConnectionString = connectionStringIS; + taTKS.Connection.ConnectionString = connectionStringIS; + } - #region utility public esposte + #endregion area table adapters - /// - /// Effettua conferma prod macchina dell'intero periodo da confermare (ultima conferma --> adesso) - /// - /// idx macchina da confermare - /// 0=periodo, 1 = giorno, 2 = turno - /// qta pezzi BUONI da confermare - /// qta pezzi SCARTO da confermare - /// DataOra in cui registrare approvazione - /// - public bool confermaProdMacchina(string idxMacchina, int modoConfProd, int numPzConfermati, int numPzScarto, DateTime DataOraApp) - { - bool answ = false; - try - { - DS_ProdTempi.stp_PzProd_getByMacchinaRow rigaProd = taPzProd2conf.GetData(idxMacchina.ToString())[0]; - // chiamo stored stp_ConfermaProduzCompleta(idxMacchina,MatrApp,dataFrom,dataTo,pezziConf) - taPzProd2conf.stp_ConfermaProduzCompleta(idxMacchina, MatrOpr, rigaProd.DataFrom, DataOraApp, numPzConfermati, numPzScarto, modoConfProd, DataOraApp, true); - // indico eseguito! - answ = true; - } - catch (Exception exc) - { - logger.lg.scriviLog($"Errore in conferma prod macchina:{Environment.NewLine}{exc}"); - } - return answ; - } - /// - /// Effettua conferma prod macchina dell'intero periodo da confermare (ultima conferma --> adesso) - /// - /// idx macchina da confermare - /// 0=periodo, 1 = giorno, 2 = turno - /// qta pezzi BUONI da confermare - /// qta pezzi LASCIATI alla macchina da confermare (2 eventi 121 rettifica neg/pos) - /// qta pezzi SCARTO da confermare - /// DataOra in cui registrare approvazione - /// - public bool confermaProdMacchinaFull(string idxMacchina, int modoConfProd, int numPzConfermati, int numPzLasciati, int numPzScarto, DateTime DataOraApp) - { - bool answ = false; - try - { - DS_ProdTempi.stp_PzProd_getByMacchinaRow rigaProd = taPzProd2conf.GetData(idxMacchina.ToString())[0]; - taPzProd2conf.stp_ConfermaProduzCompletaFull(idxMacchina, MatrOpr, rigaProd.DataFrom, DataOraApp, numPzConfermati, numPzLasciati, numPzScarto, modoConfProd, DataOraApp, true); - // indico eseguito! - answ = true; - } - catch (Exception exc) - { - logger.lg.scriviLog($"Errore in conferma prod macchina con rett ev121:{Environment.NewLine}{exc}"); - } - return answ; - } - /// - /// invia una mail al destinatario x linkare nuovi devices tramite URL - /// - /// - /// - /// - /// - public bool sendUserAuthEmail(string destinatario, string UserAuthKey, int idxDipendente) - { - bool fatto = false; - string smtpCli = ""; - string mittente = ""; - string oggetto = ""; - string userUrl = ""; - string baseUrl = ""; - string userWebUrl = ""; - string baseWebUrl = ""; - string corpo = ""; - try - { - // compongo la stringa - smtpCli = memLayer.ML.CRS("_smtpCli"); - mittente = memLayer.ML.CRS("_fromEmail"); - oggetto = "Link autorizzazione device per GPW"; - baseUrl = memLayer.ML.CRS("baseUrl"); - baseWebUrl = memLayer.ML.CRS("baseWebUrl"); - userUrl = string.Format("{2}jumper.aspx?UserAuthkey={0}&idxDipendente={1}", UserAuthKey, idxDipendente, baseUrl); - userWebUrl = string.Format("{2}jumper.aspx?UserAuthkey={0}&idxDipendente={1}", UserAuthKey, idxDipendente, baseWebUrl); - corpo = string.Format("Hai ricevuto questa email su richiesta tua o dell'Admin per poter procedere a registrare un (nuovo) devices con GPW:{0}
Per proseguire clicca sul link seguente(rete interna):
{0}{0}{1}{0}{0}

oppure sul link seguente (internet):
{0}{0}{2}{0}{0}

Team GPW Steamware", Environment.NewLine, userUrl, userWebUrl); - gestEmail.ge.mandaEmail(mittente, destinatario, oggetto, corpo); - fatto = true; - } - catch { } - return fatto; - } - /// - /// Invia email di avviso che ci sono dei TC da confermare - /// - /// - /// - public bool sendWarnTcChangeReq(string destinatario) - { - bool fatto = false; - string mittente = ""; - string oggetto = ""; - string pageUrl = ""; - string corpo = ""; - try - { - // compongo la stringa - mittente = memLayer.ML.CRS("_fromEmail"); - oggetto = memLayer.ML.CRS("oggettoChgTc"); - pageUrl = string.Format("{0}{1}", memLayer.ML.CRS("baseUrlAdmin"), memLayer.ML.CRS("pageUrlApprODL")); - corpo = string.Format(memLayer.ML.CRS("corpoChgTc"), Environment.NewLine, pageUrl); - if (memLayer.ML.CRB("_useAuthSmtp")) - { - gestEmail.geAuth.mandaEmail(mittente, destinatario, oggetto, corpo); - } - else - { - gestEmail.ge.mandaEmail(mittente, destinatario, oggetto, corpo); - } - fatto = true; - } - catch { } - return fatto; - } + #region Inizializzazione - /// - /// effettua enroll del device - /// - /// - /// - /// - /// - /// - /// - public bool enrollDevice(string UserAuthKey, string IPv4, string DeviceName, string Description, int matricola) - { - bool fatto = false; - // in primis testo se dipendente ed authKey sono validi.. - if (taOp.getByMatrAuthKey(matricola, UserAuthKey).Rows.Count > 0) - { - // salvo matrOpr - MatrOpr = matricola; - /************************************************ - * Gestione riconoscimento devices - * - * - cerco IP del device, testo se è rete interna (A) o extranet/internet (B) cercando substring "localNet" da web.config - * (A): device interni: c'è un DHCP, e "dhcpLeaseTime" deve essere pari a lease time--- - * - verifico se IP già in uso da un tempo < "dhcpLeaseTime" --> in questo caso segnalo errore e rimbalzo (NON permetto di registrare device a nuovo utente... sospetto uso "improprio" del device - * - se tempo > dhcpLeaseTime allora può aver cambiato IP: aggiorno IP e descrizione del device e proseguo - * (B): all'esterno vedo tutta una subnet NATtata con unico IP, non è + discriminante - * - le timbrature "da esterno" devono essere confermate (instrodurre "tipo timbratura" x cui interne sono autoconfermate, esterne sono "grayed" (da confermare, da admin o ad esempio se si accende secondo device utente entro 5/10 min) - * - le timbrature ext DOVREBBERO chiedere location (jScript?) e inviarla, visibile in conferma - * - * - * **********************************************/ - // calcolo il secret... - DateTime adesso = DateTime.Now; - string Dominio = memLayer.ML.CRS("dominio"); - string UsrName = memLayer.ML.CRS("user"); - // recupero dati da matricola... - try + /// + /// Oggetto MapoDb impiegato da DataLayer x i suoi accessi ai dati + /// + public MapoDb MapoDbObj = new MapoDb(); + + /// + /// Init classe + /// + public DataLayer() { - DataLayer_AnagGen.UTENTERow rigaUt = user_std.UtSn.rigaUtenteDaMatricola(matricola.ToString()); - if (rigaUt != null) - { - Dominio = rigaUt.DOMINIO; - UsrName = rigaUt.USER_NAME; - } - else - { - logger.lg.scriviLog(string.Format("non sono riuscito a recuperare RIGA utente per matricola {0}", matricola), tipoLog.ERROR); - } + initTA(); + setupConnectionStringBase(); + + // aggiunta x gestione timeout esteso (ove necessario)! + fixCommandTimeout(); + + // init oggetto MapoDb + MapoDbObj = new MapoDb(); } - catch + + /// + /// sistemazione timeout comandi nei tableadapter + /// + private void fixCommandTimeout() { - logger.lg.scriviLog(string.Format("Eccezione! non sono riuscito a recuperare utente per matricola {0}", matricola), tipoLog.ERROR); - Dominio = memLayer.ML.CRS("dominio"); - UsrName = memLayer.ML.CRS("user"); + SetAllCommandTimeouts(taComm, memLayer.ML.CRI("sqlLongCommandTimeout")); } - string Secret = authProxy.getSecret(Dominio, UsrName, matricola, DeviceName, adesso); - string devSecret = SteamCrypto.EncryptString(Secret, memLayer.ML.CRS("cookieName")); - try + + private void SetAllCommandTimeouts(object adapter, int timeout) { - // creo device + cookie! - fatto = authProxy.createNewCookie(Dominio, UsrName, matricola, DeviceName, Description, IPv4, memLayer.ML.CRS("cookieName"), DateTime.Now.AddDays(memLayer.ML.CRI("cookieDayExpire"))); - // loggo! - logger.lg.scriviLog(string.Format("Effettuato enroll nuovo device: utente {0}\\{1} | matricola {2} | DeviceName {3} | Descrizione {4} | IP {5} | nome cookcie {6} | valido sino a {7:yyyy/MM/dd}", Dominio, UsrName, matricola, DeviceName, Description, IPv4, memLayer.ML.CRS("cookieName"), DateTime.Now.AddDays(memLayer.ML.CRI("cookieDayExpire")))); - } - catch (Exception exc) - { - logger.lg.scriviLog(string.Format("Errore enroll nuovo device:{0}{1}", Environment.NewLine, exc), tipoLog.EXCEPTION); - } - } - return fatto; - } - /// - /// MatrOpr in sessione - /// - public int MatrOpr - { - get - { - int idx = 0; - try - { - idx = memLayer.ML.IntSessionObj("MatrOpr"); - } - catch { } - return idx; - } - set - { - memLayer.ML.setSessionVal("MatrOpr", value); - } - } - /// - /// Cognome Nome da MatrOpr in sessione - /// - public string CognomeNomeOpr - { - get - { - // cerco operatore... - string answ = ""; - try - { - DS_applicazione.AnagraficaOperatoriRow oper = taOp.getByMatrOpr(MatrOpr)[0]; - answ = string.Format("{0} {1}", oper.Cognome, oper.Nome); - } - catch { } - return answ; - } - } - /// - /// Processa input da IOB eventualmente registrando i segnali inviati - /// - /// - /// - /// - /// - /// - /// - public string processInput(string idxMacchina, string valore, string dtEve, string dtCurr, string contatore) - { - string answ = ""; - // 2018.10.26 controllo dtEve e dtCurr - if (dtEve == null || dtCurr == null) - { - logger.lg.scriviLog(string.Format("procInput: valori nulli date: idxMacchina: {0} | valore: {1} | dtEve: {2} | dtCurr:{3}", idxMacchina, valore, dtEve, dtCurr)); - } - else if (dtEve.Length < 17 || dtCurr.Length < 17) - { - logger.lg.scriviLog(string.Format("procInput: valori data non corretti: idxMacchina: {0} | valore: {1} | dtEve: {2} | dtCurr:{3}", idxMacchina, valore, dtEve, dtCurr)); - } - else - { - // 2017.09.14 trimmo eventualmente lo zero finale dalle date SE supera i millisecondi... - dtEve = dtEve.Length > 17 ? dtEve.Substring(0, 17) : dtEve; - dtCurr = dtCurr.Length > 17 ? dtCurr.Substring(0, 17) : dtCurr; - // registro conteggio impiego chiamate REDIS - if (memLayer.ML.CRB("IOB_RedEnab")) - { - saveCallRec("processInput"); - } - DateTime dataOraEvento = DateTime.Now; - DateTime dtEvento, dtCorrente; - // controllo: se ho valori dt x evento e orario DIVERSI per acquisitore IOB calcolo dataOraEvento corretto - if (dtEve != dtCurr) - { - // delta è un calcolo MOLTO approssimativo della differenza temporale... - Int64 delta = 0; - try - { - // se ho meno decimali x evento rispetto dtCorrente... - if (dtEve.Length < dtCurr.Length) + var commands = adapter.GetType().InvokeMember( + "CommandCollection", + BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.NonPublic, + null, adapter, new object[0]); + var sqlCommand = (SqlCommand[])commands; + foreach (var cmd in sqlCommand) { - logger.lg.scriviLog(string.Format("processInput: fix valore dtEve: {0} vs dtCurr: {1}", dtEve, dtCurr), tipoLog.INFO); - dtEve = dtEve.PadRight(dtCurr.Length, '0'); - } - delta = Convert.ToInt64(dtCurr) - Convert.ToInt64(dtEve); - // log della classe del delta (1-10, 10-100, 100-1k, 1k-10k, > 10k ms) - string deltaClass = ""; - // faccio SEMPRE calcolo esatto sennò sbaglia... - CultureInfo provider = CultureInfo.InvariantCulture; - string format = "yyyyMMddHHmmssfff"; - dtEvento = DateTime.ParseExact(dtEve, format, provider); - dtCorrente = DateTime.ParseExact(dtCurr, format, provider); - Int64 tiks = dtCorrente.Ticks - dtEvento.Ticks; - TimeSpan ts = new TimeSpan(tiks); - double ms = Math.Abs(ts.TotalMilliseconds); - // calcolo ESATTO dataora evento - dataOraEvento = dataOraEvento.AddTicks(-tiks); - if (ms <= 10) - { - deltaClass = "delta 0-10 ms"; - } - else if (ms <= 100) - { - deltaClass = "delta 10-100 ms"; - } - else if (ms <= 1000) - { - deltaClass = "delta 100-1000 ms"; - } - else if (ms <= 10000) - { - deltaClass = "delta 1-10 sec"; + cmd.CommandTimeout = timeout; } + } + + #endregion Inizializzazione + + #region utility interne + + public static List DataTableToList(DataTable dt) where T : class, new() + { + List lstItems = new List(); + if (dt != null && dt.Rows.Count > 0) + foreach (DataRow row in dt.Rows) + lstItems.Add(ConvertDataRowToGenericType(row)); else - { - deltaClass = "delta > 10 sec"; - } - // se ho deltaClass loggo - if (deltaClass != "") - { - logger.lg.scriviLog("Correzione " + deltaClass); - } - } - catch (Exception exc) - { - logger.lg.scriviLog(string.Format("Errore calcolo ms evento/ora corrente da device remoto:{0}dtEve : {1}{0}dtCurr: {2}{0}{3}", Environment.NewLine, dtEve, dtCurr, exc), tipoLog.EXCEPTION); - } + lstItems = null; + return lstItems; } - // inizio processing vero e proprio INPUT... - if (idxMacchina != null && valore != null) + + private static T ConvertDataRowToGenericType(DataRow row) where T : class, new() { - if (idxMacchina != "" && valore != "") - { - // 2017.07.11 se richiesto di NON usare singleton... riporto FUORI la gestione NUOVO oggetto - if (memLayer.ML.CRB("disable_singleton")) + Type entityType = typeof(T); + T objEntity = new T(); + foreach (DataColumn column in row.Table.Columns) { - // instanzio un nuovo oggetto MapoDb - MapoDb connDb = new MapoDb(); - // se abilitato registro evento sul DB - if (idxMacchina != "" && sLogEnab(idxMacchina)) - { - saveSigLog(idxMacchina, valore, dataOraEvento, contatore); - } - // continuo col resto - try - { - // scrivo keep alive!!! (se necessario, altrimenti è in cache...) - connDb.scriviKeepAlive(idxMacchina, DateTime.Now); - // verifico se sia una macchina MULTI ed in tal caso calcolo i SUB-systems e CHIAMERO' alla fine pure loro.... - if (isMulti(idxMacchina)) + object value = row[column.ColumnName]; + if (value == DBNull.Value) value = null; + PropertyInfo property = entityType.GetProperty(column.ColumnName, BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.Public); + try { - // inizio preprocessing - string newVal = ""; - // processo OGNI macchina a stati dell'impianto... (KEY: IdxMacchina / IdxMacchina#qualcosa, Val = IdxFamIn) - foreach (var item in mTabMSMI(idxMacchina)) - { - newVal = preProcInput(item.Key, valore); - // ora processo e salvo il valore del microstato... INTERNAMENTE gestisce i casi DB/REDIS secondo necessità - checkMicroStato(item.Key, newVal, dataOraEvento, contatore); - } + if (property != null && property.CanWrite) + property.SetValue(objEntity, value, null); + } + catch (Exception ex) + { + throw ex; + } + } + return objEntity; + } + + /// + /// registra su REDIS eventuale superamento numero limite di call x il metodo in oggetto + /// + /// + private static void saveCallRec(string callCountKey) + { + // conto la richiesta nel contatore REDIS + long nCall = memLayer.ML.setRCntI(mHash($"COUNT:pCall:{callCountKey}")); + //... se == nCall2Log scrivo su log e resetto + long nCall2Log = memLayer.ML.cdvi("nCall2Log"); + if (nCall >= nCall2Log) + { + // loggo + logger.lg.scriviLog($"{callCountKey}: {nCall} call received", tipoLog.INFO); + // resetto! + memLayer.ML.resetRCnt(mHash($"COUNT:pCall:{callCountKey}")); + } + } + + #endregion utility interne + + #region utility public esposte + + /// + /// Cognome Nome da MatrOpr in sessione + /// + public string CognomeNomeOpr + { + get + { + // cerco operatore... + string answ = ""; + try + { + DS_applicazione.AnagraficaOperatoriRow oper = taOp.getByMatrOpr(MatrOpr)[0]; + answ = string.Format("{0} {1}", oper.Cognome, oper.Nome); + } + catch { } + return answ; + } + } + + /// + /// MatrOpr in sessione + /// + public int MatrOpr + { + get + { + int idx = 0; + try + { + idx = memLayer.ML.IntSessionObj("MatrOpr"); + } + catch { } + return idx; + } + set + { + memLayer.ML.setSessionVal("MatrOpr", value); + } + } + + /// + /// Effettua conferma prod macchina dell'intero periodo da confermare (ultima conferma --> adesso) + /// + /// idx macchina da confermare + /// 0=periodo, 1 = giorno, 2 = turno + /// qta pezzi BUONI da confermare + /// qta pezzi SCARTO da confermare + /// DataOra in cui registrare approvazione + /// + public bool confermaProdMacchina(string idxMacchina, int modoConfProd, int numPzConfermati, int numPzScarto, DateTime DataOraApp) + { + bool answ = false; + try + { + DS_ProdTempi.stp_PzProd_getByMacchinaRow rigaProd = taPzProd2conf.GetData(idxMacchina.ToString())[0]; + // chiamo stored stp_ConfermaProduzCompleta(idxMacchina,MatrApp,dataFrom,dataTo,pezziConf) + taPzProd2conf.stp_ConfermaProduzCompleta(idxMacchina, MatrOpr, rigaProd.DataFrom, DataOraApp, numPzConfermati, numPzScarto, modoConfProd, DataOraApp, true); + // indico eseguito! + answ = true; + } + catch (Exception exc) + { + logger.lg.scriviLog($"Errore in conferma prod macchina:{Environment.NewLine}{exc}"); + } + return answ; + } + + /// + /// Effettua conferma prod macchina dell'intero periodo da confermare (ultima conferma --> adesso) + /// + /// idx macchina da confermare + /// 0=periodo, 1 = giorno, 2 = turno + /// qta pezzi BUONI da confermare + /// qta pezzi LASCIATI alla macchina da confermare (2 eventi 121 rettifica neg/pos) + /// qta pezzi SCARTO da confermare + /// DataOra in cui registrare approvazione + /// + public bool confermaProdMacchinaFull(string idxMacchina, int modoConfProd, int numPzConfermati, int numPzLasciati, int numPzScarto, DateTime DataOraApp) + { + bool answ = false; + try + { + DS_ProdTempi.stp_PzProd_getByMacchinaRow rigaProd = taPzProd2conf.GetData(idxMacchina.ToString())[0]; + taPzProd2conf.stp_ConfermaProduzCompletaFull(idxMacchina, MatrOpr, rigaProd.DataFrom, DataOraApp, numPzConfermati, numPzLasciati, numPzScarto, modoConfProd, DataOraApp, true); + // indico eseguito! + answ = true; + } + catch (Exception exc) + { + logger.lg.scriviLog($"Errore in conferma prod macchina con rett ev121:{Environment.NewLine}{exc}"); + } + return answ; + } + + /// + /// Rimuove Key dell'ODL corrente x una data macchina IOB + /// + /// + /// + public string emptyCurrODL(string idxMacchina) + { + string answ = ""; + try + { + memLayer.ML.redDelKey(currODLHash(idxMacchina)); + answ = "OK"; + } + catch + { + answ = "KO"; + } + return answ; + } + + /// + /// effettua enroll del device + /// + /// + /// + /// + /// + /// + /// + public bool enrollDevice(string UserAuthKey, string IPv4, string DeviceName, string Description, int matricola) + { + bool fatto = false; + // in primis testo se dipendente ed authKey sono validi.. + if (taOp.getByMatrAuthKey(matricola, UserAuthKey).Rows.Count > 0) + { + // salvo matrOpr + MatrOpr = matricola; + /************************************************ + * Gestione riconoscimento devices + * + * - cerco IP del device, testo se è rete interna (A) o extranet/internet (B) cercando substring "localNet" da web.config + * (A): device interni: c'è un DHCP, e "dhcpLeaseTime" deve essere pari a lease time--- + * - verifico se IP già in uso da un tempo < "dhcpLeaseTime" --> in questo caso segnalo errore e rimbalzo (NON permetto di registrare device a nuovo utente... sospetto uso "improprio" del device + * - se tempo > dhcpLeaseTime allora può aver cambiato IP: aggiorno IP e descrizione del device e proseguo + * (B): all'esterno vedo tutta una subnet NATtata con unico IP, non è + discriminante + * - le timbrature "da esterno" devono essere confermate (instrodurre "tipo timbratura" x cui interne sono autoconfermate, esterne sono "grayed" (da confermare, da admin o ad esempio se si accende secondo device utente entro 5/10 min) + * - le timbrature ext DOVREBBERO chiedere location (jScript?) e inviarla, visibile in conferma + * + * + * **********************************************/ + // calcolo il secret... + DateTime adesso = DateTime.Now; + string Dominio = memLayer.ML.CRS("dominio"); + string UsrName = memLayer.ML.CRS("user"); + // recupero dati da matricola... + try + { + DataLayer_AnagGen.UTENTERow rigaUt = user_std.UtSn.rigaUtenteDaMatricola(matricola.ToString()); + if (rigaUt != null) + { + Dominio = rigaUt.DOMINIO; + UsrName = rigaUt.USER_NAME; + } + else + { + logger.lg.scriviLog(string.Format("non sono riuscito a recuperare RIGA utente per matricola {0}", matricola), tipoLog.ERROR); + } + } + catch + { + logger.lg.scriviLog(string.Format("Eccezione! non sono riuscito a recuperare utente per matricola {0}", matricola), tipoLog.ERROR); + Dominio = memLayer.ML.CRS("dominio"); + UsrName = memLayer.ML.CRS("user"); + } + string Secret = authProxy.getSecret(Dominio, UsrName, matricola, DeviceName, adesso); + string devSecret = SteamCrypto.EncryptString(Secret, memLayer.ML.CRS("cookieName")); + try + { + // creo device + cookie! + fatto = authProxy.createNewCookie(Dominio, UsrName, matricola, DeviceName, Description, IPv4, memLayer.ML.CRS("cookieName"), DateTime.Now.AddDays(memLayer.ML.CRI("cookieDayExpire"))); + // loggo! + logger.lg.scriviLog(string.Format("Effettuato enroll nuovo device: utente {0}\\{1} | matricola {2} | DeviceName {3} | Descrizione {4} | IP {5} | nome cookcie {6} | valido sino a {7:yyyy/MM/dd}", Dominio, UsrName, matricola, DeviceName, Description, IPv4, memLayer.ML.CRS("cookieName"), DateTime.Now.AddDays(memLayer.ML.CRI("cookieDayExpire")))); + } + catch (Exception exc) + { + logger.lg.scriviLog(string.Format("Errore enroll nuovo device:{0}{1}", Environment.NewLine, exc), tipoLog.EXCEPTION); + } + } + return fatto; + } + + /// + /// GET elenco parametri correnti x IOB + /// + /// + /// + public List getCurrObjItems(string idxMacchina) + { + string serVal = memLayer.ML.getRSV(currParametersHash(idxMacchina)); + List actValues = new List(); + if (serVal != null) + { + try + { + actValues = JsonConvert.DeserializeObject>(serVal); + // ordino! + actValues.Sort((a, b) => (a.name.CompareTo(b.name))); + } + catch (Exception exc) + { + logger.lg.scriviLog($"Eccezione in deserializzazione getIobCurrParam{Environment.NewLine}{exc}"); + } + } + return actValues; + } + + /// + /// GET elenco parametri che richiedono una WRITE x IOB + /// + /// + /// + public List getCurrObjItemsPendigWrite(string idxMacchina) + { + string serVal = memLayer.ML.getRSV(currParametersHash(idxMacchina)); + List actValues = new List(); + List writeValues = new List(); + if (serVal != null) + { + try + { + actValues = JsonConvert.DeserializeObject>(serVal); + // cerco e rimuovo parametri sola lettura o SENZA richieste scrittura + foreach (var item in actValues) + { + if (item.writable && !string.IsNullOrEmpty(item.reqValue)) + { + writeValues.Add(item); + } + } + } + catch (Exception exc) + { + logger.lg.scriviLog($"Eccezione in deserializzazione getIobCurrParam{Environment.NewLine}{exc}"); + } + } + return writeValues; + } + + /// + /// Processa registrazione FL da IOB + /// + /// + /// + /// + /// + /// + /// + /// + public string processFluxLog(string idxMacchina, string flux, string valore, string dtEve, string dtCurr, int contatore) + { + // instanzio un nuovo oggetto MapoDb + MapoDb connDb = new MapoDb(); + // scrivo keep alive!!! (se necessario, altrimenti è in cache...) + connDb.scriviKeepAlive(idxMacchina, DateTime.Now); + // 2017.09.14 trimmo eventualmente lo zero finale dalle date SE supera i millisecondi... + dtEve = dtEve.Length > 17 ? dtEve.Substring(0, 17) : dtEve; + dtCurr = dtCurr.Length > 17 ? dtCurr.Substring(0, 17) : dtCurr; + // registro conteggio impiego chiamate REDIS + if (memLayer.ML.CRB("IOB_RedEnab")) + { + saveCallRec("processFluxLog"); + } + string answ = ""; + DateTime dataOraEvento = DateTime.Now; + DateTime dtEvento, dtCorrente; + // controllo: se ho valori dt x evento e orario DIVERSI per acquisitore IOB calcolo dataOraEvento corretto + if (dtEve != dtCurr) + { + Int64 delta = 0; + try + { + // se ho meno decimali x evento rispetto dtCorrente... + if (dtEve.Length < dtCurr.Length) + { + dtEve = dtEve.PadRight(dtCurr.Length, '0'); + } + delta = Convert.ToInt64(dtCurr) - Convert.ToInt64(dtEve); + // se meno di 60'000 ms ... + if (delta < 59999) + { + dataOraEvento = dataOraEvento.AddMilliseconds(-delta); + } + else + { + // in questo caso elimino i MS dalle stringhe e converto i datetime.... + CultureInfo provider = CultureInfo.InvariantCulture; + string format = "yyyyMMddHHmmssfff"; + dtEvento = DateTime.ParseExact(dtEve, format, provider); + dtCorrente = DateTime.ParseExact(dtCurr, format, provider); + Int64 tiks = dtCorrente.Ticks - dtEvento.Ticks; + dataOraEvento = dataOraEvento.AddTicks(-tiks); + } + } + catch (Exception exc) + { + logger.lg.scriviLog(string.Format("Errore calcolo ms evento/ora corrente da device remoto:{0}dtEve : {1}{0}dtCurr: {2}{0}{3}", Environment.NewLine, dtEve, dtCurr, exc), tipoLog.EXCEPTION); + } + } + // inizio processing vero e proprio INPUT... + if (idxMacchina != null && valore != null) + { + if (idxMacchina != "" && valore != "") + { + // 2020.01.31 nuovo OBJ + DataLayer man = new DataLayer(); + man.taFL.InsNew(idxMacchina, dataOraEvento, flux, valore, contatore); + //DataLayer.obj.taFL.InsNew(idxMacchina, dataOraEvento, flux, valore, contatore); + // registro in risposta che è andato tutto bene... + answ = "OK"; } else { - // ora processo e salvo il valore del microstato... INTERNAMENTE gestisce i casi DB/REDIS secondo necessità - checkMicroStato(idxMacchina, valore, dataOraEvento, contatore); + string errore = "Errore: parametri macchina/valore vuoti"; + logger.lg.scriviLog(errore, tipoLog.INFO); + answ = errore; + } + } + else + { + string errore = "Errore: mancano parametri macchina/valore"; + logger.lg.scriviLog(errore, tipoLog.INFO); + answ = errore; + } + return answ; + } + + /// + /// Processa input da IOB eventualmente registrando i segnali inviati + /// + /// + /// + /// + /// + /// + /// + public string processInput(string idxMacchina, string valore, string dtEve, string dtCurr, string contatore) + { + string answ = ""; + // 2018.10.26 controllo dtEve e dtCurr + if (dtEve == null || dtCurr == null) + { + logger.lg.scriviLog(string.Format("procInput: valori nulli date: idxMacchina: {0} | valore: {1} | dtEve: {2} | dtCurr:{3}", idxMacchina, valore, dtEve, dtCurr)); + } + else if (dtEve.Length < 17 || dtCurr.Length < 17) + { + logger.lg.scriviLog(string.Format("procInput: valori data non corretti: idxMacchina: {0} | valore: {1} | dtEve: {2} | dtCurr:{3}", idxMacchina, valore, dtEve, dtCurr)); + } + else + { + // 2017.09.14 trimmo eventualmente lo zero finale dalle date SE supera i millisecondi... + dtEve = dtEve.Length > 17 ? dtEve.Substring(0, 17) : dtEve; + dtCurr = dtCurr.Length > 17 ? dtCurr.Substring(0, 17) : dtCurr; + // registro conteggio impiego chiamate REDIS + if (memLayer.ML.CRB("IOB_RedEnab")) + { + saveCallRec("processInput"); + } + DateTime dataOraEvento = DateTime.Now; + DateTime dtEvento, dtCorrente; + // controllo: se ho valori dt x evento e orario DIVERSI per acquisitore IOB calcolo dataOraEvento corretto + if (dtEve != dtCurr) + { + // delta è un calcolo MOLTO approssimativo della differenza temporale... + Int64 delta = 0; + try + { + // se ho meno decimali x evento rispetto dtCorrente... + if (dtEve.Length < dtCurr.Length) + { + logger.lg.scriviLog(string.Format("processInput: fix valore dtEve: {0} vs dtCurr: {1}", dtEve, dtCurr), tipoLog.INFO); + dtEve = dtEve.PadRight(dtCurr.Length, '0'); + } + delta = Convert.ToInt64(dtCurr) - Convert.ToInt64(dtEve); + // log della classe del delta (1-10, 10-100, 100-1k, 1k-10k, > 10k ms) + string deltaClass = ""; + // faccio SEMPRE calcolo esatto sennò sbaglia... + CultureInfo provider = CultureInfo.InvariantCulture; + string format = "yyyyMMddHHmmssfff"; + dtEvento = DateTime.ParseExact(dtEve, format, provider); + dtCorrente = DateTime.ParseExact(dtCurr, format, provider); + Int64 tiks = dtCorrente.Ticks - dtEvento.Ticks; + TimeSpan ts = new TimeSpan(tiks); + double ms = Math.Abs(ts.TotalMilliseconds); + // calcolo ESATTO dataora evento + dataOraEvento = dataOraEvento.AddTicks(-tiks); + if (ms <= 10) + { + deltaClass = "delta 0-10 ms"; + } + else if (ms <= 100) + { + deltaClass = "delta 10-100 ms"; + } + else if (ms <= 1000) + { + deltaClass = "delta 100-1000 ms"; + } + else if (ms <= 10000) + { + deltaClass = "delta 1-10 sec"; + } + else + { + deltaClass = "delta > 10 sec"; + } + // se ho deltaClass loggo + if (deltaClass != "") + { + logger.lg.scriviLog("Correzione " + deltaClass); + } + } + catch (Exception exc) + { + logger.lg.scriviLog(string.Format("Errore calcolo ms evento/ora corrente da device remoto:{0}dtEve : {1}{0}dtCurr: {2}{0}{3}", Environment.NewLine, dtEve, dtCurr, exc), tipoLog.EXCEPTION); + } + } + // inizio processing vero e proprio INPUT... + if (idxMacchina != null && valore != null) + { + if (idxMacchina != "" && valore != "") + { + // 2017.07.11 se richiesto di NON usare singleton... riporto FUORI la gestione NUOVO oggetto + if (memLayer.ML.CRB("disable_singleton")) + { + // instanzio un nuovo oggetto MapoDb + MapoDb connDb = new MapoDb(); + // se abilitato registro evento sul DB + if (idxMacchina != "" && sLogEnab(idxMacchina)) + { + saveSigLog(idxMacchina, valore, dataOraEvento, contatore); + } + // continuo col resto + try + { + // scrivo keep alive!!! (se necessario, altrimenti è in cache...) + connDb.scriviKeepAlive(idxMacchina, DateTime.Now); + // verifico se sia una macchina MULTI ed in tal caso calcolo i SUB-systems e CHIAMERO' alla fine pure loro.... + if (isMulti(idxMacchina)) + { + // inizio preprocessing + string newVal = ""; + // processo OGNI macchina a stati dell'impianto... (KEY: IdxMacchina / IdxMacchina#qualcosa, Val = IdxFamIn) + foreach (var item in mTabMSMI(idxMacchina)) + { + newVal = preProcInput(item.Key, valore); + // ora processo e salvo il valore del microstato... INTERNAMENTE gestisce i casi DB/REDIS secondo necessità + checkMicroStato(item.Key, newVal, dataOraEvento, contatore); + } + } + else + { + // ora processo e salvo il valore del microstato... INTERNAMENTE gestisce i casi DB/REDIS secondo necessità + checkMicroStato(idxMacchina, valore, dataOraEvento, contatore); + } + // registro in risposta che è andato tutto bene... + answ = "OK"; + } + catch (Exception exc) + { + if (memLayer.ML.CRI("_logLevel") > 5) + { + string errore = string.Format("Errore: {0}{1}", Environment.NewLine, exc); + logger.lg.scriviLog(errore, tipoLog.EXCEPTION); + answ = errore; + } + } + } + else + { + // se abilitato registro evento sul DB + if (idxMacchina != "" && MapoDbObj.sLogEnabled(idxMacchina)) + { + saveSigLog(idxMacchina, valore, dataOraEvento, contatore); + } + // continuo col resto + try + { + // scrivo keep alive!!! (se encessario, altrimenti è in cache...) + MapoDbObj.scriviKeepAlive(idxMacchina, DateTime.Now); + // verifico se sia una macchina MULTI ed in tal caso calcolo i SUB-systems e CHIAMERO' alla fine pure loro.... + if (MapoDbObj.isMulti(idxMacchina)) + { + // inizio preprocessing + string newVal = ""; + // processo OGNI macchina a stati dell'impianto... (KEY: IdxMacchina / IdxMacchina#qualcosa, Val = IdxFamIn) + foreach (var item in getMSMI_DB(idxMacchina)) + { + newVal = preProcInput(item.Key, valore); + // ora processo e salvo il valore del microstato... + checkMicroStato(item.Key, newVal, dataOraEvento, contatore); + } + } + else + { + // ora processo e salvo il valore del microstato... + checkMicroStato(idxMacchina, valore, dataOraEvento, contatore); + } + answ = "OK"; // registro in risposta che è andato tutto bene... + } + catch (Exception exc) + { + if (memLayer.ML.CRI("_logLevel") > 5) + { + string errore = string.Format("Errore: {0}{1}", Environment.NewLine, exc); + logger.lg.scriviLog(errore, tipoLog.EXCEPTION); + answ = errore; + } + } + } + } + else + { + string errore = "Errore: parametri macchina/valore vuoti"; + logger.lg.scriviLog(errore, tipoLog.INFO); + answ = errore; + } + } + else + { + string errore = "Errore: mancano parametri macchina/valore"; + logger.lg.scriviLog(errore, tipoLog.INFO); + answ = errore; + } + } + return answ; + } + + /// + /// Processa registrazione di uno stream di dati LIVE da IOB + /// + /// + /// Dati live nel formato di lista di KVP chiave/valore1 + /// + public string processLiveJson(string idxMacchina, liveIOB liveData) + { + if (liveData == null) + { + throw new ArgumentNullException(nameof(liveData)); + } + // registro conteggio impiego chiamate REDIS + if (memLayer.ML.CRB("IOB_RedEnab")) + { + saveCallRec("processLiveJson"); + } + string answ = ""; + DateTime dataOraEvento = DateTime.Now; + // inizio processing vero e proprio INPUT... + if (!string.IsNullOrEmpty(idxMacchina) && liveData != null) + { + // SE ho dei segnali... + if (liveData.dataList.Count > 0) + { + // salvo in Redis nell'area CURR_VAL TUTTI i valori live + memLayer.ML.redSaveHashList(LiveCurrValHash(idxMacchina), liveData.dataList); + // accodo in buffer ULTIMI valori con dataora uno ad uno... + KeyValuePair[] newData = new KeyValuePair[1]; + foreach (var item in liveData.dataList) + { + // accodo update valori... + newData[0] = new KeyValuePair(dataOraEvento.ToString(), item.Value); + memLayer.ML.redSaveHash(LiveBufferHash(idxMacchina, item.Key), newData); + } + } + else + { + string errore = "Errore: formato liveData errato (split #)"; + logger.lg.scriviLog(errore, tipoLog.ERROR); + answ = errore; } // registro in risposta che è andato tutto bene... answ = "OK"; - } - catch (Exception exc) - { - if (memLayer.ML.CRI("_logLevel") > 5) - { - string errore = string.Format("Errore: {0}{1}", Environment.NewLine, exc); - logger.lg.scriviLog(errore, tipoLog.EXCEPTION); - answ = errore; - } - } } else { - // se abilitato registro evento sul DB - if (idxMacchina != "" && MapoDbObj.sLogEnabled(idxMacchina)) - { - saveSigLog(idxMacchina, valore, dataOraEvento, contatore); - } - // continuo col resto - try - { - // scrivo keep alive!!! (se encessario, altrimenti è in cache...) - MapoDbObj.scriviKeepAlive(idxMacchina, DateTime.Now); - // verifico se sia una macchina MULTI ed in tal caso calcolo i SUB-systems e CHIAMERO' alla fine pure loro.... - if (MapoDbObj.isMulti(idxMacchina)) + string errore = "Errore: mancano parametri macchina/liveData come Json"; + logger.lg.scriviLog(errore, tipoLog.ERROR); + answ = errore; + } + return answ; + } + + /// + /// Processa registrazione di uno stream di dati LIVE da IOB + /// + /// + /// Dati live nel formato chiave1|valore1#chiave2|valore2#chiave3|valore3 + /// + public string processLiveRec(string idxMacchina, string liveData) + { + if (liveData == null) + { + throw new ArgumentNullException(nameof(liveData)); + } + // registro conteggio impiego chiamate REDIS + if (memLayer.ML.CRB("IOB_RedEnab")) + { + saveCallRec("processLiveRec"); + } + string answ = ""; + DateTime dataOraEvento = DateTime.Now; + // inizio processing vero e proprio INPUT... + if (idxMacchina != null && liveData != null) + { + if (idxMacchina != "" && liveData != "") { - // inizio preprocessing - string newVal = ""; - // processo OGNI macchina a stati dell'impianto... (KEY: IdxMacchina / IdxMacchina#qualcosa, Val = IdxFamIn) - foreach (var item in getMSMI_DB(idxMacchina)) - { - newVal = preProcInput(item.Key, valore); - // ora processo e salvo il valore del microstato... - checkMicroStato(item.Key, newVal, dataOraEvento, contatore); - } + // prendo il vettore LiveData e lo splitto per variabili inviate + string[] liveSignals = liveData.Split('|'); + // SE ho dei segnali... + if (liveSignals.Length > 0) + { + KeyValuePair[] liveSet = new KeyValuePair[liveSignals.Length]; + string[] kvp; + int i = 0; + foreach (string liveKVP in liveSignals) + { + // ogni variabile la splitto come chiave/valore + kvp = liveKVP.Split(':'); + liveSet[i] = new KeyValuePair(kvp[0], kvp[1]); + i++; + } + // salvo in Redis nell'area CURR_VAL TUTTI i valori live + memLayer.ML.redSaveHash(LiveCurrValHash(idxMacchina), liveSet); + // accodo in buffer ULTIMI valori con dataora uno ad uno... + KeyValuePair[] newData = new KeyValuePair[1]; + foreach (var item in liveSet) + { + // accodo update valori... + newData[0] = new KeyValuePair(dataOraEvento.ToString(), item.Value); + memLayer.ML.redSaveHash(LiveBufferHash(idxMacchina, item.Key), newData); + } + } + else + { + string errore = "Errore: formato liveData errato (split #)"; + logger.lg.scriviLog(errore, tipoLog.ERROR); + answ = errore; + } + // registro in risposta che è andato tutto bene... + answ = "OK"; } else { - // ora processo e salvo il valore del microstato... - checkMicroStato(idxMacchina, valore, dataOraEvento, contatore); + string errore = "Errore: parametri macchina/liveData vuoti"; + logger.lg.scriviLog(errore, tipoLog.ERROR); + answ = errore; } - answ = "OK"; // registro in risposta che è andato tutto bene... - } - catch (Exception exc) - { - if (memLayer.ML.CRI("_logLevel") > 5) - { - string errore = string.Format("Errore: {0}{1}", Environment.NewLine, exc); - logger.lg.scriviLog(errore, tipoLog.EXCEPTION); - answ = errore; - } - } - } - } - else - { - string errore = "Errore: parametri macchina/valore vuoti"; - logger.lg.scriviLog(errore, tipoLog.INFO); - answ = errore; - } - } - else - { - string errore = "Errore: mancano parametri macchina/valore"; - logger.lg.scriviLog(errore, tipoLog.INFO); - answ = errore; - } - } - return answ; - } - /// - /// Calcola l'effettivo valore da passare alla macchina a stati INGRESSI data conf Macchine2FamigliaIngressi - /// - /// - /// - /// - private string preProcInput(string idxMacchina, string valore) - { - string newVal = ""; - try - { - // variabili - int valINT = 0; - int BitFilt = 0; - int BSR = 0; - bool ExplodeBit = false; - int NumBit = 0; - int newValInt = 0; - // recupero parametri... - int.TryParse(mDatiMacchinaVal(idxMacchina, "BitFilt"), out BitFilt); - int.TryParse(mDatiMacchinaVal(idxMacchina, "BSR"), out BSR); - Boolean.TryParse(mDatiMacchinaVal(idxMacchina, "ExplodeBit"), out ExplodeBit); - int.TryParse(mDatiMacchinaVal(idxMacchina, "NumBit"), out NumBit); // non usato (x ora) - // recupero valore - valINT = int.Parse(valore, NumberStyles.HexNumber); - // filtro - newValInt = utility.bMaskInt(valINT, BitFilt); - // effettuo eventuale BitShiftRight - if (BSR > 0) - { - newValInt = newValInt >> BSR; - } - // effettuo eventuale esplosione in BIT esclusivi - if (ExplodeBit) - { - newValInt = Convert.ToInt32(1 << newValInt); - } - // riconverto a STRING HEX!!! - newVal = newValInt.ToString("X"); - } - catch - { - newVal = valore; - } - - return newVal; - } - - /// - /// Processa registrazione FL da IOB - /// - /// - /// - /// - /// - /// - /// - /// - public string processFluxLog(string idxMacchina, string flux, string valore, string dtEve, string dtCurr, int contatore) - { - // instanzio un nuovo oggetto MapoDb - MapoDb connDb = new MapoDb(); - // scrivo keep alive!!! (se necessario, altrimenti è in cache...) - connDb.scriviKeepAlive(idxMacchina, DateTime.Now); - // 2017.09.14 trimmo eventualmente lo zero finale dalle date SE supera i millisecondi... - dtEve = dtEve.Length > 17 ? dtEve.Substring(0, 17) : dtEve; - dtCurr = dtCurr.Length > 17 ? dtCurr.Substring(0, 17) : dtCurr; - // registro conteggio impiego chiamate REDIS - if (memLayer.ML.CRB("IOB_RedEnab")) - { - saveCallRec("processFluxLog"); - } - string answ = ""; - DateTime dataOraEvento = DateTime.Now; - DateTime dtEvento, dtCorrente; - // controllo: se ho valori dt x evento e orario DIVERSI per acquisitore IOB calcolo dataOraEvento corretto - if (dtEve != dtCurr) - { - Int64 delta = 0; - try - { - // se ho meno decimali x evento rispetto dtCorrente... - if (dtEve.Length < dtCurr.Length) - { - dtEve = dtEve.PadRight(dtCurr.Length, '0'); - } - delta = Convert.ToInt64(dtCurr) - Convert.ToInt64(dtEve); - // se meno di 60'000 ms ... - if (delta < 59999) - { - dataOraEvento = dataOraEvento.AddMilliseconds(-delta); - } - else - { - // in questo caso elimino i MS dalle stringhe e converto i datetime.... - CultureInfo provider = CultureInfo.InvariantCulture; - string format = "yyyyMMddHHmmssfff"; - dtEvento = DateTime.ParseExact(dtEve, format, provider); - dtCorrente = DateTime.ParseExact(dtCurr, format, provider); - Int64 tiks = dtCorrente.Ticks - dtEvento.Ticks; - dataOraEvento = dataOraEvento.AddTicks(-tiks); - } - } - catch (Exception exc) - { - logger.lg.scriviLog(string.Format("Errore calcolo ms evento/ora corrente da device remoto:{0}dtEve : {1}{0}dtCurr: {2}{0}{3}", Environment.NewLine, dtEve, dtCurr, exc), tipoLog.EXCEPTION); - } - } - // inizio processing vero e proprio INPUT... - if (idxMacchina != null && valore != null) - { - if (idxMacchina != "" && valore != "") - { - // 2020.01.31 nuovo OBJ - DataLayer man = new DataLayer(); - man.taFL.InsNew(idxMacchina, dataOraEvento, flux, valore, contatore); - //DataLayer.obj.taFL.InsNew(idxMacchina, dataOraEvento, flux, valore, contatore); - // registro in risposta che è andato tutto bene... - answ = "OK"; - } - else - { - string errore = "Errore: parametri macchina/valore vuoti"; - logger.lg.scriviLog(errore, tipoLog.INFO); - answ = errore; - } - } - else - { - string errore = "Errore: mancano parametri macchina/valore"; - logger.lg.scriviLog(errore, tipoLog.INFO); - answ = errore; - } - return answ; - } - - /// - /// Processa registrazione di uno stream di dati LIVE da IOB - /// - /// - /// Dati live nel formato di lista di KVP chiave/valore1 - /// - public string processLiveJson(string idxMacchina, liveIOB liveData) - { - if (liveData == null) - { - throw new ArgumentNullException(nameof(liveData)); - } - // registro conteggio impiego chiamate REDIS - if (memLayer.ML.CRB("IOB_RedEnab")) - { - saveCallRec("processLiveJson"); - } - string answ = ""; - DateTime dataOraEvento = DateTime.Now; - // inizio processing vero e proprio INPUT... - if (!string.IsNullOrEmpty(idxMacchina) && liveData != null) - { - // SE ho dei segnali... - if (liveData.dataList.Count > 0) - { - // salvo in Redis nell'area CURR_VAL TUTTI i valori live - memLayer.ML.redSaveHashList(LiveCurrValHash(idxMacchina), liveData.dataList); - // accodo in buffer ULTIMI valori con dataora uno ad uno... - KeyValuePair[] newData = new KeyValuePair[1]; - foreach (var item in liveData.dataList) - { - // accodo update valori... - newData[0] = new KeyValuePair(dataOraEvento.ToString(), item.Value); - memLayer.ML.redSaveHash(LiveBufferHash(idxMacchina, item.Key), newData); - } - } - else - { - string errore = "Errore: formato liveData errato (split #)"; - logger.lg.scriviLog(errore, tipoLog.ERROR); - answ = errore; - } - // registro in risposta che è andato tutto bene... - answ = "OK"; - } - else - { - string errore = "Errore: mancano parametri macchina/liveData come Json"; - logger.lg.scriviLog(errore, tipoLog.ERROR); - answ = errore; - } - return answ; - } - /// - /// Processa registrazione di uno stream di dati LIVE da IOB - /// - /// - /// Dati live nel formato chiave1|valore1#chiave2|valore2#chiave3|valore3 - /// - public string processLiveRec(string idxMacchina, string liveData) - { - if (liveData == null) - { - throw new ArgumentNullException(nameof(liveData)); - } - // registro conteggio impiego chiamate REDIS - if (memLayer.ML.CRB("IOB_RedEnab")) - { - saveCallRec("processLiveRec"); - } - string answ = ""; - DateTime dataOraEvento = DateTime.Now; - // inizio processing vero e proprio INPUT... - if (idxMacchina != null && liveData != null) - { - if (idxMacchina != "" && liveData != "") - { - // prendo il vettore LiveData e lo splitto per variabili inviate - string[] liveSignals = liveData.Split('|'); - // SE ho dei segnali... - if (liveSignals.Length > 0) - { - KeyValuePair[] liveSet = new KeyValuePair[liveSignals.Length]; - string[] kvp; - int i = 0; - foreach (string liveKVP in liveSignals) - { - // ogni variabile la splitto come chiave/valore - kvp = liveKVP.Split(':'); - liveSet[i] = new KeyValuePair(kvp[0], kvp[1]); - i++; - } - // salvo in Redis nell'area CURR_VAL TUTTI i valori live - memLayer.ML.redSaveHash(LiveCurrValHash(idxMacchina), liveSet); - // accodo in buffer ULTIMI valori con dataora uno ad uno... - KeyValuePair[] newData = new KeyValuePair[1]; - foreach (var item in liveSet) - { - // accodo update valori... - newData[0] = new KeyValuePair(dataOraEvento.ToString(), item.Value); - memLayer.ML.redSaveHash(LiveBufferHash(idxMacchina, item.Key), newData); - } - } - else - { - string errore = "Errore: formato liveData errato (split #)"; - logger.lg.scriviLog(errore, tipoLog.ERROR); - answ = errore; - } - // registro in risposta che è andato tutto bene... - answ = "OK"; - } - else - { - string errore = "Errore: parametri macchina/liveData vuoti"; - logger.lg.scriviLog(errore, tipoLog.ERROR); - answ = errore; - } - } - else - { - string errore = "Errore: mancano parametri macchina/liveData"; - logger.lg.scriviLog(errore, tipoLog.ERROR); - answ = errore; - } - return answ; - } - - /// - /// Processa registrazione di un counter x una data macchina IOB - /// - /// - /// contapezzi - /// - public string saveCounter(string idxMacchina, string counter) - { - // registro conteggio impiego chiamate REDIS - if (memLayer.ML.CRB("IOB_RedEnab")) - { - saveCallRec("saveCounter"); - } - string answ = "0"; - // inizio processing vero e proprio INPUT... - if (!string.IsNullOrEmpty(idxMacchina)) - { - if (!string.IsNullOrEmpty(counter)) - { - int newCounter = -1; - int.TryParse(counter, out newCounter); - // se il conteggio è >= 0 SALVO come nuovo conteggio... - if (newCounter >= 0) - { - string redKey = pzCountHash(idxMacchina); - // verifico SE ci sia chiave in redis (ALTRIMENTI rileggo da DB) - string redVal = memLayer.ML.getRSV(redKey); - if (!string.IsNullOrEmpty(redVal)) - { - // salvo in Redis nell'area corretta il valore richiesto - memLayer.ML.setRSV(redKey, counter); - // imposto risposta... - answ = counter; } else { - // rileggo da DB e salvo e poi restituisco questo... - int currCount = pzCounterTC(idxMacchina); - memLayer.ML.setRSV(redKey, currCount.ToString()); - // imposto risposta... - answ = currCount.ToString(); + string errore = "Errore: mancano parametri macchina/liveData"; + logger.lg.scriviLog(errore, tipoLog.ERROR); + answ = errore; } - } + return answ; } - else + + /// + /// Processa registrazione EVENTO CONTEGGIO PEZZI x una data macchina IOB + /// + /// Macchina + /// Pezzi da registrare + /// + public string saveCaricoPezzi(string idxMacchina, string qty) { - string errore = "Errore: parametro counter vuoto"; - logger.lg.scriviLog(errore, tipoLog.ERROR); - answ = errore; - } - } - else - { - string errore = "Errore: parametro macchina vuoto"; - logger.lg.scriviLog(errore, tipoLog.ERROR); - answ = errore; - } - return answ; - } - /// - /// Processa registrazione EVENTO CONTEGGIO PEZZI x una data macchina IOB - /// - /// Macchina - /// Pezzi da registrare - /// - public string saveCaricoPezzi(string idxMacchina, string qty) - { - // default: 0, non registrato come cautela... - string answ = "0"; - // controllo per proseguire - if (!string.IsNullOrEmpty(idxMacchina) && !string.IsNullOrEmpty(qty)) - { - int numPzIncr = -1; - int.TryParse(qty, out numPzIncr); - // se il conteggio è >= 0 SALVO evento... - if (numPzIncr >= 0) - { - // recupero ODL corrente - var currData = currODLRowTab(idxMacchina); - // registro evento 120 --> contapezzi in blocco !!!HARD CODED!!! !!!FIXME!!! - int idxEvento = 120; - // istanziato un NUOVO oggetto x scrivere... - scriviRigaEventoBarcode(idxMacchina, idxEvento, currData[0].CodArticolo, qty); - } - // registro in risposta che è andato tutto bene... ovvero la qty richiesta... - answ = qty; - } - else - { - string errore = $"Errore: mancano parametri macchina/incremento: idxMacchina {idxMacchina} | qty {qty}"; - logger.lg.scriviLog(errore, tipoLog.ERROR); - answ = errore; - } - return answ; - } - /// - /// Salvataggio su della mappa di memoria dell'IOB x ulteriori impieghi - /// - /// - /// - /// - public bool setIobMemMap(string idxMacchina, plcMemMap currMemMap) - { - bool answ = false; - // se ho un area memoria valida... - if (currMemMap != null) - { - // salvo! - string serVal = JsonConvert.SerializeObject(currMemMap); - memLayer.ML.setRSV(memMapHash(idxMacchina), serVal); - } - return answ; - } - /// - /// GET elenco parametri correnti x IOB - /// - /// - /// - public List getCurrObjItems(string idxMacchina) - { - string serVal = memLayer.ML.getRSV(currParametersHash(idxMacchina)); - List actValues = new List(); - if (serVal != null) - { - try - { - actValues = JsonConvert.DeserializeObject>(serVal); - // ordino! - actValues.Sort((a, b) => (a.name.CompareTo(b.name))); - } - catch (Exception exc) - { - logger.lg.scriviLog($"Eccezione in deserializzazione getIobCurrParam{Environment.NewLine}{exc}"); - } - } - return actValues; - } - /// - /// GET elenco parametri che richiedono una WRITE x IOB - /// - /// - /// - public List getCurrObjItemsPendigWrite(string idxMacchina) - { - string serVal = memLayer.ML.getRSV(currParametersHash(idxMacchina)); - List actValues = new List(); - List writeValues = new List(); - if (serVal != null) - { - try - { - actValues = JsonConvert.DeserializeObject>(serVal); - // cerco e rimuovo parametri sola lettura o SENZA richieste scrittura - foreach (var item in actValues) - { - if (item.writable && !string.IsNullOrEmpty(item.reqValue)) + // default: 0, non registrato come cautela... + string answ = "0"; + // controllo per proseguire + if (!string.IsNullOrEmpty(idxMacchina) && !string.IsNullOrEmpty(qty)) { - writeValues.Add(item); + int numPzIncr = -1; + int.TryParse(qty, out numPzIncr); + // se il conteggio è >= 0 SALVO evento... + if (numPzIncr >= 0) + { + // recupero ODL corrente + var currData = currODLRowTab(idxMacchina); + // registro evento 120 --> contapezzi in blocco !!!HARD CODED!!! !!!FIXME!!! + int idxEvento = 120; + // istanziato un NUOVO oggetto x scrivere... + scriviRigaEventoBarcode(idxMacchina, idxEvento, currData[0].CodArticolo, qty); + } + // registro in risposta che è andato tutto bene... ovvero la qty richiesta... + answ = qty; } - } - } - catch (Exception exc) - { - logger.lg.scriviLog($"Eccezione in deserializzazione getIobCurrParam{Environment.NewLine}{exc}"); - } - } - return writeValues; - } - /// - /// SET elenco parametri correnti x IOB - /// - /// - /// - /// - public bool setCurrObjItems(string idxMacchina, List currValues) - { - bool answ = false; - if (currValues != null) - { - string serVal = JsonConvert.SerializeObject(currValues); - memLayer.ML.setRSV(currParametersHash(idxMacchina), serVal); - } - return answ; - } - /// - /// Effettua UPSERT elenco parametri correnti x IOB (se c'è UPDATE, se manca ADD) - /// - /// - /// - /// - public bool upsertCurrObjItems(string idxMacchina, List innovations) - { - bool answ = false; - if (innovations != null) - { - // leggo i valori attuali... - List actValues = getCurrObjItems(idxMacchina); - // per ogni valore passatomi faccio insert o update - foreach (var item in actValues) - { - // cerco nelle innovazioni SE CI SIA un valore act - objItem trovato = innovations.Find(obj => obj.uid == item.uid); - // se non trovato... - if (trovato == null) - { - // aggiungo - innovations.Add(item); - } - } - // serializzo e salvo - string serVal = JsonConvert.SerializeObject(innovations); - memLayer.ML.setRSV(currParametersHash(idxMacchina), serVal); - } - return answ; - } - /// - /// Rimuove Key dell'ODL corrente x una data macchina IOB - /// - /// - /// - public string emptyCurrODL(string idxMacchina) - { - string answ = ""; - try - { - memLayer.ML.redDelKey(currODLHash(idxMacchina)); - answ = "OK"; - } - catch - { - answ = "KO"; - } - return answ; - } - /// - /// Processa registrazione ODL corrente x macchina - /// - /// - /// cod ODL in produzione, se "" --> non c'è... - /// - public string saveCurrODL(string idxMacchina, string currODL) - { - if (currODL == null) - { - throw new ArgumentNullException(nameof(currODL)); - } - // registro conteggio impiego chiamate REDIS - if (memLayer.ML.CRB("IOB_RedEnab")) - { - saveCallRec("saveCurrODL"); - } - string answ = ""; - // inizio processing vero e proprio INPUT... - if (idxMacchina != null && currODL != null) - { - if (idxMacchina != "" && currODL != "") - { - int currOdlCacheDur = memLayer.ML.CRI("currOdlCacheDur"); - // se ODL fosse 0 USO DURATA CACHE 1/4... - if (currODL == "0") - { - currOdlCacheDur = currOdlCacheDur / 4; - } - memLayer.ML.setRSV(currODLHash(idxMacchina), currODL, currOdlCacheDur); - // registro in risposta che è andato tutto bene... - answ = "OK"; - } - else - { - string errore = string.Format("Errore: parametri macchina/currODL vuoti ({0}/{1})", idxMacchina, currODL); - logger.lg.scriviLog(errore, tipoLog.ERROR); - answ = errore; - } - } - else - { - string errore = "Errore: mancano parametri macchina/currODL"; - logger.lg.scriviLog(errore, tipoLog.ERROR); - answ = errore; - } - return answ; - } - - #region definizioni hash x REDIS - - /// - /// Hash Redis contenente i dati MP di una specifico TYPE (es StatusMacchina, StateMachineIngressi, ...) - /// - /// - /// - public static string mHash(string dataType) - { - return memLayer.ML.redHash(dataType); - } - /// - /// Hash dati STATUS x la macchina specificata - /// - /// - /// - public static string dtMaccHash(string idxMacchina) - { - return mHash(string.Format("DtMac:{0}", idxMacchina)); - } - /// - /// Hash dati EXE TASK x la macchina specificata - /// - /// - /// - public static string exeTaskHash(string idxMacchina) - { - return mHash(string.Format("ExeTask:{0}", idxMacchina)); - } - /// - /// Hash dati OPT PARAMETERS x la macchina specificata - /// - /// - /// - public static string optParHash(string idxMacchina) - { - return mHash(string.Format("OptPar:{0}", idxMacchina)); - } - /// - /// Hash dati STATUS x la macchina specificata. - /// - dati ODL - /// - dati articolo - /// - dati produzione corrente - /// - /// - /// - public static string stMaccHash(string idxMacchina) - { - return mHash(string.Format("StMac:{0}", idxMacchina)); - } - /// - /// Hash dati COUNTER x la macchina specificata - /// - /// - /// - public static string pzCountHash(string idxMacchina) - { - return mHash(string.Format("PzCount:{0}", idxMacchina)); - } - /// - /// Hash dati MemoryMap x la macchina specificata - /// - /// - /// - public static string memMapHash(string idxMacchina) - { - return mHash(string.Format("MemMap:{0}", idxMacchina)); - } - /// - /// Hash dati CurrentParameters x la macchina specificata - /// - /// - /// - public static string currParametersHash(string idxMacchina) - { - return mHash(string.Format("CurrentParameters:{0}", idxMacchina)); - } - /// - /// Hash dati Current ODL x la macchina specificata - /// - /// - /// - public static string currODLHash(string idxMacchina) - { - return mHash(string.Format("CurrODL:{0}", idxMacchina)); - } - /// - /// Hash dati Current ODL ROW x la macchina specificata - /// - /// - /// - public static string currOdlRowHash(string idxMacchina) - { - return mHash(string.Format("CurrOdlRow:{0}", idxMacchina)); - } - /// - /// Hash dati Current StatoMacchina x la macchina specificata - /// - /// - /// - public static string currStatoMaccHash(string idxMacchina) - { - return mHash(string.Format("CurrStatoMacc:{0}", idxMacchina)); - } - /// - /// Hash x VETO dello SPLIT ODL la macchina specificata - /// - /// - /// - public static string vetoSplitOdlMaccHash(string idxMacchina) - { - return mHash($"VetoOdlMacc:{idxMacchina}"); - } - /// - /// Hash dati tabella AnagStati macchina - /// - /// - public static string currAnagStatiMacc() - { - return mHash(string.Format("Anag:StatiMacc")); - } - /// - /// Hash dati LIVE x la macchina specificata - /// - /// - /// - public static string LiveCurrValHash(string idxMacchina) - { - return mHash(string.Format("LIVE:{0}:CURR_VAL", idxMacchina)); - } - /// - /// Hash dati BUFFER x la macchina specificata - /// - /// - /// - /// - public static string LiveBufferHash(string idxMacchina, string bufferName) - { - return mHash(string.Format("LIVE:{0}:{1}", idxMacchina, bufferName)); - } - /// - /// Hash dati STATE MACHINE INGRESSI x la FAMIGLIA INGRESSI specificata (per completare poi manca singolo micro stato corrente + valore letto x definire chiave) - /// - /// - /// - public static string hSMI(int idxFamIn) - { - return mHash(string.Format("hSMI:{0}", idxFamIn)); - } - /// - /// Hash dati Macchine Multi SM Ingressi - /// - /// Macchina PRINCIPALE - /// - public static string hMSMI(string IdxMacchina) - { - return mHash(string.Format("hMSMI:{0}", IdxMacchina)); - } - /// - /// Hash dati relativi all'associazione macchina <--> IOB - /// - /// Macchina PRINCIPALE - /// - public static string hM2IOB(string IdxMacchina) - { - return mHash(string.Format("hM2IOB:{0}", IdxMacchina)); - } - /// - /// Hash dati MSE - /// - /// - public static string hMSE - { - get - { - return mHash(string.Format("hMSE_DATA")); - } - } - - #endregion - - #region gestione MSE - - /// - /// Dati MSE serializzati in REDIS (get/set) - /// - public string currMSE - { - get - { - string answ = ""; - logger.lg.scriviLog("Richiesta MSE da REDIS"); - answ = memLayer.ML.getRSV(hMSE); - return answ; - } - set - { - int MSE_cacheDuration = memLayer.ML.CRI("MSE_cacheDuration"); - memLayer.ML.setRSV(hMSE, value, MSE_cacheDuration); - } - } - - #endregion - - #region gestione task macchina - - /// - /// Restitusice elenco KVP dei TASK (da passare a IOB-WIN) per l'impianto indicato - /// - /// - /// - public Dictionary mTaskMacchina(string idxMacchina) - { - // hard coded dimensione vettore DatiMacchine - Dictionary answ = new Dictionary(); - // ORA recupero da memoria redis... - try - { - string currHash = exeTaskHash(idxMacchina); - answ = memLayer.ML.redGetHashDict(currHash); - } - catch (Exception exc) - { - logger.lg.scriviLog(string.Format("Errore in compilazione dati EXE TASK x Redis - idxMacchina {2}:{0}{1}", Environment.NewLine, exc, idxMacchina)); - } - return answ; - } - /// - /// Aggiunge un task all'elenco di quelli salvati (in modalità upsert) - /// - /// - /// - /// - /// - public bool addTask4Machine(string idxMacchina, taskType taskKey, string taskVal) - { - bool answ = false; - string currHash = exeTaskHash(idxMacchina); - try - { - // leggo task attuali... - var currTask = mTaskMacchina(idxMacchina); - currTask[taskKey.ToString()] = taskVal; - answ = memLayer.ML.redSaveHashDict(currHash, currTask); - logger.lg.scriviLog($"Task ADD - idxMacchina: {idxMacchina} | taskKey: {taskKey.ToString()} | taskVal: {taskVal}"); - } - catch { } - return answ; - } - /// - /// RIMUOVE un task dall'elenco di quelli salvati - /// - /// - /// - /// - public bool remTask4Machine(string idxMacchina, taskType taskKey) - { - bool answ = false; - string currHash = exeTaskHash(idxMacchina); - try - { - // leggo task attuali... - var currTask = mTaskMacchina(idxMacchina); - currTask.Remove(taskKey.ToString()); - memLayer.ML.redDelKey(currHash); - answ = memLayer.ML.redSaveHashDict(currHash, currTask); - logger.lg.scriviLog($"Task REM - idxMacchina: {idxMacchina} | taskKey: {taskKey.ToString()}"); - } - catch { } - return answ; - } - - #endregion - - #region gestione OPT PARAMETERS macchina - - /// - /// Restitusice elenco KVP dei TASK (da passare a IOB-WIN) per l'impianto indicato - /// - /// - /// - public Dictionary mOptParMacchina(string idxMacchina) - { - // hard coded dimensione vettore DatiMacchine - Dictionary answ = new Dictionary(); - // ORA recupero da memoria redis... - try - { - string currHash = optParHash(idxMacchina); - answ = memLayer.ML.redGetHashDict(currHash); - } - catch (Exception exc) - { - logger.lg.scriviLog(string.Format("Errore in compilazione dati OPT PARAM x Redis - idxMacchina {2}:{0}{1}", Environment.NewLine, exc, idxMacchina)); - } - return answ; - } - - /// - /// Aggiunge un PARAMETRO OPZIONALE all'elenco di quelli salvati (in modalità upsert) - /// - /// - /// - /// - /// - public bool addOptPar4Machine(string idxMacchina, string taskKey, string taskVal) - { - bool answ = false; - string currHash = optParHash(idxMacchina); - try - { - // leggo task attuali... - var currVal = mOptParMacchina(idxMacchina); - currVal[taskKey] = taskVal; - answ = memLayer.ML.redSaveHashDict(currHash, currVal); - } - catch { } - return answ; - } - /// - /// RIMUOVE un PARAMETRO OPZIONALE dall'elenco di quelli salvati - /// - /// - /// - /// - public bool remOptPar4Machine(string idxMacchina, string taskKey) - { - bool answ = false; - string currHash = optParHash(idxMacchina); - try - { - // leggo task attuali... - var currVal = mOptParMacchina(idxMacchina); - currVal.Remove(taskKey); - memLayer.ML.redDelKey(currHash); - answ = memLayer.ML.redSaveHashDict(currHash, currVal); - } - catch { } - return answ; - } - - #endregion - - #region gestione attrezzaggi - - /// - /// Effettua split ODL - /// - /// - /// - public string forceSplitOdl(string idxMacchina) - { - string answ = "KO"; - // verifico NON CI SIA un veto a NUOVI split... 2 min di default... - string redKey = vetoSplitOdlMaccHash(idxMacchina); - string rawData = memLayer.ML.getRSV(redKey); - if (string.IsNullOrEmpty(rawData)) - { - // registro VETO x altri split... 2 minuti - memLayer.ML.setRSV(redKey, $"Inizio SPLIT-ODL {DateTime.Now}", 300); - // proseguo - DS_ProdTempi.ODLDataTable currData = null; - DateTime adesso = DateTime.Now; - // chiamo metodo redis/db... - try - { - // recupero ODL corrente - currData = currODLRowTab(idxMacchina); - if (currData.Count > 0) - { - // registro un evento di inizio attrezzaggio (idxTipoEv = 2) - int idxEvento = 2; - logger.lg.scriviLog($"Invio evento ODL-SPLIT per macchina {idxMacchina}, evento {idxEvento}, articolo {currData[0].CodArticolo}", tipoLog.INFO); - inputComandoMapo resCmd = scriviRigaEventoBarcode(idxMacchina, idxEvento, currData[0].CodArticolo, "ODL-SPLIT", 0, "", adesso, adesso); - // attendo 1 sec - Thread.Sleep(1000); - adesso = DateTime.Now; - // chiamo splitOdl - MapoDbObj.taODL.splitODL(currData[0].IdxODL, 0, idxMacchina, currData[0].TCRichAttr, currData[0].PzPallet, $"Nuovo ODL da forceSplitOdl", true); - // attendo 1 sec - Thread.Sleep(1000); - adesso = DateTime.Now; - // registro fine ODL (idxTipoEv = 1) - idxEvento = 1; - logger.lg.scriviLog($"Invio evento FINE ODL-SPLIT per macchina {idxMacchina}, evento {idxEvento}, articolo {currData[0].CodArticolo}", tipoLog.INFO); - resCmd = scriviRigaEventoBarcode(idxMacchina, idxEvento, currData[0].CodArticolo, "ODL-START"); - // chiamo refresh MSE - taMSE.forceRecalc(0, idxMacchina); - // resetto stato macchina... - memLayer.ML.redDelKey(currStatoMaccHash(idxMacchina)); - answ = "OK"; - logger.lg.scriviLog($"Effettuato reset e ricalcoli x split ODL per macchina {idxMacchina}", tipoLog.INFO); - - } - } - catch (Exception exc) - { - logger.lg.scriviLog($"Eccezione in forceSplitOdl{Environment.NewLine}{exc}", tipoLog.EXCEPTION); - } - } - return answ; - } - - #endregion - - #region gestione stato macchina - - /// - /// Restituisce il valore dell'intera RIGA stato macchina corrente (da redis o da DB se non trovata...) - /// - /// - /// - public DS_applicazione.StatoMacchineDataTable currSMTab(string idxMacchina) - { - DS_applicazione.StatoMacchineDataTable answTab = null; - string rCall = ""; - if (memLayer.ML.CRB("IOB_RedEnab")) - { - saveCallRec("hasStatoMacc"); - try - { - rCall = memLayer.ML.getRSV(currStatoMaccHash(idxMacchina)); - if (!string.IsNullOrEmpty(rCall)) - { - answTab = JsonConvert.DeserializeObject(rCall); - } - else - { - // 2020.01.31 uso nuovo oggetto connessione - MapoDb man = new MapoDb(); - answTab = man.currStatoMaccTab(idxMacchina); - //answTab = MapoDbObj.currStatoMaccTab(idxMacchina); - // salvo in redis... - rCall = JsonConvert.SerializeObject(answTab); - int currStatoMaccCacheDur = memLayer.ML.CRI("currStatoMaccCacheDur"); - memLayer.ML.setRSV(currStatoMaccHash(idxMacchina), rCall, currStatoMaccCacheDur); - } - } - catch (Exception exc) - { - logger.lg.scriviLog($"Eccezione in recupero currODLRow{Environment.NewLine}{exc}", tipoLog.EXCEPTION); - } - } - else - { - answTab = MapoDbObj.currStatoMaccTab(idxMacchina); - } - return answTab; - } - /// - /// Elenco stati macchina - /// - /// - public DS_applicazione.AnagraficaStatiDataTable AnagraficaStati() - { - DS_applicazione.AnagraficaStatiDataTable answTab = null; - // cerco in cache... - string rCall = ""; - if (memLayer.ML.CRB("IOB_RedEnab")) - { - saveCallRec("hasAnagStati"); - try - { - rCall = memLayer.ML.getRSV(currAnagStatiMacc()); - if (!string.IsNullOrEmpty(rCall)) - { - answTab = JsonConvert.DeserializeObject(rCall); - } - else - { - //2020.01.31 nuovo obj x evitare concorrenza - MapoDb man = new MapoDb(); - answTab = man.taAnagSt.GetData(); - //answTab = MapoDbObj.taAnagSt.GetData(); - // salvo in redis... - rCall = JsonConvert.SerializeObject(answTab); - int anagrCacheDur = memLayer.ML.CRI("anagrCacheDur"); - memLayer.ML.setRSV(currAnagStatiMacc(), rCall, anagrCacheDur); - } - } - catch (Exception exc) - { - logger.lg.scriviLog($"Eccezione in recupero currODLRow{Environment.NewLine}{exc}", tipoLog.EXCEPTION); - } - } - else - { - answTab = MapoDbObj.taAnagSt.GetData(); - } - return answTab; - } - - #endregion - - #region gestione dati macchina - - /// - /// Restitusice elenco KVP dei campi DatiMacchine + StatoMacchine per l'impianto indicato - /// - /// - /// - public Dictionary mDatiMacchine(string idxMacchina) - { - // hard coded dimensione vettore DatiMacchine - Dictionary answ = new Dictionary(); - // ORA recupero da memoria redis... - try - { - string currHash = dtMaccHash(idxMacchina); - answ = memLayer.ML.redGetHashDict(currHash); - // se è vuoto... leggo da DB e popolo! - if (answ.Count == 0) - { - answ = resetDatiMacchina(idxMacchina); - } - } - catch (Exception exc) - { - logger.lg.scriviLog(string.Format("Errore in compilazione dati Macchine x Redis - idxMacchina {2}:{0}{1}", Environment.NewLine, exc, idxMacchina)); - } - return answ; - } - /// - /// Resetta (rileggendo) i dati della macchina - /// - /// - /// - public Dictionary resetDatiMacchina(string idxMacchina) - { - string currHash = dtMaccHash(idxMacchina); - // inizio con un bel reset... - memLayer.ML.redFlushKey(currHash); - Dictionary answ = new Dictionary(); - 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) - { - logger.lg.scriviLog(string.Format("Errore in compilazione dati MSFD:{0}{1}", Environment.NewLine, exc), tipoLog.EXCEPTION); - } - // 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) - { - logger.lg.scriviLog($"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 - { - logger.lg.scriviLog("Errore in chiamata stp_MSFD_getMacc (connDb.taMSFD.getByIdxMacc(idxMacchina))"); - } - return answ; - } - /// - /// Restituisce il valore booleano se la macchina sia abilitata all'input - /// - /// - /// - public bool insEnab(string idxMacchina) - { - bool answ = false; - if (memLayer.ML.CRB("IOB_RedEnab")) - { - saveCallRec("insEnabled"); - try - { - answ = Convert.ToBoolean(mDatiMacchinaVal(idxMacchina, "insEnabled")); - } - catch { } - } - // ...oppure dritto su DB - else - { - if (memLayer.ML.CRB("disable_singleton")) - { - // instanzio un nuovo oggetto MapoDb - MapoDb connDb = new MapoDb(); - answ = connDb.insEnabled(idxMacchina); - } - else - { - // leggo DB da singleton - answ = MapoDbObj.insEnabled(idxMacchina); - } - } - return answ; - } - /// - /// Restituisce il valore dell'intera RIGA ODL corrente (da redis o da DB se non trovata...) - /// - /// - /// - public DS_ProdTempi.ODLDataTable currODLRowTab(string idxMacchina) - { - DS_ProdTempi.ODLDataTable answTab = null; - string rCall = ""; - if (memLayer.ML.CRB("IOB_RedEnab")) - { - saveCallRec("hasODL_row"); - try - { - rCall = memLayer.ML.getRSV(currOdlRowHash(idxMacchina)); - if (!string.IsNullOrEmpty(rCall)) - { - answTab = JsonConvert.DeserializeObject(rCall); - } - else - { - // istanzio un NUOVO oggetto lettura - MapoDb connDb = new MapoDb(); - answTab = connDb.currODLTab(idxMacchina); - // salvo in redis... - rCall = JsonConvert.SerializeObject(answTab); - int currOdlRowCacheDur = memLayer.ML.CRI("currOdlRowCacheDur"); - memLayer.ML.setRSV(currOdlRowHash(idxMacchina), rCall, currOdlRowCacheDur); - } - } - catch (Exception exc) - { - logger.lg.scriviLog($"Eccezione in recupero currODLRow{Environment.NewLine}{exc}", tipoLog.EXCEPTION); - } - } - else - { - // istanzio un NUOVO oggetto lettura - MapoDb connDb = new MapoDb(); - answTab = connDb.currODLTab(idxMacchina); - } - return answTab; - } - - /// - /// Restituisce il valore dell'ODL corrente (ODL deve esserci per gestione contapezzi, senza ODL NO invio/gestione ODL) - /// - /// - /// - public string currODL(string idxMacchina) - { - string answ = ""; - string rCall = ""; - if (memLayer.ML.CRB("IOB_RedEnab")) - { - saveCallRec("hasODL"); - try - { - rCall = memLayer.ML.getRSV(currODLHash(idxMacchina)); - if (rCall != null && rCall != "") - { - answ = rCall; - } - else - { - answ = getCurrODL(idxMacchina); - // salvo in redis... - saveCurrODL(idxMacchina, answ); - } - } - catch { } - } - return answ; - } - /// - /// Restituisce il valore dell'ODL corrente (ODL deve esserci per gestione contapezzi, senza ODL NO invio/gestione ODL) - /// - /// - /// indica se forzare lettura da db (true) o meno - /// - public string currODL(string idxMacchina, bool forceDb) - { - string answ = ""; - // faccio comunque verifica se sia stato letto da poco il valore... x cui anche a fronte di richiesta lettura da DB per 3 sec tengo buono valore in cache redis... - string rKey = memLayer.ML.redHash($"ODL:{idxMacchina}"); - string _idxOdl = memLayer.ML.getRSV(rKey); - if (forceDb) - { - if (!string.IsNullOrEmpty(_idxOdl)) - { - answ = _idxOdl; - } - else - { - answ = getCurrODL(idxMacchina); - // salvo in redis... - saveCurrODL(idxMacchina, answ); - memLayer.ML.setRSV(rKey, answ, 3); - } - } - else - { - answ = currODL(idxMacchina); - } - return answ; - } - /// - /// Restituisce il valore booleano se la macchina sia abilitata all'inserimento COMPLETO nel Signal Log - /// - /// - /// - public bool sLogEnab(string idxMacchina) - { - bool answ = false; - if (memLayer.ML.CRB("IOB_RedEnab")) - { - saveCallRec("sLogEnabled"); - try - { - answ = Convert.ToBoolean(mDatiMacchinaVal(idxMacchina, "sLogEnabled")); - } - catch { } - } - // ...oppure dritto su DB - else - { - answ = MapoDbObj.sLogEnabled(idxMacchina); - } - return answ; - } - - /// - /// Restituisce il contapezzi come CONTEGGIO da TCRilevati per la macchina - /// - /// - /// - public int pzCounterTC(string idxMacchina) - { - int answ = -1; - if (memLayer.ML.CRB("IOB_RedEnab")) - { - saveCallRec("getCounterTC"); - } - // variabile x controllo dati recuperati - DS_ProdTempi.StatoProdDataTable datiProdAct = null; - bool okDatiProd = false; - int taSP_ms_ant = memLayer.ML.cdvi("taStatoProd_ms_anticipo"); - DateTime dataRif = DateTime.Now.AddMilliseconds(-taSP_ms_ant); - okDatiProd = getStatoProd(idxMacchina, ref datiProdAct, dataRif); - // se NON avesse recuperato --> aspetto taSP_ms_ant e poi RICHIAMO procedura... - int maxTry = 3; - while (!okDatiProd && maxTry > 0) - { - logger.lg.scriviLog(string.Format("[pzCounterTC] Impossibile recuperare dati ODL x idxMacchina {0}", idxMacchina), tipoLog.WARNING); - // sleep... - Thread.Sleep(taSP_ms_ant * 2); - // riprovo lettura... - okDatiProd = getStatoProd(idxMacchina, ref datiProdAct, dataRif); - maxTry--; - } - - // ora proseguo SE ho trovato i dati... - if (okDatiProd) - { - if (datiProdAct != null) - { - if (datiProdAct.Count > 0) - { - if (!datiProdAct[0].IsPzTotODLNull()) + else { - // ...a questo punto recupero DAVVERO i dati (o almeno ci provo...) - try - { - // controllo - answ = datiProdAct[0].PzTotODL; - } - catch (Exception exc) - { - logger.lg.scriviLog(string.Format("[pzCounterTC] Eccezione in recupero PzTotODL x idxMacchina {0}{1}{2}", idxMacchina, Environment.NewLine, exc), tipoLog.EXCEPTION); - } + string errore = $"Errore: mancano parametri macchina/incremento: idxMacchina {idxMacchina} | qty {qty}"; + logger.lg.scriviLog(errore, tipoLog.ERROR); + answ = errore; } - } + return answ; } - } - else - { - logger.lg.scriviLog(string.Format("[pzCounterTC] Dati ODL x idxMacchina {0} non recuperati dopo tentativi reiterati...", idxMacchina), tipoLog.WARNING); - } - return answ; - } - /// - /// Recupero dati stato prod da macchina... - /// - /// - /// - /// - /// - private bool getStatoProd(string idxMacchina, ref DS_ProdTempi.StatoProdDataTable datiProdAct, DateTime dataRif) - { - bool answ = false; - try - { - // recupero con stored NUOVA... - //2020.01.31 NUOVO oggetto (NON singleton) - DataLayer man = new DataLayer(); - datiProdAct = man.taStatoProd.GetData(idxMacchina, dataRif); - if (datiProdAct.Rows.Count > 0) - { - // solo SE ho idxODL (altrimenti loggo errore) - if (datiProdAct[0].IdxOdl > 0) - { - answ = true; - } - else - { - // verifico se ho già questo errore attivo IN REDIS (altrimenti reinvio) - logger.lg.scriviLog(string.Format("pzCounterTC: Non trovato currODL x idxMacchina {0} | IdxOdl {1} | pzTot {2} | dataRif {3}", idxMacchina, datiProdAct[0].IdxOdl, datiProdAct[0].PzTotODL, dataRif), tipoLog.WARNING); - } - } - else - { - logger.lg.scriviLog("pzCounterTC: Non trovate righe in currODL x idxMacchina " + idxMacchina + ": datiProdAct vuota", tipoLog.WARNING); - } - } - catch (Exception exc) - { - logger.lg.scriviLog(string.Format("[pzCounterTC] Eccezione in pzCounterTC x idxMacchina {0}{1}{2}", idxMacchina, Environment.NewLine, exc), tipoLog.EXCEPTION); - } - return answ; - } - /// - /// Restituisce il contapezzi salvato per la macchina - /// - /// - /// - public int pzCounter(string idxMacchina) - { - int answ = -1; - string rCall = ""; - if (memLayer.ML.CRB("IOB_RedEnab")) - { - saveCallRec("getCounter"); - try + /// + /// Processa registrazione di un counter x una data macchina IOB + /// + /// + /// contapezzi + /// + public string saveCounter(string idxMacchina, string counter) { - rCall = memLayer.ML.getRSV(pzCountHash(idxMacchina)); - if (rCall != "" && rCall != null) - { - int.TryParse(rCall, out answ); - } - else - { - answ = pzCounterTC(idxMacchina); - // salvo in redis... - saveCounter(idxMacchina, answ.ToString()); - } - } - catch { } - } - return answ; - } - /// - /// Restituisce il valore booleano se la macchina sia di tipo MULTI (con più state machine x INGRESSI) - /// - /// - /// - public bool isMulti(string idxMacchina) - { - bool answ = false; - if (memLayer.ML.CRB("IOB_RedEnab")) - { - saveCallRec("isMulti"); - try - { - answ = Convert.ToBoolean(mDatiMacchinaVal(idxMacchina, "Multi") == "1"); - } - catch { } - } - // ...oppure dritto su DB - else - { - answ = MapoDbObj.isMulti(idxMacchina); - } - return answ; - } - - #endregion - - #region gestione State Machine Ingressi - - /// - /// Recupera (da DB) i dati della State Machine multi ingressi nel formato - /// key: IdxMacchina - /// value: IdxFamigliaIngresso - /// - /// - /// - public KeyValuePair[] getMSMI_DB(string idxMacchina) - { - DS_applicazione.MSFDDataTable tabMSMI = new DS_applicazione.MSFDDataTable(); - // 2017.09.13: inserisco gestione singleton condizionale - if (memLayer.ML.CRB("disable_singleton")) - { - // instanzio un nuovo oggetto MapoDb - MapoDb connDb = new MapoDb(); - tabMSMI = connDb.taMSFD.getMulti(idxMacchina); - } - else - { - // leggo DB da singleton - tabMSMI = MapoDbObj.taMSFD.getMulti(idxMacchina); - } - KeyValuePair[] answ = new KeyValuePair[tabMSMI.Count]; - // salvo tutti i valori StateMachineIngressi... - int i = 0; - foreach (var item in tabMSMI) - { - answ[i] = new KeyValuePair(item.IdxMacchina, item.IdxFamigliaIngresso.ToString()); - i++; - } - return answ; - } - /// - /// Restitusice elenco KVP - /// key: IdxMacchina - /// value: IdxFamigliaIngresso - /// - /// - /// - public KeyValuePair[] mTabMSMI(string idxMacchina) - { - // hard coded dimensione vettore DatiMacchine - KeyValuePair[] answ = new KeyValuePair[1]; - // iniziualizzo con un valore... 0/0 - answ[0] = new KeyValuePair("0", "0"); - // ORA recupero da memoria redis... - try - { - string currHash = hMSMI(idxMacchina); - answ = memLayer.ML.redGetHash(currHash); - // se è vuoto... leggo da DB e popolo! - if (answ.Length == 0) - { - answ = resetMSMI(idxMacchina); - } - } - catch (Exception exc) - { - logger.lg.scriviLog(string.Format("Errore in compilazione Tabella Multi State Machine Ingressi x Redis:{0}{1}", Environment.NewLine, exc)); - } - return answ; - } - /// - /// Resetta (rileggendo) i dati della State Machine multi ingressi nel formato - /// key: IdxMacchina - /// value: IdxFamigliaIngresso - /// - /// - /// - public KeyValuePair[] resetMSMI(string idxMacchina) - { - string currHash = hMSMI(idxMacchina); - DS_applicazione.MSFDDataTable tabMSMI = new DS_applicazione.MSFDDataTable(); - // 2017.09.13: inserisco gestione singleton condizionale - if (memLayer.ML.CRB("disable_singleton")) - { - // instanzio un nuovo oggetto MapoDb - MapoDb connDb = new MapoDb(); - tabMSMI = connDb.taMSFD.getMulti(idxMacchina); - } - else - { - // leggo DB da singleton - tabMSMI = MapoDbObj.taMSFD.getMulti(idxMacchina); - } - KeyValuePair[] answ = new KeyValuePair[tabMSMI.Count]; - // salvo tutti i valori StateMachineIngressi... - int i = 0; - foreach (var item in tabMSMI) - { - answ[i] = new KeyValuePair(item.IdxMacchina, item.IdxFamigliaIngresso.ToString()); - i++; - } - // verifico il timeout (default 60 sec...) - int tOut = (memLayer.ML.cdvi("TmOut.MSMI") <= 0) ? 60 : memLayer.ML.cdvi("TmOut.MSMI"); - // salvo in redis! - memLayer.ML.redSaveHash(currHash, answ, tOut); - return answ; - } - /// - /// Restitusice elenco KVP dei campi della State Machine ingressi nel formato - /// key: cState_nVal (current MICRO-STATE + "_" + new Value) - /// value: iTipoEv_nState (IdxTipoEv da trasmettere + New MICRO-STATE - /// - /// - /// - public KeyValuePair[] mTabSMI(int idxFamIn) - { - // hard coded dimensione vettore DatiMacchine - KeyValuePair[] answ = new KeyValuePair[1]; - // iniziualizzo con un valore... 0/0 - answ[0] = new KeyValuePair("0", "0"); - // ORA recupero da memoria redis... - try - { - string currHash = hSMI(idxFamIn); - answ = memLayer.ML.redGetHash(currHash); - // se è vuoto... leggo da DB e popolo! - if (answ.Length == 0) - { - answ = resetSMI(idxFamIn); - } - } - catch (Exception exc) - { - logger.lg.scriviLog(string.Format("Errore in compilazione State Machine Ingressi x Redis:{0}{1}", Environment.NewLine, exc)); - } - return answ; - } - /// - /// Resetta (rileggendo) i dati della State Machine ingressi nel formato - /// key: cState_nVal (current MICRO-STATE + "_" + new Value) - /// value: iTipoEv_nState (IdxTipoEv da trasmettere + New MICRO-STATE) - /// - /// - /// - public KeyValuePair[] resetSMI(int idxFamIn) - { - string currHash = hSMI(idxFamIn); - DS_applicazione.TransizioneIngressiDataTable tabSMI = new DS_applicazione.TransizioneIngressiDataTable(); - // 2017.09.13: inserisco gestione singleton condizionale - if (memLayer.ML.CRB("disable_singleton")) - { - // instanzio un nuovo oggetto MapoDb - MapoDb connDb = new MapoDb(); - tabSMI = connDb.taTransIngr.getByIdxFamIng(idxFamIn); - } - else - { - // leggo DB da singleton - tabSMI = MapoDbObj.taTransIngr.getByIdxFamIng(idxFamIn); - } - KeyValuePair[] answ = new KeyValuePair[tabSMI.Count]; - // salvo tutti i valori StateMachineIngressi... - int i = 0; - string key = ""; - string val = ""; - foreach (var item in tabSMI) - { - key = string.Format("{0}_{1}", item.IdxMicroStato, item.ValoreIngresso); - val = string.Format("{0}_{1}", item.IdxTipoEvento, item.next_IdxMicroStato); - answ[i] = new KeyValuePair(key, val); - i++; - } - // verifico il timeout (default 60 sec...) - int tOut = (memLayer.ML.cdvi("TmOut.SMI") <= 0) ? 60 : memLayer.ML.cdvi("TmOut.SMI"); - // salvo in redis! - memLayer.ML.redSaveHash(currHash, answ, tOut); - return answ; - } - /// - /// Restituisce il valore SPECIFICATO per la state machine ingressi - /// value: iTipoEv_nState (IdxTipoEv da trasmettere + New MICRO-STATE) - /// - /// - /// - /// - /// - public string valoreSMI(int idxFamIn, int idxMicroStato, int valoreIn) - { - string currHash = hSMI(idxFamIn); - string field = string.Format("{0}_{1}", idxMicroStato, valoreIn); - return memLayer.ML.redGetHashField(currHash, field); - } - /// - /// Restituisce valore di una singola chiave del dizionario DatiMacchina - /// - /// - /// - /// - public string mDatiMacchinaVal(string idxMacchina, string chiave) - { - string answ = ""; - try - { - answ = mDatiMacchine(idxMacchina)[chiave]; - } - catch { } - return answ; - } - - #endregion - - #endregion - - #region metodi spostati da MapoDB - - /// - /// restituisce il TempoCiclo effettivo (tecnico) della macchina - /// - /// - /// - public decimal getTcEffMacchina(string idxMacchina) - { - decimal tc = 0; - try - { - DS_ProdTempi.stp_repDonati_getDatiProdMacchinaPeriodoRow riga = taDatiProdMacchPer.GetData(idxMacchina, DateTime.Now.AddMinutes(-30), DateTime.Now)[0]; - if (riga.TCEffRT > 0) - { - tc = riga.TCEffRT; - } - else - { - tc = riga.TCAssegnato; - } - } - catch { } - // imposto a 99'TC - if (tc == 0) - { - tc = 99.9M; - // scrivo log per indicare mancato caricamento dati tc dichiarato e conseguente errore sul timer - 2/11/2012 EN&CV - logger.lg.scriviLog(string.Format("Impostato TC Tempo Ciclo a 99' (99.9M) causa mancato inserimento tempo ciclo dichiarato")); - } - return tc; - } - /// - /// cerca codice in anagrafica macchine ed eventualmente inserisce nuova macchina - /// - /// - private void verificaIdxMacchina(string IdxMacchina) - { - bool needDB = false; - if (!memLayer.ML.CRB("disable_verificaIdxMacchina")) - { - if (memLayer.ML.CRB("IOB_RedEnab")) - { - try - { - // esecuzione in REDIS...cerco status macchina... - if (mDatiMacchine(IdxMacchina).Count == 0) - { - needDB = true; - } - } - catch { } - } - // ...oppure segno richiesta DB... - else - { - needDB = true; - } - if (needDB) - { - // 2017.07.11 se richiesto di NON usare singleton... riporto FUORI la gestione NUOVO oggetto - if (memLayer.ML.CRB("disable_singleton")) - { - taMacchine = new DS_applicazioneTableAdapters.MacchineTableAdapter(); - MapoDbObj.taMSM = new DS_applicazioneTableAdapters.MicroStatoMacchinaTableAdapter(); - } - // verifico esistenza macchina - if (taMacchine.GetByIdx(IdxMacchina).Rows.Count == 0) - { - // inserisco nuova macchina... - taMacchine.Insert(IdxMacchina, "9999", IdxMacchina, "Macchina non codificata", "-", "http://", "nd", "col", 0, 0); - } - // verifico ci sia un microstato macchina... - if (MapoDbObj.taMSM.getByIdxMacchina(IdxMacchina).Rows.Count == 0) - { - // inserisco nuovo stato... - MapoDbObj.taMSM.Insert(IdxMacchina, 0, DateTime.Now, "00"); - } - } - } - } - /// - /// restituisce una tabella con tutte le transizioni degli ingressi per una data macchina - /// - /// - /// - public DS_applicazione.TransizioneIngressiDataTable getMatriceIngressi(string idxMacchina) - { - DS_applicazione.TransizioneIngressiDataTable answ; - try - { - answ = taTranIngr.getMatriceByIdxMacchina(idxMacchina); - } - catch - { - answ = null; - } - return answ; - } - /// - /// controlla se da il segnale di "microstato" deriva un evento da generare - modalità OFFLINE - /// - /// idx macchina - /// valore ingresso - /// data-ora evento (server) - /// sequenza dati inviati - /// - public inputComandoMapo checkMicroStato(string idxMacchina, string valore, DateTime dtEve, string contatore) - { - int _logLevel = memLayer.ML.CRI("_logLevel"); - // recupero SE IMPIEGATO REDIS i valori del Dictionary della macchina... - Dictionary datiMacc = mDatiMacchine(idxMacchina); - - if (_logLevel > 6) - { - logger.lg.scriviLog(string.Format("[ChkMiSt]{2}---------------------------{2}Richiesta verifica INPUT per Macchina {0}, seriale {1}", idxMacchina, valore, Environment.NewLine), tipoLog.INFO); - } - // formatto output - inputComandoMapo answ = new inputComandoMapo(); - DS_applicazione.TransizioneIngressiDataTable TabTransIn; - DS_applicazione.TransizioneIngressiRow rigaTransIn = null; - // verifico se esista la macchina altrimenti la creo... REDIS compliant - verificaIdxMacchina(idxMacchina); - string CodArticolo = ""; - if (memLayer.ML.CRB("IOB_RedEnab")) - { - try - { - // esecuzione in REDIS - CodArticolo = datiMacc["CodArticolo"]; - } - catch { } - } - // ...oppure dritto su DB - else - { - // esecuzione in DB... - // recupero CodArticolo corretto - try - { - // 2017.07.11 se richiesto di NON usare singleton... riporto FUORI la gestione NUOVO oggetto - if (memLayer.ML.CRB("disable_singleton")) - { - // 2017.07.10 forzo init x errori "sovrapposizioni" - taDatiMacchine = new DS_ProdTempiTableAdapters.DatiMacchineTableAdapter(); - } - CodArticolo = taDatiMacchine.getByIdx(idxMacchina)[0].CodArticolo_A; - } - catch (Exception exc) - { - logger.lg.scriviLog(string.Format("[ChkMiSt_4a] - Eccezione in recupero CodArticolo:{0}{1}", Environment.NewLine, exc), tipoLog.EXCEPTION); - } - } - // recupero next microstato - int? valINT = 0; - try - { - valINT = int.Parse(valore, System.Globalization.NumberStyles.HexNumber); - // esecuzione in REDIS... - if (memLayer.ML.CRB("IOB_RedEnab")) - { - try - { - int idxFamIn = Convert.ToInt32(datiMacc["IdxFamIn"]); - int idxMicroStato = Convert.ToInt32(datiMacc["IdxMicroStato"]); - int valIOB = Convert.ToInt32(valINT); - int idxTipoEv = 0; - int next_idxMS = idxMicroStato; - // verifico esistenza tab SMI... - string fiHASH = DataLayer.hSMI(idxFamIn); - string todoSMI = ""; - bool trovato = memLayer.ML.redHashPresentSz(fiHASH); - if (!trovato) - { - // ricarico tabella! - KeyValuePair[] valori = mTabSMI(idxFamIn); - } - // recupero singolo valore (stringa) x chiave - todoSMI = valoreSMI(idxFamIn, idxMicroStato, valIOB); - // solo se ho trovato un risultato nella tab SMI della famiglia macchina... - if (todoSMI != "") - { - // splitto e salvo valori OUT... - string[] valori = todoSMI.Split('_'); - idxTipoEv = Convert.ToInt32(valori[0]); - next_idxMS = Convert.ToInt32(valori[1]); - // creo la riga tipizzatya dai dati di redis x procedere... - DS_applicazione.TransizioneIngressiDataTable tab = new DS_applicazione.TransizioneIngressiDataTable(); - rigaTransIn = tab.NewTransizioneIngressiRow(); - rigaTransIn.IdxFamigliaIngresso = idxFamIn; - rigaTransIn.IdxMicroStato = idxMicroStato; - rigaTransIn.ValoreIngresso = valIOB; - rigaTransIn.IdxTipoEvento = idxTipoEv; - rigaTransIn.next_IdxMicroStato = next_idxMS; - } - } - catch { } - } - // ...oppure dritto su DB - else - { - // 2017.07.11 se richiesto di NON usare singleton... riporto FUORI la gestione NUOVO oggetto - if (memLayer.ML.CRB("disable_singleton")) - { - // 2017.06.09 forzo init x errori "sovrapposizioni" - MapoDbObj.taTransIngr = new DS_applicazioneTableAdapters.TransizioneIngressiTableAdapter(); - } - TabTransIn = MapoDbObj.taTransIngr.getByIdxMacchinaValore(idxMacchina, valINT); - if (TabTransIn.Rows.Count > 0) - { - rigaTransIn = TabTransIn[0]; - } - } - } - catch (Exception exc) - { - logger.lg.scriviLog(string.Format("[ChkMiSt_5a] - - Eccezione in recupero riga Trans ingressi per idxMacchina {3} e valore {2}:{0}{1}", Environment.NewLine, exc, valINT, idxMacchina), tipoLog.EXCEPTION); - } - // effettuo update vari SU DB!!! - if (rigaTransIn != null) - { - try - { - if (_logLevel > 5) - { - logger.lg.scriviLog(string.Format("[ChkMiSt_6a] - Salvo Update Microstato:{0}macchina: {1} | valore seriale: {2} | next micro stato: {3}", Environment.NewLine, idxMacchina, valINT, rigaTransIn.next_IdxMicroStato), tipoLog.INFO); - } - // 2017.07.11 se richiesto di NON usare singleton... riporto FUORI la gestione NUOVO oggetto - if (memLayer.ML.CRB("disable_singleton")) - { - // 2017.06.09 forzo init x errori "sovrapposizioni" - MapoDbObj.taMSM = new DS_applicazioneTableAdapters.MicroStatoMacchinaTableAdapter(); - } - // salvo nuovo microstato... - MapoDbObj.taMSM.updateQuery(rigaTransIn.next_IdxMicroStato, dtEve, valore, idxMacchina); - // controllo se c'è evento - if (rigaTransIn.IdxTipoEvento > 0) - { - if (_logLevel > 5) - { - logger.lg.scriviLog(string.Format("[ChkMiSt_7a] - Salvo evento:{0}macchina: {1} | tipoEvento: {2} | CodArticolo: {3} | contatore: {4} | valore: {5}", Environment.NewLine, idxMacchina, rigaTransIn.IdxTipoEvento, CodArticolo, contatore, valore), tipoLog.INFO); - } - string valEsteso = string.Format("[{0}] {1}", contatore.PadLeft(3, '0'), valore); - // aggiunto contatore! - answ = scriviRigaEvento(idxMacchina, rigaTransIn.IdxTipoEvento, CodArticolo, valEsteso, 0, "-", dtEve, DateTime.Now); - // 2017.09.12 SE era in modalità redis RICARICA dati macchina... + // registro conteggio impiego chiamate REDIS if (memLayer.ML.CRB("IOB_RedEnab")) { - resetDatiMacchina(idxMacchina); + saveCallRec("saveCounter"); } - if (_logLevel > 5) + string answ = "0"; + // inizio processing vero e proprio INPUT... + if (!string.IsNullOrEmpty(idxMacchina)) { - logger.lg.scriviLog(string.Format("[ChkMiSt_a] - Macchina {0} | seriale(INT) {1} | valEsteso {3} | answ {4}{2}---------------------------{2}", idxMacchina, valINT, Environment.NewLine, valEsteso, answ), tipoLog.INFO); - } - } - } - catch (Exception exc) - { - logger.lg.scriviLog(string.Format("[ChkMiSt_8a] - Eccezione:{0}{1}", Environment.NewLine, exc), tipoLog.EXCEPTION); - } - } - return answ; - } - /// - /// controlla se da il segnale di "microstato" deriva un evento da generare - modalità OFFLINE - /// - /// idx macchina - /// valore ingresso - /// data-ora evento (server) - /// - public inputComandoMapo checkMicroStato(string idxMacchina, string valore, DateTime dtEve) - { - if (memLayer.ML.CRI("_logLevel") > 6) - { - logger.lg.scriviLog(string.Format("{2}---------------------------{2}Richiesta verifica INPUT per Macchina {0}, seriale {1}", idxMacchina, valore, Environment.NewLine), tipoLog.INFO); - } - // formatto output - inputComandoMapo answ = new inputComandoMapo(); - DS_applicazione.TransizioneIngressiDataTable TabTransIn; - DS_applicazione.TransizioneIngressiRow rigaTransIn = null; - // verifico se esista la macchina altrimenti la creo... - verificaIdxMacchina(idxMacchina); - string CodArticolo = ""; - // recupero CodArticolo corretto - try - { - // 2017.07.10 forzo init x errori "sovrapposizioni" - taDatiMacchine = new DS_ProdTempiTableAdapters.DatiMacchineTableAdapter(); - CodArticolo = taDatiMacchine.getByIdx(idxMacchina)[0].CodArticolo_A; - } - catch (Exception exc) - { - logger.lg.scriviLog(string.Format("[ChkMiSt_4b] - Eccezione in recupero CodArticolo:{0}{1}", Environment.NewLine, exc), tipoLog.EXCEPTION); - } - // recupero next microstato - //int? valINT = Convert.ToInt32(valore); - int? valINT = 0; - try - { - // 2017.06.09 forzo init x errori "sovrapposizioni" - MapoDbObj.taTransIngr = new DS_applicazioneTableAdapters.TransizioneIngressiTableAdapter(); - valINT = int.Parse(valore, System.Globalization.NumberStyles.HexNumber); - TabTransIn = MapoDbObj.taTransIngr.getByIdxMacchinaValore(idxMacchina, valINT); - if (TabTransIn.Rows.Count > 0) - { - rigaTransIn = TabTransIn[0]; - } - } - catch (Exception exc) - { - logger.lg.scriviLog(string.Format("[ChkMiSt_5b] - Eccezione in recupero riga Trans ingressi per idxMacchina {3} e valore {2}:{0}{1}", Environment.NewLine, exc, valINT, idxMacchina), tipoLog.EXCEPTION); - } - int _logLevel = memLayer.ML.CRI("_logLevel"); - // effettuo update vari - if (rigaTransIn != null) - { - try - { - if (_logLevel > 5) - { - logger.lg.scriviLog(string.Format("[ChkMiSt_6b] - Salvo Update Microstato:{0}macchina: {1} | valore seriale: {2} | next micro stato: {3}", Environment.NewLine, idxMacchina, valINT, rigaTransIn.next_IdxMicroStato), tipoLog.INFO); - } - // salvo nuovo microstato... - MapoDbObj.taMSM.updateQuery(rigaTransIn.next_IdxMicroStato, dtEve, valore, idxMacchina); - // controllo se c'è evento - if (rigaTransIn.IdxTipoEvento > 0) - { - if (_logLevel > 5) - { - logger.lg.scriviLog(string.Format("[ChkMiSt_7b] - Salvo evento:{0}macchina: {1} | tipoEvento: {2} | CodArticolo: {3}", Environment.NewLine, idxMacchina, rigaTransIn.IdxTipoEvento, CodArticolo), tipoLog.INFO); - } - answ = scriviRigaEvento(idxMacchina, rigaTransIn.IdxTipoEvento, CodArticolo, valore, 0, "-", dtEve, DateTime.Now); - if (_logLevel > 5) - { - logger.lg.scriviLog(string.Format("[ChkMiSt_b] -Macchina {0}, seriale(INT) {1}{2}---------------------------{2}", idxMacchina, valINT, Environment.NewLine), tipoLog.INFO); - } - } - } - catch (Exception exc) - { - logger.lg.scriviLog(string.Format("[ChkMiSt_8b] - Eccezione:{0}{1}", Environment.NewLine, exc), tipoLog.EXCEPTION); - } - } - return answ; - } - /// - /// controlla se da il segnale di "microstato" deriva un evento da generare - /// - /// - /// - /// - public inputComandoMapo checkMicroStato(string idxMacchina, string valore) - { - // wrapper ad ora corrente... - return checkMicroStato(idxMacchina, valore, DateTime.Now); - } - /// - /// 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) - { - int _logLevel = memLayer.ML.CRI("_logLevel"); - 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) + if (!string.IsNullOrEmpty(counter)) { - MapoDbObj.taDiario.InsStatoBatch(IdxMacchina, InizioStato, rigaTransStati.next_IdxStato, CodArt, Value, MatrOpr, pallet); - // aggiorno MSE - taMSE.forceRecalc(0, IdxMacchina); + int newCounter = -1; + int.TryParse(counter, out newCounter); + // se il conteggio è >= 0 SALVO come nuovo conteggio... + if (newCounter >= 0) + { + string redKey = pzCountHash(idxMacchina); + // verifico SE ci sia chiave in redis (ALTRIMENTI rileggo da DB) + string redVal = memLayer.ML.getRSV(redKey); + if (!string.IsNullOrEmpty(redVal)) + { + // salvo in Redis nell'area corretta il valore richiesto + memLayer.ML.setRSV(redKey, counter); + // imposto risposta... + answ = counter; + } + else + { + // rileggo da DB e salvo e poi restituisco questo... + int currCount = pzCounterTC(idxMacchina); + memLayer.ML.setRSV(redKey, currCount.ToString()); + // imposto risposta... + answ = currCount.ToString(); + } + } } - } - else - { - if (_logLevel > 6) + else { - logger.lg.scriviLog($"Non trovata riga per: BARCODE | IdxMacchina: {IdxMacchina} | IdxTipo: {IdxTipo} | CodArt: {CodArt} | Value: {Value} | MatrOpr: {MatrOpr} | pallet: {pallet}", tipoLog.INFO); + string errore = "Errore: parametro counter vuoto"; + logger.lg.scriviLog(errore, tipoLog.ERROR); + answ = errore; } - } } - } - catch (Exception exc) - { - // non dovrebbe succedere... input utente da barcode dovrebbero TUTTI essere inseriti in tab transizione con famiglia 1... - logger.lg.scriviLog($"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) + else { - 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) - { - logger.lg.scriviLog($"Non trovata riga per: HW | IdxMacchina: {IdxMacchina} | IdxTipo: {IdxTipo} | CodArt: {CodArt} | Value: {Value} | MatrOpr: {MatrOpr} | pallet: {pallet}", tipoLog.INFO); - } - } + string errore = "Errore: parametro macchina vuoto"; + logger.lg.scriviLog(errore, tipoLog.ERROR); + answ = errore; } - } - catch (Exception exc) - { - // non trovo riga [0]... NON scrivo! - logger.lg.scriviLog($"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; - } - } - /// - /// scrive una riga di evento nel db - /// - /// codice macchina - /// idx evento - /// Codice Articolo - /// valore - /// matricola operatore - /// pallet (vuoto se nd) - /// data-ora dell'evento - /// data-ora corrente dell'invio - /// - public inputComandoMapo scriviRigaEvento(string IdxMacchina, int IdxTipo, string CodArticolo, string Value, int MatrOpr, string pallet, DateTime eventTime, DateTime currentTime) - { - int inserito = 0; - // 2017.07.11 se richiesto di NON usare singleton... riporto FUORI la gestione NUOVO oggetto - if (memLayer.ML.CRB("disable_singleton")) - { - // 2017.06.09 forzo init x errori "sovrapposizioni" - MapoDbObj.taEvList = new DS_applicazioneTableAdapters.EventListTableAdapter(); - } - try - { - // verifico se esista la macchina altrimenti la creo... - verificaIdxMacchina(IdxMacchina); - // calcolo dataOra reale (evento + delta(ora server - ora remota) - DateTime dataOra = eventTime.Add(DateTime.Now - currentTime); - // inserisco evento - inserito = MapoDbObj.taEvList.Insert(IdxMacchina, dataOra, IdxTipo, CodArticolo, Value, MatrOpr, pallet); - // faccio controllo per eventuale cambio stato da tab transizioni... - checkCambiaStatoBatch(tipoInputEvento.hw, IdxMacchina, dataOra, IdxTipo, CodArticolo, Value, MatrOpr, pallet); - } - catch (Exception exc) - { - logger.lg.scriviLog(string.Format("Errore in fase di scrittura evento con i seguenti dati:{0} macchina {1}{0} IdxTipo {2}{0} CodArticolo {3}{0} Value {4}{0} MatrOpr {5}{0} Pallet {6}{0} eventTime {7}{0} currentTime {8}{0} eccezione: {0}{9}", Environment.NewLine, IdxMacchina, IdxTipo, CodArticolo, Value, MatrOpr, pallet, eventTime, currentTime, exc), tipoLog.EXCEPTION); - } - // formatto output - inputComandoMapo answ = new inputComandoMapo(); - answ.outValue = inserito.ToString(); - answ.needStatusRefresh = true; - return answ; - } - /// - /// scrive una riga di evento nel db - /// - /// codice macchina - /// idx evento - /// Codice Articolo - /// valore - /// matricola operatore - /// pallet (vuoto se nd) - /// - public inputComandoMapo scriviRigaEvento(string IdxMacchina, int IdxTipo, string CodArticolo, string Value, int MatrOpr, string pallet) - { - int inserito = 0; - // 2017.06.09 forzo init x errori "sovrapposizioni" - MapoDbObj.taEvList = new DS_applicazioneTableAdapters.EventListTableAdapter(); - try - { - // verifico se esista la macchina altrimenti la creo... - verificaIdxMacchina(IdxMacchina); - DateTime dataOra = DateTime.Now; - // inserisco evento - inserito = MapoDbObj.taEvList.Insert(IdxMacchina, dataOra, IdxTipo, CodArticolo, Value, MatrOpr, pallet); - // faccio controllo per eventuale cambio stato da tab transizioni... - checkCambiaStatoBatch(tipoInputEvento.hw, IdxMacchina, dataOra, IdxTipo, CodArticolo, Value, MatrOpr, pallet); - } - catch (Exception exc) - { - logger.lg.scriviLog(string.Format("Errore in fase di scrittura evento con i seguenti dati:{0} macchina {1}{0} IdxTipo {2}{0} CodArticolo {3}{0} Value {4}{0} MatrOpr {5}{0} Pallet {6}{0} eccezione:{0}{7}", Environment.NewLine, IdxMacchina, IdxTipo, CodArticolo, Value, MatrOpr, pallet, exc), tipoLog.EXCEPTION); - } - // formatto output - inputComandoMapo answ = new inputComandoMapo(); - answ.outValue = inserito.ToString(); - answ.needStatusRefresh = true; - return answ; - } - /// - /// scrive una riga di evento nel db SENZA passare operatore e pallet (mette a 0 e "-") - /// - /// codice macchina - /// idx evento - /// Codice Articolo - /// valore - /// - public inputComandoMapo scriviRigaEvento(string IdxMacchina, int IdxTipo, string CodArticolo, string Value) - { - int inserito = 0; - try - { - // verifico se esista la macchina altrimenti la creo... - verificaIdxMacchina(IdxMacchina); - DateTime dataOra = DateTime.Now; - // inserisco evento - inserito = MapoDbObj.taEvList.Insert(IdxMacchina, dataOra, IdxTipo, CodArticolo, Value, 0, "-"); - // faccio controllo per eventuale cambio stato da tab transizioni... - checkCambiaStatoBatch(tipoInputEvento.hw, IdxMacchina, dataOra, IdxTipo, CodArticolo, Value, 0, "-"); - } - catch - { - logger.lg.scriviLog(string.Format("Errore in fase di scrittura evento con i seguenti dati:{0} macchina {1}{0} IdxTipo {2}{0} CodArticolo {3}{0} Value {4}{0} eccezione: {0}{5}", Environment.NewLine, IdxMacchina, IdxTipo, CodArticolo, Value), tipoLog.EXCEPTION); - } - // formatto output - inputComandoMapo answ = new inputComandoMapo(); - answ.outValue = inserito.ToString(); - answ.needStatusRefresh = true; - return answ; - } - - /// - /// scrive una riga di evento inviato da Barcode nel db - /// - /// codice macchina - /// idx evento - /// Codice Articolo - /// valore - /// matricola operatore - /// pallet (vuoto se nd) - /// data-ora dell'evento - /// data-ora corrente dell'invio - /// - public inputComandoMapo scriviRigaEventoBarcode(string IdxMacchina, int IdxTipo, string CodArticolo, string Value, int MatrOpr, string pallet, DateTime eventTime, DateTime currentTime) - { - int inserito = 0; - try - { - // verifico se esista la macchina altrimenti la creo... - verificaIdxMacchina(IdxMacchina); - // calcolo dataOra reale (evento + delta(ora server - ora remota) - DateTime dataOra = eventTime.Add(DateTime.Now - currentTime); - // inserisco evento - inserito = MapoDbObj.taEvList.Insert(IdxMacchina, dataOra, IdxTipo, CodArticolo, Value, MatrOpr, pallet); - // faccio controllo per eventuale cambio stato da tab transizioni... - checkCambiaStatoBatch(tipoInputEvento.barcode, IdxMacchina, dataOra, IdxTipo, CodArticolo, Value, MatrOpr, pallet); - } - catch (Exception exc) - { - logger.lg.scriviLog(string.Format("Errore in fase di scrittura evento con i seguenti dati:{0} macchina {1}{0} IdxTipo {2}{0} CodArticolo {3}{0} Value {4}{0} MatrOpr {5}{0} Pallet {6}{0} eventTime {7}{0} currentTime {8}{0} eccezione: {0}{9}", Environment.NewLine, IdxMacchina, IdxTipo, CodArticolo, Value, MatrOpr, pallet, eventTime, currentTime, exc), tipoLog.EXCEPTION); - } - // formatto output - inputComandoMapo answ = new inputComandoMapo(); - answ.outValue = inserito.ToString(); - answ.needStatusRefresh = true; - return answ; - } - /// - /// scrive una riga di evento inviato da Barcode nel db - /// - /// codice macchina - /// idx evento - /// Codice Articolo - /// valore - /// matricola operatore - /// pallet (vuoto se nd) - /// - public inputComandoMapo scriviRigaEventoBarcode(string IdxMacchina, int IdxTipo, string CodArticolo, string Value, int MatrOpr, string pallet) - { - int inserito = 0; - try - { - // verifico se esista la macchina altrimenti la creo... - verificaIdxMacchina(IdxMacchina); - DateTime dataOra = DateTime.Now; - // inserisco evento - inserito = MapoDbObj.taEvList.Insert(IdxMacchina, dataOra, IdxTipo, CodArticolo, Value, MatrOpr, pallet); - // faccio controllo per eventuale cambio stato da tab transizioni... - checkCambiaStatoBatch(tipoInputEvento.barcode, IdxMacchina, dataOra, IdxTipo, CodArticolo, Value, MatrOpr, pallet); - } - catch (Exception exc) - { - logger.lg.scriviLog(string.Format("Errore in fase di scrittura evento con i seguenti dati:{0} macchina {1}{0} IdxTipo {2}{0} CodArticolo {3}{0} Value {4}{0} MatrOpr {5}{0} Pallet {6}{0} eccezione: {0}{7}", Environment.NewLine, IdxMacchina, IdxTipo, CodArticolo, Value, MatrOpr, pallet, exc), tipoLog.EXCEPTION); - } - // formatto output - inputComandoMapo answ = new inputComandoMapo(); - answ.outValue = inserito.ToString(); - answ.needStatusRefresh = true; - return answ; - } - /// - /// scrive una riga di evento inviato da Barcode nel db SENZA operatore e pallet (mette a 0 e "-") - /// - /// codice macchina - /// idx evento - /// Codice Articolo - /// valore - /// - public inputComandoMapo scriviRigaEventoBarcode(string IdxMacchina, int IdxTipo, string CodArticolo, string Value) - { - int inserito = 0; - try - { - // verifico se esista la macchina altrimenti la creo... - verificaIdxMacchina(IdxMacchina); - DateTime dataOra = DateTime.Now; - // inserisco evento - inserito = MapoDbObj.taEvList.Insert(IdxMacchina, dataOra, IdxTipo, CodArticolo, Value, 0, "-"); - // faccio controllo per eventuale cambio stato da tab transizioni... - checkCambiaStatoBatch(tipoInputEvento.barcode, IdxMacchina, dataOra, IdxTipo, CodArticolo, Value, 0, "-"); - } - catch - { - logger.lg.scriviLog(string.Format("Errore in fase di scrittura evento con i seguenti dati:{0} macchina {1}{0} IdxTipo {2}{0} CodArticolo {3}{0} Value {4}{0} eccezione: {0}{5}", Environment.NewLine, IdxMacchina, IdxTipo, CodArticolo, Value), tipoLog.EXCEPTION); - } - // formatto output - inputComandoMapo answ = new inputComandoMapo(); - answ.outValue = inserito.ToString(); - answ.needStatusRefresh = true; - return answ; - } - /// - /// scrive una riga di stato nel diario di bordo - /// - /// codice macchina - /// idx stato - /// Codice Articolo - /// valore - /// matricola operatore - /// pallet (vuoto se nd) - /// data-ora dell'evento - /// data-ora corrente dell'invio - /// - public inputComandoMapo scriviRigaStato(string IdxMacchina, int IdxStato, string CodArticolo, string Value, int MatrOpr, string pallet, DateTime eventTime, DateTime currentTime) - { - int inserito = 0; - try - { - // verifico se esista la macchina altrimenti la creo... - verificaIdxMacchina(IdxMacchina); - // calcolo dataOra reale (evento + delta(ora server - ora remota) - DateTime dataOra = eventTime.Add(DateTime.Now - currentTime); - // inserisco la nuova riga di stato mentre il trigger aggiorna le tab... - inserito = MapoDbObj.taDiario.Insert(IdxMacchina, dataOra, null, IdxStato, null, Value, CodArticolo, null, null, MatrOpr, pallet); - } - catch - { - logger.lg.scriviLog(string.Format("Errore in fase di scrittura stato con i seguenti dati:{0} macchina {1}{0} IdxStato {2}{0} CodArticolo {3}{0} Value {4}{0} MatrOpr {5}{0} Pallet {6}{0} eventTime {7}{0} currentTime {8}{0} eccezione: {0}{9}", Environment.NewLine, IdxMacchina, IdxStato, CodArticolo, Value, MatrOpr, pallet, eventTime, currentTime), tipoLog.EXCEPTION); - } - // formatto output - inputComandoMapo answ = new inputComandoMapo(); - answ.outValue = inserito.ToString(); - answ.needStatusRefresh = true; - return answ; - } - /// - /// rigenera la tab diario di bordo x la macchian richiesta nell'intervallo definito - /// - /// - /// - /// - public void rigeneraDiarioDiBordo(string IdxMacchina, DateTime dataInizio, DateTime dataFine) - { - // elimino da diario di bordo i valori nell'intervallo... - MapoDbObj.taDiario.DeleteByMacchinaPeriodo(IdxMacchina, dataInizio, dataFine); - // seleziono le righe eventi interessate e le processo 1 ad 1... - DS_applicazione.EventListDataTable tabEventi = MapoDbObj.taEvList.GetByMacchinaPeriodo(IdxMacchina, dataInizio, dataFine); - foreach (DS_applicazione.EventListRow rigaEv in tabEventi) - { - if (rigaEv.IdxTipo <= 12) // è barcode - { - checkCambiaStatoBatch(tipoInputEvento.barcode, IdxMacchina, rigaEv.InizioStato, rigaEv.IdxTipo, rigaEv.CodArticolo, rigaEv.Value, rigaEv.MatrOpr, rigaEv.pallet); + return answ; } - else // è hw + + /// + /// Processa registrazione ODL corrente x macchina + /// + /// + /// cod ODL in produzione, se "" --> non c'è... + /// + public string saveCurrODL(string idxMacchina, string currODL) { - checkCambiaStatoBatch(tipoInputEvento.hw, IdxMacchina, rigaEv.InizioStato, rigaEv.IdxTipo, rigaEv.CodArticolo, rigaEv.Value, rigaEv.MatrOpr, rigaEv.pallet); + if (currODL == null) + { + throw new ArgumentNullException(nameof(currODL)); + } + // registro conteggio impiego chiamate REDIS + if (memLayer.ML.CRB("IOB_RedEnab")) + { + saveCallRec("saveCurrODL"); + } + string answ = ""; + // inizio processing vero e proprio INPUT... + if (idxMacchina != null && currODL != null) + { + if (idxMacchina != "" && currODL != "") + { + int currOdlCacheDur = memLayer.ML.CRI("currOdlCacheDur"); + // se ODL fosse 0 USO DURATA CACHE 1/4... + if (currODL == "0") + { + currOdlCacheDur = currOdlCacheDur / 4; + } + memLayer.ML.setRSV(currODLHash(idxMacchina), currODL, currOdlCacheDur); + // registro in risposta che è andato tutto bene... + answ = "OK"; + } + else + { + string errore = string.Format("Errore: parametri macchina/currODL vuoti ({0}/{1})", idxMacchina, currODL); + logger.lg.scriviLog(errore, tipoLog.ERROR); + answ = errore; + } + } + else + { + string errore = "Errore: mancano parametri macchina/currODL"; + logger.lg.scriviLog(errore, tipoLog.ERROR); + answ = errore; + } + return answ; } - } - } - /// - /// salva il segnale di "microstato" - /// - /// idx macchina - /// valore ingresso - /// data-ora evento (server) - /// sequenza dati inviati - /// - public void saveSigLog(string idxMacchina, string valore, DateTime dtEve, string contatore) - { - int cont = 0; - try - { - cont = Convert.ToInt32(contatore); - } - catch { } - // 2017.07.11 se richiesto di NON usare singleton... riporto FUORI la gestione NUOVO oggetto - if (memLayer.ML.CRB("disable_singleton")) - { - // 2017.06.09 forzo init x errori "sovrapposizioni" - taSigLog = new DS_applicazioneTableAdapters.SignalLogTableAdapter(); - } - taSigLog.Insert(DateTime.Now, idxMacchina, valore, dtEve, cont); - } - /// - /// restituisce valore dell'ODL attivo (iniziato e NON concluso) - /// - /// - /// - public string getCurrODL(string idxMacchina) - { - string answ = ""; - // recupero con stored NUOVA... - DS_ProdTempi.ODLDataTable tabOdl = taODL.getByMacchina(idxMacchina); - if (tabOdl.Rows.Count > 0) - { - // solo SE ho idxODL (altrimenti loggo errore) - if (tabOdl[0].IdxODL > 0) + + /// + /// invia una mail al destinatario x linkare nuovi devices tramite URL + /// + /// + /// + /// + /// + public bool sendUserAuthEmail(string destinatario, string UserAuthKey, int idxDipendente) { - answ = tabOdl[0].IdxODL.ToString(); - answ = answ == "" ? "0" : answ; + bool fatto = false; + string smtpCli = ""; + string mittente = ""; + string oggetto = ""; + string userUrl = ""; + string baseUrl = ""; + string userWebUrl = ""; + string baseWebUrl = ""; + string corpo = ""; + try + { + // compongo la stringa + smtpCli = memLayer.ML.CRS("_smtpCli"); + mittente = memLayer.ML.CRS("_fromEmail"); + oggetto = "Link autorizzazione device per GPW"; + baseUrl = memLayer.ML.CRS("baseUrl"); + baseWebUrl = memLayer.ML.CRS("baseWebUrl"); + userUrl = string.Format("{2}jumper.aspx?UserAuthkey={0}&idxDipendente={1}", UserAuthKey, idxDipendente, baseUrl); + userWebUrl = string.Format("{2}jumper.aspx?UserAuthkey={0}&idxDipendente={1}", UserAuthKey, idxDipendente, baseWebUrl); + corpo = string.Format("Hai ricevuto questa email su richiesta tua o dell'Admin per poter procedere a registrare un (nuovo) devices con GPW:{0}
Per proseguire clicca sul link seguente(rete interna):
{0}{0}{1}{0}{0}

oppure sul link seguente (internet):
{0}{0}{2}{0}{0}

Team GPW Steamware", Environment.NewLine, userUrl, userWebUrl); + gestEmail.ge.mandaEmail(mittente, destinatario, oggetto, corpo); + fatto = true; + } + catch { } + return fatto; } - else + + /// + /// Invia email di avviso che ci sono dei TC da confermare + /// + /// + /// + public bool sendWarnTcChangeReq(string destinatario) { - answ = "0"; - logger.lg.scriviLog("[currODL] Errore in currODL x idxMacchina " + idxMacchina + ": IdxODL = 0"); + bool fatto = false; + string mittente = ""; + string oggetto = ""; + string pageUrl = ""; + string corpo = ""; + try + { + // compongo la stringa + mittente = memLayer.ML.CRS("_fromEmail"); + oggetto = memLayer.ML.CRS("oggettoChgTc"); + pageUrl = string.Format("{0}{1}", memLayer.ML.CRS("baseUrlAdmin"), memLayer.ML.CRS("pageUrlApprODL")); + corpo = string.Format(memLayer.ML.CRS("corpoChgTc"), Environment.NewLine, pageUrl); + if (memLayer.ML.CRB("_useAuthSmtp")) + { + gestEmail.geAuth.mandaEmail(mittente, destinatario, oggetto, corpo); + } + else + { + gestEmail.ge.mandaEmail(mittente, destinatario, oggetto, corpo); + } + fatto = true; + } + catch { } + return fatto; } - } - else - { - // se è empty --> 0!!! - answ = "0"; - } - // ultimo controllo su idxOdl... - answ = answ == "" ? "0" : answ; - // restituisco! - return answ; - } - #endregion + /// + /// SET elenco parametri correnti x IOB + /// + /// + /// + /// + public bool setCurrObjItems(string idxMacchina, List currValues) + { + bool answ = false; + if (currValues != null) + { + string serVal = JsonConvert.SerializeObject(currValues); + memLayer.ML.setRSV(currParametersHash(idxMacchina), serVal); + } + return answ; + } - #region scritture eventi simulati + /// + /// Salvataggio su della mappa di memoria dell'IOB x ulteriori impieghi + /// + /// + /// + /// + public bool setIobMemMap(string idxMacchina, plcMemMap currMemMap) + { + bool answ = false; + // se ho un area memoria valida... + if (currMemMap != null) + { + // salvo! + string serVal = JsonConvert.SerializeObject(currMemMap); + memLayer.ML.setRSV(memMapHash(idxMacchina), serVal); + } + return answ; + } - public int scriviRigaEventoSimulata(DateTime dataOra, string IdxMacchina, int IdxTipo, string CodArticolo, string Value, int MatrOpr, string pallet) - { - // verifico se esista la macchina altrimenti la creo... - verificaIdxMacchina(IdxMacchina); - // inserisco evento - int inserito = MapoDbObj.taEvList.Insert(IdxMacchina, dataOra, IdxTipo, CodArticolo, Value, MatrOpr, pallet); - return inserito; - } - public int scriviRigaStatoSimulata(DateTime dataOra, string IdxMacchina, int IdxStato, string CodArticolo, string Value, int MatrOpr, string pallet) - { - // verifico se esista la macchina altrimenti la creo... - verificaIdxMacchina(IdxMacchina); - // inserisco la nuova riga di stato mentre il trigger aggiorna le tab... - int inserito = MapoDbObj.taDiario.Insert(IdxMacchina, dataOra, null, IdxStato, null, Value, CodArticolo, null, null, MatrOpr, pallet); - return inserito; - } + /// + /// Effettua UPSERT elenco parametri correnti x IOB (se c'è UPDATE, se manca ADD) + /// + /// + /// + /// + public bool upsertCurrObjItems(string idxMacchina, List innovations) + { + bool answ = false; + if (innovations != null) + { + // leggo i valori attuali... + List actValues = getCurrObjItems(idxMacchina); + // per ogni valore passatomi faccio insert o update + foreach (var item in actValues) + { + // cerco nelle innovazioni SE CI SIA un valore act + objItem trovato = innovations.Find(obj => obj.uid == item.uid); + // se non trovato... + if (trovato == null) + { + // aggiungo + innovations.Add(item); + } + } + // serializzo e salvo + string serVal = JsonConvert.SerializeObject(innovations); + memLayer.ML.setRSV(currParametersHash(idxMacchina), serVal); + } + return answ; + } - public int scriviRigaEventoSimulata(DateTime dataOra, string IdxMacchina, int IdxTipo, string CodArticolo, string Value) - { - // verifico se esista la macchina altrimenti la creo... - verificaIdxMacchina(IdxMacchina); - // inserisco evento - int inserito = MapoDbObj.taEvList.Insert(IdxMacchina, dataOra, IdxTipo, CodArticolo, Value, 0, "-"); - return inserito; - } - public int scriviRigaStatoSimulata(DateTime dataOra, string IdxMacchina, int IdxStato, string CodArticolo, string Value) - { - // verifico se esista la macchina altrimenti la creo... - verificaIdxMacchina(IdxMacchina); - // inserisco la nuova riga di stato mentre il trigger aggiorna le tab... - int inserito = MapoDbObj.taDiario.Insert(IdxMacchina, dataOra, null, IdxStato, null, Value, CodArticolo, null, null, 0, "-"); - return inserito; - } + /// + /// Calcola l'effettivo valore da passare alla macchina a stati INGRESSI data conf Macchine2FamigliaIngressi + /// + /// + /// + /// + private string preProcInput(string idxMacchina, string valore) + { + string newVal = ""; + try + { + // variabili + int valINT = 0; + int BitFilt = 0; + int BSR = 0; + bool ExplodeBit = false; + int NumBit = 0; + int newValInt = 0; + // recupero parametri... + int.TryParse(mDatiMacchinaVal(idxMacchina, "BitFilt"), out BitFilt); + int.TryParse(mDatiMacchinaVal(idxMacchina, "BSR"), out BSR); + Boolean.TryParse(mDatiMacchinaVal(idxMacchina, "ExplodeBit"), out ExplodeBit); + int.TryParse(mDatiMacchinaVal(idxMacchina, "NumBit"), out NumBit); // non usato (x ora) + // recupero valore + valINT = int.Parse(valore, NumberStyles.HexNumber); + // filtro + newValInt = utility.bMaskInt(valINT, BitFilt); + // effettuo eventuale BitShiftRight + if (BSR > 0) + { + newValInt = newValInt >> BSR; + } + // effettuo eventuale esplosione in BIT esclusivi + if (ExplodeBit) + { + newValInt = Convert.ToInt32(1 << newValInt); + } + // riconverto a STRING HEX!!! + newVal = newValInt.ToString("X"); + } + catch + { + newVal = valore; + } - #endregion - } + return newVal; + } + + #region definizioni hash x REDIS + + /// + /// Hash dati MSE + /// + /// + public static string hMSE + { + get + { + return mHash(string.Format("hMSE_DATA")); + } + } + + /// + /// Hash dati tabella AnagStati macchina + /// + /// + public static string currAnagStatiMacc() + { + return mHash(string.Format("Anag:StatiMacc")); + } + + /// + /// Hash dati Current ODL x la macchina specificata + /// + /// + /// + public static string currODLHash(string idxMacchina) + { + return mHash(string.Format("CurrODL:{0}", idxMacchina)); + } + + /// + /// Hash dati Current ODL ROW x la macchina specificata + /// + /// + /// + public static string currOdlRowHash(string idxMacchina) + { + return mHash(string.Format("CurrOdlRow:{0}", idxMacchina)); + } + + /// + /// Hash dati CurrentParameters x la macchina specificata + /// + /// + /// + public static string currParametersHash(string idxMacchina) + { + return mHash(string.Format("CurrentParameters:{0}", idxMacchina)); + } + + /// + /// Hash dati Current StatoMacchina x la macchina specificata + /// + /// + /// + public static string currStatoMaccHash(string idxMacchina) + { + return mHash(string.Format("CurrStatoMacc:{0}", idxMacchina)); + } + + /// + /// Hash dati STATUS x la macchina specificata + /// + /// + /// + public static string dtMaccHash(string idxMacchina) + { + return mHash(string.Format("DtMac:{0}", idxMacchina)); + } + + /// + /// Hash dati EXE TASK x la macchina specificata + /// + /// + /// + public static string exeTaskHash(string idxMacchina) + { + return mHash(string.Format("ExeTask:{0}", idxMacchina)); + } + + /// + /// Hash dati relativi all'associazione macchina <--> IOB + /// + /// Macchina PRINCIPALE + /// + public static string hM2IOB(string IdxMacchina) + { + return mHash(string.Format("hM2IOB:{0}", IdxMacchina)); + } + + /// + /// Hash dati Macchine Multi SM Ingressi + /// + /// Macchina PRINCIPALE + /// + public static string hMSMI(string IdxMacchina) + { + return mHash(string.Format("hMSMI:{0}", IdxMacchina)); + } + + /// + /// Hash dati STATE MACHINE INGRESSI x la FAMIGLIA INGRESSI specificata (per completare poi manca singolo micro stato corrente + valore letto x definire chiave) + /// + /// + /// + public static string hSMI(int idxFamIn) + { + return mHash(string.Format("hSMI:{0}", idxFamIn)); + } + + /// + /// Hash dati BUFFER x la macchina specificata + /// + /// + /// + /// + public static string LiveBufferHash(string idxMacchina, string bufferName) + { + return mHash(string.Format("LIVE:{0}:{1}", idxMacchina, bufferName)); + } + + /// + /// Hash dati LIVE x la macchina specificata + /// + /// + /// + public static string LiveCurrValHash(string idxMacchina) + { + return mHash(string.Format("LIVE:{0}:CURR_VAL", idxMacchina)); + } + + /// + /// Hash dati MemoryMap x la macchina specificata + /// + /// + /// + public static string memMapHash(string idxMacchina) + { + return mHash(string.Format("MemMap:{0}", idxMacchina)); + } + + /// + /// Hash Redis contenente i dati MP di una specifico TYPE (es StatusMacchina, StateMachineIngressi, ...) + /// + /// + /// + public static string mHash(string dataType) + { + return memLayer.ML.redHash(dataType); + } + + /// + /// Hash dati OPT PARAMETERS x la macchina specificata + /// + /// + /// + public static string optParHash(string idxMacchina) + { + return mHash(string.Format("OptPar:{0}", idxMacchina)); + } + + /// + /// Hash dati COUNTER x la macchina specificata + /// + /// + /// + public static string pzCountHash(string idxMacchina) + { + return mHash(string.Format("PzCount:{0}", idxMacchina)); + } + + /// + /// Hash dati STATUS x la macchina specificata. + /// - dati ODL + /// - dati articolo + /// - dati produzione corrente + /// + /// + /// + public static string stMaccHash(string idxMacchina) + { + return mHash(string.Format("StMac:{0}", idxMacchina)); + } + + /// + /// Hash x VETO dello SPLIT ODL la macchina specificata + /// + /// + /// + public static string vetoSplitOdlMaccHash(string idxMacchina) + { + return mHash($"VetoOdlMacc:{idxMacchina}"); + } + + #endregion definizioni hash x REDIS + + #region gestione MSE + + /// + /// Dati MSE serializzati in REDIS (get/set) + /// + public string currMSE + { + get + { + string answ = ""; + logger.lg.scriviLog("Richiesta MSE da REDIS"); + answ = memLayer.ML.getRSV(hMSE); + return answ; + } + set + { + int MSE_cacheDuration = memLayer.ML.CRI("MSE_cacheDuration"); + memLayer.ML.setRSV(hMSE, value, MSE_cacheDuration); + } + } + + #endregion gestione MSE + + #region gestione task macchina + + /// + /// Aggiunge un task all'elenco di quelli salvati (in modalità upsert) + /// + /// + /// + /// + /// + public bool addTask4Machine(string idxMacchina, taskType taskKey, string taskVal) + { + bool answ = false; + string currHash = exeTaskHash(idxMacchina); + try + { + // leggo task attuali... + var currTask = mTaskMacchina(idxMacchina); + currTask[taskKey.ToString()] = taskVal; + answ = memLayer.ML.redSaveHashDict(currHash, currTask); + logger.lg.scriviLog($"Task ADD - idxMacchina: {idxMacchina} | taskKey: {taskKey.ToString()} | taskVal: {taskVal}"); + } + catch { } + return answ; + } + + /// + /// Restitusice elenco KVP dei TASK (da passare a IOB-WIN) per l'impianto indicato + /// + /// + /// + public Dictionary mTaskMacchina(string idxMacchina) + { + // hard coded dimensione vettore DatiMacchine + Dictionary answ = new Dictionary(); + // ORA recupero da memoria redis... + try + { + string currHash = exeTaskHash(idxMacchina); + answ = memLayer.ML.redGetHashDict(currHash); + } + catch (Exception exc) + { + logger.lg.scriviLog(string.Format("Errore in compilazione dati EXE TASK x Redis - idxMacchina {2}:{0}{1}", Environment.NewLine, exc, idxMacchina)); + } + return answ; + } + + /// + /// RIMUOVE un task dall'elenco di quelli salvati + /// + /// + /// + /// + public bool remTask4Machine(string idxMacchina, taskType taskKey) + { + bool answ = false; + string currHash = exeTaskHash(idxMacchina); + try + { + // leggo task attuali... + var currTask = mTaskMacchina(idxMacchina); + currTask.Remove(taskKey.ToString()); + memLayer.ML.redDelKey(currHash); + answ = memLayer.ML.redSaveHashDict(currHash, currTask); + logger.lg.scriviLog($"Task REM - idxMacchina: {idxMacchina} | taskKey: {taskKey.ToString()}"); + } + catch { } + return answ; + } + + #endregion gestione task macchina + + #region gestione OPT PARAMETERS macchina + + /// + /// Aggiunge un PARAMETRO OPZIONALE all'elenco di quelli salvati (in modalità upsert) + /// + /// + /// + /// + /// + public bool addOptPar4Machine(string idxMacchina, string taskKey, string taskVal) + { + bool answ = false; + string currHash = optParHash(idxMacchina); + try + { + // leggo task attuali... + var currVal = mOptParMacchina(idxMacchina); + currVal[taskKey] = taskVal; + answ = memLayer.ML.redSaveHashDict(currHash, currVal); + } + catch { } + return answ; + } + + /// + /// Restitusice elenco KVP dei TASK (da passare a IOB-WIN) per l'impianto indicato + /// + /// + /// + public Dictionary mOptParMacchina(string idxMacchina) + { + // hard coded dimensione vettore DatiMacchine + Dictionary answ = new Dictionary(); + // ORA recupero da memoria redis... + try + { + string currHash = optParHash(idxMacchina); + answ = memLayer.ML.redGetHashDict(currHash); + } + catch (Exception exc) + { + logger.lg.scriviLog(string.Format("Errore in compilazione dati OPT PARAM x Redis - idxMacchina {2}:{0}{1}", Environment.NewLine, exc, idxMacchina)); + } + return answ; + } + + /// + /// RIMUOVE un PARAMETRO OPZIONALE dall'elenco di quelli salvati + /// + /// + /// + /// + public bool remOptPar4Machine(string idxMacchina, string taskKey) + { + bool answ = false; + string currHash = optParHash(idxMacchina); + try + { + // leggo task attuali... + var currVal = mOptParMacchina(idxMacchina); + currVal.Remove(taskKey); + memLayer.ML.redDelKey(currHash); + answ = memLayer.ML.redSaveHashDict(currHash, currVal); + } + catch { } + return answ; + } + + #endregion gestione OPT PARAMETERS macchina + + #region gestione attrezzaggi + + /// + /// Effettua split ODL + /// + /// + /// + public string forceSplitOdl(string idxMacchina) + { + string answ = "KO"; + // verifico NON CI SIA un veto a NUOVI split... 2 min di default... + string redKey = vetoSplitOdlMaccHash(idxMacchina); + string rawData = memLayer.ML.getRSV(redKey); + if (string.IsNullOrEmpty(rawData)) + { + // registro VETO x altri split... 2 minuti + memLayer.ML.setRSV(redKey, $"Inizio SPLIT-ODL {DateTime.Now}", 300); + // proseguo + DS_ProdTempi.ODLDataTable currData = null; + DateTime adesso = DateTime.Now; + // chiamo metodo redis/db... + try + { + // recupero ODL corrente + currData = currODLRowTab(idxMacchina); + if (currData.Count > 0) + { + // registro un evento di inizio attrezzaggio (idxTipoEv = 2) + int idxEvento = 2; + logger.lg.scriviLog($"Invio evento ODL-SPLIT per macchina {idxMacchina}, evento {idxEvento}, articolo {currData[0].CodArticolo}", tipoLog.INFO); + inputComandoMapo resCmd = scriviRigaEventoBarcode(idxMacchina, idxEvento, currData[0].CodArticolo, "ODL-SPLIT", 0, "", adesso, adesso); + // attendo 1 sec + Thread.Sleep(1000); + adesso = DateTime.Now; + // chiamo splitOdl + MapoDbObj.taODL.splitODL(currData[0].IdxODL, 0, idxMacchina, currData[0].TCRichAttr, currData[0].PzPallet, $"Nuovo ODL da forceSplitOdl", true); + // attendo 1 sec + Thread.Sleep(1000); + adesso = DateTime.Now; + // registro fine ODL (idxTipoEv = 1) + idxEvento = 1; + logger.lg.scriviLog($"Invio evento FINE ODL-SPLIT per macchina {idxMacchina}, evento {idxEvento}, articolo {currData[0].CodArticolo}", tipoLog.INFO); + resCmd = scriviRigaEventoBarcode(idxMacchina, idxEvento, currData[0].CodArticolo, "ODL-START"); + // chiamo refresh MSE + taMSE.forceRecalc(0, idxMacchina); + // resetto stato macchina... + memLayer.ML.redDelKey(currStatoMaccHash(idxMacchina)); + answ = "OK"; + logger.lg.scriviLog($"Effettuato reset e ricalcoli x split ODL per macchina {idxMacchina}", tipoLog.INFO); + } + } + catch (Exception exc) + { + logger.lg.scriviLog($"Eccezione in forceSplitOdl{Environment.NewLine}{exc}", tipoLog.EXCEPTION); + } + } + return answ; + } + + #endregion gestione attrezzaggi + + #region gestione stato macchina + + /// + /// Elenco stati macchina + /// + /// + public DS_applicazione.AnagraficaStatiDataTable AnagraficaStati() + { + DS_applicazione.AnagraficaStatiDataTable answTab = null; + // cerco in cache... + string rCall = ""; + if (memLayer.ML.CRB("IOB_RedEnab")) + { + saveCallRec("hasAnagStati"); + try + { + rCall = memLayer.ML.getRSV(currAnagStatiMacc()); + if (!string.IsNullOrEmpty(rCall)) + { + answTab = JsonConvert.DeserializeObject(rCall); + } + else + { + //2020.01.31 nuovo obj x evitare concorrenza + MapoDb man = new MapoDb(); + answTab = man.taAnagSt.GetData(); + //answTab = MapoDbObj.taAnagSt.GetData(); + // salvo in redis... + rCall = JsonConvert.SerializeObject(answTab); + int anagrCacheDur = memLayer.ML.CRI("anagrCacheDur"); + memLayer.ML.setRSV(currAnagStatiMacc(), rCall, anagrCacheDur); + } + } + catch (Exception exc) + { + logger.lg.scriviLog($"Eccezione in recupero currODLRow{Environment.NewLine}{exc}", tipoLog.EXCEPTION); + } + } + else + { + answTab = MapoDbObj.taAnagSt.GetData(); + } + return answTab; + } + + /// + /// Restituisce il valore dell'intera RIGA stato macchina corrente (da redis o da DB se non trovata...) + /// + /// + /// + public DS_applicazione.StatoMacchineDataTable currSMTab(string idxMacchina) + { + DS_applicazione.StatoMacchineDataTable answTab = null; + string rCall = ""; + if (memLayer.ML.CRB("IOB_RedEnab")) + { + saveCallRec("hasStatoMacc"); + try + { + rCall = memLayer.ML.getRSV(currStatoMaccHash(idxMacchina)); + if (!string.IsNullOrEmpty(rCall)) + { + answTab = JsonConvert.DeserializeObject(rCall); + } + else + { + // 2020.01.31 uso nuovo oggetto connessione + MapoDb man = new MapoDb(); + answTab = man.currStatoMaccTab(idxMacchina); + //answTab = MapoDbObj.currStatoMaccTab(idxMacchina); + // salvo in redis... + rCall = JsonConvert.SerializeObject(answTab); + int currStatoMaccCacheDur = memLayer.ML.CRI("currStatoMaccCacheDur"); + memLayer.ML.setRSV(currStatoMaccHash(idxMacchina), rCall, currStatoMaccCacheDur); + } + } + catch (Exception exc) + { + logger.lg.scriviLog($"Eccezione in recupero currODLRow{Environment.NewLine}{exc}", tipoLog.EXCEPTION); + } + } + else + { + answTab = MapoDbObj.currStatoMaccTab(idxMacchina); + } + return answTab; + } + + #endregion gestione stato macchina + + #region gestione dati macchina + + /// + /// Restituisce il valore dell'ODL corrente (ODL deve esserci per gestione contapezzi, senza ODL NO invio/gestione ODL) + /// + /// + /// + public string currODL(string idxMacchina) + { + string answ = ""; + string rCall = ""; + if (memLayer.ML.CRB("IOB_RedEnab")) + { + saveCallRec("hasODL"); + try + { + rCall = memLayer.ML.getRSV(currODLHash(idxMacchina)); + if (rCall != null && rCall != "") + { + answ = rCall; + } + else + { + answ = getCurrODL(idxMacchina); + // salvo in redis... + saveCurrODL(idxMacchina, answ); + } + } + catch { } + } + return answ; + } + + /// + /// Restituisce il valore dell'ODL corrente (ODL deve esserci per gestione contapezzi, senza ODL NO invio/gestione ODL) + /// + /// + /// indica se forzare lettura da db (true) o meno + /// + public string currODL(string idxMacchina, bool forceDb) + { + string answ = ""; + // faccio comunque verifica se sia stato letto da poco il valore... x cui anche a fronte di richiesta lettura da DB per 3 sec tengo buono valore in cache redis... + string rKey = memLayer.ML.redHash($"ODL:{idxMacchina}"); + string _idxOdl = memLayer.ML.getRSV(rKey); + if (forceDb) + { + if (!string.IsNullOrEmpty(_idxOdl)) + { + answ = _idxOdl; + } + else + { + answ = getCurrODL(idxMacchina); + // salvo in redis... + saveCurrODL(idxMacchina, answ); + memLayer.ML.setRSV(rKey, answ, 3); + } + } + else + { + answ = currODL(idxMacchina); + } + return answ; + } + + /// + /// Restituisce il valore dell'intera RIGA ODL corrente (da redis o da DB se non trovata...) + /// + /// + /// + public DS_ProdTempi.ODLDataTable currODLRowTab(string idxMacchina) + { + DS_ProdTempi.ODLDataTable answTab = null; + string rCall = ""; + if (memLayer.ML.CRB("IOB_RedEnab")) + { + saveCallRec("hasODL_row"); + try + { + rCall = memLayer.ML.getRSV(currOdlRowHash(idxMacchina)); + if (!string.IsNullOrEmpty(rCall)) + { + answTab = JsonConvert.DeserializeObject(rCall); + } + else + { + // istanzio un NUOVO oggetto lettura + MapoDb connDb = new MapoDb(); + answTab = connDb.currODLTab(idxMacchina); + // salvo in redis... + rCall = JsonConvert.SerializeObject(answTab); + int currOdlRowCacheDur = memLayer.ML.CRI("currOdlRowCacheDur"); + memLayer.ML.setRSV(currOdlRowHash(idxMacchina), rCall, currOdlRowCacheDur); + } + } + catch (Exception exc) + { + logger.lg.scriviLog($"Eccezione in recupero currODLRow{Environment.NewLine}{exc}", tipoLog.EXCEPTION); + } + } + else + { + // istanzio un NUOVO oggetto lettura + MapoDb connDb = new MapoDb(); + answTab = connDb.currODLTab(idxMacchina); + } + return answTab; + } + + /// + /// Restituisce il valore booleano se la macchina sia abilitata all'input + /// + /// + /// + public bool insEnab(string idxMacchina) + { + bool answ = false; + if (memLayer.ML.CRB("IOB_RedEnab")) + { + saveCallRec("insEnabled"); + try + { + answ = Convert.ToBoolean(mDatiMacchinaVal(idxMacchina, "insEnabled")); + } + catch { } + } + // ...oppure dritto su DB + else + { + if (memLayer.ML.CRB("disable_singleton")) + { + // instanzio un nuovo oggetto MapoDb + MapoDb connDb = new MapoDb(); + answ = connDb.insEnabled(idxMacchina); + } + else + { + // leggo DB da singleton + answ = MapoDbObj.insEnabled(idxMacchina); + } + } + return answ; + } + + /// + /// Restituisce il valore booleano se la macchina sia di tipo MULTI (con più state machine x INGRESSI) + /// + /// + /// + public bool isMulti(string idxMacchina) + { + bool answ = false; + if (memLayer.ML.CRB("IOB_RedEnab")) + { + saveCallRec("isMulti"); + try + { + answ = Convert.ToBoolean(mDatiMacchinaVal(idxMacchina, "Multi") == "1"); + } + catch { } + } + // ...oppure dritto su DB + else + { + answ = MapoDbObj.isMulti(idxMacchina); + } + return answ; + } + + /// + /// Restitusice elenco KVP dei campi DatiMacchine + StatoMacchine per l'impianto indicato + /// + /// + /// + public Dictionary mDatiMacchine(string idxMacchina) + { + // hard coded dimensione vettore DatiMacchine + Dictionary answ = new Dictionary(); + // ORA recupero da memoria redis... + try + { + string currHash = dtMaccHash(idxMacchina); + answ = memLayer.ML.redGetHashDict(currHash); + // se è vuoto... leggo da DB e popolo! + if (answ.Count == 0) + { + answ = resetDatiMacchina(idxMacchina); + } + } + catch (Exception exc) + { + logger.lg.scriviLog(string.Format("Errore in compilazione dati Macchine x Redis - idxMacchina {2}:{0}{1}", Environment.NewLine, exc, idxMacchina)); + } + return answ; + } + + /// + /// Restituisce il contapezzi salvato per la macchina + /// + /// + /// + public int pzCounter(string idxMacchina) + { + int answ = -1; + string rCall = ""; + if (memLayer.ML.CRB("IOB_RedEnab")) + { + saveCallRec("getCounter"); + try + { + rCall = memLayer.ML.getRSV(pzCountHash(idxMacchina)); + if (rCall != "" && rCall != null) + { + int.TryParse(rCall, out answ); + } + else + { + answ = pzCounterTC(idxMacchina); + // salvo in redis... + saveCounter(idxMacchina, answ.ToString()); + } + } + catch { } + } + return answ; + } + + /// + /// Restituisce il contapezzi come CONTEGGIO da TCRilevati per la macchina + /// + /// + /// + public int pzCounterTC(string idxMacchina) + { + int answ = -1; + if (memLayer.ML.CRB("IOB_RedEnab")) + { + saveCallRec("getCounterTC"); + } + // variabile x controllo dati recuperati + DS_ProdTempi.StatoProdDataTable datiProdAct = null; + bool okDatiProd = false; + int taSP_ms_ant = memLayer.ML.cdvi("taStatoProd_ms_anticipo"); + DateTime dataRif = DateTime.Now.AddMilliseconds(-taSP_ms_ant); + okDatiProd = getStatoProd(idxMacchina, ref datiProdAct, dataRif); + // se NON avesse recuperato --> aspetto taSP_ms_ant e poi RICHIAMO procedura... + int maxTry = 3; + while (!okDatiProd && maxTry > 0) + { + logger.lg.scriviLog(string.Format("[pzCounterTC] Impossibile recuperare dati ODL x idxMacchina {0}", idxMacchina), tipoLog.WARNING); + // sleep... + Thread.Sleep(taSP_ms_ant * 2); + // riprovo lettura... + okDatiProd = getStatoProd(idxMacchina, ref datiProdAct, dataRif); + maxTry--; + } + + // ora proseguo SE ho trovato i dati... + if (okDatiProd) + { + if (datiProdAct != null) + { + if (datiProdAct.Count > 0) + { + if (!datiProdAct[0].IsPzTotODLNull()) + { + // ...a questo punto recupero DAVVERO i dati (o almeno ci provo...) + try + { + // controllo + answ = datiProdAct[0].PzTotODL; + } + catch (Exception exc) + { + logger.lg.scriviLog(string.Format("[pzCounterTC] Eccezione in recupero PzTotODL x idxMacchina {0}{1}{2}", idxMacchina, Environment.NewLine, exc), tipoLog.EXCEPTION); + } + } + } + } + } + else + { + logger.lg.scriviLog(string.Format("[pzCounterTC] Dati ODL x idxMacchina {0} non recuperati dopo tentativi reiterati...", idxMacchina), tipoLog.WARNING); + } + return answ; + } + + /// + /// Resetta (rileggendo) i dati della macchina + /// + /// + /// + public Dictionary resetDatiMacchina(string idxMacchina) + { + string currHash = dtMaccHash(idxMacchina); + // inizio con un bel reset... + memLayer.ML.redFlushKey(currHash); + Dictionary answ = new Dictionary(); + 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) + { + logger.lg.scriviLog(string.Format("Errore in compilazione dati MSFD:{0}{1}", Environment.NewLine, exc), tipoLog.EXCEPTION); + } + // 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) + { + logger.lg.scriviLog($"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 + { + logger.lg.scriviLog("Errore in chiamata stp_MSFD_getMacc (connDb.taMSFD.getByIdxMacc(idxMacchina))"); + } + return answ; + } + + /// + /// Restituisce il valore booleano se la macchina sia abilitata all'inserimento COMPLETO nel Signal Log + /// + /// + /// + public bool sLogEnab(string idxMacchina) + { + bool answ = false; + if (memLayer.ML.CRB("IOB_RedEnab")) + { + saveCallRec("sLogEnabled"); + try + { + answ = Convert.ToBoolean(mDatiMacchinaVal(idxMacchina, "sLogEnabled")); + } + catch { } + } + // ...oppure dritto su DB + else + { + answ = MapoDbObj.sLogEnabled(idxMacchina); + } + return answ; + } + + /// + /// Recupero dati stato prod da macchina... + /// + /// + /// + /// + /// + private bool getStatoProd(string idxMacchina, ref DS_ProdTempi.StatoProdDataTable datiProdAct, DateTime dataRif) + { + bool answ = false; + try + { + // recupero con stored NUOVA... + //2020.01.31 NUOVO oggetto (NON singleton) + DataLayer man = new DataLayer(); + datiProdAct = man.taStatoProd.GetData(idxMacchina, dataRif); + if (datiProdAct.Rows.Count > 0) + { + // solo SE ho idxODL (altrimenti loggo errore) + if (datiProdAct[0].IdxOdl > 0) + { + answ = true; + } + else + { + // verifico se ho già questo errore attivo IN REDIS (altrimenti reinvio) + logger.lg.scriviLog($"pzCounterTC: Non trovato currODL x idxMacchina {idxMacchina} ", $"idxMacchina {idxMacchina} | IdxOdl {datiProdAct[0].IdxOdl} | pzTot {datiProdAct[0].PzTotODL} | dataRif {dataRif}", tipoLog.WARNING); + } + } + else + { + logger.lg.scriviLog($"pzCounterTC: Non trovate righe in currODL {idxMacchina}", $"Non trovate righe in currODL x idxMacchina {idxMacchina}: datiProdAct vuota", tipoLog.WARNING); + } + } + catch (Exception exc) + { + logger.lg.scriviLog($"[pzCounterTC] Eccezione in pzCounterTC x idxMacchina {idxMacchina}", $"[pzCounterTC] Eccezione in pzCounterTC x idxMacchina {idxMacchina}{Environment.NewLine}{exc}", tipoLog.EXCEPTION); + } + return answ; + } + + #endregion gestione dati macchina + + #region gestione State Machine Ingressi + + /// + /// Recupera (da DB) i dati della State Machine multi ingressi nel formato + /// key: IdxMacchina + /// value: IdxFamigliaIngresso + /// + /// + /// + public KeyValuePair[] getMSMI_DB(string idxMacchina) + { + DS_applicazione.MSFDDataTable tabMSMI = new DS_applicazione.MSFDDataTable(); + // 2017.09.13: inserisco gestione singleton condizionale + if (memLayer.ML.CRB("disable_singleton")) + { + // instanzio un nuovo oggetto MapoDb + MapoDb connDb = new MapoDb(); + tabMSMI = connDb.taMSFD.getMulti(idxMacchina); + } + else + { + // leggo DB da singleton + tabMSMI = MapoDbObj.taMSFD.getMulti(idxMacchina); + } + KeyValuePair[] answ = new KeyValuePair[tabMSMI.Count]; + // salvo tutti i valori StateMachineIngressi... + int i = 0; + foreach (var item in tabMSMI) + { + answ[i] = new KeyValuePair(item.IdxMacchina, item.IdxFamigliaIngresso.ToString()); + i++; + } + return answ; + } + + /// + /// Restituisce valore di una singola chiave del dizionario DatiMacchina + /// + /// + /// + /// + public string mDatiMacchinaVal(string idxMacchina, string chiave) + { + string answ = ""; + try + { + answ = mDatiMacchine(idxMacchina)[chiave]; + } + catch { } + return answ; + } + + /// + /// Restitusice elenco KVP + /// key: IdxMacchina + /// value: IdxFamigliaIngresso + /// + /// + /// + public KeyValuePair[] mTabMSMI(string idxMacchina) + { + // hard coded dimensione vettore DatiMacchine + KeyValuePair[] answ = new KeyValuePair[1]; + // iniziualizzo con un valore... 0/0 + answ[0] = new KeyValuePair("0", "0"); + // ORA recupero da memoria redis... + try + { + string currHash = hMSMI(idxMacchina); + answ = memLayer.ML.redGetHash(currHash); + // se è vuoto... leggo da DB e popolo! + if (answ.Length == 0) + { + answ = resetMSMI(idxMacchina); + } + } + catch (Exception exc) + { + logger.lg.scriviLog(string.Format("Errore in compilazione Tabella Multi State Machine Ingressi x Redis:{0}{1}", Environment.NewLine, exc)); + } + return answ; + } + + /// + /// Restitusice elenco KVP dei campi della State Machine ingressi nel formato + /// key: cState_nVal (current MICRO-STATE + "_" + new Value) + /// value: iTipoEv_nState (IdxTipoEv da trasmettere + New MICRO-STATE + /// + /// + /// + public KeyValuePair[] mTabSMI(int idxFamIn) + { + // hard coded dimensione vettore DatiMacchine + KeyValuePair[] answ = new KeyValuePair[1]; + // iniziualizzo con un valore... 0/0 + answ[0] = new KeyValuePair("0", "0"); + // ORA recupero da memoria redis... + try + { + string currHash = hSMI(idxFamIn); + answ = memLayer.ML.redGetHash(currHash); + // se è vuoto... leggo da DB e popolo! + if (answ.Length == 0) + { + answ = resetSMI(idxFamIn); + } + } + catch (Exception exc) + { + logger.lg.scriviLog(string.Format("Errore in compilazione State Machine Ingressi x Redis:{0}{1}", Environment.NewLine, exc)); + } + return answ; + } + + /// + /// Resetta (rileggendo) i dati della State Machine multi ingressi nel formato + /// key: IdxMacchina + /// value: IdxFamigliaIngresso + /// + /// + /// + public KeyValuePair[] resetMSMI(string idxMacchina) + { + string currHash = hMSMI(idxMacchina); + DS_applicazione.MSFDDataTable tabMSMI = new DS_applicazione.MSFDDataTable(); + // 2017.09.13: inserisco gestione singleton condizionale + if (memLayer.ML.CRB("disable_singleton")) + { + // instanzio un nuovo oggetto MapoDb + MapoDb connDb = new MapoDb(); + tabMSMI = connDb.taMSFD.getMulti(idxMacchina); + } + else + { + // leggo DB da singleton + tabMSMI = MapoDbObj.taMSFD.getMulti(idxMacchina); + } + KeyValuePair[] answ = new KeyValuePair[tabMSMI.Count]; + // salvo tutti i valori StateMachineIngressi... + int i = 0; + foreach (var item in tabMSMI) + { + answ[i] = new KeyValuePair(item.IdxMacchina, item.IdxFamigliaIngresso.ToString()); + i++; + } + // verifico il timeout (default 60 sec...) + int tOut = (memLayer.ML.cdvi("TmOut.MSMI") <= 0) ? 60 : memLayer.ML.cdvi("TmOut.MSMI"); + // salvo in redis! + memLayer.ML.redSaveHash(currHash, answ, tOut); + return answ; + } + + /// + /// Resetta (rileggendo) i dati della State Machine ingressi nel formato + /// key: cState_nVal (current MICRO-STATE + "_" + new Value) + /// value: iTipoEv_nState (IdxTipoEv da trasmettere + New MICRO-STATE) + /// + /// + /// + public KeyValuePair[] resetSMI(int idxFamIn) + { + string currHash = hSMI(idxFamIn); + DS_applicazione.TransizioneIngressiDataTable tabSMI = new DS_applicazione.TransizioneIngressiDataTable(); + // 2017.09.13: inserisco gestione singleton condizionale + if (memLayer.ML.CRB("disable_singleton")) + { + // instanzio un nuovo oggetto MapoDb + MapoDb connDb = new MapoDb(); + tabSMI = connDb.taTransIngr.getByIdxFamIng(idxFamIn); + } + else + { + // leggo DB da singleton + tabSMI = MapoDbObj.taTransIngr.getByIdxFamIng(idxFamIn); + } + KeyValuePair[] answ = new KeyValuePair[tabSMI.Count]; + // salvo tutti i valori StateMachineIngressi... + int i = 0; + string key = ""; + string val = ""; + foreach (var item in tabSMI) + { + key = string.Format("{0}_{1}", item.IdxMicroStato, item.ValoreIngresso); + val = string.Format("{0}_{1}", item.IdxTipoEvento, item.next_IdxMicroStato); + answ[i] = new KeyValuePair(key, val); + i++; + } + // verifico il timeout (default 60 sec...) + int tOut = (memLayer.ML.cdvi("TmOut.SMI") <= 0) ? 60 : memLayer.ML.cdvi("TmOut.SMI"); + // salvo in redis! + memLayer.ML.redSaveHash(currHash, answ, tOut); + return answ; + } + + /// + /// Restituisce il valore SPECIFICATO per la state machine ingressi + /// value: iTipoEv_nState (IdxTipoEv da trasmettere + New MICRO-STATE) + /// + /// + /// + /// + /// + public string valoreSMI(int idxFamIn, int idxMicroStato, int valoreIn) + { + string currHash = hSMI(idxFamIn); + string field = string.Format("{0}_{1}", idxMicroStato, valoreIn); + return memLayer.ML.redGetHashField(currHash, field); + } + + #endregion gestione State Machine Ingressi + + #endregion utility public esposte + + #region metodi spostati da MapoDB + + /// + /// controlla se da il segnale di "microstato" deriva un evento da generare - modalità OFFLINE + /// + /// idx macchina + /// valore ingresso + /// data-ora evento (server) + /// sequenza dati inviati + /// + public inputComandoMapo checkMicroStato(string idxMacchina, string valore, DateTime dtEve, string contatore) + { + int _logLevel = memLayer.ML.CRI("_logLevel"); + // recupero SE IMPIEGATO REDIS i valori del Dictionary della macchina... + Dictionary datiMacc = mDatiMacchine(idxMacchina); + + if (_logLevel > 6) + { + logger.lg.scriviLog(string.Format("[ChkMiSt]{2}---------------------------{2}Richiesta verifica INPUT per Macchina {0}, seriale {1}", idxMacchina, valore, Environment.NewLine), tipoLog.INFO); + } + // formatto output + inputComandoMapo answ = new inputComandoMapo(); + DS_applicazione.TransizioneIngressiDataTable TabTransIn; + DS_applicazione.TransizioneIngressiRow rigaTransIn = null; + // verifico se esista la macchina altrimenti la creo... REDIS compliant + verificaIdxMacchina(idxMacchina); + string CodArticolo = ""; + if (memLayer.ML.CRB("IOB_RedEnab")) + { + try + { + // esecuzione in REDIS + CodArticolo = datiMacc["CodArticolo"]; + } + catch { } + } + // ...oppure dritto su DB + else + { + // esecuzione in DB... + // recupero CodArticolo corretto + try + { + // 2017.07.11 se richiesto di NON usare singleton... riporto FUORI la gestione NUOVO oggetto + if (memLayer.ML.CRB("disable_singleton")) + { + // 2017.07.10 forzo init x errori "sovrapposizioni" + taDatiMacchine = new DS_ProdTempiTableAdapters.DatiMacchineTableAdapter(); + } + CodArticolo = taDatiMacchine.getByIdx(idxMacchina)[0].CodArticolo_A; + } + catch (Exception exc) + { + logger.lg.scriviLog(string.Format("[ChkMiSt_4a] - Eccezione in recupero CodArticolo:{0}{1}", Environment.NewLine, exc), tipoLog.EXCEPTION); + } + } + // recupero next microstato + int? valINT = 0; + try + { + valINT = int.Parse(valore, System.Globalization.NumberStyles.HexNumber); + // esecuzione in REDIS... + if (memLayer.ML.CRB("IOB_RedEnab")) + { + try + { + int idxFamIn = Convert.ToInt32(datiMacc["IdxFamIn"]); + int idxMicroStato = Convert.ToInt32(datiMacc["IdxMicroStato"]); + int valIOB = Convert.ToInt32(valINT); + int idxTipoEv = 0; + int next_idxMS = idxMicroStato; + // verifico esistenza tab SMI... + string fiHASH = DataLayer.hSMI(idxFamIn); + string todoSMI = ""; + bool trovato = memLayer.ML.redHashPresentSz(fiHASH); + if (!trovato) + { + // ricarico tabella! + KeyValuePair[] valori = mTabSMI(idxFamIn); + } + // recupero singolo valore (stringa) x chiave + todoSMI = valoreSMI(idxFamIn, idxMicroStato, valIOB); + // solo se ho trovato un risultato nella tab SMI della famiglia macchina... + if (todoSMI != "") + { + // splitto e salvo valori OUT... + string[] valori = todoSMI.Split('_'); + idxTipoEv = Convert.ToInt32(valori[0]); + next_idxMS = Convert.ToInt32(valori[1]); + // creo la riga tipizzatya dai dati di redis x procedere... + DS_applicazione.TransizioneIngressiDataTable tab = new DS_applicazione.TransizioneIngressiDataTable(); + rigaTransIn = tab.NewTransizioneIngressiRow(); + rigaTransIn.IdxFamigliaIngresso = idxFamIn; + rigaTransIn.IdxMicroStato = idxMicroStato; + rigaTransIn.ValoreIngresso = valIOB; + rigaTransIn.IdxTipoEvento = idxTipoEv; + rigaTransIn.next_IdxMicroStato = next_idxMS; + } + } + catch { } + } + // ...oppure dritto su DB + else + { + // 2017.07.11 se richiesto di NON usare singleton... riporto FUORI la gestione NUOVO oggetto + if (memLayer.ML.CRB("disable_singleton")) + { + // 2017.06.09 forzo init x errori "sovrapposizioni" + MapoDbObj.taTransIngr = new DS_applicazioneTableAdapters.TransizioneIngressiTableAdapter(); + } + TabTransIn = MapoDbObj.taTransIngr.getByIdxMacchinaValore(idxMacchina, valINT); + if (TabTransIn.Rows.Count > 0) + { + rigaTransIn = TabTransIn[0]; + } + } + } + catch (Exception exc) + { + logger.lg.scriviLog(string.Format("[ChkMiSt_5a] - - Eccezione in recupero riga Trans ingressi per idxMacchina {3} e valore {2}:{0}{1}", Environment.NewLine, exc, valINT, idxMacchina), tipoLog.EXCEPTION); + } + // effettuo update vari SU DB!!! + if (rigaTransIn != null) + { + try + { + if (_logLevel > 5) + { + logger.lg.scriviLog(string.Format("[ChkMiSt_6a] - Salvo Update Microstato:{0}macchina: {1} | valore seriale: {2} | next micro stato: {3}", Environment.NewLine, idxMacchina, valINT, rigaTransIn.next_IdxMicroStato), tipoLog.INFO); + } + // 2017.07.11 se richiesto di NON usare singleton... riporto FUORI la gestione NUOVO oggetto + if (memLayer.ML.CRB("disable_singleton")) + { + // 2017.06.09 forzo init x errori "sovrapposizioni" + MapoDbObj.taMSM = new DS_applicazioneTableAdapters.MicroStatoMacchinaTableAdapter(); + } + // salvo nuovo microstato... + MapoDbObj.taMSM.updateQuery(rigaTransIn.next_IdxMicroStato, dtEve, valore, idxMacchina); + // controllo se c'è evento + if (rigaTransIn.IdxTipoEvento > 0) + { + if (_logLevel > 5) + { + logger.lg.scriviLog(string.Format("[ChkMiSt_7a] - Salvo evento:{0}macchina: {1} | tipoEvento: {2} | CodArticolo: {3} | contatore: {4} | valore: {5}", Environment.NewLine, idxMacchina, rigaTransIn.IdxTipoEvento, CodArticolo, contatore, valore), tipoLog.INFO); + } + string valEsteso = string.Format("[{0}] {1}", contatore.PadLeft(3, '0'), valore); + // aggiunto contatore! + answ = scriviRigaEvento(idxMacchina, rigaTransIn.IdxTipoEvento, CodArticolo, valEsteso, 0, "-", dtEve, DateTime.Now); + // 2017.09.12 SE era in modalità redis RICARICA dati macchina... + if (memLayer.ML.CRB("IOB_RedEnab")) + { + resetDatiMacchina(idxMacchina); + } + if (_logLevel > 5) + { + logger.lg.scriviLog(string.Format("[ChkMiSt_a] - Macchina {0} | seriale(INT) {1} | valEsteso {3} | answ {4}{2}---------------------------{2}", idxMacchina, valINT, Environment.NewLine, valEsteso, answ), tipoLog.INFO); + } + } + } + catch (Exception exc) + { + logger.lg.scriviLog(string.Format("[ChkMiSt_8a] - Eccezione:{0}{1}", Environment.NewLine, exc), tipoLog.EXCEPTION); + } + } + return answ; + } + + /// + /// controlla se da il segnale di "microstato" deriva un evento da generare - modalità OFFLINE + /// + /// idx macchina + /// valore ingresso + /// data-ora evento (server) + /// + public inputComandoMapo checkMicroStato(string idxMacchina, string valore, DateTime dtEve) + { + if (memLayer.ML.CRI("_logLevel") > 6) + { + logger.lg.scriviLog(string.Format("{2}---------------------------{2}Richiesta verifica INPUT per Macchina {0}, seriale {1}", idxMacchina, valore, Environment.NewLine), tipoLog.INFO); + } + // formatto output + inputComandoMapo answ = new inputComandoMapo(); + DS_applicazione.TransizioneIngressiDataTable TabTransIn; + DS_applicazione.TransizioneIngressiRow rigaTransIn = null; + // verifico se esista la macchina altrimenti la creo... + verificaIdxMacchina(idxMacchina); + string CodArticolo = ""; + // recupero CodArticolo corretto + try + { + // 2017.07.10 forzo init x errori "sovrapposizioni" + taDatiMacchine = new DS_ProdTempiTableAdapters.DatiMacchineTableAdapter(); + CodArticolo = taDatiMacchine.getByIdx(idxMacchina)[0].CodArticolo_A; + } + catch (Exception exc) + { + logger.lg.scriviLog(string.Format("[ChkMiSt_4b] - Eccezione in recupero CodArticolo:{0}{1}", Environment.NewLine, exc), tipoLog.EXCEPTION); + } + // recupero next microstato + //int? valINT = Convert.ToInt32(valore); + int? valINT = 0; + try + { + // 2017.06.09 forzo init x errori "sovrapposizioni" + MapoDbObj.taTransIngr = new DS_applicazioneTableAdapters.TransizioneIngressiTableAdapter(); + valINT = int.Parse(valore, System.Globalization.NumberStyles.HexNumber); + TabTransIn = MapoDbObj.taTransIngr.getByIdxMacchinaValore(idxMacchina, valINT); + if (TabTransIn.Rows.Count > 0) + { + rigaTransIn = TabTransIn[0]; + } + } + catch (Exception exc) + { + logger.lg.scriviLog(string.Format("[ChkMiSt_5b] - Eccezione in recupero riga Trans ingressi per idxMacchina {3} e valore {2}:{0}{1}", Environment.NewLine, exc, valINT, idxMacchina), tipoLog.EXCEPTION); + } + int _logLevel = memLayer.ML.CRI("_logLevel"); + // effettuo update vari + if (rigaTransIn != null) + { + try + { + if (_logLevel > 5) + { + logger.lg.scriviLog(string.Format("[ChkMiSt_6b] - Salvo Update Microstato:{0}macchina: {1} | valore seriale: {2} | next micro stato: {3}", Environment.NewLine, idxMacchina, valINT, rigaTransIn.next_IdxMicroStato), tipoLog.INFO); + } + // salvo nuovo microstato... + MapoDbObj.taMSM.updateQuery(rigaTransIn.next_IdxMicroStato, dtEve, valore, idxMacchina); + // controllo se c'è evento + if (rigaTransIn.IdxTipoEvento > 0) + { + if (_logLevel > 5) + { + logger.lg.scriviLog(string.Format("[ChkMiSt_7b] - Salvo evento:{0}macchina: {1} | tipoEvento: {2} | CodArticolo: {3}", Environment.NewLine, idxMacchina, rigaTransIn.IdxTipoEvento, CodArticolo), tipoLog.INFO); + } + answ = scriviRigaEvento(idxMacchina, rigaTransIn.IdxTipoEvento, CodArticolo, valore, 0, "-", dtEve, DateTime.Now); + if (_logLevel > 5) + { + logger.lg.scriviLog(string.Format("[ChkMiSt_b] -Macchina {0}, seriale(INT) {1}{2}---------------------------{2}", idxMacchina, valINT, Environment.NewLine), tipoLog.INFO); + } + } + } + catch (Exception exc) + { + logger.lg.scriviLog(string.Format("[ChkMiSt_8b] - Eccezione:{0}{1}", Environment.NewLine, exc), tipoLog.EXCEPTION); + } + } + return answ; + } + + /// + /// controlla se da il segnale di "microstato" deriva un evento da generare + /// + /// + /// + /// + public inputComandoMapo checkMicroStato(string idxMacchina, string valore) + { + // wrapper ad ora corrente... + return checkMicroStato(idxMacchina, valore, DateTime.Now); + } + + /// + /// restituisce valore dell'ODL attivo (iniziato e NON concluso) + /// + /// + /// + public string getCurrODL(string idxMacchina) + { + string answ = ""; + // recupero con stored NUOVA... + DS_ProdTempi.ODLDataTable tabOdl = taODL.getByMacchina(idxMacchina); + if (tabOdl.Rows.Count > 0) + { + // solo SE ho idxODL (altrimenti loggo errore) + if (tabOdl[0].IdxODL > 0) + { + answ = tabOdl[0].IdxODL.ToString(); + answ = answ == "" ? "0" : answ; + } + else + { + answ = "0"; + logger.lg.scriviLog("[currODL] Errore in currODL x idxMacchina " + idxMacchina + ": IdxODL = 0"); + } + } + else + { + // se è empty --> 0!!! + answ = "0"; + } + // ultimo controllo su idxOdl... + answ = answ == "" ? "0" : answ; + // restituisco! + return answ; + } + + /// + /// restituisce una tabella con tutte le transizioni degli ingressi per una data macchina + /// + /// + /// + public DS_applicazione.TransizioneIngressiDataTable getMatriceIngressi(string idxMacchina) + { + DS_applicazione.TransizioneIngressiDataTable answ; + try + { + answ = taTranIngr.getMatriceByIdxMacchina(idxMacchina); + } + catch + { + answ = null; + } + return answ; + } + + /// + /// restituisce il TempoCiclo effettivo (tecnico) della macchina + /// + /// + /// + public decimal getTcEffMacchina(string idxMacchina) + { + decimal tc = 0; + try + { + DS_ProdTempi.stp_repDonati_getDatiProdMacchinaPeriodoRow riga = taDatiProdMacchPer.GetData(idxMacchina, DateTime.Now.AddMinutes(-30), DateTime.Now)[0]; + if (riga.TCEffRT > 0) + { + tc = riga.TCEffRT; + } + else + { + tc = riga.TCAssegnato; + } + } + catch { } + // imposto a 99'TC + if (tc == 0) + { + tc = 99.9M; + // scrivo log per indicare mancato caricamento dati tc dichiarato e conseguente errore sul timer - 2/11/2012 EN&CV + logger.lg.scriviLog(string.Format("Impostato TC Tempo Ciclo a 99' (99.9M) causa mancato inserimento tempo ciclo dichiarato")); + } + return tc; + } + + /// + /// rigenera la tab diario di bordo x la macchian richiesta nell'intervallo definito + /// + /// + /// + /// + public void rigeneraDiarioDiBordo(string IdxMacchina, DateTime dataInizio, DateTime dataFine) + { + // elimino da diario di bordo i valori nell'intervallo... + MapoDbObj.taDiario.DeleteByMacchinaPeriodo(IdxMacchina, dataInizio, dataFine); + // seleziono le righe eventi interessate e le processo 1 ad 1... + DS_applicazione.EventListDataTable tabEventi = MapoDbObj.taEvList.GetByMacchinaPeriodo(IdxMacchina, dataInizio, dataFine); + foreach (DS_applicazione.EventListRow rigaEv in tabEventi) + { + if (rigaEv.IdxTipo <= 12) // è barcode + { + checkCambiaStatoBatch(tipoInputEvento.barcode, IdxMacchina, rigaEv.InizioStato, rigaEv.IdxTipo, rigaEv.CodArticolo, rigaEv.Value, rigaEv.MatrOpr, rigaEv.pallet); + } + else // è hw + { + checkCambiaStatoBatch(tipoInputEvento.hw, IdxMacchina, rigaEv.InizioStato, rigaEv.IdxTipo, rigaEv.CodArticolo, rigaEv.Value, rigaEv.MatrOpr, rigaEv.pallet); + } + } + } + + /// + /// salva il segnale di "microstato" + /// + /// idx macchina + /// valore ingresso + /// data-ora evento (server) + /// sequenza dati inviati + /// + public void saveSigLog(string idxMacchina, string valore, DateTime dtEve, string contatore) + { + int cont = 0; + try + { + cont = Convert.ToInt32(contatore); + } + catch { } + // 2017.07.11 se richiesto di NON usare singleton... riporto FUORI la gestione NUOVO oggetto + if (memLayer.ML.CRB("disable_singleton")) + { + // 2017.06.09 forzo init x errori "sovrapposizioni" + taSigLog = new DS_applicazioneTableAdapters.SignalLogTableAdapter(); + } + taSigLog.Insert(DateTime.Now, idxMacchina, valore, dtEve, cont); + } + + /// + /// scrive una riga di evento nel db + /// + /// codice macchina + /// idx evento + /// Codice Articolo + /// valore + /// matricola operatore + /// pallet (vuoto se nd) + /// data-ora dell'evento + /// data-ora corrente dell'invio + /// + public inputComandoMapo scriviRigaEvento(string IdxMacchina, int IdxTipo, string CodArticolo, string Value, int MatrOpr, string pallet, DateTime eventTime, DateTime currentTime) + { + int inserito = 0; + // 2017.07.11 se richiesto di NON usare singleton... riporto FUORI la gestione NUOVO oggetto + if (memLayer.ML.CRB("disable_singleton")) + { + // 2017.06.09 forzo init x errori "sovrapposizioni" + MapoDbObj.taEvList = new DS_applicazioneTableAdapters.EventListTableAdapter(); + } + try + { + // verifico se esista la macchina altrimenti la creo... + verificaIdxMacchina(IdxMacchina); + // calcolo dataOra reale (evento + delta(ora server - ora remota) + DateTime dataOra = eventTime.Add(DateTime.Now - currentTime); + // inserisco evento + inserito = MapoDbObj.taEvList.Insert(IdxMacchina, dataOra, IdxTipo, CodArticolo, Value, MatrOpr, pallet); + // faccio controllo per eventuale cambio stato da tab transizioni... + checkCambiaStatoBatch(tipoInputEvento.hw, IdxMacchina, dataOra, IdxTipo, CodArticolo, Value, MatrOpr, pallet); + } + catch (Exception exc) + { + logger.lg.scriviLog(string.Format("Errore in fase di scrittura evento con i seguenti dati:{0} macchina {1}{0} IdxTipo {2}{0} CodArticolo {3}{0} Value {4}{0} MatrOpr {5}{0} Pallet {6}{0} eventTime {7}{0} currentTime {8}{0} eccezione: {0}{9}", Environment.NewLine, IdxMacchina, IdxTipo, CodArticolo, Value, MatrOpr, pallet, eventTime, currentTime, exc), tipoLog.EXCEPTION); + } + // formatto output + inputComandoMapo answ = new inputComandoMapo(); + answ.outValue = inserito.ToString(); + answ.needStatusRefresh = true; + return answ; + } + + /// + /// scrive una riga di evento nel db + /// + /// codice macchina + /// idx evento + /// Codice Articolo + /// valore + /// matricola operatore + /// pallet (vuoto se nd) + /// + public inputComandoMapo scriviRigaEvento(string IdxMacchina, int IdxTipo, string CodArticolo, string Value, int MatrOpr, string pallet) + { + int inserito = 0; + // 2017.06.09 forzo init x errori "sovrapposizioni" + MapoDbObj.taEvList = new DS_applicazioneTableAdapters.EventListTableAdapter(); + try + { + // verifico se esista la macchina altrimenti la creo... + verificaIdxMacchina(IdxMacchina); + DateTime dataOra = DateTime.Now; + // inserisco evento + inserito = MapoDbObj.taEvList.Insert(IdxMacchina, dataOra, IdxTipo, CodArticolo, Value, MatrOpr, pallet); + // faccio controllo per eventuale cambio stato da tab transizioni... + checkCambiaStatoBatch(tipoInputEvento.hw, IdxMacchina, dataOra, IdxTipo, CodArticolo, Value, MatrOpr, pallet); + } + catch (Exception exc) + { + logger.lg.scriviLog(string.Format("Errore in fase di scrittura evento con i seguenti dati:{0} macchina {1}{0} IdxTipo {2}{0} CodArticolo {3}{0} Value {4}{0} MatrOpr {5}{0} Pallet {6}{0} eccezione:{0}{7}", Environment.NewLine, IdxMacchina, IdxTipo, CodArticolo, Value, MatrOpr, pallet, exc), tipoLog.EXCEPTION); + } + // formatto output + inputComandoMapo answ = new inputComandoMapo(); + answ.outValue = inserito.ToString(); + answ.needStatusRefresh = true; + return answ; + } + + /// + /// scrive una riga di evento nel db SENZA passare operatore e pallet (mette a 0 e "-") + /// + /// codice macchina + /// idx evento + /// Codice Articolo + /// valore + /// + public inputComandoMapo scriviRigaEvento(string IdxMacchina, int IdxTipo, string CodArticolo, string Value) + { + int inserito = 0; + try + { + // verifico se esista la macchina altrimenti la creo... + verificaIdxMacchina(IdxMacchina); + DateTime dataOra = DateTime.Now; + // inserisco evento + inserito = MapoDbObj.taEvList.Insert(IdxMacchina, dataOra, IdxTipo, CodArticolo, Value, 0, "-"); + // faccio controllo per eventuale cambio stato da tab transizioni... + checkCambiaStatoBatch(tipoInputEvento.hw, IdxMacchina, dataOra, IdxTipo, CodArticolo, Value, 0, "-"); + } + catch + { + logger.lg.scriviLog(string.Format("Errore in fase di scrittura evento con i seguenti dati:{0} macchina {1}{0} IdxTipo {2}{0} CodArticolo {3}{0} Value {4}{0} eccezione: {0}{5}", Environment.NewLine, IdxMacchina, IdxTipo, CodArticolo, Value), tipoLog.EXCEPTION); + } + // formatto output + inputComandoMapo answ = new inputComandoMapo(); + answ.outValue = inserito.ToString(); + answ.needStatusRefresh = true; + return answ; + } + + /// + /// scrive una riga di evento inviato da Barcode nel db + /// + /// codice macchina + /// idx evento + /// Codice Articolo + /// valore + /// matricola operatore + /// pallet (vuoto se nd) + /// data-ora dell'evento + /// data-ora corrente dell'invio + /// + public inputComandoMapo scriviRigaEventoBarcode(string IdxMacchina, int IdxTipo, string CodArticolo, string Value, int MatrOpr, string pallet, DateTime eventTime, DateTime currentTime) + { + int inserito = 0; + try + { + // verifico se esista la macchina altrimenti la creo... + verificaIdxMacchina(IdxMacchina); + // calcolo dataOra reale (evento + delta(ora server - ora remota) + DateTime dataOra = eventTime.Add(DateTime.Now - currentTime); + // inserisco evento + inserito = MapoDbObj.taEvList.Insert(IdxMacchina, dataOra, IdxTipo, CodArticolo, Value, MatrOpr, pallet); + // faccio controllo per eventuale cambio stato da tab transizioni... + checkCambiaStatoBatch(tipoInputEvento.barcode, IdxMacchina, dataOra, IdxTipo, CodArticolo, Value, MatrOpr, pallet); + } + catch (Exception exc) + { + logger.lg.scriviLog(string.Format("Errore in fase di scrittura evento con i seguenti dati:{0} macchina {1}{0} IdxTipo {2}{0} CodArticolo {3}{0} Value {4}{0} MatrOpr {5}{0} Pallet {6}{0} eventTime {7}{0} currentTime {8}{0} eccezione: {0}{9}", Environment.NewLine, IdxMacchina, IdxTipo, CodArticolo, Value, MatrOpr, pallet, eventTime, currentTime, exc), tipoLog.EXCEPTION); + } + // formatto output + inputComandoMapo answ = new inputComandoMapo(); + answ.outValue = inserito.ToString(); + answ.needStatusRefresh = true; + return answ; + } + + /// + /// scrive una riga di evento inviato da Barcode nel db + /// + /// codice macchina + /// idx evento + /// Codice Articolo + /// valore + /// matricola operatore + /// pallet (vuoto se nd) + /// + public inputComandoMapo scriviRigaEventoBarcode(string IdxMacchina, int IdxTipo, string CodArticolo, string Value, int MatrOpr, string pallet) + { + int inserito = 0; + try + { + // verifico se esista la macchina altrimenti la creo... + verificaIdxMacchina(IdxMacchina); + DateTime dataOra = DateTime.Now; + // inserisco evento + inserito = MapoDbObj.taEvList.Insert(IdxMacchina, dataOra, IdxTipo, CodArticolo, Value, MatrOpr, pallet); + // faccio controllo per eventuale cambio stato da tab transizioni... + checkCambiaStatoBatch(tipoInputEvento.barcode, IdxMacchina, dataOra, IdxTipo, CodArticolo, Value, MatrOpr, pallet); + } + catch (Exception exc) + { + logger.lg.scriviLog(string.Format("Errore in fase di scrittura evento con i seguenti dati:{0} macchina {1}{0} IdxTipo {2}{0} CodArticolo {3}{0} Value {4}{0} MatrOpr {5}{0} Pallet {6}{0} eccezione: {0}{7}", Environment.NewLine, IdxMacchina, IdxTipo, CodArticolo, Value, MatrOpr, pallet, exc), tipoLog.EXCEPTION); + } + // formatto output + inputComandoMapo answ = new inputComandoMapo(); + answ.outValue = inserito.ToString(); + answ.needStatusRefresh = true; + return answ; + } + + /// + /// scrive una riga di evento inviato da Barcode nel db SENZA operatore e pallet (mette a 0 e "-") + /// + /// codice macchina + /// idx evento + /// Codice Articolo + /// valore + /// + public inputComandoMapo scriviRigaEventoBarcode(string IdxMacchina, int IdxTipo, string CodArticolo, string Value) + { + int inserito = 0; + try + { + // verifico se esista la macchina altrimenti la creo... + verificaIdxMacchina(IdxMacchina); + DateTime dataOra = DateTime.Now; + // inserisco evento + inserito = MapoDbObj.taEvList.Insert(IdxMacchina, dataOra, IdxTipo, CodArticolo, Value, 0, "-"); + // faccio controllo per eventuale cambio stato da tab transizioni... + checkCambiaStatoBatch(tipoInputEvento.barcode, IdxMacchina, dataOra, IdxTipo, CodArticolo, Value, 0, "-"); + } + catch + { + logger.lg.scriviLog(string.Format("Errore in fase di scrittura evento con i seguenti dati:{0} macchina {1}{0} IdxTipo {2}{0} CodArticolo {3}{0} Value {4}{0} eccezione: {0}{5}", Environment.NewLine, IdxMacchina, IdxTipo, CodArticolo, Value), tipoLog.EXCEPTION); + } + // formatto output + inputComandoMapo answ = new inputComandoMapo(); + answ.outValue = inserito.ToString(); + answ.needStatusRefresh = true; + return answ; + } + + /// + /// scrive una riga di stato nel diario di bordo + /// + /// codice macchina + /// idx stato + /// Codice Articolo + /// valore + /// matricola operatore + /// pallet (vuoto se nd) + /// data-ora dell'evento + /// data-ora corrente dell'invio + /// + public inputComandoMapo scriviRigaStato(string IdxMacchina, int IdxStato, string CodArticolo, string Value, int MatrOpr, string pallet, DateTime eventTime, DateTime currentTime) + { + int inserito = 0; + try + { + // verifico se esista la macchina altrimenti la creo... + verificaIdxMacchina(IdxMacchina); + // calcolo dataOra reale (evento + delta(ora server - ora remota) + DateTime dataOra = eventTime.Add(DateTime.Now - currentTime); + // inserisco la nuova riga di stato mentre il trigger aggiorna le tab... + inserito = MapoDbObj.taDiario.Insert(IdxMacchina, dataOra, null, IdxStato, null, Value, CodArticolo, null, null, MatrOpr, pallet); + } + catch + { + logger.lg.scriviLog(string.Format("Errore in fase di scrittura stato con i seguenti dati:{0} macchina {1}{0} IdxStato {2}{0} CodArticolo {3}{0} Value {4}{0} MatrOpr {5}{0} Pallet {6}{0} eventTime {7}{0} currentTime {8}{0} eccezione: {0}{9}", Environment.NewLine, IdxMacchina, IdxStato, CodArticolo, Value, MatrOpr, pallet, eventTime, currentTime), tipoLog.EXCEPTION); + } + // 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) + { + int _logLevel = memLayer.ML.CRI("_logLevel"); + 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) + { + logger.lg.scriviLog($"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... + logger.lg.scriviLog($"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) + { + logger.lg.scriviLog($"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! + logger.lg.scriviLog($"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; + } + } + + /// + /// cerca codice in anagrafica macchine ed eventualmente inserisce nuova macchina + /// + /// + private void verificaIdxMacchina(string IdxMacchina) + { + bool needDB = false; + if (!memLayer.ML.CRB("disable_verificaIdxMacchina")) + { + if (memLayer.ML.CRB("IOB_RedEnab")) + { + try + { + // esecuzione in REDIS...cerco status macchina... + if (mDatiMacchine(IdxMacchina).Count == 0) + { + needDB = true; + } + } + catch { } + } + // ...oppure segno richiesta DB... + else + { + needDB = true; + } + if (needDB) + { + // 2017.07.11 se richiesto di NON usare singleton... riporto FUORI la gestione NUOVO oggetto + if (memLayer.ML.CRB("disable_singleton")) + { + taMacchine = new DS_applicazioneTableAdapters.MacchineTableAdapter(); + MapoDbObj.taMSM = new DS_applicazioneTableAdapters.MicroStatoMacchinaTableAdapter(); + } + // verifico esistenza macchina + if (taMacchine.GetByIdx(IdxMacchina).Rows.Count == 0) + { + // inserisco nuova macchina... + taMacchine.Insert(IdxMacchina, "9999", IdxMacchina, "Macchina non codificata", "-", "http://", "nd", "col", 0, 0); + } + // verifico ci sia un microstato macchina... + if (MapoDbObj.taMSM.getByIdxMacchina(IdxMacchina).Rows.Count == 0) + { + // inserisco nuovo stato... + MapoDbObj.taMSM.Insert(IdxMacchina, 0, DateTime.Now, "00"); + } + } + } + } + + #endregion metodi spostati da MapoDB + + #region scritture eventi simulati + + public int scriviRigaEventoSimulata(DateTime dataOra, string IdxMacchina, int IdxTipo, string CodArticolo, string Value, int MatrOpr, string pallet) + { + // verifico se esista la macchina altrimenti la creo... + verificaIdxMacchina(IdxMacchina); + // inserisco evento + int inserito = MapoDbObj.taEvList.Insert(IdxMacchina, dataOra, IdxTipo, CodArticolo, Value, MatrOpr, pallet); + return inserito; + } + + public int scriviRigaEventoSimulata(DateTime dataOra, string IdxMacchina, int IdxTipo, string CodArticolo, string Value) + { + // verifico se esista la macchina altrimenti la creo... + verificaIdxMacchina(IdxMacchina); + // inserisco evento + int inserito = MapoDbObj.taEvList.Insert(IdxMacchina, dataOra, IdxTipo, CodArticolo, Value, 0, "-"); + return inserito; + } + + public int scriviRigaStatoSimulata(DateTime dataOra, string IdxMacchina, int IdxStato, string CodArticolo, string Value, int MatrOpr, string pallet) + { + // verifico se esista la macchina altrimenti la creo... + verificaIdxMacchina(IdxMacchina); + // inserisco la nuova riga di stato mentre il trigger aggiorna le tab... + int inserito = MapoDbObj.taDiario.Insert(IdxMacchina, dataOra, null, IdxStato, null, Value, CodArticolo, null, null, MatrOpr, pallet); + return inserito; + } + + public int scriviRigaStatoSimulata(DateTime dataOra, string IdxMacchina, int IdxStato, string CodArticolo, string Value) + { + // verifico se esista la macchina altrimenti la creo... + verificaIdxMacchina(IdxMacchina); + // inserisco la nuova riga di stato mentre il trigger aggiorna le tab... + int inserito = MapoDbObj.taDiario.Insert(IdxMacchina, dataOra, null, IdxStato, null, Value, CodArticolo, null, null, 0, "-"); + return inserito; + } + + #endregion scritture eventi simulati + } } + #if false ///