From 75ffa237d3a4dd859bfd38b68bb6bf172e349932 Mon Sep 17 00:00:00 2001 From: "Samuele E. Locatelli" Date: Thu, 1 Oct 2020 12:08:21 +0200 Subject: [PATCH] Fix simulazione NUOVO DoppioPallet --- IOB-UT/TCMan.cs | 286 +++++------ IOB-WIN/IobSimula.cs | 1172 ++++++++++++++++++++++-------------------- 2 files changed, 747 insertions(+), 711 deletions(-) diff --git a/IOB-UT/TCMan.cs b/IOB-UT/TCMan.cs index 9a42b2f9..b657707f 100644 --- a/IOB-UT/TCMan.cs +++ b/IOB-UT/TCMan.cs @@ -5,157 +5,157 @@ using System.Text; namespace IOB_UT { - /// - /// TCiclo management class - /// - public class TCMan - { - #region private obj - /// - /// Ultimo TCiclo osservato + /// TCiclo management class /// - protected double _lastTC { get; set; } = 0; - - /// - /// Contapezzi IOB - /// - protected int _pzCountIOB { get; set; } = 0; - - /// - /// Contapezzi PLC - /// - protected int _pzCountPLC { get; set; } = 0; - - /// - /// Fattore lambda (innovazione) per calcolo EWMA valore TCiclo corrente - /// - protected double lambda { get; set; } = 0.4; - - /// - /// Fattore massimo ammesso di delay x il TCiclo - /// - protected double maxDelayFactor { get; set; } = 1.2; - - /// - /// Incremento amssimo pezzi per cui fare calcolo del tempociclo attuale - /// - protected double maxIncrPz { get; set; } = 2; - - #endregion private obj - - #region contapezzi e TCiclo - - /// - /// Classe gestione TCiclo - /// - /// Fattore lambda x EWMA smooth - /// Massimo fattore ritardo TC x errore - /// Massimo incremento numPz x considerare calcolo TCiclo - public TCMan(double lambdaWeight, double maxDelayTcFact, double maxIncrPzCount) + public class TCMan { - lambda = lambdaWeight; - maxDelayFactor = maxDelayTcFact; - maxIncrPz = maxIncrPzCount; - } + #region private obj - /// - /// Indica se sia attivo allarme per TCiclo sopra soglia - /// - public bool alarmDelayTC - { - get - { - bool answ = false; - // solo se ho dei pezzi rilevati... - if (pzCountPLC > 0 && pzCountIOB > 0) + /// + /// Fattore lambda (innovazione) per calcolo EWMA valore TCiclo corrente + /// + protected double _lambda { get; set; } = 0.4; + + /// + /// Ultimo TCiclo osservato + /// + protected double _lastTC { get; set; } = 0; + + /// + /// Fattore massimo ammesso di delay x il TCiclo + /// + protected double _maxDelayFactor { get; set; } = 1.2; + + /// + /// Incremento amssimo pezzi per cui fare calcolo del tempociclo attuale + /// + protected double _maxIncrPz { get; set; } = 2; + + /// + /// Contapezzi IOB + /// + protected int _pzCountIOB { get; set; } = 0; + + /// + /// Contapezzi PLC + /// + protected int _pzCountPLC { get; set; } = 0; + + #endregion private obj + + #region contapezzi e TCiclo + + /// + /// Classe gestione TCiclo + /// + /// Fattore lambda x EWMA smooth + /// Massimo fattore ritardo TC x errore + /// Massimo incremento numPz x considerare calcolo TCiclo + public TCMan(double lambda, double maxDelayFactor, double maxIncrPz) { - answ = (currTC >= limitTC); + _lambda = lambda; + _maxDelayFactor = maxDelayFactor; + _maxIncrPz = maxIncrPz; } - return answ; - } - } - /// - /// Valore TCiclo medio attuale (EWMA) - /// - public double avgTC { get; set; } = 0; - - /// - /// TCiclo corrente - /// - public double currTC - { - get - { - DateTime adesso = DateTime.Now; - return adesso.Subtract(lastObservedData).TotalSeconds; - } - } - - /// - /// Ultimo dato (incremento PzCount) registrato - /// - public DateTime lastObservedData { get; set; } = DateTime.Now.AddMinutes(-1); - - /// - /// Ultimo TCiclo osservato - /// - public double lastTC - { - get - { - return _lastTC; - } - } - - /// - /// Limite allarme per il TCiclo (come media TCiclo * maxDelayFactor) - /// - /// - public double limitTC - { - get - { - return avgTC * maxDelayFactor; - } - } - - /// - /// Contapezzi IOB - /// - public int pzCountIOB { get; set; } = 0; - - /// - /// Contapezzi PLC - /// - public int pzCountPLC - { - get - { - return _pzCountPLC; - } - set - { - DateTime adesso = DateTime.Now; - int incrPz = value - _pzCountPLC; - if (incrPz > 0) + /// + /// Indica se sia attivo allarme per TCiclo sopra soglia + /// + public bool alarmDelayTC { - // calcolo lastTC... - _lastTC = adesso.Subtract(lastObservedData).TotalSeconds / incrPz; - // eseguo verifica x ricalcolo soglie... - bool validData = (incrPz) < maxIncrPz; - if (validData) - { - avgTC = lambda * lastTC + (1 - lambda) * avgTC; - } + get + { + bool answ = false; + // solo se ho dei pezzi rilevati... + if (pzCountPLC > 0 && pzCountIOB > 0) + { + answ = (currTC >= limitTC); + } + return answ; + } } - _pzCountPLC = value; - // aggiorno dato osservazione... - lastObservedData = adesso; - } - } - #endregion contapezzi e TCiclo - } + /// + /// Valore TCiclo medio attuale (EWMA) + /// + public double avgTC { get; set; } = 0; + + /// + /// TCiclo corrente + /// + public double currTC + { + get + { + DateTime adesso = DateTime.Now; + return adesso.Subtract(lastObservedData).TotalSeconds; + } + } + + /// + /// Ultimo dato (incremento PzCount) registrato + /// + public DateTime lastObservedData { get; set; } = DateTime.Now.AddMinutes(-1); + + /// + /// Ultimo TCiclo osservato + /// + public double lastTC + { + get + { + return _lastTC; + } + } + + /// + /// Limite allarme per il TCiclo (come media TCiclo * maxDelayFactor) + /// + /// + public double limitTC + { + get + { + return avgTC * _maxDelayFactor; + } + } + + /// + /// Contapezzi IOB + /// + public int pzCountIOB { get; set; } = 0; + + /// + /// Contapezzi PLC + /// + public int pzCountPLC + { + get + { + return _pzCountPLC; + } + set + { + DateTime adesso = DateTime.Now; + int incrPz = value - _pzCountPLC; + if (incrPz > 0) + { + // calcolo lastTC... + _lastTC = adesso.Subtract(lastObservedData).TotalSeconds / incrPz; + // eseguo verifica x ricalcolo soglie... + bool validData = (incrPz) < _maxIncrPz; + if (validData) + { + avgTC = _lambda * lastTC + (1 - _lambda) * avgTC; + } + } + _pzCountPLC = value; + // aggiorno dato osservazione... + lastObservedData = adesso; + } + } + + #endregion contapezzi e TCiclo + } } \ No newline at end of file diff --git a/IOB-WIN/IobSimula.cs b/IOB-WIN/IobSimula.cs index cfeef427..0dd69349 100644 --- a/IOB-WIN/IobSimula.cs +++ b/IOB-WIN/IobSimula.cs @@ -5,604 +5,640 @@ using System.Collections.Generic; namespace IOB_WIN { - public class IobSimula : IobGeneric - { - #region Protected Fields - - /// - /// Parametri simulazione oscillazione bit 2 - /// - protected simPar bit2; - - /// - /// Parametri simulazione oscillazione bit 3 - /// - protected simPar bit3; - - /// - /// Parametri simulazione oscillazione bit 4 - /// - protected simPar bit4; - - /// - /// Parametri simulazione oscillazione bit 5 - /// - protected simPar bit5; - - /// - /// pallet corrente - /// - protected int cP = 1; - - /// - /// ultimo controllo decremento eventi - /// - protected DateTime lastEvCheck; - - /// - /// Ultimo istante in cui sono stati generati dati di simulazione - /// - protected DateTime lastSimData; - - /// - /// Durata minima ODL x reset quando pezzi iob > pezzi macchina... - /// - protected int minDurataODL = 480; - - /// - /// pallet successivo (next) - /// - protected int nP = 1; - - /// - /// periodo base del simulatore (in millisecondi) - /// - protected int periodoMSec = 1000; - - /// - /// variabile di appoggio x stato segnale contapezzo - /// - protected bool sigPzCount = false; - - /// - /// BOOL: indica se simulare powerOn/Off (bit 0 e 1) compresi WarmUp e CoolDown - /// - protected bool simPowerOnOff; - - /// - /// Tempo di MINIMO attesa x simulazione parametri - /// - protected int waitSimPar = utils.CRI("waitSimPar"); - - #endregion Protected Fields - - /// - /// Ora spegniemnto (standard) - /// - public int tOff = 22; - - /// - /// Ora dia ccensione (standard) - /// - public int tOn = 6; - - /// - /// estende l'init della classe base... - /// - /// - /// - public IobSimula(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf) + public class IobSimula : IobGeneric { - // gestione invio ritardato contapezzi - pzCountDelay = utils.CRI("pzCountDelay"); - DateTime adesso = DateTime.Now; - lastPzCountSend = adesso; - lastWarnODL = adesso; - lastEvCheck = adesso; - lastSimData = adesso; - // sistemo parametri x simulazione... - if (cIobConf.optPar.Count > 0) - { - if (!string.IsNullOrEmpty(getOptPar("PER_BASE"))) + #region Protected Fields + + /// + /// Parametri simulazione oscillazione bit 2 + /// + protected simPar bit2; + + /// + /// Parametri simulazione oscillazione bit 3 + /// + protected simPar bit3; + + /// + /// Parametri simulazione oscillazione bit 4 + /// + protected simPar bit4; + + /// + /// Parametri simulazione oscillazione bit 5 + /// + protected simPar bit5; + + /// + /// Parametri simulazione oscillazione bit 6 + /// + protected simPar bit6; + + /// + /// Parametri simulazione oscillazione bit 7 + /// + protected simPar bit7; + + /// + /// pallet corrente + /// + protected int cP = 1; + + /// + /// ultimo controllo decremento eventi + /// + protected DateTime lastEvCheck; + + /// + /// Ultimo istante in cui sono stati generati dati di simulazione + /// + protected DateTime lastSimData; + + /// + /// Durata minima ODL x reset quando pezzi iob > pezzi macchina... + /// + protected int minDurataODL = 480; + + /// + /// pallet successivo (next) + /// + protected int nP = 1; + + /// + /// periodo base del simulatore (in millisecondi) + /// + protected int periodoMSec = 1000; + + /// + /// variabile di appoggio x stato segnale contapezzo + /// + protected bool sigPzCount = false; + + /// + /// BOOL: indica se simulare powerOn/Off (bit 0 e 1) compresi WarmUp e CoolDown + /// + protected bool simPowerOnOff; + + /// + /// Tempo di MINIMO attesa x simulazione parametri + /// + protected int waitSimPar = utils.CRI("waitSimPar"); + + #endregion Protected Fields + + /// + /// Ora spegniemnto (standard) + /// + public int tOff = 22; + + /// + /// Ora dia ccensione (standard) + /// + public int tOn = 6; + + /// + /// estende l'init della classe base... + /// + /// + /// + public IobSimula(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf) { - int.TryParse(getOptPar("PER_BASE"), out periodoMSec); - // aggiungo NOISE... +/- 20% - Random rnd = new Random(); - int noise = rnd.Next(1, periodoMSec / 5); - periodoMSec += noise - (periodoMSec / 10); + // gestione invio ritardato contapezzi + pzCountDelay = utils.CRI("pzCountDelay"); + DateTime adesso = DateTime.Now; + lastPzCountSend = adesso; + lastWarnODL = adesso; + lastEvCheck = adesso; + lastSimData = adesso; + // sistemo parametri x simulazione... + if (cIobConf.optPar.Count > 0) + { + if (!string.IsNullOrEmpty(getOptPar("PER_BASE"))) + { + int.TryParse(getOptPar("PER_BASE"), out periodoMSec); + // aggiungo NOISE... +/- 20% + Random rnd = new Random(); + int noise = rnd.Next(1, periodoMSec / 5); + periodoMSec += noise - (periodoMSec / 10); + } + simPowerOnOff = false; + bool.TryParse(getOptPar("SIM_POW_ON_OFF"), out simPowerOnOff); + int.TryParse(getOptPar("T_ON"), out tOn); + int.TryParse(getOptPar("T_OFF"), out tOff); + bit2 = setupSimPar("SIM_PZCNT"); + bit3 = setupSimPar("SIM_ALARM"); + bit4 = setupSimPar("SIM_MANU"); + bit5 = setupSimPar("SIM_SLOW"); + bit6 = setupSimPar("SIM_WUCD"); + bit7 = setupSimPar("SIM_EMRG"); + int.TryParse(getOptPar("MIN_DURATA_ODL"), out minDurataODL); + } + setParamPlc(); + // ricarico da server i dati dei pezzi fatti... + lgInfo("Init contapezzi SIMULA: pzCntReload(true)"); + if (!isMulti) + { + pzCntReload(true); + } + // imposto pezzi CNC ai pezzi contati da server... + contapezziPLC = contapezziIOB; + lgInfo($"Impostazione iniziale contatori: contapezzi macchina contapezziPLC: {contapezziPLC} | contapezziIOB: {contapezziIOB}"); } - simPowerOnOff = false; - bool.TryParse(getOptPar("SIM_POW_ON_OFF"), out simPowerOnOff); - int.TryParse(getOptPar("T_ON"), out tOn); - int.TryParse(getOptPar("T_OFF"), out tOff); - bit2 = setupSimPar("SIM_PZCNT"); - bit3 = setupSimPar("SIM_ALARM"); - bit4 = setupSimPar("SIM_MANU"); - bit5 = setupSimPar("SIM_SLOW"); - int.TryParse(getOptPar("MIN_DURATA_ODL"), out minDurataODL); - } - setParamPlc(); - // ricarico da server i dati dei pezzi fatti... - lgInfo("Init contapezzi SIMULA: pzCntReload(true)"); - if (!isMulti) - { - pzCntReload(true); - } - // imposto pezzi CNC ai pezzi contati da server... - contapezziPLC = contapezziIOB; - lgInfo($"Impostazione iniziale contatori: contapezzi macchina contapezziPLC: {contapezziPLC} | contapezziIOB: {contapezziIOB}"); - } - /// - /// Setup aprametri di simulazione per BIT indicato - /// - /// - private simPar setupSimPar(string keyName) - { - simPar answ = new simPar(); - if (cIobConf.optPar.Count > 0) - { - if (cIobConf.optPar.ContainsKey(keyName)) + /// + /// Effettua reset del contapezzi + /// + /// + public override bool resetcontapezziPLC() { - string fullVal = getOptPar(keyName); - if (!string.IsNullOrEmpty(fullVal) && fullVal.IndexOf("|") > 0) - { - string[] param = fullVal.Split('|'); - int.TryParse(param[0], out answ.wait); - int.TryParse(param[1], out answ.duration); - // aggiongo noise, +/- 40%... - Random rnd = new Random(); - int noise = rnd.Next(1, answ.wait * 40 / 100); - answ.wait += noise - (answ.wait * 20 / 100); - } + bool answ = false; + // ...SE abilitato da conf IOB + if (cIobConf.optPar.Count > 0 && getOptPar("ENABLE_PZ_RESET") == "TRUE") + { + // fingo di aver fatto... + answ = true; + } + return answ; } - } - return answ; - } - /// - /// Effettua reset del contapezzi - /// - /// - public override bool resetcontapezziPLC() - { - bool answ = false; - // ...SE abilitato da conf IOB - if (cIobConf.optPar.Count > 0 && getOptPar("ENABLE_PZ_RESET") == "TRUE") - { - // fingo di aver fatto... - answ = true; - } - return answ; - } - - public override void tryConnect() - { - base.tryConnect(); - connectionOk = true; - } - - public override void tryDisconnect() - { - base.tryDisconnect(); - connectionOk = false; - } - - #region Metodi specifici (da verificare/completare in implementazione) - - /// - /// Decodifica il resto dell'area x i dati accessori (allarmi, ...) - /// - private void decodeOtherData() - { - } - - /// - /// Effettua decodifica aree memoria alla bitmap usata x MAPO - /// - private void decodeToBaseBitmap() - { - // init a zero... - B_input = 0; - bool sendContapezzi = false; - /* ----------------------------------------------------- - * bitmap MAPO - * B0: POWER_ON - * B1: RUN - * B2: pzCount - * B3: allarme - * B4: manuale - * B5: allarme TCiclo - * B6: pallet 1 (SE doppio pallet) - * B7: pallet 2 (SE doppio pallet) - ----------------------------------------------------- */ - - // di base macchina in RUN - B_input = 3; - - /*---------------------------------------- - * Simulazione segnali con priorità: - * - Power ON / OFF (bit0/1) - * - ALLARMI - * - SLOW - * - MANUALE - * - contapezzi - * - *----------------------------------------*/ - - // se simulo PowerOn/Off --> spegnimento con CoolDown e accensione con WarmUp.. - if (simPowerOnOff) - { - DateTime adesso = DateTime.Now; - // se l'orario è dopo le tOff (tipicamente 22) --> NO RUN... - if (adesso.Hour >= tOff || adesso.Hour <= tOn) + public override void tryConnect() { - // se prima/ultima mezz'ora è ancora accesa NON in run... - if (adesso.AddMinutes(-30).Hour < tOff || adesso.AddMinutes(30).Hour > tOn) - { - B_input = 1; - } - else - { + base.tryConnect(); + connectionOk = true; + } + + public override void tryDisconnect() + { + base.tryDisconnect(); + connectionOk = false; + } + + /// + /// Setup aprametri di simulazione per BIT indicato + /// + /// + private simPar setupSimPar(string keyName) + { + simPar answ = new simPar(); + if (cIobConf.optPar.Count > 0) + { + if (cIobConf.optPar.ContainsKey(keyName)) + { + string fullVal = getOptPar(keyName); + if (!string.IsNullOrEmpty(fullVal) && fullVal.IndexOf("|") > 0) + { + string[] param = fullVal.Split('|'); + int.TryParse(param[0], out answ.wait); + int.TryParse(param[1], out answ.duration); + // aggiongo noise, +/- 40%... + Random rnd = new Random(); + int noise = rnd.Next(1, answ.wait * 40 / 100); + answ.wait += noise - (answ.wait * 20 / 100); + } + } + } + return answ; + } + + #region Metodi specifici (da verificare/completare in implementazione) + + /// + /// Recupera e processa allarmi CNC... + /// + public override Dictionary getCncAlarms() + { + Dictionary outVal = new Dictionary(); + return outVal; + } + + /// + /// Recupero dati dinamici... + /// + public override Dictionary getDynData() + { + // valore non presente in vers default... se gestito fare override + Dictionary outVal = new Dictionary(); + // verificare periodo SIM parametri... se passato li invio altrimenti NO... FIX a 20 sec + if (lastSimData.AddSeconds(waitSimPar) < DateTime.Now) + { + Random rnd = new Random(); + // controllo conf memorie json (se ci sono...) + try + { + if (memMap.mMapWrite.Count > 0) + { + foreach (var item in memMap.mMapWrite) + { + outVal.Add(item.Key, item.Value.value); + } + } + if (memMap.mMapRead.Count > 0) + { + foreach (var item in memMap.mMapRead) + { + // uso factor come valore MAX ammesso + int randVal = rnd.Next(item.Value.minVal, item.Value.maxVal); + outVal.Add(item.Key, randVal.ToString()); + } + } + } + catch + { } + lastSimData = DateTime.Now; + } + return outVal; + } + + /// + /// Recupero programma in lavorazione + /// + /// + public override string getPrgName() + { + // valore non presente in vers default... se gestito fare override + string prgName = string.Format("DEMO_{0:00}", DateTime.Now.Minute); + return prgName; + } + + /// + /// Recupero info sistema generiche + /// + public override Dictionary getSysInfo() + { + // valore non presente in vers default... se gestito fare override + Dictionary outVal = new Dictionary(); + outVal.Add("MACHINE", "IOB_SIM"); + return outVal; + } + + /// + /// Effettua vero processing contapezzi + /// + public override void processContapezzi() + { + } + + /// + /// Processo contatori eventi... + /// + public override void processVHF() + { + if (lastEvCheck.AddMilliseconds(periodoMSec) < DateTime.Now) + { + // decremento contatore ultimo evento + bit2.wait--; + bit3.wait--; + bit4.wait--; + bit5.wait--; + lastEvCheck = DateTime.Now; + } + } + + /// + /// Effettua lettura semafori principale + /// Parametri da aggiornare x display in form + /// + public override void readSemafori(ref newDisplayData currDispData) + { + base.readSemafori(ref currDispData); + // decodifica e gestione + decodeToBaseBitmap(); + decodeOtherData(); + reportRawInput(ref currDispData); + } + + /// + /// Decodifica il resto dell'area x i dati accessori (allarmi, ...) + /// + private void decodeOtherData() + { + } + + /// + /// Effettua decodifica aree memoria alla bitmap usata x MAPO + /// + private void decodeToBaseBitmap() + { + // init a zero... B_input = 0; - } - } - } - // in primis verifico SE posso inviare in blocco i pezzi...... SE MP online e SE NON E' MULTI - if (MPOnline && !isMulti) - { - // SE IOB online... - if (IobOnline) - { - // se il contapezzi è OLTRE il valore inviato.... - if (contapezziPLC > contapezziIOB) - { - // invio SOLO SE sono OLTRE i numSim pz e li invio TUTTI in blocco - if ((contapezziPLC - contapezziIOB) > minSendPzCountBlock) + bool sendContapezzi = false; + /* ----------------------------------------------------- + * bitmap MAPO + * B0: POWER_ON + * B1: RUN + * B2: pzCount + * B3: allarme + * B4: manuale + * B5: allarme TCiclo (SLOW) + * B6: WarmUp_CoolDown + * B7: EmergArmed (1 = NON emergenza, 0 = emergenza) + * B8: pallet 1 (SE doppio pallet) + * B9: pallet 2 (SE doppio pallet) + ----------------------------------------------------- */ + + // di base macchina in RUN + B_input = 3; + + /*---------------------------------------- + * Simulazione segnali con priorità: + * - Power ON / OFF (bit0/1) + * - ALLARMI + * - MANUALE + * - SLOW + * - contapezzi + * - emergenza + * + *----------------------------------------*/ + + // se simulo PowerOn/Off --> spegnimento con CoolDown e accensione con WarmUp.. + if (simPowerOnOff) { - trySendPzCountBlock(); - sigPzCount = false; - } - // altrimenti invio 1 segnale - else - { - // se NON STAVA inviando di già... - if (!sigPzCount) - { - // segnalo BIT (1 pz) - B_input += (1 << 2); - sigPzCount = true; - // salvo nuovo contapezzi (incremento di 1...) + richiesta refresh conteggio - contapezziIOB++; - needRefreshPzCount = true; - // invio conferma contapezzi.. - string retVal = utils.callUrl($"{urlSetPzCount}{contapezziIOB}"); - // verifica salvataggio - if (retVal != contapezziIOB.ToString()) + DateTime adesso = DateTime.Now; + // se l'orario è dopo le tOff (tipicamente 22) --> NO RUN... + if (adesso.Hour >= tOff || adesso.Hour <= tOn) { - // errore salvataggio contapezzi - lgInfo($"Errore salvataggio Contapezzi SIMULA 01: contapezziIOB {contapezziIOB} | risposta: {retVal}"); - // rileggo il counter pezzi da server - pzCntReload(true); + // se prima/ultima mezz'ora è ancora accesa NON in run... + if (adesso.AddMinutes(-30).Hour < tOff || adesso.AddMinutes(30).Hour > tOn) + { + B_input = 1; + } + else + { + B_input = 0; + } } - } - else - { - string retVal = utils.callUrl($"{urlSetPzCount}{contapezziIOB}"); - if (retVal != contapezziIOB.ToString()) + } + // in primis verifico SE posso inviare in blocco i pezzi...... SE MP online e SE NON E' MULTI + if (MPOnline && !isMulti) + { + // SE IOB online... + if (IobOnline) { - // errore salvataggio contapezzi - lgInfo($"Errore salvataggio Contapezzi SIMULA 02: contapezziIOB {contapezziIOB} | risposta: {retVal}"); - // rileggo il counter pezzi da server - pzCntReload(true); + // se il contapezzi è OLTRE il valore inviato.... + if (contapezziPLC > contapezziIOB) + { + // invio SOLO SE sono OLTRE i numSim pz e li invio TUTTI in blocco + if ((contapezziPLC - contapezziIOB) > minSendPzCountBlock) + { + trySendPzCountBlock(); + sigPzCount = false; + } + // altrimenti invio 1 segnale + else + { + // se NON STAVA inviando di già... + if (!sigPzCount) + { + // segnalo BIT (1 pz) + B_input += (1 << 2); + sigPzCount = true; + // salvo nuovo contapezzi (incremento di 1...) + richiesta refresh conteggio + contapezziIOB++; + needRefreshPzCount = true; + // invio conferma contapezzi.. + string retVal = utils.callUrl($"{urlSetPzCount}{contapezziIOB}"); + // verifica salvataggio + if (retVal != contapezziIOB.ToString()) + { + // errore salvataggio contapezzi + lgInfo($"Errore salvataggio Contapezzi SIMULA 01: contapezziIOB {contapezziIOB} | risposta: {retVal}"); + // rileggo il counter pezzi da server + pzCntReload(true); + } + } + else + { + string retVal = utils.callUrl($"{urlSetPzCount}{contapezziIOB}"); + if (retVal != contapezziIOB.ToString()) + { + // errore salvataggio contapezzi + lgInfo($"Errore salvataggio Contapezzi SIMULA 02: contapezziIOB {contapezziIOB} | risposta: {retVal}"); + // rileggo il counter pezzi da server + pzCntReload(true); + } + sigPzCount = false; + } + } + lgInfo($"S01: Valori contatori: contapezzi macchina contapezziPLC: {contapezziPLC} | contapezziIOB: {contapezziIOB} | contapezziPLC > contapezziIOB"); + } } - sigPzCount = false; - } } - lgInfo($"S01: Valori contatori: contapezzi macchina contapezziPLC: {contapezziPLC} | contapezziIOB: {contapezziIOB} | contapezziPLC > contapezziIOB"); - } - } - } - // questa parte la processo SOLO SE sono in run --> B_input == 3 - if (B_input == 3) - { - // verifico COMUNQUE limite tciclo slow... - if (tcMan.alarmDelayTC) - { - // segnalo BIT - B_input += (1 << 5); - } - - if (bit3.wait <= 0) - { - // segnalo BIT - B_input += (1 << 3); - // decremento duration - bit3.duration--; - // controllo se sia scaduta la duration... in quel caso reset... - if (bit3.duration <= 0) - { - bit3 = setupSimPar("SIM_ALARM"); - } - } - else if (bit4.wait <= 0) - { - // segnalo BIT - B_input += (1 << 4); - // decremento duration - bit4.duration--; - // controllo se sia scaduta la duration... in quel caso reset... - if (bit4.duration <= 0) - { - bit4 = setupSimPar("SIM_MANU"); - } - // in manuale: provo split ODL - trySplitOdl(); - } - else if (bit5.wait <= 0) - { - // segnalo BIT - B_input += (1 << 5); - // decremento duration - bit5.duration--; - // controllo se sia scaduta la duration... in quel caso reset... - if (bit5.duration <= 0) - { - bit5 = setupSimPar("SIM_SLOW"); - } - } - else if (bit2.wait <= 0) - { - // salvo nuovo contapezziPLC (incremento RAND 0..3) - var rand = new Random(); - // se online vero delta altrimenti solo 0..1 50% probabilità - int delta = IobOnline ? rand.Next(1, 4) : rand.Next(0, 2); - if (!isMulti) - { - // solo se MP online... - if (MPOnline) + // questa parte la processo SOLO SE sono in run --> B_input == 3 + if (B_input == 3) { - contapezziPLC += delta; - lgInfo($"S01: Valori contatori: contapezzi macchina contapezziPLC: {contapezziPLC} | contapezziIOB: {contapezziIOB} | aggiunto delta {delta}"); - } - } - // SOLO SE sono online... - if (IobOnline) - { - // se multipallet --> cP a zero! - if (isMulti) - { - cP = 0; - } - // se NON Multi fa contapezzi... - else - { - // SE NON SONO GIA' OLTRE il contapezzi - if (contapezziIOB < contapezziPLC) - { - // segnalo BIT (1 pz) - B_input += (1 << 2); - } - } - // decremento duration - bit2.duration--; - // controllo se sia scaduta la duration... in quel caso reset... - if (bit2.duration <= 0) - { - bit2 = setupSimPar("SIM_PZCNT"); - sendContapezzi = true; - // salvo nuovo contapezzi (incremento di 1...) + richiesta refresh conteggio - contapezziIOB++; - needRefreshPzCount = true; - lgInfo($"S01: Valori contatori: contapezzi macchina contapezziPLC: {contapezziPLC} | contapezziIOB: {contapezziIOB} - incremento contapezzi per bit2.duration <= 0"); - } - if (sendContapezzi) - { - // controllo se ALMENO sia pingabile il server - if (checkServerAlive) - { - // invio a server contapezzi (aggiornato) - string retVal = utils.callUrl(urlSetPzCount + contapezziIOB.ToString()); - // verifica se tutto OK - if (retVal != contapezziIOB.ToString()) + if (bit3.wait <= 0) { - // errore salvataggio contapezzi - lgInfo($"Errore salvataggio Contapezzi SIMULA 03: contapezziIOB {contapezziIOB} | risposta: {retVal}"); - // se non sono multi... - if (!isMulti) - { - // rileggo il counter pezzi da server - pzCntReload(true); - } + // segnalo BIT + B_input += (1 << 3); + // decremento duration + bit3.duration--; + // controllo se sia scaduta la duration... in quel caso reset... + if (bit3.duration <= 0) + { + bit3 = setupSimPar("SIM_ALARM"); + } } - // resetto timer... - lastPzCountSend = DateTime.Now; - } + else if (bit6.wait <= 0) + { + // segnalo BIT + B_input += (1 << 6); + // decremento duration + bit6.duration--; + // controllo se sia scaduta la duration... in quel caso reset... + if (bit6.duration <= 0) + { + bit6 = setupSimPar("SIM_WUCD"); + } + // in manuale: provo split ODL + trySplitOdl(); + } + else if (bit7.wait <= 0) + { + // segnalo BIT + B_input += (1 << 7); + // decremento duration + bit7.duration--; + // controllo se sia scaduta la duration... in quel caso reset... + if (bit7.duration <= 0) + { + bit7 = setupSimPar("SIM_EMRG"); + } + // in manuale: provo split ODL + trySplitOdl(); + } + else if (bit4.wait <= 0) + { + // segnalo BIT + B_input += (1 << 4); + // decremento duration + bit4.duration--; + // controllo se sia scaduta la duration... in quel caso reset... + if (bit4.duration <= 0) + { + bit4 = setupSimPar("SIM_MANU"); + } + // in manuale: provo split ODL + trySplitOdl(); + } + else if (bit5.wait <= 0 || tcMan.alarmDelayTC) + { + // segnalo BIT + B_input += (1 << 5); + // decremento duration + bit5.duration--; + // controllo se sia scaduta la duration... in quel caso reset... + if (bit5.duration <= 0) + { + bit5 = setupSimPar("SIM_SLOW"); + } + } + else if (bit2.wait <= 0) + { + // salvo nuovo contapezziPLC (incremento RAND 0..3) + var rand = new Random(); + // se online vero delta altrimenti solo 0..1 50% probabilità + int delta = IobOnline ? rand.Next(1, 4) : rand.Next(0, 2); + if (!isMulti) + { + // solo se MP online... + if (MPOnline) + { + contapezziPLC += delta; + lgInfo($"S01: Valori contatori: contapezzi macchina contapezziPLC: {contapezziPLC} | contapezziIOB: {contapezziIOB} | aggiunto delta {delta}"); + } + } + // SOLO SE sono online... + if (IobOnline) + { + // se multipallet --> cP a zero! + if (isMulti) + { + cP = 0; + } + // se NON Multi fa contapezzi... + else + { + // SE NON SONO GIA' OLTRE il contapezzi + if (contapezziIOB < contapezziPLC) + { + // segnalo BIT (1 pz) + B_input += (1 << 2); + } + } + // decremento duration + bit2.duration--; + // controllo se sia scaduta la duration... in quel caso reset... + if (bit2.duration <= 0) + { + bit2 = setupSimPar("SIM_PZCNT"); + sendContapezzi = true; + // salvo nuovo contapezzi (incremento di 1...) + richiesta refresh conteggio + contapezziIOB++; + needRefreshPzCount = true; + lgInfo($"S01: Valori contatori: contapezzi macchina contapezziPLC: {contapezziPLC} | contapezziIOB: {contapezziIOB} - incremento contapezzi per bit2.duration <= 0"); + } + if (sendContapezzi) + { + // controllo se ALMENO sia pingabile il server + if (checkServerAlive) + { + // invio a server contapezzi (aggiornato) + string retVal = utils.callUrl(urlSetPzCount + contapezziIOB.ToString()); + // verifica se tutto OK + if (retVal != contapezziIOB.ToString()) + { + // errore salvataggio contapezzi + lgInfo($"Errore salvataggio Contapezzi SIMULA 03: contapezziIOB {contapezziIOB} | risposta: {retVal}"); + // se non sono multi... + if (!isMulti) + { + // rileggo il counter pezzi da server + pzCntReload(true); + } + } + // resetto timer... + lastPzCountSend = DateTime.Now; + } + } + // provo a fare split ODL SE NON E' multi.... + trySplitOdl(); + } + } + // se multi gestisco il bit delle tavole... + if (isMulti) + { + // se sono in fase di fronte d'uscita (invio contapezzi) INVERTO nP... + if (sendContapezzi) + { + nP = nP == 1 ? 2 : 1; + // assegno a cP il valore nP... + cP = nP; + contapezziPLC++; + } + // se cP > 0 --> segnalo bit tavola... + if (cP == 1) + { + B_input += (1 << 8); + } + else if (cP == 2) + { + B_input += (1 << 9); + } + } + + // init obj display + newDisplayData currDispData = new newDisplayData(); + currDispData.counter = contapezziIOB; + currDispData.semOut = Semaforo.SV; + raiseRefresh(currDispData); } - // provo a fare split ODL SE NON E' multi.... - trySplitOdl(); - } - } - // se multi gestisco il bit delle tavole... - if (isMulti) - { - // se sono in fase di fronte d'uscita (invio contapezzi) INVERTO nP... - if (sendContapezzi) - { - nP = nP == 1 ? 2 : 1; - // assegno a cP il valore nP... - cP = nP; - contapezziPLC++; - } - // se cP > 0 --> segnalo bit tavola... - if (cP == 1) - { - B_input += (1 << 6); - } - else if (cP == 2) - { - B_input += (1 << 7); - } } - // init obj display - newDisplayData currDispData = new newDisplayData(); - currDispData.counter = contapezziIOB; - currDispData.semOut = Semaforo.SV; - raiseRefresh(currDispData); - } - } - - /// - /// provo a chaimare split ODL - /// - private void trySplitOdl() - { - if (!isMulti) - { - // solo se ODL è in lavorazione da ALMENO minDurataODL minuti... - DateTime inizioOdl = DateTime.Now.AddDays(-1); - string rawDataInizio = callUrl(urlInizioOdlIob, false); - DateTime.TryParse(rawDataInizio, out inizioOdl); - if (DateTime.Now.Subtract(inizioOdl).TotalMinutes > minDurataODL) + /// + /// provo a chaimare split ODL + /// + private void trySplitOdl() { - // invio reset ODL... - forceSplitOdl(); - } - } - } - - /// - /// Recupera e processa allarmi CNC... - /// - public override Dictionary getCncAlarms() - { - Dictionary outVal = new Dictionary(); - return outVal; - } - - /// - /// Recupero dati dinamici... - /// - public override Dictionary getDynData() - { - // valore non presente in vers default... se gestito fare override - Dictionary outVal = new Dictionary(); - // verificare periodo SIM parametri... se passato li invio altrimenti NO... FIX a 20 sec - if (lastSimData.AddSeconds(waitSimPar) < DateTime.Now) - { - Random rnd = new Random(); - // controllo conf memorie json (se ci sono...) - try - { - if (memMap.mMapWrite.Count > 0) - { - foreach (var item in memMap.mMapWrite) + if (!isMulti) { - outVal.Add(item.Key, item.Value.value); + // solo se ODL è in lavorazione da ALMENO minDurataODL minuti... + DateTime inizioOdl = DateTime.Now.AddDays(-1); + string rawDataInizio = callUrl(urlInizioOdlIob, false); + DateTime.TryParse(rawDataInizio, out inizioOdl); + if (DateTime.Now.Subtract(inizioOdl).TotalMinutes > minDurataODL) + { + // invio reset ODL... + forceSplitOdl(); + } } - } - if (memMap.mMapRead.Count > 0) - { - foreach (var item in memMap.mMapRead) - { - // uso factor come valore MAX ammesso - int randVal = rnd.Next(item.Value.minVal, item.Value.maxVal); - outVal.Add(item.Key, randVal.ToString()); - } - } } - catch - { } - lastSimData = DateTime.Now; - } - return outVal; + + #endregion Metodi specifici (da verificare/completare in implementazione) } /// - /// Recupero programma in lavorazione + /// Configuraizone eventi da simulare /// - /// - public override string getPrgName() + public class simPar { - // valore non presente in vers default... se gestito fare override - string prgName = string.Format("DEMO_{0:00}", DateTime.Now.Minute); - return prgName; + #region Public Fields + + /// + /// Durata dell'evento + /// + public int duration = 1; + + /// + /// DateTime ultimo evento + /// + public DateTime lastEv = DateTime.Now; + + /// + /// Attesa per evento + /// + public int wait = 10; + + #endregion Public Fields } - - /// - /// Recupero info sistema generiche - /// - public override Dictionary getSysInfo() - { - // valore non presente in vers default... se gestito fare override - Dictionary outVal = new Dictionary(); - outVal.Add("MACHINE", "IOB_SIM"); - return outVal; - } - - /// - /// Effettua vero processing contapezzi - /// - public override void processContapezzi() - { - } - - /// - /// Processo contatori eventi... - /// - public override void processVHF() - { - if (lastEvCheck.AddMilliseconds(periodoMSec) < DateTime.Now) - { - // decremento contatore ultimo evento - bit2.wait--; - bit3.wait--; - bit4.wait--; - bit5.wait--; - lastEvCheck = DateTime.Now; - } - } - - /// - /// Effettua lettura semafori principale - /// Parametri da aggiornare x display in form - /// - public override void readSemafori(ref newDisplayData currDispData) - { - base.readSemafori(ref currDispData); - // decodifica e gestione - decodeToBaseBitmap(); - decodeOtherData(); - reportRawInput(ref currDispData); - } - - #endregion Metodi specifici (da verificare/completare in implementazione) - } - - /// - /// Configuraizone eventi da simulare - /// - public class simPar - { - #region Public Fields - - /// - /// Durata dell'evento - /// - public int duration = 1; - - /// - /// DateTime ultimo evento - /// - public DateTime lastEv = DateTime.Now; - - /// - /// Attesa per evento - /// - public int wait = 10; - - #endregion Public Fields - } } \ No newline at end of file