diff --git a/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj b/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj index 3d52cbe7..81df6715 100644 --- a/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj +++ b/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj @@ -379,17 +379,14 @@ Form - Form - - @@ -587,8 +584,6 @@ - - diff --git a/IOB-WIN-NEXT/Iob/Kawasaki.cs b/IOB-WIN-NEXT/Iob/Kawasaki.cs deleted file mode 100644 index cbafcf2f..00000000 --- a/IOB-WIN-NEXT/Iob/Kawasaki.cs +++ /dev/null @@ -1,1103 +0,0 @@ -using IOB_UT_NEXT; -using MapoSDK; -using System; -using System.Collections.Generic; -using System.Net.NetworkInformation; - -namespace IOB_WIN_NEXT.Iob -{ - public class Kawasaki : Iob.GenericNext, IDisposable - { - #region Public Constructors - - /// - /// estende l'init della classe base... - /// - /// - /// - public Kawasaki(AdapterFormNext caller, IobConfiguration IOBConf) : base(caller, IOBConf) - { - // gestione invio ritardato contapezzi - pzCountDelay = utils.CRI("pzCountDelay"); - lastPzCountSend = DateTime.Now; - lastWarnODL = DateTime.Now; - // init connessione - setConnection(); - - // test completo funzionalità kawasaki, da TOGLIERE in prod... -#if DEBUG - kawasakiFullTest(); -#endif - } - - #endregion Public Constructors - - #region Public Enums - - /// - /// Enum segnali macchina ulteriori (ByteSignals) - /// - [Flags] - public enum bitSignals - { - NONE = 0, - TRANSF_AUTO = 1 << 0, - PUNZ_AUTO = 1 << 1, - BARR_TAV_RIPR = 1 << 2, - ARIA_OK = 1 << 3, - CONS_TRANS_OK = 1 << 4, - TAV_A = 1 << 5, - TAV_B = 1 << 6, - RICH_ACCESSO = 1 << 7 - } - - /// - /// Enum segnali status macchina (ByteStatus) come flag - /// - [Flags] - public enum bitStatus - { - NONE = 0, - POWER_ON = 1 << 0, - AUTO = 1 << 1, - RUN = 1 << 2, - ERROR = 1 << 3, - ALARM = 1 << 4, - EMERG_OK = 1 << 5, - DOOR_CLOSED = 1 << 6, - READY_LOAD = 1 << 7 - } - - #endregion Public Enums - - #region Public Methods - - /// - /// Metodo dispose x il currPLC contenuto - /// - public void Dispose() - { - KAWASAKI_ref.disconnect(); - KAWASAKI_ref.Dispose(); - } - - /// - /// Processo i task richiesti e li elimino dalla coda 1:1 - /// - /// - public override Dictionary executeTasks(Dictionary task2exe) - { - // Verificare il protocollo: dovrebbe togliere SOLO i task eseguiti... - Dictionary taskDone = new Dictionary(); - bool taskOk = false; - string taskVal = ""; - - // cerco task specifici: se ho startSetup --> imposto bit DBB701.DBB0.4 - foreach (var item in task2exe) - { - taskOk = false; - taskVal = ""; - // converto richiesta in enum... - taskType tName = taskType.nihil; - Enum.TryParse(item.Key, out tName); - // controllo sulla KEY - switch (tName) - { - case taskType.nihil: - case taskType.fixStopSetup: - case taskType.setArt: - case taskType.setComm: - case taskType.setProg: - case taskType.sendWatchDogMes2Plc: - taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC"; - break; - - case taskType.forceResetPzCount: - // reset contapezzi inizio setup - taskOk = resetContapezziPLC(); - taskVal = taskOk ? "FORCE RESET PZ COUNT" : "FORCE RESET DISABLED | NO EXEC"; - break; - - case taskType.forceSetPzCount: - // reset contapezzi inizio setup - int newPzCount = 0; - int.TryParse(item.Value, out newPzCount); - if (newPzCount >= 0) - { - taskOk = setcontapezziPLC(newPzCount); - taskVal = taskOk ? $"FORCE SET PZ COUNT TO {newPzCount}" : $"FORCE SET PZ COUNT TO {newPzCount} | NO EXEC"; - } - else - { - taskVal = $"ERROR IN FORCE SET PZ COUNT TO {newPzCount}"; - } - break; - - case taskType.startSetup: - // reset contapezzi inizio setup - taskOk = resetContapezziPLC(); - taskVal = taskOk ? "RESET: SETUP START" : "PZ RESET DISABLED | NO EXEC"; - break; - - case taskType.stopSetup: - // reset contapezzi fine setup // reset contapezzi fine setup SE - // ESPLICITAMENTE IMPOSTATO - if (cIobConf.optPar.Count > 0 && getOptPar("ENABLE_PZ_RESET_stopSetup") == "TRUE") - { - resetContapezziPLC(); - } - taskVal = taskOk ? "RESET: SETUP END" : "PZ RESET DISABLED | NO EXEC"; - break; - - default: - taskVal = "SKIPPED | NO EXEC"; - break; - } - taskDone.Add(item.Key, taskVal); - } - - return taskDone; - } - - /// - /// Recupero dati dinamici... - /// - public override Dictionary getDynData() - { - // valore non presente in vers default... se gestito fare override - Dictionary outVal = new Dictionary(); - outVal.Add("LAST_MISS", lastMissRobot); - outVal.Add("LAST_TC", lastTC.ToString()); - outVal.Add("NUM_PZ_PREL", pzPrelevati.ToString()); - outVal.Add("NUM_PZ_LAV", pzCounter.ToString()); - outVal.Add("CURR_SIGNALS", currBitmapSignals.ToString()); - return outVal; - } - - /// - /// Recupero programma in lavorazione - /// - /// - public override string getPrgName() - { - // valore non presente in vers default... se gestito fare override - string prgName = ""; - 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", machineName); - return outVal; - } - - /// - /// Effettua vero processing contapezzi - /// - public override void processContapezzi() - { - if (utils.CRB("enableContapezzi")) - { - try - { - // hard coded... !!!FARE!!! rivedere megio conf - contapezziPLC = pzCounter; - // verifico quale modalità sia richiesta: STD (6711) oppure BIT (Custom, con - // indicazione area) - if (cIobConf.optPar.Count > 0 && !string.IsNullOrEmpty(getOptPar("PZCOUNT_MODE"))) - { -#if false - string memAddr = getOptPar("PZCOUNT_MODE"); - if (memAddr.StartsWith("STD")) - { - // inizio verifica area memoria/parametro levando prima parte codice - memAddr = memAddr.Replace("STD.", ""); - object outputVal = new object(); - // verifico se si tratta di lettura area DB... formato tipo STD.DB700.DBB22.W - if (memAddr.StartsWith("DB")) - { - memAreaSiemens areaCounter = new memAreaSiemens(memAddr); - - if (isVerboseLog) - { - lgInfo("[0] area memoria: {1}.{2}.{3}", memAddr, areaCounter.DbNum, areaCounter.indiceMem, areaCounter.tipoMem); - } - // copio da blocco già letto... con switch x tipo dati --> tipo lettura... e salvo - // ultimo conteggio rilevato - switch (areaCounter.tipoMem) - { - case "B": - byte valB = RawInput[areaCounter.indiceMem]; - outputVal = valB; - break; - - case "W": - ushort valW = S7.Net.Types.Word.FromByteArray(RawInput.Skip(areaCounter.indiceMem).Take(2).ToArray()); - outputVal = valW; - break; - - case "DW": - uint valDW = S7.Net.Types.Word.FromByteArray(RawInput.Skip(areaCounter.indiceMem).Take(4).ToArray()); - outputVal = valDW; - - break; - - default: - break; - } - // salvo... - Int32.TryParse(outputVal.ToString(), out contapezziPLC); - if (isVerboseLog) - { - lgInfo("[2] outputVal contapezzi: {0}", outputVal); - lgInfo("[3] contapezziPLC contapezzi: {0}", contapezziPLC); - } - } - stopwatch.Stop(); - } -#endif - } - } - catch (Exception exc) - { - lgError(exc, "Errore in contapezzi KAWASAKI"); - } - } - } - - /// - /// Effettua processing del recupero delle OVERRIDE (spindle, feedrate, rapid) - /// - public override void processOverride() - { - } - - /// - /// Effettua lettura semafori principale Parametri da - /// aggiornare x display in form - /// - public override void readSemafori(ref newDisplayData currDispData) - { - base.readSemafori(ref currDispData); - try - { - if (verboseLog) - { - lgInfo("inizio read semafori"); - } - currDispData.semIn = Semaforo.SV; - - // effettuo TUTTE le letture - threadOk = commThreadOk; - cStatus = currBitmapStatus; - cSignals = currBitmapSignals; - contapezziPLC = pzCounter; - // decodifica e gestione - decodeToBaseBitmap(); - decodeOtherData(); - reportRawInput(ref currDispData); - // se trova ok thread --> aggiorno ultima lettura - if (threadOk) - { - lastReadPLC = DateTime.Now; - } - } - catch - { - currDispData.semIn = Semaforo.SR; - } - } - - /// - /// Effettua reset del contapezzi - /// - /// - public override bool resetContapezziPLC() - { - // impiego override metodo set... - bool answ = setcontapezziPLC(0); -#if false - bool answ = false; - // ...SE abilitato da conf IOB - if (cIobConf.optPar.Count > 0 && getOptPar("ENABLE_PZ_RESET") == "TRUE") - { - // scrivo valore 0 x il contapezzi - try - { - pzCounter = 0; - } - catch (Exception exc) - { - lgError(exc, "Errore in RESET contapezzi KAWASAKI"); - connectionOk = false; - } - answ = true; - } - else - { - lgError("Impossibile effettuare RESET contapezzi KAWASAKI, mancanza parametro OPT:ENABLE_PZ_RESET"); - } -#endif - return answ; - } - - /// - /// Effettua IMPOSTAZIONE FORZATA del contapezzi - /// - /// - public override bool setcontapezziPLC(int newPzCount) - { - bool answ = false; - // ...SE abilitato da conf IOB - if (cIobConf.optPar.Count > 0 && getOptPar("ENABLE_PZ_RESET") == "TRUE") - { - // scrivo valore 0 x il contapezzi - try - { - pzCounter = newPzCount; - } - catch (Exception exc) - { - lgError(exc, "Errore in SET contapezzi KAWASAKI"); - connectionOk = false; - } - answ = true; - } - else - { - lgError("Impossibile effettuare SET contapezzi KAWASAKI, mancanza parametro OPT:ENABLE_PZ_RESET"); - } - return answ; - } - - /// - /// Override connessione - /// - public override void tryConnect() - { - if (!connectionOk) - { - // controllo che il ping sia stato tentato almeno pingTestSec fa... - if (DateTime.Now.Subtract(lastPING).TotalSeconds > utils.CRI("pingTestSec")) - { - if (verboseLog || periodicLog) - { - lgInfo("KAWASAKI: ConnKO - tryConnect"); - } - // in primis salvo data ping... - lastPING = DateTime.Now; - // se passa il ping faccio il resto... - if (testPingMachine == IPStatus.Success) - { - string szStatusConnection = ""; - try - { - // ora provo connessione... - parentForm.commPlcActive = true; - string connPar = string.Format("TCP {0}", cIobConf.cncIpAddr); - KAWASAKI_ref.connect(connPar); - parentForm.commPlcActive = false; - lgInfo("szStatusConnection: " + KAWASAKI_ref.IsConnected); - connectionOk = true; - // verifico se sta girando - if (connectionOk) - { - queueInEnabCurr = true; - if (adpRunning) - { - lgInfo("Connessione OK"); - } - } - else - { - lgError("Impossibile procedere, connessione mancante..."); - } - } - catch (Exception exc) - { - lgFatal(string.Format("Errore nella connessione all'adapter KAWASAKI: {0}{1}{2}", szStatusConnection, Environment.NewLine, exc)); - connectionOk = false; - lgInfo(string.Format("Eccezione in TryConnect, Adapter KAWASAKI NON running, pausa di {0} msec prima di ulteriori tentativi di riconnessione", utils.CRI("waitRecMSec"))); - } - } - else - { - // loggo no risposta ping ... - connectionOk = false; - needRefresh = true; - if (verboseLog || periodicLog) - { - lgInfo(string.Format("Attenzione: KAWASAKI controllo PING fallito per IP {0}", cIobConf.cncPingAddr)); - } - } - } - } - // se non è ancora connesso faccio processing memoria caso disconnesso... - if (!connectionOk) - { - // processo semafori ed invio... - processMemoryDiscon(); - } - } - - /// - /// Override disconnessione - /// - public override void tryDisconnect() - { - if (connectionOk) - { - connectionOk = false; - string szStatusConnection = ""; - try - { - KAWASAKI_ref.disconnect(); - lgInfo(szStatusConnection); - lgInfo("Effettuata disconnessione adapter KAWASAKI!"); - } - catch (Exception exc) - { - lgFatal(exc, "Errore nella disconnessione dall'adapter KAWASAKI"); - } - } - else - { - lgError("IMPOSSIBILE effettuare disconnessione KAWASAKI: Connessione non disponibile..."); - } - queueInEnabCurr = false; - needRefresh = true; - } - - #endregion Public Methods - - #region Protected Fields - - /// - /// Comando inviato al robot - /// - protected string comando; - - /// - /// Variabile SIGNALS corrente (8bit INT) - /// - protected string cSignals; - - /// - /// Variabile STATUS corrente (8bit INT) - /// - protected string cStatus; - - /// - /// Oggetto MAIN x connessione KAWASAKI - /// - protected KRcc.Commu KAWASAKI_ref; - - /// - /// Ultima missione svolta da robot - /// - protected string lastMissRobot; - - /// - /// Ultimo TC registrato da robot - /// - protected decimal lastRecTC; - - /// - /// Nome e seriale macchina - /// - protected string macName = ""; - - /// - /// Num pezzi prelevati - /// - protected int numPzPrel; - - /// - /// Array delle risposte dal controllo KAWASAKI - /// - protected System.Collections.ArrayList resDataArray; - - /// - /// Variabile verifica thread comunicazione - /// - protected bool threadOk = false; - - #endregion Protected Fields - - #region Protected Properties - - /// - /// Verifica se il thread 4 di comm sia attivo - /// - protected bool commThreadOk - { - get - { - bool answ = false; - if (KAWASAKI_ref.IsConnected) - { - int retVal = 0; - resDataArray = KAWASAKI_ref.command("TYPE TASK (1004)", 3000); // thread 4 ok --> " 1\r\n" - int.TryParse(resDataArray[1].ToString().Replace("\n", "").Replace("\r", ""), out retVal); - answ = (retVal == 1); - } - return answ; - } - } - - /// - /// Restituisce SEGNALI macchina nel formato: - /// B0: Transfer in auto - /// B1: Punzonatrice in AUTO - /// B2: Barriera tavola ripristinata - /// B3: Aria in linea OK - /// B4: Console Transfer in fuori ingombro - /// B5: TAV A - /// B6: TAV B - /// B7: Richiesta accesso attiva - /// - protected string currBitmapSignals - { - get - { - string answ = ""; - if (KAWASAKI_ref.IsConnected) - { - resDataArray = KAWASAKI_ref.command("TYPE $signal", 3000); // segnali --> "1|0|1|1|1|0|0|0\r\n" - answ = resDataArray[1].ToString().Replace("\n", "").Replace("\r", "").Replace("|", ""); -#if false - // reverse stringa (B0 portato a sx) - szBitmap = utils.reverseStr(szBitmap); - // ora converto bitmap string in INT - answ = Convert.ToInt32(szBitmap, 2); -#endif - } - return answ; - } - } - - /// - /// Restituisce stato macchina nel formato (da sx a dx): - /// B0: POWER_ON - /// B1: AUTO - /// B2: RUN - /// B3: ERROR - /// B4: ALLARME - /// B5: EMERGENZA OK - /// B6: PORTA CHIUSA - /// B7: PRONTO AL LOAD - /// - protected string currBitmapStatus - { - get - { - string answ = ""; - if (KAWASAKI_ref.IsConnected) - { - resDataArray = KAWASAKI_ref.command("TYPE $status", 3000); // status --> "0|0|1|0|0|1|0|0\r\n" - answ = resDataArray[1].ToString().Replace("\n", "").Replace("\r", "").Replace("|", ""); -#if false - // reverse stringa (B0 portato a sx) - szBitmap = utils.reverseStr(szBitmap); - // ora converto bitmap string in INT - answ = Convert.ToInt32(szBitmap, 2); -#endif - } - return answ; - } - } - - /// - /// Recupera ultima missione svolta - /// - protected string lastMission - { - get - { - string answ = ""; - if (KAWASAKI_ref.IsConnected) - { - resDataArray = KAWASAKI_ref.command("TYPE $exe", 3000); // missione --> "\r\n" (vuoto, no missione) - answ = resDataArray[1].ToString().Replace("\n", "").Replace("\r", ""); - } - return answ; - } - } - - /// - /// Oggetto per lettura ULTIMO TC rilevato - /// - protected decimal lastTC - { - get - { - decimal answ = 0; - if (KAWASAKI_ref.IsConnected) - { - resDataArray = KAWASAKI_ref.command("TYPE r_tempo", 3000); // ultimo TCiclo rilevato --> " 349.19\r\n" - decimal.TryParse(resDataArray[1].ToString().Replace("\n", "").Replace("\r", "").Replace(".", ","), out answ); - } - return answ; - } - } - - /// - /// Recupera nome e seriale macchina - /// - protected string machineName - { - get - { - string answ = ""; - if (KAWASAKI_ref.IsConnected) - { - resDataArray = KAWASAKI_ref.command("TYPE $id_true", 3000); // id macchina --> "BX100N-B001 Sn. 2366\r\n" - answ = resDataArray[1].ToString().Replace("\n", "").Replace("\r", ""); - } - return answ; - } - } - - /// - /// Oggetto per lettura/scrittura counter pezzi robot - /// - protected int pzCounter - { - get - { - int answ = 0; - if (KAWASAKI_ref.IsConnected) - { - resDataArray = KAWASAKI_ref.command("TYPE i_cicli", 3000); // num cicli depositati/fatti --> " 0\r\n" - int.TryParse(resDataArray[1].ToString().Replace("\n", "").Replace("\r", ""), out answ); - } - return answ; - } - set - { - if (KAWASAKI_ref.IsConnected) - { - comando = string.Format("i_cicli={0}", value); - // scrivo valore cicli - resDataArray = KAWASAKI_ref.command(comando, 3000); // imposto cicli depositati/fatti --> " 0\r\n" - } - } - } - - /// - /// Oggetto per lettura counter pezzi PRELEVATI - /// - protected int pzPrelevati - { - get - { - int answ = 0; - if (KAWASAKI_ref.IsConnected) - { - resDataArray = KAWASAKI_ref.command("TYPE i_prelevati", 3000); // num pz prelevati --> "0\r\n" - int.TryParse(resDataArray[1].ToString().Replace("\n", "").Replace("\r", ""), out answ); - } - return answ; - } - } - - #endregion Protected Properties - - #region Protected Methods - - /// - /// Imposto connessione - /// - protected virtual void setConnection() - { - // Creo oggetto connessione NC - parentForm.commPlcActive = true; - lgInfoStartup("Start init Adapter KAWASAKI all'IP {0} | --> IOB {1}", cIobConf.cncIpAddr, cIobConf.codIOB); - - // inizializzo correttamente aree memoria secondo CONF - iniFileName - IniFile fIni = new IniFile(cIobConf.iniFileName); - // fix enable prgName - enablePrgName = fIni.ReadBoolean("CNC", "GETPRGNAME", true); - - // SE è necessario refresh... - if (needRefresh) - { - lgInfoStartup("Refreshing connection..."); - // ora tento avvio PLC... SE PING OK... - if (testPingMachine == IPStatus.Success) - { - try - { - string connPar = string.Format("TCP {0}", cIobConf.cncIpAddr); - KAWASAKI_ref = new KRcc.Commu(connPar); - // disconnetto e connetto... - if (isVerboseLog) - { - lgInfo("KAWASAKI: tryDisconnect"); - } - - lgInfo("End init Adapter KAWASAKI"); - if (isVerboseLog) - { - lgInfo("KAWASAKI CONNESSIONE AVVENUTA"); - } - } - catch (Exception exc) - { - lgError(exc, "Errore in INIT KAWASAKI Commu"); - } - needRefresh = false; - } - parentForm.commPlcActive = false; - // gestione pzCounter - if (utils.CRB("enableContapezzi")) - { - lgInfo("KAWASAKI: inizio gestione contapezzi"); - try - { - // verifico quale modalità sia richiesta: STD (6711) oppure BIT (Custom, con - // indicazione area) - if (cIobConf.optPar.Count > 0 && !string.IsNullOrEmpty(getOptPar("PZCOUNT_MODE"))) - { - if (getOptPar("PZCOUNT_MODE").StartsWith("STD")) - { - lgInfo("Init contapezzi KAWASAKI: pzCntReload(true)"); - pzCntReload(true); - // refresh associazione Macchina - IOB - SendM2IOB(); - // invio altri dati accessori... - SendMachineConf(); - // per adesso imposto lettura fanuc == contapezzi (poi farà vera lettura...) - contapezziPLC = contapezziIOB; - } - else - { - contapezziIOB = 0; - lgInfo("Contapezzi STD disabilitato: modalità {0}", getOptPar("PZCOUNT_MODE")); - } - } - else - { - contapezziIOB = 0; - lgInfo("Parametro mancante PZCOUNT_MODE"); - } - } - catch (Exception exc) - { - lgError(exc, "Errore in contapezzi KAWASAKI"); - } - } - } - } - - #endregion Protected Methods - - #region Private Fields - - /// - /// LookUpTable di decodifica da CNC a segnali tipo bitmap MAPO - /// - private Dictionary signLUT = new Dictionary(); - - #endregion Private Fields - - #region Private Methods - - /// - /// Decodifica il resto dell'area x i dati accessori (allarmi, ...) - /// - private void decodeOtherData() - { - if (verboseLog) - { - } - } - - /// - /// Effettua decodifica aree memoria alla bitmap usata x MAPO - /// - private void decodeToBaseBitmap() - { - // init a zero... - B_input = 0; - /* ----------------------------------------------------- - * bitmap MAPO - * B0: POWER_ON - * B1: RUN - * B2: pzCount - * B3: allarme - * B4: manuale - * B5: emergenza - * B6: error prog - * B7: auto mode - ----------------------------------------------------- */ - // bit 0 (poweron) imposto a 1 SE connected... - B_input = KAWASAKI_ref.IsConnected ? 1 : 0; - // RUN - if (cStatus[2] == '1') - { - B_input += (1 << 1); - } - // ERROR prog/macchina - if (cStatus[3] == '1') - { - B_input += (1 << 6); - } - // allarme - if (cStatus[4] == '1') - { - B_input += (1 << 3); - } - // Automatico (porta chiusa) - if (cStatus[6] == '1' || cStatus[1] == '1') - { - B_input += (1 << 4); - } - // NON EMERGENZA (1=armed, 0=triggered) - if (cStatus[5] == '0') - { - B_input += (1 << 5); - } - // procedo SOLO SE è enabled IOB - if (IobOnline) - { - try - { - currODL = utils.callUrl(urlGetCurrODL); - // solo SE HO un ODL... - if (string.IsNullOrEmpty(currODL) || currODL == "0") - { - if (periodicLog) - { - lgInfo(string.Format("Kawasaki | Lettura ODL andata a vuoto: currODL: {0}", currODL)); - } - } - else - { // se variato o scaduto timeout log... - if (periodicLog || (currIdxODL.ToString() != currODL)) - { - lgInfo(string.Format("Kawasaki | Lettura ODL, currODL: {0} --> currIdxODL prec: {1}", currODL, currIdxODL)); - } - // provo a salvare nuovo ODL - int.TryParse(currODL, out currIdxODL); - } - } - catch (Exception exc) - { - if (DateTime.Now.Subtract(lastWarnODL).TotalSeconds > 15) - { - lgError(exc, "Errore in fase di chiamata URL x ODL corrente | URL chiamato: {0}", urlGetCurrODL); - lastWarnODL = DateTime.Now; - } - } - } - else - { - // imposto currODL a vuoto! - currODL = ""; - if (periodicLog) - { - lgInfo($"Kawasaki | Lettura ODL non effettuata: IobOnline: {IobOnline} | currODL impostato a vuoto"); - } - } - if (!string.IsNullOrEmpty(currODL)) - { - if (currODL != "0") - { - // ora processo il contapezzi... controllo se è passato intervallo minimo tra 2 - // controlli/elaborazioni x distanziare invio e ridurre letture - if (DateTime.Now >= lastPzCountSend.AddMilliseconds(pzCountDelay)) - { - // se sono differenti MOSTRO... - if (contapezziPLC != contapezziIOB) - { - // registro contapezzi - lgInfo($"Differenza Contapezzi CNC/IOB: contapezziPLC: {contapezziPLC} | contapezziIOB: {contapezziIOB}"); - } - // verifico se variato contapezzi... e se passato ritardo minimo... - if (contapezziPLC > contapezziIOB) - { - // salvo nuovo contapezzi (incremento di 1...) + richiesta refresh conteggio - contapezziIOB++; - needRefreshPzCount = true; - // salvo in semaforo! - B_input += (1 << 2); - // registro contapezzi - lgInfo($"contapezziPLC KAWASAKI: {contapezziPLC} | contapezziIOB {contapezziIOB}"); - } - else if (contapezziIOB > contapezziPLC) - { - lgInfo($"Contapezzi IOB > CNC --> NON INVIO (contapezziPLC: {contapezziPLC} < contapezziIOB: {contapezziIOB})"); - } - - // 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 KAWASAKI: contapezziPLC {contapezziPLC} | contapezziIOB {contapezziIOB} | risposta: {retVal}"); - // rileggo il counter pezzi da server - pzCntReload(true); - } - // resetto timer... - lastPzCountSend = DateTime.Now; - } - } - else - { - lgError("Attenzione non trovato ODL --> currODL = 0"); - } - } - else - { - if (DateTime.Now >= lastPzCountSend.AddMilliseconds(pzCountDelay)) - { - lgError($"Attenzione: mancanza ODL non procedo con gestione contapezzi. contapezziPLC KAWASAKI {contapezziPLC} | contapezziIOB {contapezziIOB}"); - // resetto timer... - lastPzCountSend = DateTime.Now; - } - } - - // log opzionale! - if (verboseLog) - { - lgInfo($"Trasformazione B_input: {B_input}"); - } - } - - /// - /// Test completo funzioni kawasaki - /// - private void kawasakiFullTest() - { - // faccio un try-catch di test vari... - try - { - //string connPar = string.Format("TCP {0}", cIobConf.cncIpAddr); - //KAWASAKI_ref = new KRcc.Commu(connPar); - //KAWASAKI_ref = new KRcc.Commu("TCP 192.168.0.92"); - if (KAWASAKI_ref.IsConnected) - { - // connect ok - resDataArray = KAWASAKI_ref.command("where", 3000); - // WHERE [RET] Console.WriteLine(resDataArray[1]); [0] = 0 [1] = JT1 JT2 JT3 JT4 - // JT5 JT6 - // -23.205 - 39.967 - 13.176 95.663 71.402 - 21.512 X[mm] Y[mm] Z[mm] O[deg] - // A[deg] T[deg] - // - 489.620 693.940 1564.733 92.612 131.285 7.482 - - threadOk = commThreadOk; - macName = machineName; - cStatus = currBitmapStatus; - cSignals = currBitmapSignals; - contapezziPLC = pzCounter; - numPzPrel = pzPrelevati; - lastRecTC = lastTC; - lastMissRobot = lastMission; - } - // test contapezzi -#if false - // leggo i pezzi - int currCount = pzCounter; - // imposto a 100 - pzCounter = 100; - // rileggo x verifica - int newCount = pzCounter; - // reimposto corretti - pzCounter = currCount; -#endif - // test gest programmi -#if true - //saveProgram("prog", "default"); - sendProgram("prog", "default2"); -#endif - } - catch (Exception e) - { // e.Message = "can't connect TCP/IP" or // "can't login" - Console.WriteLine(e.Message); - } - } - - /// - /// Effettua salvataggio del programma corrente - /// - /// Dir di riferimento - /// Nome Programma (se mancasse *.as lo aggiunge) - private void saveProgram(string progDir = "prog", string progName = "current.as") - { - // path completo - progName = progName.EndsWith(".as") ? progName : progName + ".as"; - string prgPath = progName;// string.Format("{0}/{1}", progDir, progName); - if (KAWASAKI_ref.IsConnected) - { - // comandi x setup programma... - resDataArray = KAWASAKI_ref.command("ferma", 3000); // ferma processi (all) --> "" - resDataArray = KAWASAKI_ref.command("togli", 3000); // toglie processi da pronta esecuzione --> "" - - //resp = com.command("SAVE nome_del_file", 3000); // salvataggio file... FORSE --> "\u0005\u0002Bnome_del_file.as\u0017" --> verificare DOVE salva... - - int ret = KAWASAKI_ref.save(prgPath); // SAVE current.as[RET] - if (ret == 0) - { - // Success - } - if (ret == -1) - { - // Communication error - } - if (ret == -2) - { - // Robot Controller error - } - if (ret == -3) - { - // Internal error - } - } - } - - /// - /// Effettua invio del programma di alvorazione al ROBOT Dir di - /// riferimentoNome Programma (se mancasse *.as lo aggiunge) - /// - private void sendProgram(string progDir = "prog", string progName = "default.as") - { - // path completo - progName = progName.EndsWith(".as") ? progName : progName + ".as"; - string prgPath = progName;// string.Format("{0}/{1}", progDir, progName); - - // comandi x setup programma... - resDataArray = KAWASAKI_ref.command("ferma", 3000); // ferma processi (all) --> "" - resDataArray = KAWASAKI_ref.command("togli", 3000); // toglie processi da pronta esecuzione --> "" - - if (KAWASAKI_ref.IsConnected) - { - // carico... - KAWASAKI_ref.asInquiry = delegate (string as_msg) - { - Console.WriteLine(as_msg); if (as_msg.StartsWith("Are you sure ?")) - { - return "0\n"; // 0 [RET] - } - - if (as_msg.StartsWith("Load data?")) - { - return "1\n"; // 1 [RET] - } - - return null; - }; - int retLoad = KAWASAKI_ref.load(prgPath, "/Q"); // LOAD/Q default.as[RET] - } - } - - #endregion Private Methods - } -} \ No newline at end of file diff --git a/IOB-WIN-NEXT/Iob/Mitsubishi.cs b/IOB-WIN-NEXT/Iob/Mitsubishi.cs deleted file mode 100644 index 28c5035d..00000000 --- a/IOB-WIN-NEXT/Iob/Mitsubishi.cs +++ /dev/null @@ -1,2144 +0,0 @@ -using EgwProxy.MultiCncLib.CNC; -using IOB_UT_NEXT; -using MapoSDK; -using Newtonsoft.Json; -using Org.BouncyCastle.Utilities.Collections; -using System; -using System.Collections.Generic; -using System.Data.SqlTypes; -using System.Linq; -using System.Net; -using System.Net.NetworkInformation; -using System.Text; -using System.Threading; - -namespace IOB_WIN_NEXT.Iob -{ - public class Mitsubishi : Iob.GenericNext - { - #region Public Constructors - - /// - /// Estende l'init della classe base... - /// - /// - /// - public Mitsubishi(AdapterFormNext caller, IobConfiguration IOBConf) : base(caller, IOBConf) - { - lgInfo("Start init Mitsubishi"); - // gestione invio ritardato contapezzi - pzCountDelay = utils.CRI("pzCountDelay"); - lastPzCountSend = DateTime.Now; - lastWarnODL = DateTime.Now; - - // inizializzo correttamente aree memoria secondo CONF - iniFileName - IniFile fIni = new IniFile(IOBConf.iniFileName); - - // inizializzo aree di memoria correnti... - MemVarStart = fIni.ReadInteger("MEMORY", "AREAV_START", 500); - MemVarSize = fIni.ReadInteger("MEMORY", "AREAV_SIZE", 1); - ParamStart = fIni.ReadInteger("MEMORY", "PAR_START", 8001); - ParamSize = fIni.ReadInteger("MEMORY", "PAR_SIZE", 1); - SignStart = fIni.ReadInteger("MEMORY", "SIGN_START", 10096); - SignSize = fIni.ReadInteger("MEMORY", "SIGN_SIZE", 1); - - // loggo aree di memoria avviate... - lgInfo($"Avviata area di memoria Var: {MemVarSize} vars"); - lgInfo($"Avviata area di memoria Param: {ParamSize} params"); - - // fix enable prgName - enablePrgName = fIni.ReadBoolean("CNC", "GETPRGNAME", true); - - // effettuo lettura della conf sigLUT... cercando 1:1 i bit... - string currBit = ""; - string memArea = ""; - for (int i = 0; i < 8; i++) - { - currBit = $"BIT{i}"; - memArea = fIni.ReadString("MEMORY", currBit, ""); - // se trovo un valore... - if (!string.IsNullOrEmpty(memArea)) - { - signLUT.Add(currBit, memArea); - } - } - - // recupero sysType del controllo, sennò default M700L... - string sEZNC_SYS = getOptPar("EZNC_SYS"); - if (!string.IsNullOrEmpty(sEZNC_SYS)) - { - sysType = (SYSTEMTYPE)Enum.Parse(typeof(SYSTEMTYPE), sEZNC_SYS); - } - lgInfo($"Start init Mitsubishi | SysType: {sysType}"); - - // gestione override contapezzi - enablePzCountByApp = utils.CRB("enableContapezzi"); - enablePzCountByIob = (getOptPar("ENABLE_PZCOUNT") == "TRUE"); - disablePzCountByIob = (getOptPar("DISABLE_PZCOUNT") == "FALSE"); - - // gestione override idx articoli... - if (!string.IsNullOrEmpty(getOptPar("NUM_ART_CHR_TRIM"))) - { - string NUM_ART_CHR_TRIM = getOptPar("NUM_ART_CHR_TRIM"); - bool.TryParse(NUM_ART_CHR_TRIM, out numArtCharTrim); - } - if (!string.IsNullOrEmpty(getOptPar("MAX_CHAR_DESC"))) - { - string MAX_CHAR_DESC = getOptPar("MAX_CHAR_DESC"); - int.TryParse(MAX_CHAR_DESC, out maxVarStrLen); - } - - // leggo conf x ricerca valori memoria da tracciare in log di continuo... - mem2trace = fIni.ReadString("OPTPAR", "MEM_2_TRACE", ""); - - // è little endian (NON serve conversione) - hasBigEndian = false; - lgInfoStartup($"Start init Adapter MITSUBISHI | IP {IOBConf.cncIpAddr}:{IOBConf.cncPort} per IOB {IOBConf.codIOB}"); - - // Creo oggetto connessione NC - parentForm.commPlcActive = true; - - // init oggetto - oEZNcAutCom = new EZNCAUTLib.DispEZNcCommunication(); - int.TryParse(IOBConf.cncPort, out ezPort); - ipAddr = IOBConf.cncIpAddr; - - parentForm.commPlcActive = false; - - // effettuo tryConnect... - lgInfo("MITSUBISHI startup: tryConnect"); - tryConnect(); - if ((enablePzCountByApp || enablePzCountByIob) && !(disablePzCountByIob)) - { - lgInfo("MITSUBISHI: inizio gestione contapezzi"); - try - { - // verifico quale modalità sia richiesta: STD (6711) oppure BIT (Custom, con - // indicazione area) - if (cIobConf.optPar.Count > 0 && !string.IsNullOrEmpty(getOptPar("PZCOUNT_MODE"))) - { - if (getOptPar("PZCOUNT_MODE").StartsWith("STD")) - { - lgInfo("Init contapezzi MITSUBISHI: pzCntReload(true)"); - pzCntReload(true); - // refresh associazione Macchina - IOB - SendM2IOB(); - // invio altri dati accessori... - SendMachineConf(); - // per adesso imposto lettura MITSUBISHI == contapezzi (poi farà vera lettura...) - contapezziPLC = contapezziIOB; - } - else - { - contapezziIOB = 0; - lgInfo("Contapezzi STD disabilitato: modalità {0}", getOptPar("PZCOUNT_MODE")); - } - } - else - { - contapezziIOB = 0; - lgInfo("Parametro mancante PZCOUNT_MODE"); - } - } - catch (Exception exc) - { - lgError(exc, "Errore in contapezzi MITSUBISHI 01"); - } - } - // finisco INIT ADAPTER - lgInfo("End init Adapter MITSUBISHI"); - } - - #endregion Public Constructors - - #region Public Methods - - /// - /// Processo i task richiesti e li elimino dalla coda 1:1 - /// - /// - public override Dictionary executeTasks(Dictionary task2exe) - { - // Verificare il protocollo: dovrebbe togliere SOLO i task eseguiti... - Dictionary taskDone = new Dictionary(); - if (task2exe != null) - { - bool taskOk = false; - string taskVal = ""; - string newVal = ""; - string memAddr = ""; - long valLong = 0; - // cerco task specifici: se ho startSetup --> imposto bit DBB701.DBB0.4 - foreach (var item in task2exe) - { - taskOk = false; - taskVal = ""; - // converto richiesta in enum... - taskType tName = taskType.nihil; - Enum.TryParse(item.Key, out tName); - switch (tName) - { - case taskType.setArt: - case taskType.setComm: - lgInfo($"Richiesta scrittura {tName}"); - // salvo in memoria il valore richiesto... - if (memMap != null && memMap.mMapWrite != null) - { - if (memMap.mMapWrite.ContainsKey(item.Key)) - { - dataConf currMem = memMap.mMapWrite[item.Key]; - memAddr = currMem.memAddr; - taskVal = $"SET task: {item.Key} --> {newVal} | mem: {currMem.memAddr} - {currMem.size} byte"; - // salvo il nuovo valore nella memoria... così prox invio lo trasmetterà - memMap.mMapWrite[item.Key].value = newVal; - } - else - { - taskVal = $"NO DATA MEM, SET task: {item.Key} --> {newVal} ({item.Value})"; - } - } - else - { - taskVal = $"NO MemMap found, SET task: {item.Key} --> {newVal} ({item.Value})"; - } - // salvo in currProd.. - upsertKey(item.Key, item.Value); - break; - - case taskType.nihil: - case taskType.fixStopSetup: - case taskType.forceResetPzCount: - case taskType.setProg: - case taskType.forceSetPzCount: - case taskType.sendWatchDogMes2Plc: - taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC"; - lgInfo($"Chiamata senza processing: taskOk: {taskOk} | taskVal: {taskVal}"); - break; - - case taskType.setArtNum: - lgInfo($"Richiesta scrittura CodART numerico"); - // in primis faccio una chiamata per tutta la tab SE fosse vuoto il dict - // di traduzione - if (DictNumArt == null || DictNumArt.Count == 0) - { - getNumArt(""); - lgInfo($"Recuperato DictNumArt, trovati {DictNumArt.Count} rec"); - } - // chiamo server x avere decodifica valore INT - newVal = getNumArt(item.Value); - // se c'è gestione semplificata num articolo --> usa trim dei soli - // caratteri alfabetici lasciando numeri.. - if (numArtCharTrim) - { - newVal = baseUtils.GetNumbers(item.Value); - } - // converto int... - long.TryParse(newVal, out valLong); - // procedo come il resto cercando mappatura in memMap: recupero dati da memMap... - if (memMap != null && memMap.mMapWrite != null) - { - if (memMap.mMapWrite.ContainsKey(item.Key)) - { - dataConf currMem = memMap.mMapWrite[item.Key]; - memAddr = currMem.memAddr; - taskVal = $"SET task: {item.Key} --> {newVal} | mem: {currMem.memAddr} - {currMem.size} byte"; - // salvo il nuovo valore nella memoria... così prox invio lo trasmetterà - memMap.mMapWrite[item.Key].value = newVal; - } - else - { - taskVal = $"NO DATA MEM, SET task: {item.Key} --> {newVal} ({item.Value})"; - } - } - else - { - taskVal = $"NO MemMap found, SET task: {item.Key} --> {newVal} ({item.Value})"; - } - - // invio a controller... - taskOk = setNumArt(valLong); - //se ho successo rileggo ed eventualmente sistemo valore - if (taskOk) - { - var rVal = getValByMemAddr(memAddr); - if (rVal == newVal) - { - lgInfo("All OK"); - // invio aggiornamento x reset richiesta... test! - sendOptVal(item.Key, newVal); - } - else - { - lgError($"Error | memAddr: {memAddr} | rVal: {rVal} | newVal: {newVal}"); - } - } - else - { - lgError("Errore in scrittura SetNumArt"); - } - // salvo in currProd.. - upsertKey(item.Key, item.Value); - break; - - case taskType.setCommNum: - lgInfo($"Richiesta scrittura cod COMMESSA numerica"); - // chiamo server x avere decodifica valore INT - newVal = getNumComm(item.Value); - // converto int... - long.TryParse(newVal, out valLong); - //riscrivo senza eventuali zeri... - newVal = valLong > 0 ? $"{valLong}" : newVal; - lgTrace($"Conv.Int numComm | newVal: {newVal} | valLong: {valLong}"); - // procedo come il resto cercando mappatura in memMap: recupero dati da memMap... - if (memMap != null && memMap.mMapWrite != null) - { - if (memMap.mMapWrite.ContainsKey(item.Key)) - { - dataConf currMem = memMap.mMapWrite[item.Key]; - memAddr = currMem.memAddr; - taskVal = $"SET task: {item.Key} --> {newVal} | mem: {currMem.memAddr} - {currMem.size} byte"; - // salvo il nuovo valore nella memoria... così prox invio lo trasmetterà - memMap.mMapWrite[item.Key].value = newVal; - } - else - { - taskVal = $"NO DATA MEM, SET task: {item.Key} --> {newVal} ({item.Value})"; - } - } - else - { - taskVal = $"NO MemMap found, SET task: {item.Key} --> {newVal} ({item.Value})"; - } - - // invio a controller... - taskOk = setNumCom(valLong); - //se ho successo rileggo ed eventualmente sistemo valore - if (taskOk) - { - //var rVal = getValByParam("SET_NUM_COM"); - var rVal = getValByMemAddr(memAddr); - if (rVal == newVal) - { - lgInfo("All OK"); - // invio aggiornamento x reset richiesta... test! - sendOptVal(item.Key, newVal); - } - else - { - lgError($"Error | memAddr: {memAddr} | rVal: {rVal} | newVal: {newVal}"); - } - } - else - { - lgError("Errore in scrittura SetNumCom"); - } - // salvo in currProd.. - upsertKey(item.Key, item.Value); - break; - - case taskType.setPzComm: - int pzReq = 0; - int.TryParse(item.Value, out pzReq); - // procedo come il resto cercando mappatura in memMap: recupero dati da memMap... - if (memMap != null && memMap.mMapWrite != null) - { - if (memMap.mMapWrite.ContainsKey(item.Key)) - { - dataConf currMem = memMap.mMapWrite[item.Key]; - memAddr = currMem.memAddr; - taskVal = $"SET task: {item.Key} --> {newVal} | mem: {currMem.memAddr} - {currMem.size} byte"; - // salvo il nuovo valore nella memoria... così prox invio lo trasmetterà - memMap.mMapWrite[item.Key].value = newVal; - } - else - { - taskVal = $"NO DATA MEM, SET task: {item.Key} --> {newVal} ({item.Value})"; - } - } - else - { - taskVal = $"NO MemMap found, SET task: {item.Key} --> {newVal} ({item.Value})"; - } - // set pezzi richiesti inizio setup - taskOk = setPzComm(pzReq); - //se ho successo rileggo ed eventualmente sistemo valore - if (taskOk) - { - var rVal = getValByMemAddr(memAddr); - if (rVal == newVal) - { - lgInfo("All OK"); - // invio aggiornamento x reset richiesta... test! - sendOptVal(item.Key, newVal); - } - else - { - lgError($"Error | memAddr: {memAddr} | rVal: {rVal} | newVal: {newVal}"); - } - } - else - { - lgError("Errore in scrittura SetNumCom"); - } - taskVal = taskOk ? "RESET: SETUP START" : "PZ RESET DISABLED | NO EXEC"; - lgInfo($"Chiamata startSetup: taskOk: {taskOk} | taskVal: {taskVal}"); - - // salvo in currProd.. - upsertKey(item.Key, item.Value); - break; - - case taskType.startSetup: - // reset contapezzi inizio setup - taskOk = resetContapezziPLC(); - taskVal = taskOk ? "RESET: SETUP START" : "PZ RESET DISABLED | NO EXEC"; - lgInfo($"Chiamata startSetup: taskOk: {taskOk} | taskVal: {taskVal}"); - break; - - case taskType.stopSetup: - // reset contapezzi fine setup SE ESPLICITAMENTE IMPOSTATO - if (cIobConf.optPar.Count > 0 && getOptPar("ENABLE_PZ_RESET_stopSetup") == "TRUE") - { - taskOk = resetContapezziPLC(); - } - taskVal = taskOk ? "RESET: SETUP END" : "PZ RESET DISABLED | NO EXEC"; - lgInfo($"Chiamata stopSetup: taskOk: {taskOk} | taskVal: {taskVal}"); - break; - - case taskType.setParameter: - lgInfo($"Chiamata setParameter | NO processing: taskOk: {taskOk} | taskVal: {taskVal}"); - taskVal = "setParameter | SKIPPED | NO EXEC"; - break; - - default: - lgInfo($"Chiamata default senza processing: taskOk: {taskOk} | taskVal: {taskVal}"); - taskVal = "SKIPPED | NO EXEC"; - break; - } - - // aggiungo task! - taskDone.Add(item.Key, taskVal); - } - } - return taskDone; - } - - /// - /// Recupero dati dinamici... - /// - public override Dictionary getDynData() - { - Dictionary outVal = new Dictionary(); - // processo SOLO SE connected... - if (connectionOk) - { - // leggo i valori Var - ReadMitsubVars(); - - // cerco tra tutte le aree write le VARS... - foreach (var item in memMap.mMapWrite) - { - if (item.Value.memAddr.StartsWith("VAR")) - { - // certo in dict ed accodo... - int iVar = 0; - string sVar = item.Value.memAddr.Replace("VAR.", ""); - int.TryParse(sVar, out iVar); - if (iVar > 0) - { - // cerco in dizionario... - if (DictVar.ContainsKey(iVar)) - { - outVal.Add(item.Key, $"{DictVar[iVar]}"); - upsertKey(item.Key, $"{DictVar[iVar]}"); - } - } - } - } - // cerco tra tutte le aree read le VARS... - foreach (var item in memMap.mMapRead) - { - if (item.Value.memAddr.StartsWith("VAR")) - { - // certo in dict ed accodo... - int iVar = 0; - string sVar = item.Value.memAddr.Replace("VAR.", ""); - int.TryParse(sVar, out iVar); - if (iVar > 0) - { - // cerco in dizionario... - if (DictVar.ContainsKey(iVar)) - { - outVal.Add(item.Key, $"{DictVar[iVar]}"); - upsertKey(item.Key, $"{DictVar[iVar]}"); - } - } - } - } - // aggiungo DynData... calcolato come variazione pezzi e lampade... - if (outVal.ContainsKey("DYNDATA")) - { - outVal.Remove("DYNDATA"); - } - StringBuilder sb = new StringBuilder(); - // inserisco i segnali - sb.Append("SIGN:["); - foreach (var item in DictSign) - { - sb.Append($"{item.Key}:{item.Value}|"); - } - // inserisco parametri - sb.Append("] PAR:["); - foreach (var item in DictParam) - { - sb.Append($"{item.Key}:{item.Value}|"); - } - // inserisco le variabili - sb.Append("] VAR:["); - foreach (var item in outVal) - { - sb.Append($"{item.Value}|"); - } - sb.Append("]"); - outVal.Add("DYNDATA", sb.ToString()); - } - return outVal; - } - - /// - /// Recupero programma in lavorazione - /// - /// - public override string getPrgName() - { - string prgName = ""; - // recupero NUOVO prgName... - try - { - int iRet = oEZNcAutCom.Program_GetProgramNumber2((Int32)PROGRAMTYPE.EZNC_MAINPRG, out String strProgramNo); - - // recupero nome programma MAIN - prgName = utils.purgedChar2String(strProgramNo); - // trimmo path del programma SE presente - prgName = prgName.Replace(utils.CRS("basePrgMemPath"), ""); - lgInfo("Current PROG: {0}", prgName); - } - catch (Exception exc) - { - lgError(string.Format("Eccezione in recupero PRG NAME MAIN:{0}{1}", Environment.NewLine, exc)); - connectionOk = false; - } - return prgName; - } - - /// - /// Recupero info lavorazione come Dictionary... - /// - SYSINFO: (prima KEY globale) TUTTI i valori separati da # (x fare check modifica) - /// - altre stringhe: ogni singolo parametro / valore - /// - /// - public override Dictionary getSysInfo() - { - Dictionary outVal = new Dictionary(); - stopwatch.Restart(); - try - { - oEZNcAutCom.System_GetSystemInformation(0, out int partSys); - outVal.Add("PartSys", $"{partSys}"); - oEZNcAutCom.System_GetSystemInformation(1, out int numAx); - outVal.Add("NumAxis", $"{numAx}"); - oEZNcAutCom.System_GetSerialNo(out string serNo); - outVal.Add("SerialNo", $"{serNo}"); - for (int i = 0; i < 3; i++) - { - oEZNcAutCom.System_GetVersion(0, i, out string pVers); - outVal.Add($"V_{i}", $"{pVers}"); - } - } - catch (Exception exc) - { - lgError($"Eccezione in getSysInfo{Environment.NewLine}{exc}"); - connectionOk = false; - } - if (utils.CRB("recTime")) - { - TimingData.addResult(cIobConf.codIOB, string.Format("SYS-INFO"), stopwatch.ElapsedTicks); - } - return outVal; - } - - /// - /// Effettua vero processing contapezzi da configurazione - /// PZCOUNT_MODE: pezzi lavorati (parziale) - /// PZGTOT_MODE: pezzi lavorati totali - /// PZREQ_MODE: pezzi richiesti - /// - public override void processContapezzi() - { - if ((enablePzCountByApp || enablePzCountByIob) && !(disablePzCountByIob)) - { - // procedo SOLO SE ho connessione... - if (connectionOk) - { - try - { - // lettura parametri per procedere - ReadMitsubParams(); - // controllo di AVERE parametri opzionali x conteggi vari - if (cIobConf.optPar.Count > 0) - { - // contapezzi ATTUALE - string memAddr = getOptPar("PZCOUNT_MODE"); - if (!string.IsNullOrEmpty(memAddr)) - { - // verifico quale modalità sia richiesta: STD oppure CST (Custom, TBD) - if (memAddr.StartsWith("STD")) - { - // inizio verifica area memoria/parametro levando prima parte codice - memAddr = memAddr.Replace("STD.", ""); - } - - // verifico SE sia di tipo PAR e cerco valore... - int cntAddr = 0; - if (memAddr.StartsWith("PAR.")) - { - // recupero parametro... - int.TryParse(memAddr.Replace("PAR.", ""), out cntAddr); - } - // cerco in dizionario... - if (DictParam.ContainsKey(cntAddr)) - { - string rawVal = DictParam[cntAddr]; - int newVal = -1; - Int32.TryParse(rawVal, out newVal); - contapezziPLC = newVal > -1 ? newVal : contapezziPLC; - } - - stopwatch.Stop(); - } - } - } - catch (Exception exc) - { - lgError(exc, "Errore in contapezzi MITSUBISHI 02"); - connectionOk = false; - } - } - else - { - lgError("Errore: manca connessione in contapezzi MITSUBISHI"); - } - } - } - - /// - /// Recupero altri counters se ci sono - /// - public override void processOtherCounters() - { - try - { - // lettura parametri per procedere - ReadMitsubParams(); - - // controllo di AVERE parametri opzionali x conteggi vari - if (cIobConf.optPar.Count > 0) - { - // gestione con ricerca in memoria Write / optPar... - if (string.IsNullOrEmpty(memAddrPzReq)) - { - lgTrace("PzReq disabilitato | NO memConf.Write | NO optPar"); - } - else - { - sendOptVal(memNamePzReq, getValByMemAddr(memAddrPzReq)); - } - if (string.IsNullOrEmpty(memAddrArt)) - { - lgTrace("Articolo disabilitato | NO memConf.Write | NO optPar"); - } - else - { - sendOptVal(memNameArt, getValByMemAddr(memAddrArt)); - } - if (string.IsNullOrEmpty(memAddrCom)) - { - lgTrace("Commessa disabilitata | NO memConf.Write | NO optPar"); - } - else - { - sendOptVal(memNameCom, getValByMemAddr(memAddrCom)); - } - if (string.IsNullOrEmpty(memAddrPzCnt)) - { - lgTrace("PzCount disabilitato | NO memConf.Write | NO optPar"); - } - else - { - sendOptVal(memNamePzCnt, getValByMemAddr(memAddrPzCnt)); - } - if (string.IsNullOrEmpty(memAddrPzCntTot)) - { - lgTrace("PzCntTOT disabilitato | NO memConf.Write | NO optPar"); - } - else - { - sendOptVal(memNamePzCntTot, getValByMemAddr(memAddrPzCntTot)); - } - if (string.IsNullOrEmpty(memAddrCaden)) - { - lgTrace("Cadenza disabilitata | NO memConf.Write | NO optPar"); - } - else - { - sendOptVal(memNameCaden, getValByMemAddr(memAddrCaden)); - } - } - } - catch (Exception exc) - { - lgError(exc, "Eccezione in processOtherCounters"); - } - } - - /// - /// Effettua lettura semafori principale Parametri da - /// aggiornare x display in form - /// - public override void readSemafori(ref newDisplayData currDispData) - { - DateTime adesso = DateTime.Now; - base.readSemafori(ref currDispData); - // verifico non sia in veto invio iniziale... - if (queueInEnabCurr) - { - try - { - if (verboseLog) - { - lgInfo("inizio read semafori"); - } - - currDispData.semIn = Semaforo.SV; - ReadMitsubGenData(); - // salvo il solo BYTE dell'input decifrando il semaforo... - decodeToBitmap(); - reportRawInput(ref currDispData); - } - catch (Exception exc) - { - lgError(string.Format("Eccezione in readSemafori:{0}{1}", Environment.NewLine, exc)); - connectionOk = false; - currDispData.semIn = Semaforo.SR; - } - } - else - { - lgDebug($"[VETO readSemafori] | veto attivo alle {adesso:yyyy.MM.dd HH:mm:ss}"); - checkVetoQueueIn(); - } - } - - /// - /// 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") - { - // scrivo valore 0 x il contapezzi - try - { - // contapezzi ATTUALE - if (!string.IsNullOrEmpty(getOptPar("PZCOUNT_MODE"))) - { - int valReq = 0; - // scrivo valore 0 x il contapezzi - try - { - answ = writeMitsubMem("NumPz", memAddrPzCnt, valReq); - } - catch (Exception exc) - { - lgError($"Errore in SET NumPz MITSUBISHI{Environment.NewLine}{exc}"); - } - answ = true; - } - } - catch (Exception exc) - { - lgError(exc, "Errore in RESET contapezzi MITSUBISHI"); - connectionOk = false; - } - answ = true; - } - return answ; - } - - /// - /// Effettua impostazione del valore numerico ARTICOLO (specifico MITSUBISHI) - /// - /// - public bool setNumArt(double valReq) - { - bool answ = false; - string memAddr = memAddrArt; - lgTrace($"INIT setNumArt | memAddr: {memAddr}"); - if (cIobConf.optPar.Count > 0 && !string.IsNullOrEmpty(memAddr)) - { - // scrivo valore richiesto in area configurata - try - { - answ = writeMitsubMem("CodArt", memAddr, valReq); - } - catch (Exception exc) - { - lgError(exc, "Errore in setNumArt MITSUBISHI"); - } - } - return answ; - } - - /// - /// Effettua impostazione del valore numerico COMMESSA (specifico MITSUBISHI) - /// - /// - public bool setNumCom(double valReq) - { - bool answ = false; - // verifico quale modalità sia richiesta - string memAddr = memAddrCom; - lgTrace($"INIT setNumCom | memAddr: {memAddr}"); - if (cIobConf.optPar.Count > 0 && !string.IsNullOrEmpty(memAddr)) - { - lgTrace($"setNumCom | memAddr: {memAddr} | valReq: {valReq}"); - // scrivo valore richiesto in area configurata - try - { - answ = writeMitsubMem("ODL", memAddr, valReq); - } - catch (Exception exc) - { - lgError(exc, "Errore in setNumCom MITSUBISHI"); - } - answ = true; - } - return answ; - } - - /// - /// Effettua impostazione del conteggio pezzi richiesti - /// - /// - public override bool setPzComm(int valReq) - { - bool answ = false; - // ...SE abilitato da conf IOB - if (cIobConf.optPar.Count > 0 && getOptPar("ENABLE_PZ_REQ") == "TRUE") - { - // scrivo valore 0 x il contapezzi - try - { - bool write1 = writeMitsubMem("NumPz", memAddrPzReq, valReq); - bool write2 = writeMitsubMem("PzOdl", memAddrPzReqOdl, valReq); - answ = write1 && write2; - } - catch (Exception exc) - { - lgError($"Errore in SET NumPz MITSUBISHI{Environment.NewLine}{exc}"); - } - answ = true; - } - return answ; - } - - /// - /// Override connessione - /// - public override void tryConnect() - { - if (!connectionOk) - { - // controllo che il ping sia stato tentato almeno pingTestSec fa... - if (DateTime.Now.Subtract(lastPING).TotalSeconds > utils.CRI("pingTestSec")) - { - if (verboseLog || periodicLog) - { - lgInfo("MITSUBISHI: ConnKO - tryConnect"); - } - // in primis salvo data ping... - lastPING = DateTime.Now; - // ora PING!!! - Ping pingSender = new Ping(); - IPAddress address = IPAddress.Loopback; - IPAddress.TryParse(cIobConf.cncIpAddr, out address); - PingReply reply; - try - { - // se != null --> uso address... - if (address != null) - { - reply = pingSender.Send(address, 100); - } - else - { - reply = pingSender.Send(cIobConf.cncIpAddr, 100); - } - } - catch - { - reply = pingSender.Send(IPAddress.Loopback, 100); - } - // se passa il ping faccio il resto... - if (reply.Status == IPStatus.Success) - { - string szStatusConnection = ""; - try - { - // ora provo connessione... - parentForm.commPlcActive = true; - - // Open communication - int iRet = 0; - oEZNcAutCom = new EZNCAUTLib.DispEZNcCommunication(); - iRet = oEZNcAutCom.SetTCPIPProtocol(ipAddr, ezPort); - iRet = oEZNcAutCom.Open3((int)sysType, 1, 10, hostName); - parentForm.commPlcActive = false; - lgInfo($"Mitubishi | open Result: {iRet}"); - connectionOk = iRet == 0; - connectionOk = true; - // refresh stato allarmi!!! - if (connectionOk) - { - checkVetoQueueIn(); - dtAvvioAdp = DateTime.Now; - if (adpRunning) - { - lgInfo("Connessione OK"); - } - } - else - { - lgError("Impossibile procedere, connessione mancante..."); - } - } - catch (Exception exc) - { - lgFatal(string.Format("Errore nella connessione all'adapter MITSUBISHI: {0}{1}{2}", szStatusConnection, Environment.NewLine, exc)); - connectionOk = false; - lgInfo(string.Format("Eccezione in TryConnect, Adapter NON running, pausa di {0} msec prima di ulteriori tentativi di riconnessione", utils.CRI("waitRecMSec"))); - } - } - else - { - // loggo no risposta ping ... - connectionOk = false; - if (verboseLog || periodicLog) - { - lgInfo(string.Format("Attenzione: controllo PING fallito per IP {0} - {1}", cIobConf.cncPingAddr, reply.Status)); - } - } - } - } - // se non è ancora connesso faccio procesisng memoria caso disconnesso... - if (!connectionOk) - { - // processo semafori ed invio... - processMemoryDiscon(); - } - } - - /// - /// Override disconnessione - /// - public override void tryDisconnect() - { - if (connectionOk) - { - string szStatusConnection = ""; - try - { - // Close. - var iRet = oEZNcAutCom.Close(); - //Release object - oEZNcAutCom = null; - connectionOk = false; - // resetto timing! - TimingData.resetData(); - lgInfo(szStatusConnection); - lgInfo("Effettuata disconnessione adapter MITSUBISHI!"); - } - catch (Exception exc) - { - lgFatal(exc, "Errore nella disconnessione dall'adapter MITSUBISHI"); - } - } - else - { - lgError("IMPOSSIBILE effettuare disconnessione: Connessione non disponibile..."); - } - queueInEnabCurr = false; - } - - #endregion Public Methods - - #region Protected Fields - - /// - /// Porta di comunicazione INT - /// - protected int ezPort = 683; - - /// - /// Nome amcchina x connessione - /// - protected string hostName = "EZNC_LOCALHOST"; - - /// - /// Nome/IP del CN - /// - protected string ipAddr = ""; - - /// - /// Obj di comunicazione Mitsubishi - /// - protected EZNCAUTLib.DispEZNcCommunication oEZNcAutCom = null; - - #endregion Protected Fields - - #region Protected Methods - - /// - /// Metodo da overridare x scrivere DAVVERO i parametri sul PLC - /// - /// - protected override void plcWriteParams(ref List updatedPar) - { - lgTrace($"plcWriteParams: richiesta per {updatedPar.Count} params"); - foreach (var item in updatedPar) - { - lgInfo($"ITEM | {item.uid} | {item.value}"); - // effettuo scrittura SE configurata in write param... - bool fatto = false; - double valReq = 0; - if (memMap != null && memMap.mMapWrite != null) - { - if (memMap.mMapWrite.ContainsKey(item.uid)) - { - double.TryParse(item.value, out valReq); - var currSet = memMap.mMapWrite[item.uid]; - if (string.IsNullOrEmpty(currSet.memAddr)) - { - fatto = true; - } - else - { - fatto = writeMitsubMem(currSet.description, currSet.memAddr, valReq); - } - } - } - // salvo i valori ricevuti - upsertKey(item.uid, item.reqValue); - // se i valori richiesto e fatto corrispondono... resetto! - if (fatto && item.reqValue.Trim() == item.value.Trim()) - { - // resetto richiesta! - item.reqValue = ""; - } - } - } - - #endregion Protected Methods - - #region Private Fields - - private DateTime lastParRefr = DateTime.Now; - - private DateTime lastSigRefr = DateTime.Now; - - private DateTime lastVarRefr = DateTime.Now; - - /// - /// Max num caratteri string ammessi VAR label - /// - private int maxVarStrLen = 7; - - /// - /// Num celle Var da leggere - /// - private int MemVarSize = 1; - - /// - /// Indirizzo partenza lettura Var(100/500) - /// - private int MemVarStart = 500; - - /// - /// Num celle Param da leggere - /// - private int ParamSize = 1; - - /// - /// Indirizzo partenza lettura Param - /// - private int ParamStart = 8000; - - /// - /// LookUpTable di decodifica da CNC a segnali tipo bitmap MAPO - /// - private Dictionary signLUT = new Dictionary(); - - /// - /// Num celle Signal da leggere - /// - private int SignSize = 3; - - /// - /// Indirizzo partenza lettura Signal - /// - private int SignStart = 10096; - - /// - /// Tipo di controllo gestito - /// - private SYSTEMTYPE sysType = SYSTEMTYPE.EZNC_SYS_MELDAS700L; - - #endregion Private Fields - - #region Private Enums - - /// - /// Tipo program - /// - private enum PROGRAMTYPE - { - /// - /// Main Program メインプログラム - /// - EZNC_MAINPRG = 0, - - /// - /// Sub Program サブプログラム - /// - EZNC_SUBPRG = 1, - } - - /// - /// Controllo specifico da gestire - /// - private enum SYSTEMTYPE - { - /// - /// M700L - /// - EZNC_SYS_MELDAS700L = 5, - - /// - /// M700M - /// - EZNC_SYS_MELDAS700M = 6, - - /// - /// C70 - /// - EZNC_SYS_MELDASC70 = 7, - - /// - /// M800L - /// - EZNC_SYS_MELDAS800L = 8, - - /// - /// M800M - /// - EZNC_SYS_MELDAS800M = 9, - - /// - /// C80 - /// - EZNC_SYS_CNCC80 = 10, - } - - #endregion Private Enums - - #region Private Properties - - /// - /// Dictionary contenuto memorie Param - /// - private Dictionary DictParam { get; set; } = new Dictionary(); - - /// - /// Dictionary contenuto dati Signal (es Y) - /// - private Dictionary DictSign { get; set; } = new Dictionary(); - - /// - /// Dictionary contenuto memorie Var - /// - private Dictionary DictVar { get; set; } = new Dictionary(); - - private string memAddrArt - { - get - { - string memAddr = ""; - if (memMap != null && memMap.mMapWrite != null) - { - //cerco in primis modalità NUM altrimenti standard... - if (memMap.mMapWrite.ContainsKey("setArtNum")) - { - memAddr = memMap.mMapWrite["setArtNum"].memAddr; - } - // se vuoto provo altra alternativa... - if (string.IsNullOrEmpty(memAddr) && memMap.mMapWrite.ContainsKey("setArt")) - { - memAddr = memMap.mMapWrite["setArt"].memAddr; - } - } - // se non trovato... leggo da OPT_PAR - if (string.IsNullOrEmpty(memAddr)) - { - memAddr = getOptPar("SET_NUM_ART"); - } - // bonifica variabile da definizione STD iniziale... - if (memAddr.StartsWith("STD")) - { - memAddr = memAddr.Replace("STD.", ""); - } - return memAddr; - } - } - - private string memAddrCaden - { - get - { - string memAddr = ""; - if (memMap != null && memMap.mMapWrite != null) - { - //cerco in primis modalità NUM altrimenti standard... - if (memMap.mMapWrite.ContainsKey("Cadenza")) - { - memAddr = memMap.mMapWrite["Cadenza"].memAddr; - } - } - // se non trovato... leggo da OPT_PAR - if (string.IsNullOrEmpty(memAddr)) - { - memAddr = getOptPar("PZCAD_MODE"); - } - // bonifica variabile da definizione STD iniziale... - if (memAddr.StartsWith("STD")) - { - memAddr = memAddr.Replace("STD.", ""); - } - return memAddr; - } - } - - private string memAddrCom - { - get - { - string memAddr = ""; - if (memMap != null && memMap.mMapWrite != null) - { - //cerco in primis modalità NUM altrimenti standard... - if (memMap.mMapWrite.ContainsKey("setCommNum")) - { - memAddr = memMap.mMapWrite["setCommNum"].memAddr; - } - // se vuoto provo altra alternativa... - if (string.IsNullOrEmpty(memAddr) && memMap.mMapWrite.ContainsKey("setComm")) - { - memAddr = memMap.mMapWrite["setComm"].memAddr; - } - } - // se non trovato... leggo da OPT_PAR - if (string.IsNullOrEmpty(memAddr)) - { - memAddr = getOptPar("SET_NUM_COM"); - } - // bonifica variabile da definizione STD iniziale... - if (memAddr.StartsWith("STD")) - { - memAddr = memAddr.Replace("STD.", ""); - } - return memAddr; - } - } - - private string memAddrPzCnt - { - get - { - string memAddr = ""; - if (memMap != null && memMap.mMapWrite != null) - { - //cerco in primis modalità NUM altrimenti standard... - if (memMap.mMapWrite.ContainsKey("ContatoreParziale")) - { - memAddr = memMap.mMapWrite["ContatoreParziale"].memAddr; - } - } - // se non trovato... leggo da OPT_PAR - if (string.IsNullOrEmpty(memAddr)) - { - memAddr = getOptPar("PZCOUNT_MODE"); - } - // bonifica variabile da definizione STD iniziale... - if (memAddr.StartsWith("STD")) - { - memAddr = memAddr.Replace("STD.", ""); - } - return memAddr; - } - } - - private string memAddrPzCntTot - { - get - { - string memAddr = ""; - if (memMap != null && memMap.mMapWrite != null) - { - //cerco in primis modalità NUM altrimenti standard... - if (memMap.mMapWrite.ContainsKey("ContatoreAssoluto")) - { - memAddr = memMap.mMapWrite["ContatoreAssoluto"].memAddr; - } - } - // se non trovato... leggo da OPT_PAR - if (string.IsNullOrEmpty(memAddr)) - { - memAddr = getOptPar("PZGTOT_MODE"); - } - // bonifica variabile da definizione STD iniziale... - if (memAddr.StartsWith("STD")) - { - memAddr = memAddr.Replace("STD.", ""); - } - return memAddr; - } - } - - private string memAddrPzReq - { - get - { - string memAddr = ""; - if (memMap != null && memMap.mMapWrite != null) - { - //cerco in primis modalità NUM altrimenti standard... - if (memMap.mMapWrite.ContainsKey("setPzComm")) - { - memAddr = memMap.mMapWrite["setPzComm"].memAddr; - } - } - // se non trovato... leggo da OPT_PAR - if (string.IsNullOrEmpty(memAddr)) - { - memAddr = getOptPar("PZREQ_MODE"); - } - // bonifica variabile da definizione STD iniziale... - if (memAddr.StartsWith("STD")) - { - memAddr = memAddr.Replace("STD.", ""); - } - return memAddr; - } - } - - /// - /// Area memoria PzOdl, NON abilitata in scrittura utente (è duplo/copia) - /// - private string memAddrPzReqOdl - { - get - { - string memAddr = ""; - //cerco prima in read area - if (memMap != null && memMap.mMapRead != null) - { - //cerco in primis modalità NUM altrimenti standard... - if (memMap.mMapRead.ContainsKey("setPzCommOdl")) - { - memAddr = memMap.mMapRead["setPzCommOdl"].memAddr; - } - } - // cerco anche in write se non trovata.. - if (string.IsNullOrEmpty(memAddr)) - { - if (memMap != null && memMap.mMapWrite != null) - { - //cerco in primis modalità NUM altrimenti standard... - if (memMap.mMapWrite.ContainsKey("setPzCommOdl")) - { - memAddr = memMap.mMapWrite["setPzCommOdl"].memAddr; - } - } - } - // bonifica variabile da definizione STD iniziale... - if (memAddr.StartsWith("STD")) - { - memAddr = memAddr.Replace("STD.", ""); - } - return memAddr; - } - } - - private string memNameArt - { - get - { - string memName = ""; - if (memMap != null && memMap.mMapWrite != null) - { - //cerco in primis modalità NUM altrimenti standard... - if (memMap.mMapWrite.ContainsKey("setArtNum")) - { - memName = "setArtNum"; - } - // se vuoto provo altra alternativa... - if (string.IsNullOrEmpty(memName) && memMap.mMapWrite.ContainsKey("setArt")) - { - memName = "setArt"; - } - } - // se non trovato... leggo da OPT_PAR - if (string.IsNullOrEmpty(memName)) - { - memName = "PZ_COUNT"; - } - return memName; - } - } - - private string memNameCaden - { - get - { - string memName = ""; - if (memMap != null && memMap.mMapWrite != null) - { - //cerco in primis modalità NUM altrimenti standard... - if (memMap.mMapWrite.ContainsKey("Cadenza")) - { - memName = "Cadenza"; - } - } - // se non trovato... leggo da OPT_PAR - if (string.IsNullOrEmpty(memName)) - { - memName = "CICLE_CAD"; - } - return memName; - } - } - - private string memNameCom - { - get - { - string memName = ""; - if (memMap != null && memMap.mMapWrite != null) - { - //cerco in primis modalità NUM altrimenti standard... - if (memMap.mMapWrite.ContainsKey("setCommNum")) - { - memName = "setCommNum"; - } - // se vuoto provo altra alternativa... - if (string.IsNullOrEmpty(memName) && memMap.mMapWrite.ContainsKey("setComm")) - { - memName = "setComm"; - } - } - // se non trovato... leggo da OPT_PAR - if (string.IsNullOrEmpty(memName)) - { - memName = "SET_NUM_COM"; - } - return memName; - } - } - - private string memNamePzCnt - { - get - { - string memName = ""; - if (memMap != null && memMap.mMapWrite != null) - { - //cerco in primis modalità NUM altrimenti standard... - if (memMap.mMapWrite.ContainsKey("ContatoreParziale")) - { - memName = "ContatoreParziale"; - } - } - // se non trovato... leggo da OPT_PAR - if (string.IsNullOrEmpty(memName)) - { - memName = "PZ_COUNT"; - } - return memName; - } - } - - private string memNamePzCntTot - { - get - { - string memName = ""; - if (memMap != null && memMap.mMapWrite != null) - { - //cerco in primis modalità NUM altrimenti standard... - if (memMap.mMapWrite.ContainsKey("ContatoreAssoluto")) - { - memName = "ContatoreAssoluto"; - } - } - // se non trovato... leggo da OPT_PAR - if (string.IsNullOrEmpty(memName)) - { - memName = "PZ_GTOT"; - } - return memName; - } - } - - private string memNamePzReq - { - get - { - string memName = ""; - if (memMap != null && memMap.mMapWrite != null) - { - //cerco in primis modalità NUM altrimenti standard... - if (memMap.mMapWrite.ContainsKey("setPzComm")) - { - memName = "setPzComm"; - } - } - // se non trovato... leggo da OPT_PAR - if (string.IsNullOrEmpty(memName)) - { - memName = "PZ_REQ"; - } - return memName; - } - } - - #endregion Private Properties - - #region Private Methods - - /// - /// Effettua decodifica aree memoria alla bitmap usata x MAPO - /// - private void decodeToBitmap() - { - /*------------------------------------------ - * Bitmap MAPO STD 54 - * B0: POWER_ON - * B1: RUN - * B2: pzCount - * B3: allarme - * B4: manuale - * B5: Emerg (1 = emergenza, 0 = NON emergenza) - * - *------------------------------------------*/ - // init a zero... - B_input = 0; - if (connectionOk) - { - // vedere conf: - // Y60: RED - // Y61: YELLOW - // Y62: GREEN - // Y63: BLUE - - // default connesso = poweron, valutare se blue? - B_input += 1 << 0; - - string bKey = ""; - string bVal = ""; - // decodifico impiegando dictionary... cercando il TIPO di memoria & co... - char area; - // valore INVERTED (default è false) - bool invSignal = false; - string memArea = ""; - string cVal = ""; - string[] memIdx; - int bitNum = 0; - int byteNum = 0; - int byte2check = 0; - for (int i = 0; i < 8; i++) - { - bKey = $"BIT{i}"; - // cerco se ci sia in LUT - if (signLUT.ContainsKey(bKey)) - { - // recupero nome variabile... - bVal = signLUT[bKey]; - // se l'area è PZCOUNT... processo PUNTUALMENTE il CONTAPEZZI... - if (bVal.StartsWith("PZCOUNT")) - { - // disabilito pzcount singolo -#if false - // procedo SOLO SE è enabled IOB - if (IobOnline) - { - try - { - currODL = utils.callUrl(urlGetCurrODL); - // solo SE HO un ODL... - if (string.IsNullOrEmpty(currODL) || currODL == "0") - { - if (periodicLog) - { - lgInfo(string.Format("MITSUBISHI | Lettura ODL andata a vuoto: currODL: {0}", currODL)); - } - } - else - { - // se variato o scaduto timeout log... - if (periodicLog || ($"{currIdxODL}" != currODL)) - { - lgInfo(string.Format("MITSUBISHI | Lettura ODL, currODL: {0} --> currIdxODL prec: {1}", currODL, currIdxODL)); - } - // provo a salvare nuovo ODL - int.TryParse(currODL, out currIdxODL); - } - } - catch (Exception exc) - { - if (DateTime.Now.Subtract(lastWarnODL).TotalSeconds > 15) - { - lgError(exc, "Errore in fase di chiamata URL x ODL corrente | URL chiamato: {0}", urlGetCurrODL); - lastWarnODL = DateTime.Now; - } - } - } - else - { - // imposto currODL a vuoto! - currODL = ""; - if (periodicLog) - { - lgInfo($"MITSUBISHI | Lettura ODL non effettuata: IobOnline: {IobOnline} | currODL impostato a vuoto"); - } - } - if (!string.IsNullOrEmpty(currODL) && currODL != "0") - { - // controllo se è passato intervallo minimo tra 2 - // controlli/elaborazioni x distanziare invio e ridurre letture - if (DateTime.Now >= lastPzCountSend.AddMilliseconds(pzCountDelay)) - { - // se sono differenti MOSTRO... - if (contapezziPLC != contapezziIOB) - { - // registro contapezzi - lgInfo($"Differenza Contapezzi: contapezziPLC: {contapezziPLC} | contapezziIOB {contapezziIOB}"); - } - - if ((enablePzCountByApp || enablePzCountByIob) && !(disablePzCountByIob)) - { - // verifico se variato contapezzi... - if (contapezziPLC > contapezziIOB) - { - // salvo nuovo contapezzi (incremento di 1...) + - // richiesta refresh conteggio - contapezziIOB++; - needRefreshPzCount = true; - // salvo in semaforo! - B_input += 1 << 2; - // registro contapezzi - lgInfo($"contapezziPLC MITSUBISHI: {contapezziPLC} | contapezziIOB {contapezziIOB}"); - } - // 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 MITSUBISHI: contapezziPLC {contapezziPLC} | contapezziIOB {contapezziIOB} | risposta: {retVal}"); - // rileggo il counter pezzi da server - pzCntReload(true); - } - // resetto timer... - lastPzCountSend = DateTime.Now; - } - } - } - else - { - if (DateTime.Now >= lastPzCountSend.AddMilliseconds(pzCountDelay)) - { - lgInfo($"Attenzione: mancanza ODL non procedo con gestione contapezzi. contapezziPLC MITSUBISHI: {contapezziPLC} | contapezziIOB {contapezziIOB}"); - // resetto timer... - lastPzCountSend = DateTime.Now; - } - } -#endif - } - else // area "normale" byte.bit - { - // di norma è segnale normale => 1, altrimenti inverse => 0... - invSignal = false; - // cerco se sia inverse (primo char "!") --> registro e elimino char... - invSignal = bVal.StartsWith("!"); - // se è da tracciare... - if (mem2trace.Contains($"|{bKey}|")) - { - if (invSignal) - { - lgTrace($"Segnale invertito | bVal: {bVal}"); - } - } - // tolgo comunque inversione... - bVal = bVal.Replace("!", ""); - - // recupero int key - int iKey = 0; - int.TryParse(bVal, out iKey); - // leggo dizionario richiesto - if (DictSign.ContainsKey(iKey)) - { - cVal = DictSign[iKey]; - } - - // a secondo che sia segnale normale o inverso... - if (invSignal) - { - // controllo se il bit sia NON attivo (basso)... == 0 - if (cVal == "0") - { - B_input += 1 << i; - } - } - else - { - // controllo se il bit sia attivo (alto)... == 1 - if (cVal == "1") - { - B_input += 1 << i; - } - } - - // se è da tracciare... - if (mem2trace.Contains($"|{bKey}|")) - { - var bMapAct = Convert.ToString(byte2check, 2).PadLeft(8, '0'); - var bMapReq = Convert.ToString((1 << bitNum), 2).PadLeft(8, '0'); - lgTrace($"Valore | bKey: {bKey} | bVal: {bVal} | byte: {bMapAct} | tgt: {bMapReq} | B_input: {B_input}"); - } - } - } - } - } - // log opzionale! - if (verboseLog) - { - lgInfo(string.Format("Trasformazione B_input: {0}", B_input)); - } - } - - /// - /// Recupera il valore da memoria per successivo processing - /// - /// - /// - private string getValByMemAddr(string memAddr) - { - lgTrace($"inizio getValByMemAddr | memAddr: {memAddr}"); - string answ = ""; - // verifico quale modalità sia richiesta: STD (6711) oppure BIT (Custom, con indicazione area) - if (memAddr.StartsWith("STD")) - { - // inizio verifica area memoria/parametro levando prima parte codice - memAddr = memAddr.Replace("STD.", ""); - } - // var di appoggio - int cntAddr = 0; - // verifico se si tratta di lettura parametro... formato tipo STD.PAR.8001 - if (memAddr.StartsWith("PAR.")) - { - // recupero parametro... - int.TryParse(memAddr.Replace("PAR.", ""), out cntAddr); - // cerco in dizionario... - if (DictParam.ContainsKey(cntAddr)) - { - answ = DictParam[cntAddr]; - } - } - else if (memAddr.StartsWith("VAR.")) - { - // recupero parametro... - int.TryParse(memAddr.Replace("VAR.", ""), out cntAddr); - // cerco in dizionario... - if (DictVar.ContainsKey(cntAddr)) - { - answ = $"{DictVar[cntAddr]}"; - } - } - return answ; - } - - /// - /// Recupera il valore INT dal nome del parametro per successivo processing - /// - /// - /// - private string getValByParam(string varName) - { - string memAddr = getOptPar(varName); - string answ = getValByMemAddr(memAddr); - if (isVerboseLog) - { - lgInfo($"[3] PAR letto: {varName} | {answ}"); - } - return answ; - } - - /// - /// Lettura dati generici (es var Y) - /// - private void ReadMitsubGenData() - { - DateTime adesso = DateTime.Now; - int parSPeriod = samplePeriod; - // controllo se sia passato il samplePeriod minimo... - if (adesso.Subtract(lastSigRefr.AddMilliseconds(parSPeriod)).TotalSeconds > 0) - { - lastSigRefr = adesso; - stopwatch.Restart(); - // in primis: leggo i valor in sequenza e salvo in dizionario... - object pvRead = "bbb"; - // sezione segnali: cablata 53... - int sec = 53; - // Start da Y60 (Hex) --> 10000+96 - for (int i = SignStart; i < SignStart + SignSize; i++) - { - oEZNcAutCom.Generic_ReadData(0, sec, i, ref pvRead); - UpsertSign(i, $"{pvRead}"); - if (verboseLog) - { - lgTrace($"Sign | {i} : {pvRead}"); - } - } - // recording tempi - if (utils.CRB("recTime")) - { - TimingData.addResult(cIobConf.codIOB, $"Sign{SignSize}-R", stopwatch.ElapsedTicks); - } - stopwatch.Stop(); - } - else - { - lgTrace($"Saltata ReadMitsubGenData x periodo minimo {parSPeriod} ms"); - } - } - - /// - /// Lettura area parametri mitsubishi come configurato - /// - private void ReadMitsubParams() - { - DateTime adesso = DateTime.Now; - int parSPeriod = samplePeriod * 3; - // controllo se sia passato il samplePeriod minimo... - if (adesso.Subtract(lastParRefr.AddMilliseconds(parSPeriod)).TotalSeconds > 0) - { - lastParRefr = adesso; - // per prima cosa processo la lettura parametri e li salvo in DICT - int lAxis = 0; - object parValue = ""; - stopwatch.Restart(); - int iRet = oEZNcAutCom.Parameter_GetData3(0, ParamStart, ParamSize, lAxis, out parValue); - if (utils.CRB("recTime")) - { - TimingData.addResult(cIobConf.codIOB, $"R{ParamSize}-PAR", stopwatch.ElapsedTicks); - } - // converto in array di string... - string[] rawData = (string[])parValue; - // salvo in dict... - for (int i = 0; i < ParamSize; i++) - { - UpsertParam(ParamStart + i, rawData[i]); - } - } - else - { - lgTrace($"Saltata ReadMitsubParams x periodo minimo {parSPeriod} ms"); - } - } - - /// - /// Lettura area Var100/Var500 mitsubishi come configurato - /// - private void ReadMitsubVars() - { - DateTime adesso = DateTime.Now; - int parSPeriod = samplePeriod * 5; - // controllo se sia passato il samplePeriod minimo... - if (adesso.Subtract(lastVarRefr.AddMilliseconds(parSPeriod)).TotalSeconds > 0) - { - lastVarRefr = adesso; - // per prima cosa processo la lettura Variabili e li salvo in DICT - double pData = 0; - int pType = 0; - stopwatch.Restart(); - for (int i = MemVarStart; i < MemVarStart + MemVarSize; i++) - { - oEZNcAutCom.CommonVariable_Read2(i, out pData, out pType); - UpsertVar(i, pData); - if (verboseLog) - { - lgTrace($"Var | {i} : {pData}"); - } - } - if (utils.CRB("recTime")) - { - TimingData.addResult(cIobConf.codIOB, $"R{MemVarSize}-VAR", stopwatch.ElapsedTicks); - } - } - else - { - lgTrace($"Saltata ReadMitsubVars x periodo minimo {parSPeriod} ms"); - } - } - - /// - /// Upsert info in DICT dei Params (es 8001..8003 contatori pezzi) - /// - /// - /// - private void UpsertParam(int key, string value) - { - if (DictParam.ContainsKey(key)) - { - DictParam[key] = value; - } - else - { - DictParam.Add(key, value); - } - } - - /// - /// Upsert info in DICT dei SIGNAL (es Y) - /// - /// - /// - private void UpsertSign(int key, string value) - { - if (DictSign.ContainsKey(key)) - { - DictSign[key] = value; - } - else - { - DictSign.Add(key, value); - } - } - - /// - /// Upsert info in DICT dei VAR (es Var100, Var500) - /// - /// - /// - private void UpsertVar(int key, double value) - { - if (DictVar.ContainsKey(key)) - { - DictVar[key] = value; - } - else - { - DictVar.Add(key, value); - } - } - -#if false - /// - /// Scrive valore richiesto nella memoria richiesta - /// - /// - /// - /// - /// - private bool writeMitsubMem(string memName, string memAddr, int valReq) - { - bool answ = false; - lgTrace($"INIT {memName} | memAddr: {memAddr}"); - // contapezzi ATTUALE - if (!string.IsNullOrEmpty(memAddr)) - { - if (memAddr.StartsWith("STD")) - { - // inizio verifica area memoria/parametro levando prima parte codice - memAddr = memAddr.Replace("STD.", ""); - } - // var di appoggio - int cntAddr = 0; - // verifico se si tratta di tipo VAR... formato tipo VAR.501 - if (memAddr.StartsWith("VAR.")) - { - // recupero parametro... - int.TryParse(memAddr.Replace("VAR.", ""), out cntAddr); - lgTrace($"VAR | {memName} Write 01 | memAddr: {memAddr} | idx: {cntAddr}"); - // processo SET valore - stopwatch.Restart(); - if (cntAddr > 0) - { - double vTransf = (double)valReq; - // scrivo valore - int iRet = oEZNcAutCom.CommonVariable_Write2(cntAddr, vTransf, 1); - // trimmo se necessario memName... - if (memName.Length > maxVarStrLen) - { - memName = memName.Substring(0, maxVarStrLen); - } - // scrivo label - iRet = oEZNcAutCom.CommonVariable_SetName(cntAddr, memName); - lgTrace($"VAR | {memName} Write 02 | memAddr: {memAddr} | valReq: {valReq} | vTransf: {vTransf}"); - if (utils.CRB("recTime")) - { - TimingData.addResult(cIobConf.codIOB, "VAR-W", stopwatch.ElapsedTicks); - } - answ = iRet == 0; - // se successo --> rileggo! - if (answ) - { - ReadMitsubVars(); - } - } - stopwatch.Stop(); - } - else if (memAddr.StartsWith("PAR.")) - { - // recupero parametro... - int.TryParse(memAddr.Replace("PAR.", ""), out cntAddr); - lgTrace($"PAR | {memName} Write 01 | memAddr: {memAddr} | idx: {cntAddr}"); - // processo SET valore - stopwatch.Restart(); - if (cntAddr > 0) - { - // scrivo pz req come PAR... - int lAxis = 0; - string[] sValue = new string[1]; - sValue[0] = $"{valReq}"; - int iRet = oEZNcAutCom.Parameter_SetData3(0, cntAddr, lAxis, (object)sValue); - lgTrace($"PAR | {memName} Write 02 | memAddr: {memAddr} | valReq: {valReq}"); - if (utils.CRB("recTime")) - { - TimingData.addResult(cIobConf.codIOB, "PAR-W", stopwatch.ElapsedTicks); - } - answ = iRet == 0; - // se successo --> rileggo! - if (answ) - { - ReadMitsubParams(); - } - } - stopwatch.Stop(); - } - } - return answ; - } -#endif - - /// - /// Scrive valore richiesto nella memoria richiesta - /// - /// - /// - /// - /// - private bool writeMitsubMem(string memName, string memAddr, double valReq) - { - bool answ = false; - lgTrace($"INIT {memName} | memAddr: {memAddr}"); - // contapezzi ATTUALE - if (!string.IsNullOrEmpty(memAddr)) - { - if (memAddr.StartsWith("STD")) - { - // inizio verifica area memoria/parametro levando prima parte codice - memAddr = memAddr.Replace("STD.", ""); - } - // var di appoggio - int cntAddr = 0; - // verifico se si tratta di tipo VAR... formato tipo VAR.501 - if (memAddr.StartsWith("VAR.")) - { - // recupero parametro... - int.TryParse(memAddr.Replace("VAR.", ""), out cntAddr); - lgTrace($"VAR | {memName} Write 01 | memAddr: {memAddr} | idx: {cntAddr}"); - // processo SET valore - stopwatch.Restart(); - if (cntAddr > 0) - { - // scrivo valore - int iRet = oEZNcAutCom.CommonVariable_Write2(cntAddr, valReq, 1); - // trimmo se necessario memName... - if (memName.Length > maxVarStrLen) - { - memName = memName.Substring(0, maxVarStrLen); - } - // scrivo label - iRet = oEZNcAutCom.CommonVariable_SetName(cntAddr, memName); - lgTrace($"VAR | {memName} Write 02 | memAddr: {memAddr} | valReq: {valReq}"); - if (utils.CRB("recTime")) - { - TimingData.addResult(cIobConf.codIOB, "VAR-W", stopwatch.ElapsedTicks); - } - answ = iRet == 0; - // se successo --> rileggo! - if (answ) - { - ReadMitsubVars(); - } - } - stopwatch.Stop(); - } - else if (memAddr.StartsWith("PAR.")) - { - // recupero parametro... - int.TryParse(memAddr.Replace("PAR.", ""), out cntAddr); - lgTrace($"PAR | {memName} Write 01 | memAddr: {memAddr} | idx: {cntAddr}"); - // processo SET valore - stopwatch.Restart(); - if (cntAddr > 0) - { - // scrivo pz req come PAR... - int lAxis = 0; - string[] sValue = new string[1]; - // cablato: zero decimali... - sValue[0] = $"{valReq:N0}"; - int iRet = oEZNcAutCom.Parameter_SetData3(0, cntAddr, lAxis, (object)sValue); - lgTrace($"PAR | {memName} Write 02 | memAddr: {memAddr} | valReq: {valReq}"); - if (utils.CRB("recTime")) - { - TimingData.addResult(cIobConf.codIOB, "PAR-W", stopwatch.ElapsedTicks); - } - answ = iRet == 0; - // se successo --> rileggo! - if (answ) - { - ReadMitsubParams(); - } - } - stopwatch.Stop(); - } - } - return answ; - } - - #endregion Private Methods - } -} \ No newline at end of file diff --git a/IOB-WIN-NEXT/Iob/Omron.cs b/IOB-WIN-NEXT/Iob/Omron.cs deleted file mode 100644 index c6eb73f6..00000000 --- a/IOB-WIN-NEXT/Iob/Omron.cs +++ /dev/null @@ -1,851 +0,0 @@ -using IOB_UT_NEXT; -using MapoSDK; -using System; -using System.Collections.Generic; -using System.Net.NetworkInformation; -using System.Text; -using System.Threading; - -namespace IOB_WIN_NEXT.Iob -{ - public class Omron : Iob.GenericNext - { - #region Public Constructors - - /// - /// estende l'init della classe base... - /// - /// - /// - public Omron(AdapterFormNext caller, IobConfiguration IOBConf) : base(caller, IOBConf) - { - // gestione invio ritardato contapezzi - pzCountDelay = utils.CRI("pzCountDelay"); - lastPzCountSend = DateTime.Now; - lastWarnODL = DateTime.Now; - - // imposto i parametri PLC - setParamPlc(); - } - - #endregion Public Constructors - - #region Public Methods - - /// - /// Processo i task richiesti e li elimino dalla coda 1:1 - /// - /// - public override Dictionary executeTasks(Dictionary task2exe) - { - // uso metodo base x ora - return base.executeTasks(task2exe); - } - - /// - /// Recupero dati dinamici... - /// - public override Dictionary getDynData() - { - // valore non presente in vers default... se gestito fare override - Dictionary outVal = new Dictionary(); - outVal.Add("kgAct", pesoRilevato.ToString()); - outVal.Add("kgImp", pesoRichiesto.ToString()); - return outVal; - } - - /// - /// Effettua vero processing contapezzi - /// - public override void processContapezzi() - { - if (utils.CRB("enableContapezzi")) - { -#if false - try - { - // hard coded... !!!FARE!!! rivedere megio conf - contapezziPLC = pzCounter; - // verifico quale modalità sia richiesta: STD (6711) oppure BIT (Custom, con indicazione area) - if (cIobConf.optPar.Count > 0 && getOptPar("PZCOUNT_MODE") != "") - { - } - } - catch (Exception exc) - { - lgError(exc, "Errore in contapezzi OMRON"); - } -#endif - } - } - - /// - /// Effettua lettura semafori principale Parametri da - /// aggiornare x display in form - /// - public override void readSemafori(ref newDisplayData currDispData) - { - base.readSemafori(ref currDispData); - try - { - if (verboseLog) - { - lgInfo("inizio read semafori"); - } - - currDispData.semIn = Semaforo.SV; - - // effettuo TUTTE le letture - OMRON_ref.ReadWords(OmronFinsTCP.Net.PlcMemory.CIO, 0, 60, out memReadCIO_IN); - OMRON_ref.ReadWords(OmronFinsTCP.Net.PlcMemory.CIO, 100, 10, out memReadCIO_OUT); - //OMRON_ref.ReadWords(OmronFinsTCP.Net.PlcMemory.DM, 0, 8, out memReadDM); - //OMRON_ref.ReadWords(OmronFinsTCP.Net.PlcMemory.WR, 0, 8, out memReadWR); - - contapezziPLC = pesoRilevato; - // decodifica e gestione - decodeToBaseBitmap(); - reportRawInput(ref currDispData); - } - catch - { - currDispData.semIn = Semaforo.SR; - } - } - - /// - /// Effettua reset del contapezzi, in questo caso il conteggio dei KG - /// - /// - public override bool resetContapezziPLC() - { - bool answ = false; -#if false - // ...SE abilitato da conf IOB - if (cIobConf.optPar.Count > 0 && getOptPar("ENABLE_PZ_RESET") == "TRUE") - { - // scrivo valore 0 x il contapezzi - try - { - pzCounter = 0; - } - catch (Exception exc) - { - lgError(exc, "Errore in RESET contapezzi OMRON"); - connectionOk = false; - } - answ = true; - } - else - { - lgError("Impossibile effettuare RESET contapezzi OMRON, mancanza parametro OPT:ENABLE_PZ_RESET"); - } -#endif - return answ; - } - - /// - /// Effettua IMPOSTAZIONE FORZATA del contapezzi, in questo caso il conteggio dei KG - /// - /// - public override bool setcontapezziPLC(int newPzCount) - { - bool answ = false; -#if false - // ...SE abilitato da conf IOB - if (cIobConf.optPar.Count > 0 && getOptPar("ENABLE_PZ_RESET") == "TRUE") - { - // scrivo valore 0 x il contapezzi - try - { - pzCounter = newPzCount; - } - catch (Exception exc) - { - lgError(exc, "Errore in SET contapezzi OMRON"); - connectionOk = false; - } - answ = true; - } - else - { - lgError("Impossibile effettuare SET contapezzi OMRON, mancanza parametro OPT:ENABLE_PZ_RESET"); - } -#endif - return answ; - } - - /// - /// Override connessione - /// - public override void tryConnect() - { - if (!connectionOk) - { - // controllo che il ping sia stato tentato almeno pingTestSec fa... - if (DateTime.Now.Subtract(lastPING).TotalSeconds > utils.CRI("pingTestSec")) - { - if (verboseLog || periodicLog) - { - lgInfo("OMRON: ConnKO - tryConnect"); - } - // in primis salvo data ping... - lastPING = DateTime.Now; - // se passa il ping faccio il resto... - if (testPingMachine == IPStatus.Success) - { - string szStatusConnection = ""; - try - { - // ora provo connessione... - parentForm.commPlcActive = true; - short esitoLink = doConnect(); - lgInfo($"szStatusConnection OMRON, esitoLink: {esitoLink}"); - parentForm.commPlcActive = false; - // imposto i parametri... - setParamPlc(); - connectionOk = true; - // refresh stato connessione!!! - if (connectionOk) - { - queueInEnabCurr = true; - if (adpRunning) - { - lgInfo("Connessione OK"); - } - } - else - { - lgError("Impossibile procedere, connessione mancante..."); - } - } - catch (Exception exc) - { - lgFatal($"Errore nella connessione all'adapter OMRON: {szStatusConnection}{Environment.NewLine}{exc}"); - connectionOk = false; - lgInfo($"Eccezione in TryConnect, Adapter OMRON NON running, pausa di {utils.CRI("waitRecMSec")} msec prima di ulteriori tentativi di riconnessione"); - } - } - else - { - // loggo no risposta ping ... - connectionOk = false; - if (verboseLog || periodicLog) - { - lgInfo($"Attenzione: OMRON controllo PING fallito per IP {cIobConf.cncPingAddr}"); - } - } - } - } - else - { - needRefresh = true; - } - // se non è ancora connesso faccio procesisng memoria caso disconnesso... - if (!connectionOk) - { - // processo semafori ed invio... - processMemoryDiscon(); - } - } - - /// - /// Override disconnessione - /// - public override void tryDisconnect() - { - if (connectionOk) - { - string szStatusConnection = ""; - try - { - OMRON_ref.Close(); - connectionOk = false; - lgInfo(szStatusConnection); - lgInfo("Effettuata disconnessione adapter OMRON!"); - } - catch (Exception exc) - { - lgFatal(exc, "Errore nella disconnessione dall'adapter OMRON"); - } - } - else - { - lgError("IMPOSSIBILE effettuare disconnessione OMRON: Connessione non disponibile..."); - } - queueInEnabCurr = false; - } - - #endregion Public Methods - - #region Protected Fields - - /// - /// Array valori letti da memoria CIO INGRESSI - /// - protected short[] memReadCIO_IN; - - /// - /// Array valori letti da memoria CIO USCITE - /// - protected short[] memReadCIO_OUT; - - /// - /// Array valori letti da memoria DM - /// - protected short[] memReadDM; - - /// - /// Array valori letti da memoria WR - /// - protected short[] memReadWR; - - /// - /// Array valori SCRITTI su memoria CIO - /// - protected short[] memWriteCIO; - - /// - /// Array valori SCRITTI su memoria DM - /// - protected short[] memWriteDM; - - /// - /// Array valori SCRITTI su memoria WR - /// - protected short[] memWriteWR; - - /// - /// Oggetto MAIN x connessione OMRON - /// - protected OmronFinsTCP.Net.EtherNetPLC OMRON_ref; - - /// - /// Array delle risposte dal controllo OMRON - /// - protected System.Collections.ArrayList resDataArray; - - #endregion Protected Fields - - #region Protected Properties - - /// - /// Lettura scrittura commessa da OMRON (come array di coppie di byte) - /// - protected string commessa - { - get - { - string answ = ""; - short[] response; - byte[] byteData = new byte[20]; - try - { - // leggo - OMRON_ref.ReadWords(OmronFinsTCP.Net.PlcMemory.WR, 0, 10, out response); - // copio come byte... - Buffer.BlockCopy(response, 0, byteData, 0, response.Length); - answ = Encoding.ASCII.GetString(byteData); - } - catch - { } - return answ; - } - set - { - // converto in byte la mia stringa - byte[] valByte = Encoding.ASCII.GetBytes(value); - // limite 20 char... imposto a 20! - int maxChar = valByte.Length < 20 ? valByte.Length : 20; - // creao un array di 10 short MAX - short[] valoriWord = new short[10]; - // copio i valori - Buffer.BlockCopy(valByte, 0, valoriWord, 0, maxChar); - // scrivo su OMRON! - OMRON_ref.WriteWords(OmronFinsTCP.Net.PlcMemory.WR, 0, 10, valoriWord); - } - } - - /// - /// Verifico se abbia ALMENO un errore... - /// - protected bool hasError - { - get - { - bool answ = false; - if (memReadCIO_OUT != null) - { - answ = ((memReadCIO_OUT[4] & (1 << 7)) != 0); - } -#if false - bool answ = false; - // controllo primi errori, parto dal primo e poi OR - answ = answ || ((memReadCIO[0] & (1 << 7)) == 1); - answ = answ || ((memReadCIO[1] & (1 << 0)) == 1); - answ = answ || ((memReadCIO[1] & (1 << 1)) == 1); - answ = answ || ((memReadCIO[1] & (1 << 3)) == 1); - answ = answ || (memReadCIO[2] > 0); - answ = answ || ((memReadCIO[3] & (1 << 0)) == 1); - answ = answ || ((memReadCIO[3] & (1 << 1)) == 1); -#endif - return answ; - } - } - - /// - /// Oggetto get/set per lettura (DM22-23) /scrittura (DM26-27) PESO RICHIESTO - /// - protected int pesoRichiesto - { - get - { - int answ = 0; - try - { - short[] valDM; - OMRON_ref.ReadWords(OmronFinsTCP.Net.PlcMemory.DM, 22, 2, out valDM); - answ = convDHD(valDM[0]) + 10000 * convDHD(valDM[1]); - } - catch - { } - return answ; - } - set - { - short[] valDM = intToShort(value); - OMRON_ref.WriteWords(OmronFinsTCP.Net.PlcMemory.DM, 26, 2, valDM); - // ora devo "comandare scrittura" su OMRON... - - // sollevo bit 65.0 x azzeramento - OMRON_ref.WriteWord(OmronFinsTCP.Net.PlcMemory.CIO, 65, 1); - Thread.Sleep(500); - // ora sollevo bit e 65.1 x indicare nuovo valore... - OMRON_ref.WriteWord(OmronFinsTCP.Net.PlcMemory.CIO, 65, 2); - // ora attendo ed abbasso tutti i bit - Thread.Sleep(500); - OMRON_ref.WriteWord(OmronFinsTCP.Net.PlcMemory.CIO, 65, 0); - } - } - - /// - /// Oggetto per lettura PESO rilevato (DM20-21) - /// - protected int pesoRilevato - { - get - { - int answ = 0; - try - { - short[] valDM; - OMRON_ref.ReadWords(OmronFinsTCP.Net.PlcMemory.DM, 20, 2, out valDM); - // legge delle coppie di valori INT, vanno trasformati in HEX e POI accodati, - // dove il primo è x 1 e il secondo x 10000 (in pratica va in testa) esempio - // 12540 --> diviso in 1 | 2540 --> in HEX diventa 1 | 9472, ma il 9472 va su - // byte[0] e 1 su byte[1] - answ = convDHD(valDM[0]) + 10000 * convDHD(valDM[1]); - } - catch - { } - return answ; - } - } - - /// - /// Oggetto get/set x portata - /// - protected int portata - { - get - { - int answ = 0; - try - { - short valDM; - OMRON_ref.ReadWord(OmronFinsTCP.Net.PlcMemory.DM, 50, out valDM); - answ = convDHD(valDM); - } - catch - { } - return answ; - } - set - { - // scrivo portata su memoria DM50... - short portata = (short)convHD("0x" + value.ToString("0000")); - OMRON_ref.WriteWord(OmronFinsTCP.Net.PlcMemory.DM, 50, portata); - } - } - - /// - /// Oggetto get/set x quantità richiesta LOTTO - /// - protected int quantitaLotto - { - get - { - int answ = 0; - try - { - short[] valDM; - OMRON_ref.ReadWords(OmronFinsTCP.Net.PlcMemory.DM, 52, 2, out valDM); - answ = convDHD(valDM[0]) + 10000 * convDHD(valDM[1]); - } - catch - { } - return answ; - } - set - { - short[] valDM = intToShort(value); - OMRON_ref.WriteWords(OmronFinsTCP.Net.PlcMemory.DM, 52, 2, valDM); - } - } - - #endregion Protected Properties - - #region Protected Methods - - /// - /// Calcola la conversione da byte --> num decimale --> HEX --> conversione come - /// stringa in INT - /// - /// - /// - protected static int convDHD(short valore) - { - // legge delle coppie di valori INT, vanno trasformati in HEX e POI accodati, dove il - // primo è x 1 e il secondo x 10000 (in pratica va in testa) esempio 12540 --> diviso in - // 1 | 2540 --> in HEX diventa 1 | 9472, ma il 9472 va su byte[0] e 1 su byte[1] - int answ = 0; - string hexVal = valore.ToString("x"); - int.TryParse(hexVal, out answ); - return answ; - } - - /// - /// Converte un valore di 2 short in un unico numero accostato: - /// es: legge delle coppie di valori INT, vanno trasformati in HEX e POI accodati, dove il - /// primo è x 1 e il secondo x 10000 (in pratica va in testa) 12540 --> diviso in 1 | - /// 2540 --> in HEX diventa 1 | 9472, ma il 9472 va su byte[0] e 1 su byte[1] - /// - /// - /// - protected static int convFromHex(short[] valori) - { - int answ = 0; - string fullVal = $"{convDHD(valori[1]).ToString("D4")}{convDHD(valori[0]).ToString("D4")}"; - int.TryParse(fullVal, out answ); - return answ; - } - - /// - /// Calcola la conversione da INTERO a intero HEX x OMRON - /// - /// - /// - protected static int convHD(string hexVal) - { - int answ = 0; - if (!string.IsNullOrEmpty(hexVal)) - { - try - { - if (!hexVal.StartsWith("0x")) - { - hexVal = "0x" + hexVal; - } - answ = Convert.ToInt32(hexVal, 16); - } - catch - { } - } - return answ; - } - - /// - /// Converte un valore INT in un array di due SHORT valido x scrivere su OMRON - /// - /// - /// - protected static short[] intToShort(int value) - { - short[] valDM = new short[2]; - short highVal = (short)(value / 10000); - short lowVal = (short)(value - highVal * 10000); - valDM[0] = (short)convHD("0x" + lowVal.ToString("0000")); - valDM[1] = (short)convHD("0x" + highVal.ToString("0000")); - return valDM; - } - - /// - /// OVerride metodo x scrittura parametri su PLC - /// - /// - protected override void plcWriteParams(ref List updatedPar) - { - int valInt = 0; - if (updatedPar != null) - { - // controllo i parametri... ne gestisco 4... - foreach (var item in updatedPar) - { - lgInfo($"Richiesti processing plcWriteParams per {item.name} | valore richiesto {item.reqValue} | valore attuale {item.value}"); - string readBackVal = ""; - switch (item.uid) - { - case "kgRich": - // 2023.09.19 value --> reqValue - int.TryParse(item.reqValue, out valInt); - pesoRichiesto = valInt; - readBackVal = pesoRichiesto.ToString(); - break; - - case "kgLotto": - // 2023.09.19 value --> reqValue - int.TryParse(item.reqValue, out valInt); - quantitaLotto = valInt; - readBackVal = quantitaLotto.ToString(); - break; - - case "portata": - // 2023.09.19 value --> reqValue - int.TryParse(item.reqValue, out valInt); - portata = valInt; - readBackVal = portata.ToString(); - break; - - case "setComm": - // 2023.09.19 value --> reqValue - commessa = item.reqValue; - readBackVal = commessa; - break; - - default: - break; - } - // SE non corrispondessero LOGGO ERRORE... - if (item.value != readBackVal) - { - lgError($"Errore in plcWriteParams: uid {item.uid} | Wrote {item.value} | ReadBack {readBackVal}"); - } - // 2023.09.19 resetto richiesta - else - { - item.reqValue = ""; - } - } - } - } - - #endregion Protected Methods - - #region Private Fields - - /// - /// LookUpTable di decodifica da CNC a segnali tipo bitmap MAPO - /// - private Dictionary signLUT = new Dictionary(); - - #endregion Private Fields - - #region Private Methods - - /// - /// Effettua decodifica aree memoria alla bitmap usata x MAPO - /// - private void decodeToBaseBitmap() - { - // init a zero... - B_input = 0; - - /* ----------------------------------------------------- - * bitmap MAPO - * B0: POWER_ON - * B1: RUN - * B2: pzCount -- non usato - * B3: allarme - * B4: manuale -- non usato - * B5: carico SILOS - * B6: carico AUTOBOTTE - ----------------------------------------------------- */ - - // in primis test ping! - bool pingOk = testPingMachine == IPStatus.Success; - if (pingOk) - { - // versione pre 2023: controllo SOLO ping... - //// bit 0 (poweron) imposto a 1 SE pingo... - //B_input = testPingMachine == IPStatus.Success ? 1 : 0; - - // recupero i bit! check poweron = aux inseriti - bool runAux = ((memReadCIO_IN[0] & (1 << 0)) != 0); - // check lavora = filtro ON (DEVE ANDARE ma VIENE RILEVATO DOPO, POTREBBE andare da - // solo x scaricare...) - bool runFiltro = ((memReadCIO_IN[0] & (1 << 1)) != 0); - // check carico silos/autobotte - bool caricoSilos = ((memReadCIO_IN[55] & (1 << 2)) != 0); - bool caricoAutobotte = ((memReadCIO_IN[50] & (1 << 2)) != 0); - - // Costruzione HEX B_input - - // RUN se CIO_bit 0.00 è POWER ON... - B_input = runAux ? 1 : 0; - // RUN se CIO_bit 0.01 è RUN FILTRO... - if (runFiltro || caricoAutobotte || caricoSilos) - { - // SE HO carico silos OPPURE carico autobotte --> RUN - B_input += (1 << 1); - } - // ERROR generale (CORREGGERE!) - if (hasError) - { - B_input += (1 << 3); - } - - // carico SILOS - if (caricoSilos) - { - B_input += (1 << 5); - } - // carico AUTOBOTTE - if (caricoAutobotte) - { - B_input += (1 << 6); - } - - // procedo SOLO SE è enabled IOB - if (IobOnline) - { - try - { - currODL = utils.callUrl(urlGetCurrODL); - // solo SE HO un ODL... - if (string.IsNullOrEmpty(currODL) || currODL == "0") - { - if (periodicLog) - { - lgInfo(string.Format("OMRON | Lettura ODL andata a vuoto: currODL: {0}", currODL)); - } - } - else - { - // se variato o scaduto timeout log... - if (periodicLog || (currIdxODL.ToString() != currODL)) - { - lgInfo(string.Format("OMRON | Lettura ODL, currODL: {0} --> currIdxODL prec: {1}", currODL, currIdxODL)); - } - // provo a salvare nuovo ODL - int.TryParse(currODL, out currIdxODL); - } - } - catch (Exception exc) - { - if (DateTime.Now.Subtract(lastWarnODL).TotalSeconds > 15) - { - lgError(exc, "Errore in fase di chiamata URL x ODL corrente | URL chiamato: {0}", urlGetCurrODL); - lastWarnODL = DateTime.Now; - } - } - } - else - { - // imposto currODL a vuoto! - currODL = ""; - if (periodicLog) - { - lgInfo($"Omron | Lettura ODL non effettuata: IobOnline: {IobOnline} | currODL impostato a vuoto"); - } - } - // log opzionale! - if (verboseLog) - { - lgInfo(string.Format("Trasformazione B_input: {0}", B_input)); - } - } - } - - /// - /// Vera connessione ad OMRON - /// - /// - private short doConnect() - { - // avvio un oggetto di comunicazione OMRON - OMRON_ref = new OmronFinsTCP.Net.EtherNetPLC(); - short port = 9600; - short.TryParse(cIobConf.cncPort, out port); - lgInfo($"Chiamata apertura OMRON FINS: {cIobConf.cncIpAddr}:{port}"); - short esitoLink = OMRON_ref.Link(cIobConf.cncIpAddr, port, 500); - return esitoLink; - } - - /// - /// Test completo funzioni OMRON - /// - private void omronWriteTest() - { - commessa = "OMRON EDF TEST"; - - // scrivo portata - portata = 444; - - // scrivo pesatura richiesta - pesoRichiesto = 22222; - - // scrivo DM 52-53 del lotto richiesto - quantitaLotto = 66666; - } - - /// - /// Lettura e log valori x debug - /// - private void readAndLog() - { - OMRON_ref.ReadWords(OmronFinsTCP.Net.PlcMemory.CIO, 0, 8, out memReadCIO_IN); - OMRON_ref.ReadWords(OmronFinsTCP.Net.PlcMemory.CIO, 100, 8, out memReadCIO_OUT); - OMRON_ref.ReadWords(OmronFinsTCP.Net.PlcMemory.DM, 0, 8, out memReadDM); - OMRON_ref.ReadWords(OmronFinsTCP.Net.PlcMemory.WR, 0, 8, out memReadWR); - - if (isVerboseLog) - { - lgInfo("Effettuata lettura dati CIO"); - foreach (var item in memReadCIO_IN) - { - lgInfo($"Valori: {item} --> {baseUtils.binaryForm(item)}"); - } - lgInfo("Effettuata lettura dati DM"); - foreach (var item in memReadDM) - { - lgInfo($"Valori: {item} --> {baseUtils.binaryForm(item)}"); - } - lgInfo("Effettuata lettura dati WR"); - foreach (var item in memReadWR) - { - lgInfo($"Valori: {item} --> {baseUtils.binaryForm(item)}"); - } - } - short[] respDM20; - short[] respDM22; - OMRON_ref.ReadWords(OmronFinsTCP.Net.PlcMemory.DM, 20, 2, out respDM20); - OMRON_ref.ReadWords(OmronFinsTCP.Net.PlcMemory.DM, 22, 2, out respDM22); - if (isVerboseLog) - { - // legge delle coppie di valori INT, vanno trasformati in HEX e POI accodati, dove - // il primo è x 1 e il secondo x 10000 (in pratica va in testa) - lgInfo("Effettuata lettura dati respDM20"); - foreach (var item in respDM20) - { - lgInfo($"Valori: {item} --> {baseUtils.binaryForm(item)}"); - } - lgInfo("Effettuata lettura dati respDM22"); - foreach (var item in respDM22) - { - lgInfo($"Valori: {item} --> {baseUtils.binaryForm(item)}"); - } - } - } - - #endregion Private Methods - } -} \ No newline at end of file diff --git a/IOB-WIN-NEXT/IobFile/FileEurom63.cs b/IOB-WIN-NEXT/IobFile/FileEurom63.cs deleted file mode 100644 index 1daccf57..00000000 --- a/IOB-WIN-NEXT/IobFile/FileEurom63.cs +++ /dev/null @@ -1,923 +0,0 @@ -using IOB_UT_NEXT; -using MapoSDK; -using Newtonsoft.Json; -using System; -using System.Globalization; -using System.IO; -using System.Text.RegularExpressions; -using System.Threading; -using System.Windows.Forms; - -namespace IOB_WIN_NEXT.IobFile -{ - public class FileEurom63 : IobFile.FileGen - { - #region Public Constructors - - /// - /// Estende l'init della classe base... - /// - /// - /// - public FileEurom63(AdapterFormNext caller, IobConfiguration IOBConf) : base(caller, IOBConf) - { - lgInfo("INIT IobFileEurom63"); - appPath = Path.GetDirectoryName(Application.ExecutablePath); - - string MAX_DELAY_SEC = getOptPar("MAX_DELAY_SEC"); - string CACHE_MULT = getOptPar("CACHE_MULT"); - int.TryParse(MAX_DELAY_SEC, out maxDelaySec); - int.TryParse(CACHE_MULT, out cacheMult); - -#if DEBUG - maxDelaySec = 60 * 60 * 24; -#endif - } - - #endregion Public Constructors - - #region Public Methods - - /// - /// Effettua vero processing contapezzi - /// - public override void processContapezzi() - { - if (utils.CRB("enableContapezzi")) - { - try - { - // controllo se sono in sampling della produzione - if (actLevel >= Eurom63.ComLevel.ProdRequested) - { - /************************************************************ - * - * EXAMPLE - * DATE, TIME, ActCntCyc, ActTimCyc, ActTimFill, @OutXhour, SetDescJob - * 20201007, 21:29:52, 5302, 8.61, 0.50, 10058, Nr. 1000987654.01 - * - * devo prendere il 3° valore - * - * - ************************************************************/ - - // leggo il file della produzione HARD CODED... - var sessProd = confE63.ActiveSessions[5]; - string currPzCount = ""; - if (sessProd != null) - { - if (sessProd.Active) - { - // nome file... - string fileName = $"{BaseDir}\\{sessProd.SessionName}.DAT"; - if (File.Exists(fileName)) - { - string rawData = ""; - using (var fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) - using (var textReader = new StreamReader(fileStream)) - { - rawData = textReader.ReadToEnd(); - } - // ora splitto in linee - string[] rawLines = Regex.Split(rawData, "\r\n|\r|\n"); - int numRow = rawLines.Length; - - // devo avere almeno 2 righe... - if (numRow >= 2) - { - string[] statusData = rawLines[1].Split(','); - currPzCount = statusData[2].Trim(); - // salvo se valido - if (!string.IsNullOrEmpty(currPzCount)) - { - int newVal = -1; - Int32.TryParse(currPzCount, out newVal); - // verifico SE il contapezzi vada moltiplicato x il - // fattore pzPallet... - if (confE63.PzPallet > 1) - { - newVal = newVal * confE63.PzPallet; - } - // aggiorno contapezzi - contapezziPLC = newVal > -1 ? newVal : contapezziPLC; - } - // ora verifico SE siano validi anche le dataora dei valori - // letti (< 20 sec ritardo da ora...) - string data = statusData[0].Trim(); - string ora = statusData[1].Trim(); - DateTime adesso = DateTime.Now; - DateTime lastPub = adesso.AddMinutes(-1); - CultureInfo provider = CultureInfo.InvariantCulture; - try - { - lastPub = DateTime.ParseExact($"{data} {ora}", "yyyyMMdd HH:mm:ss", provider); - } - catch - { } - if (Math.Abs(lastPub.Subtract(adesso).TotalSeconds) > maxDelaySec) - { - sessProd.SessionValidUntil = adesso; - // elimino file RSP... - cleanupResp(sessProd.SessionName); - } - } - } - } - else - { - actLevel = Eurom63.ComLevel.StatusRequested; - } - } - else - { - actLevel = Eurom63.ComLevel.StatusRequested; - } - } - } - catch (Exception exc) - { - lgError($"Eccezione in processContapezzi:{Environment.NewLine}{exc}"); - } - } - } - - /// - /// Effettua lettura semafori principale Parametri da - /// aggiornare x display in form - /// - public override void readSemafori(ref newDisplayData currDispData) - { - base.readSemafori(ref currDispData); - // in primis controllo status... - checkCommStatus(); - - // init a zero... - B_input = 0; - string currStatus = "99999"; - bool readDone = false; - DateTime adesso = DateTime.Now; - // leggo il file dela produzione HARD CODED... - var sessStatus = confE63.ActiveSessions[4]; - // ciclo! - try - { - // controllo se sono in sampling dello stato - if (actLevel >= Eurom63.ComLevel.StatusRequested) - { - /* ----------------------------------------------------- - * bitmap MAPO - * B0: POWER_ON - * B1: RUN - * B2: pzCount - * B3: allarme - * B4: manuale - * B5: allarme TCiclo (SLOW) - * B6: avvio/spegnimento - * B7: Emergenza armata (1= pronto, 0 = emergenza) --> DA INVIARE!!! - ----------------------------------------------------- */ - - /****************************************************************** - * - * EXAMPLE file content - * DATE, TIME, ActStsMach - * 20201007, 21:28:10, 0A000 - * - * Configurazione array status: 5 char status decoding - * - * Pos1: (status) - * 0: poweron - * 1: poweroff - * - * Pos2: (mode) - * A: AUTO - * S: SEMI auto - * M: Manual - * U: Setup - * H: Hord - * C: Maintenance - * 0: Unknown - * I: Idle - * - * Pos3: (assist call) - * 0: No assistance - * 2: Assistance required - * - * Pos4: (Bad part) - * 0: last cycle not bad - * 1: last cycle bad - * - * Pos5: Active Alarm - * 0: No alarm - * 1: Alarm - * - * - * - *******************************************************************/ - - if (sessStatus != null) - { - if (sessStatus.Active) - { - // nome file... - string fileName = $"{BaseDir}\\{sessStatus.SessionName}.DAT"; - if (File.Exists(fileName)) - { - string rawData = ""; - using (var fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) - using (var textReader = new StreamReader(fileStream)) - { - rawData = textReader.ReadToEnd(); - } - if (!string.IsNullOrEmpty(rawData)) - { - // ora splitto in linee - string[] rawLines = Regex.Split(rawData, "\r\n|\r|\n"); - int numRow = rawLines.Length; - - // devo avere almeno 2 righe... - if (numRow >= 2) - { - string[] statusData = rawLines[1].Split(','); - if (statusData.Length >= 3) - { - currStatus = statusData[2].Trim(); - if (!string.IsNullOrEmpty(currStatus)) - { - currDispData.semIn = Semaforo.SV; - } - // salvo in cache! - Last_CurrStatus.Value = currStatus; - Last_CurrStatus.ValidUntil = DateTime.Now.AddSeconds(maxDelaySec * cacheMult); - - // ora verifico SE siano validi anche le dataora dei - // valori letti (< 20 sec ritardo da ora...) - string data = statusData[0].Trim(); - string ora = statusData[1].Trim(); - DateTime lastPub = adesso.AddMinutes(-1); - CultureInfo provider = CultureInfo.InvariantCulture; - try - { - lastPub = DateTime.ParseExact($"{data} {ora}", "yyyyMMdd HH:mm:ss", provider); - } - catch - { } - if (Math.Abs(lastPub.Subtract(adesso).TotalSeconds) > maxDelaySec) - { - sessStatus.SessionValidUntil = adesso; - // elimino file RSP... - cleanupResp(sessStatus.SessionName); - } - readDone = true; - } - else - { - lgError($"Decodifica StatusData in errore: trovati {statusData.Length} campi in {rawLines}"); - // se valido RILEGGO ultimo curr status - if (Last_CurrStatus.ValidUntil > adesso) - { - currStatus = Last_CurrStatus.Value; - } - } - } - else - { - lgError($"Lettura file stato in errore: trovate {numRow} linee"); - } - } - // se valido RILEGGO ultimo curr status - if (Last_CurrStatus.ValidUntil > adesso) - { - currStatus = Last_CurrStatus.Value; - } - } - else - { - // se valido RILEGGO ultimo curr status - if (Last_CurrStatus.ValidUntil > adesso) - { - currStatus = Last_CurrStatus.Value; - } - // abbasso status... - actLevel--; - } - } - else - { - // se valido RILEGGO ultimo curr status - if (Last_CurrStatus.ValidUntil > adesso) - { - currStatus = Last_CurrStatus.Value; - } - } - } - else - { - // se valido RILEGGO ultimo curr status - if (Last_CurrStatus.ValidUntil > adesso) - { - currStatus = Last_CurrStatus.Value; - } - } - - // processo il currentStatus... parto da poweron - B_input = currStatus[0] == '1' ? 0 : 1; - - // aggiungo il bit NON emergenza - B_input += (1 << 7); - - // ora MODE - switch (currStatus[1]) - { - case 'A': - B_input += (1 << 1); - break; - - case 'S': - case 'M': - case 'U': - B_input += (1 << 4); - break; - - default: - // loggo cosa trovo (CREDO - break; - } - // ora cerco allarmi - if (currStatus[4] == '1') - { - B_input += (1 << 3); - } - // controllo se diverso faccio log! - if (!B_input.Equals(Last_B_Input.Value)) - { - lgInfo($"B_Input variato: {Last_B_Input.Value} --> {B_input} | currStatus: {currStatus}"); - } - // salvo B_Input in cache! - Last_B_Input.Value = B_input; - Last_B_Input.ValidUntil = DateTime.Now.AddSeconds(maxDelaySec * cacheMult); - } - // se disponibile riporto B_Input precedente - else - { - if (Last_B_Input.ValidUntil > adesso) - { - B_input = Last_B_Input.Value; - } - } - // riporto bitmap... - reportRawInput(ref currDispData); - } - catch (Exception exc) - { - lgError(exc, "Errore in readSemafori x IOB FILE"); - if (currDispData != null) - currDispData.semIn = Semaforo.SR; - } - - // ultimo controllo... - if (!readDone) - { - // se valido RILEGGO ultimo B_INPUT - if (Last_B_Input.ValidUntil > adesso) - { - B_input = Last_B_Input.Value; - } - } - } - - /// - /// Effettua reset del contapezzi, NON PERMESSO per EM63 (read only) - /// - /// - public override bool resetContapezziPLC() - { - bool answ = false; - return answ; - } - - /// - /// Effettua IMPOSTAZIONE FORZATA del contapezzi, NON PERMESSO per EM63 (read only) - /// - /// - public override bool setcontapezziPLC(int newPzCount) - { - bool answ = false; - return answ; - } - - /// - /// Connessione - /// - public override void tryConnect() - { - var nextLevel = Eurom63.ComLevel.IsConnected; - var connectSession = confE63.ActiveSessions[0]; - processSession(nextLevel, ref connectSession); - queueInEnabCurr = true; - } - - /// - /// Disconnessione - /// - public override void tryDisconnect() - { - connectionOk = false; - queueInEnabCurr = false; - try - { - abortPrevJob(); - cleanupFolder(); - } - catch (Exception exc) - { - lgError(exc, "Eccezione in tryDisconnect"); - } - } - - #endregion Public Methods - - #region Internal Methods - - /// - /// Metodi preliminari x comunicazione: - /// - richiesta connessione - /// - richiesta stato attivo - /// - internal void checkCommStatus() - { - // init obj display - newDisplayData currDispData = new newDisplayData(); - currDispData.semIn = Semaforo.ND; - - switch (actLevel) - { - case Eurom63.ComLevel.None: - tryConnect(); - currDispData.semIn = Semaforo.SS; - break; - - case Eurom63.ComLevel.IsConnected: - requestInfo(); - currDispData.semIn = Semaforo.SS; - break; - - case Eurom63.ComLevel.HasInfo: - setMachineTime(); - currDispData.semIn = Semaforo.SS; - break; - - case Eurom63.ComLevel.TimeSet: - abortPrevJob(); - currDispData.semIn = Semaforo.SG; - break; - - case Eurom63.ComLevel.ChannelOk: - requestStatusData(); - currDispData.semIn = Semaforo.SG; - break; - - case Eurom63.ComLevel.StatusRequested: - requestProdData(); - currDispData.semIn = Semaforo.SV; - break; - - case Eurom63.ComLevel.ProdRequested: - checkSampling(); - currDispData.semIn = Semaforo.SV; - break; - - default: - break; - } - if (utils.CRB("verbose")) - { - lgInfo($"DONE checkCommStatus | actLevel {actLevel}"); - } - raiseRefresh(currDispData); - } - - /// - /// Pulizia preliminare folder comunicazione - /// - internal override void cleanupFolder() - { - // elimino OGNI file per tipo configurato - foreach (var cleanExt in confE63.cleanupExt) - { - string[] file2del = Directory.GetFiles(BaseDir, cleanExt); - foreach (var file in file2del) - { - try - { - File.Delete(file); - } - catch - { } - } - } - } - - /// - /// Pulizia folder dai file RSP della sessione - /// - internal void cleanupResp(string sessionName) - { - string[] file2del = Directory.GetFiles(BaseDir, $"{sessionName}.RSP"); - foreach (var file in file2del) - { - try - { - File.Delete(file); - } - catch - { } - } - } - - /// - /// Ricarica conf adapter... - /// - internal override void reloadAdapterConf() - { - // init obj display - newDisplayData currDispData = new newDisplayData(); - lgInfo("BEGIN reloadAdapterConf"); - // inizializzo LUT decodifica - string jsonConf = getOptPar("LUT_CONF"); - if (!string.IsNullOrEmpty(jsonConf)) - { - string jsonFullPath = $"{Application.StartupPath}/DATA/CONF/{jsonConf}"; - lgInfo($"Apertura file {jsonFullPath}"); - StreamReader reader = new StreamReader(jsonFullPath); - string jsonData = reader.ReadToEnd(); - if (!string.IsNullOrEmpty(jsonData)) - { - try - { - confE63 = JsonConvert.DeserializeObject(jsonData); - - // salvo baseUri - BaseDir = confE63.BaseDir; - lgInfo($"baseDir = {BaseDir}"); - // imposto a zero la bitmap x riavvio! - B_input = 0; - // FORZO invio dati... - accodaSigIN(ref currDispData); - // loggo! - lgInfo($"init input bitmap to zero: {B_input}"); - } - catch (Exception exc) - { - lgError(exc, "Eccezione in decodifica conf json"); - } - } - reader.Dispose(); - } - lgInfo("DONE reloadAdapterConf"); - raiseRefresh(currDispData); - } - - #endregion Internal Methods - - #region Protected Fields - - protected static DateTime lastStatusDecr = DateTime.Now; - - /// - /// step di comunicazione attivo - /// - protected Eurom63.ComLevel actLevel = Eurom63.ComLevel.None; - - /// - /// DIrectory eseguibile corrente - /// - protected string appPath = Directory.GetCurrentDirectory(); - - /// - /// Moltiplicatore durata cache - /// - protected int cacheMult = 4; - - /// - /// Oggetti decodificati da pagina - /// - protected Eurom63.ProtoConf confE63; - - /// - /// Valore currStatus validato (per gestione "disconnessioni") - /// - protected CachedInt Last_B_Input = new CachedInt() { Value = 0 }; - - /// - /// Valore currStatus validato (per gestione "disconnessioni") - /// - protected CachedString Last_CurrStatus = new CachedString() { Value = "00000" }; - - /// - /// Massimo delay lettura dati prima di considerarli scaduti (30 sec, ma x test 1 gg) - /// - protected int maxDelaySec = 30; - - #endregion Protected Fields - - #region Protected Methods - - protected void abortPrevJob() - { - var nextLevel = Eurom63.ComLevel.ChannelOk; - var connectSession = confE63.ActiveSessions[3]; - processSession(nextLevel, ref connectSession); -#if false - // qui per sicurezza PULISCE TUTTO - cleanupFolder(); -#endif - } - - /// - /// Verifica una sessione configurata (ovvero la comunicazione su TUTTI i file associati) - /// - /// - /// - protected bool checkRequest(Eurom63.Session session) - { - bool answ = false; - string fileName = ""; - if (session != null) - { - fileName = $"{BaseDir}\\{session.SessionName}.REQ"; - answ = File.Exists(fileName); - } - return answ; - } - - /// - /// Verifica se ci sia una risposta POSITIVA - /// - /// - /// - protected bool checkResp(Eurom63.Session session) - { - bool answ = false; - string fileName = ""; - if (session != null) - { - fileName = $"{BaseDir}\\{session.SessionName}.RSP"; - if (File.Exists(fileName)) - { - // verifico contenuto - //string rawData = File.ReadAllText(fileName); - string rawData = ""; - // lettura in modo NON esclusivo... - using (var fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) - using (var textReader = new StreamReader(fileStream)) - { - rawData = textReader.ReadToEnd(); - } - // se la stringa session.RespOk contiene | significa ci sono + valori ammessi e - // li controlla tutti - if (session.RespOk.Contains("|")) - { - // splitto e testo tutti... - string[] validRespOk = session.RespOk.Split('|'); - foreach (var item in validRespOk) - { - answ = answ || rawData.Contains(item); - } - } - else - { - answ = rawData.Contains(session.RespOk); - } - } - } - return answ; - } - - /// - /// verifica periodica dei campionamenti: - /// - i due jobs devono essere attivi e non scaduti - /// - non devo aver già resettato... - /// - protected void checkSampling() - { - var currSession = confE63.ActiveSessions[4]; - checkSessionActive(currSession, Eurom63.ComLevel.ChannelOk); - - currSession = confE63.ActiveSessions[5]; - checkSessionActive(currSession, Eurom63.ComLevel.ChannelOk); - } - - /// - /// Elimina i file della sessione indicata (SE è un task ciclico --> solo RSP) - /// - /// - /// - protected bool cleanupSession(Eurom63.Session session) - { - bool answ = false; - if (session != null) - { - // solo se scaduta validità... - if (session.SessionValidUntil < DateTime.Now) - { - string searchPattern = $"{session.SessionName}.*"; - // task ciclico? - if (session.Cycle) - { - // solo risposta! - searchPattern = $"{session.SessionName}.RSP"; - } - string[] file2del = Directory.GetFiles(BaseDir, searchPattern); - foreach (var file in file2del) - { - try - { - File.Delete(file); - } - catch - { } - } - } - } - return answ; - } - - /// - /// Processa una sessione - /// - andando a verificare l'esistenza della REQ + se esito positivo pulizia - /// - andando a richeidere di nuovo risposta - /// - /// - /// - protected void processSession(Eurom63.ComLevel nextLevel, ref Eurom63.Session connectSession) - { - if (connectSession != null) - { - // controllo esistenza directory --> segno connected... - connectionOk = Directory.Exists(BaseDir); - DateTime adesso = DateTime.Now; - if (connectionOk) - { - // verifico se ci sia risp CONNECT - if (checkResp(connectSession)) - { - // aggiorno livello - actLevel = nextLevel; - parentForm.displayTaskAndLog($"Adp Level: {nextLevel}"); - // elimino file sessione - cleanupSession(connectSession); - connectSession.Active = connectSession.Cycle; - connectSession.Passed = true; - } - // verifico SE ci sia la richiesta sennò la chiedo... - else if (!checkRequest(connectSession)) - { - copyRequestFiles(connectSession, adesso); - } - // richiedo SE non ci fosse i dati CONNECT... - else - { - // evito di richiedere SE non fosse già scaduta richiesta... - if (adesso > connectSession.RetryVeto || !checkRequest(connectSession)) - { - // pulisco eventuali risp vecchie - cleanupResp(connectSession.SessionName); - copyRequestFiles(connectSession, adesso); - } - } - } - else - { - // aspetto prima di riprovare... - Thread.Sleep(50); - } - } - else - { - // aspetto prima di riprovare... - Thread.Sleep(50); - } - } - - /// - /// Processa i file della sessione indicata (copy + transform) - /// - /// - /// - protected bool processSessionFile(Eurom63.Session session) - { - bool answ = false; - if (session != null) - { - string fileFrom = ""; - string fileTo = ""; - // processo OGNI file sessione x farne copia - foreach (var file2Proc in session.FileList) - { - fileFrom = $"{appPath}\\{file2Proc.Path}"; - fileTo = $"{BaseDir}\\{Path.GetFileName(file2Proc.Path)}"; - string rawData = File.ReadAllText(fileFrom); - - if (file2Proc.OprReq == Eurom63.FileOpr.Copy) - { - // scrivo! - File.WriteAllText(fileTo, rawData); - } - else - { - // leggo file originale... e processo sostituzioni - rawData = rawData.Replace("{DTNow}", DateTime.Now.ToString("HHmmssyyyyMMdd")); - // ora in posizione definitiva - File.WriteAllText(fileTo, rawData); - } - } - } - return answ; - } - - /// - /// Effettua richiesta info x macchina (validare startup process) - /// - protected void requestInfo() - { - var nextLevel = Eurom63.ComLevel.HasInfo; - var connectSession = confE63.ActiveSessions[1]; - processSession(nextLevel, ref connectSession); - } - - protected void requestProdData() - { - var nextLevel = Eurom63.ComLevel.ProdRequested; - var connectSession = confE63.ActiveSessions[5]; - processSession(nextLevel, ref connectSession); - } - - protected void requestStatusData() - { - var nextLevel = Eurom63.ComLevel.StatusRequested; - var connectSession = confE63.ActiveSessions[4]; - processSession(nextLevel, ref connectSession); - } - - protected void setMachineTime() - { - var nextLevel = Eurom63.ComLevel.TimeSet; - var connectSession = confE63.ActiveSessions[2]; - processSession(nextLevel, ref connectSession); - } - - #endregion Protected Methods - - #region Private Methods - - /// - /// Se la sessione fosse scaduta o non attiva --> torna al livello indicato - /// - /// - private void checkSessionActive(Eurom63.Session currSession, Eurom63.ComLevel nextLevel) - { - // SOLO SE ha senso che controllo (sono in sampling...) - if (actLevel > Eurom63.ComLevel.HasInfo) - { - DateTime adesso = DateTime.Now; - // devono essere ATTIVE le sessioni di campionamento... e NON scadute - if (!currSession.Active || currSession.SessionValidUntil < adesso) - { - // controllo ultimo downgrade status - if (lastStatusDecr.AddSeconds(3) < adesso) - { - // elimino TUTTE le risposte... - cleanupResp(currSession.SessionName); - // registro downgrade status... - lastStatusDecr = adesso; - // imposto livellotornando indietro di 1 alla volta... senza andare in negativoS - actLevel = actLevel - 1; - actLevel = actLevel > 0 ? actLevel : 0; - lgInfo($"Sessione inattiva, {actLevel + 1} --> {actLevel}"); - } - } - } - } - - /// - /// Effettua copia file richeiste + update timing - /// - /// - /// - private void copyRequestFiles(Eurom63.Session connectSession, DateTime adesso) - { - // processo richiesta - processSessionFile(connectSession); - if (adesso > connectSession.SessionValidUntil) - { - connectSession.Active = !connectSession.Cycle; - } - connectSession.Passed = false; - connectSession.SessionStarted = adesso; - connectSession.SessionValidUntil = adesso.AddMinutes(connectSession.ValidityMinutes); - connectSession.RetryVeto = adesso.AddSeconds(connectSession.RetrySec); - } - - #endregion Private Methods - } -} \ No newline at end of file diff --git a/IOB-WIN-NEXT/IobFile/FileGen.cs b/IOB-WIN-NEXT/IobFile/FileGen.cs deleted file mode 100644 index 1c081754..00000000 --- a/IOB-WIN-NEXT/IobFile/FileGen.cs +++ /dev/null @@ -1,358 +0,0 @@ -using IOB_UT_NEXT; -using MapoSDK; -using System; -using System.Collections.Generic; -using System.IO; -using System.Threading; - -namespace IOB_WIN_NEXT.IobFile -{ - /// - /// Generica classe per implementare IOB basato su scambio FILE - /// - public class FileGen : Iob.GenericNext, IDisposable - { - /* -------------------------------------------------------------------------------- - * Controlli dotati di GENERICA funzionalità scambio info tramite file - * - * -------------------------------------------------------------------------------- */ - - #region Public Constructors - - /// - /// Estende l'init della classe base... - /// - /// - /// - public FileGen(AdapterFormNext caller, IobConfiguration IOBConf) : base(caller, IOBConf) - { - lgInfo("INIT FileGen"); - //reloadAdapterConf(); - } - - #endregion Public Constructors - - #region Public Methods - - public void Dispose() - { - GC.SuppressFinalize(this); - } - - /// - /// Recupero dati dinamici in formato dictionary - /// - /// - public override Dictionary getDynData() - { - lgInfo("Chiamata getDynData x IOB FILE!"); - Dictionary outVal = new Dictionary(); -#if false - try - { - /* ---------------------------------------------------------- - * Recupero dalla TUTTE le chiavi richieste... - * */ - - string cKey = ""; - string cVal = ""; - // processo tutti i DynData... - foreach (var item in monitoredItems.DynData) - { - // cerco elemento indicato - element = driver.FindElement(By.Id(item.val)); - cVal = element.Text; - // verifico nome o key... - if (!string.IsNullOrEmpty(item.name)) - { - cKey = item.name; - } - else - { - element = driver.FindElement(By.Id(item.key)); - cKey = element.Text; - } - // controllo se devo inviare (per tipo di dato, x scadenza) - if (monItem2Send(cVal, item)) - { - item.actVal = cVal; - item.DTScad = DateTime.Now.AddSeconds(item.sPeriod); - // accodo! - outVal.Add(cKey, cVal); - } - } - } - catch (Exception exc) - { - lgError(exc, "Errore in getDynData x IOB FILE"); - } -#endif - return outVal; - } - - /// - /// Effettua processing del recupero delle OVERRIDE (spindle, feedrate, rapid) - /// - public override void processOverride() - { - } - - /// - /// Effettua lettura semafori principale - /// Parametri da aggiornare x display in form - /// - public override void readSemafori(ref newDisplayData currDispData) - { - base.readSemafori(ref currDispData); - // init a zero... - B_input = 0; - // ciclo! - try - { -#if false - // controllo SE il driver SIA attivo... - if (driver != null) - { - string cKey = ""; - string cVal = ""; - // IPOTESI: un UNICO oggetto decodifica status - if (monitoredItems.Status.Count == 1) - { - var item = monitoredItems.Status[0]; - // cerco elemento indicato - element = driver.FindElement(By.Id(item.val)); - cKey = element.Text; - // verifico se mancasse il mapping... - if (!item.codeMapping.ContainsKey(cKey)) - { - processUnknStatus(cKey); - } - else - { - // ora decodifico da variabile status a valore secondo impostazione "codeMapping" - cVal = item.codeMapping[cKey]; - B_input = int.Parse(cVal, System.Globalization.NumberStyles.HexNumber); - if (currDispData != null) - { - currDispData.semIn = Semaforo.SV; - } - } - } - } - else - { - lgError("Errore: driver non pronto (null)"); - } -#endif - // riporto bitmap... - reportRawInput(ref currDispData); - } - catch (Exception exc) - { - lgError(exc, "Errore in readSemafori x IOB FILE"); - if (currDispData != null) - currDispData.semIn = Semaforo.SR; - } - } - - public override void startAdapter(bool resetQueue) - { - // in primis RICARICO conf specifica... - reloadAdapterConf(); - // pulizia preliminare folder - cleanupFolder(); - // continuo con start... - base.startAdapter(resetQueue); - } - - /// - /// Override x chiusura driver... - /// - /// - /// - public override void stopAdapter(bool tryRestart, bool forceDequeue) - { - try - { -#if false - // in primis chiudo driver... - if (driver != null) - { - driver.Quit(); - } -#endif - } - catch (Exception exc) - { - lgError(exc, "Eccezione in tryDisconnect"); - } - // continuo - base.stopAdapter(tryRestart, forceDequeue); - } - - /// - /// Connessione - /// - public override void tryConnect() - { - // controllo ping --> segno connected... - connectionOk = Directory.Exists(BaseDir); - if (connectionOk) - { - queueInEnabCurr = true; -#if false - try - { - // modalità sincrona - startDriver(); - lgInfo("Completato start driver"); - } - catch (Exception exc) - { - lgError(exc, "Eccezione in tryConnect"); - } -#endif - } - else - { - // aspetto prima di riprovare... - Thread.Sleep(200); - } - } - - /// - /// Disconnessione - /// - public override void tryDisconnect() - { - connectionOk = false; - queueInEnabCurr = false; - try - { -#if false - // in primis chiudo driver... - if (driver != null) - //if (driver != null && driver.WindowHandles.Count > 0) - { - driver.Quit(); - } -#endif - } - catch (Exception exc) - { - lgError(exc, "Eccezione in tryDisconnect"); - } - } - - #endregion Public Methods - - #region Internal Methods - - /// - /// Pulizia preliminare folder comunicazione - /// - internal virtual void cleanupFolder() - { - - } - - /// - /// Ricarica conf adapter... - /// - internal virtual void reloadAdapterConf() - { -#if false - // init obj display - newDisplayData currDispData = new newDisplayData(); - lgInfo("BEGIN reloadAdapterConf"); - // inizializzo LUT decodifica - string jsonConf = getOptPar("LUT_CONF"); - if (!string.IsNullOrEmpty(jsonConf)) - { - string jsonFullPath = $"{Application.StartupPath}/DATA/CONF/{jsonConf}"; - lgInfo($"Apertura file {jsonFullPath}"); - StreamReader reader = new StreamReader(jsonFullPath); - string jsonData = reader.ReadToEnd(); - if (!string.IsNullOrEmpty(jsonData)) - { - try - { - monitoredItems = JsonConvert.DeserializeObject(jsonData); - // salvo baseUri - baseDir = monitoredItems.SrvData.baseUri; - lgInfo($"baseUri = {baseDir}"); - // imposto a zero la bitmap x riavvio! - B_input = 0; - // FORZO invio dati... - accodaSigIN(ref currDispData); - // loggo! - lgInfo($"init input bitmap to zero: {B_input}"); - } - catch (Exception exc) - { - lgError(exc, "Eccezione in decodifica conf json"); - } - } - reader.Dispose(); - } - lgInfo("DONE reloadAdapterConf"); - raiseRefresh(currDispData); -#endif - } - - #endregion Internal Methods - - #region Protected Fields - - /// - /// Cartella di base per interscambio - /// - protected string BaseDir = @"C:\Steamware"; - - /// - /// Array di configurazione degli oggetti da cercare x decodifica e recupero info - /// - protected Dictionary dataLocatorLUT; - - /// - /// Vettore della frequenza di ogni status trovato... invio ogni 100 rilevazioni (modulo - /// 100, resto == 1) - /// - protected Dictionary freqUnknStatus = new Dictionary(); - - #endregion Protected Fields - - #region Private Methods - - /// - /// Processo stati unknown... - /// - /// - private void processUnknStatus(string cKey) - { - // cerco se avevo già una key nella dictionary... - if (freqUnknStatus.ContainsKey(cKey)) - { - freqUnknStatus[cKey]++; - // se è 1 ogni 100 (%100, resto ==1) --> loggo... - if (freqUnknStatus[cKey] % 100 == 1) - { - lgInfo($"Errore in decodifica status: MAPPING non trovato per {cKey} | freq: {freqUnknStatus[cKey]}"); - // accodo come invio di tipo FLOG... - string sVal = string.Format("[UnknStatus] {0}, freq: {1}", cKey, freqUnknStatus); - // chiamo accodamento... - accodaFLog(sVal, qEncodeFLog("UnknStatus", sVal)); - } - } - else - { - // creo chiave con freq = 1 - freqUnknStatus.Add(cKey, 1); - // log iniziale - lgInfo($"Errore in decodifica status: MAPPING non trovato per {cKey}"); - } - } - - #endregion Private Methods - } -} \ No newline at end of file diff --git a/IOB-WIN-NEXT/IobFile/IobFileSoitaab.cs b/IOB-WIN-NEXT/IobFile/IobFileSoitaab.cs deleted file mode 100644 index 0a894adf..00000000 --- a/IOB-WIN-NEXT/IobFile/IobFileSoitaab.cs +++ /dev/null @@ -1,629 +0,0 @@ -#if false -using EgwProxy.SqlDb.DbModels; -#endif -using IOB_UT_NEXT; -using MapoSDK; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net.NetworkInformation; -using static IOB_UT_NEXT.CustomObj; - -namespace IOB_WIN_NEXT.IobFile -{ - /// - /// Adapter specializzato per SOITAAB x la SOLA lettura stato macchina da log, da accoppiare a - /// adapter x IOB LANTEK x scrittura PODL - /// - IN: LOGFile macchina diretto - /// - OUT: --> sigLog - /// --> fluxLog - /// - - public class IobFileSoitaab : Iob.GenericNext - { - #region Public Constructors - - /// - /// Costruttore dell'IOB FileBased SOITAAB - /// - /// AdapterForm chiamante - /// Configurazione IOB per avvio - public IobFileSoitaab(AdapterFormNext caller, IobConfiguration IOBConf) : base(caller, IOBConf) - { - DateTime adesso = DateTime.Now; - string VetoReadSec = getOptPar("VetoReadSec"); - - setupSpecialParams(); - if (pathList.ContainsKey("path-remBase")) - { - logDirPath = pathList["path-remBase"]; - } - // fix parametri veto - if (!string.IsNullOrEmpty(VetoReadSec)) - { - int.TryParse(VetoReadSec, out vetoReadFileSec); - } - - string sFluxOnRead = getOptPar("sendFluxOnRead"); - if (!string.IsNullOrEmpty("sendFluxOnRead")) - { - bool.TryParse(sFluxOnRead, out sendFluxOnRead); - } - - // init a zero.... - B_input = 0; - - // provo prima lettura logfile - try - { - // eseguo subito un ciclo acquisizione log + processing - bool acquireLog = getRemoteLog(); - if (acquireLog) - { - bool sentSignLog = processSignLogTable(adesso); - } - } - catch (Exception exc) - { - lgError($"Eccezione in IobFileSoitaab{Environment.NewLine}{exc}"); - } - - lastPING = DateTime.Now.AddHours(-1); - } - - #endregion Public Constructors - - #region Public Methods - - /// - /// Implementazione custom esecuzione task specifici - /// - /// - /// - public override Dictionary executeTasks(Dictionary task2exe) - { - DateTime adesso = DateTime.Now; - // NON fa nulla... anche se non dovrebbe richiamarlo - Dictionary taskDone = new Dictionary(); - lastReadPLC = DateTime.Now; - return taskDone; - } - - /// - /// Recupero dati dinamici... - /// - public override Dictionary getDynData() - { - DateTime adesso = DateTime.Now; - // dizionario vuoto / faccio direttamente accodamento in FluxLog - Dictionary outVal = new Dictionary(); - // processo ed accodo! - processFluxLogTable(adesso); - lastReadPLC = DateTime.Now; - return outVal; - } - - /// - /// Effettua lettura semafori principale Parametri da - /// aggiornare x display in form - /// - public override void readSemafori(ref newDisplayData currDispData) - { - DateTime adesso = DateTime.Now; - if (connectionOk) - { - // controllo veto checkDB - if (adesso > vetoDataRead) - { - // predispongo prox veto... - vetoDataRead = adesso.AddSeconds(vetoReadFileSec); - // semaforo - currDispData.semIn = Semaforo.SV; - // verifico SignLog e processo - bool acquireLog = getRemoteLog(); - bool sentSignLog = processSignLogTable(adesso); - // verifico ProdData e processo - bool sentProdData = processProdDataTable(adesso); - } - } - else - { - B_input = 0; - currDispData.semIn = Semaforo.SR; - } - } - - /// - /// Override connessione - /// - public override void tryConnect() - { - if (!connectionOk) - { - // controllo che il ping sia stato tentato almeno pingTestSec fa... - if (DateTime.Now.Subtract(lastPING).TotalSeconds > utils.CRI("pingTestSec")) - { - if (verboseLog || periodicLog) - { - lgInfo("FileSoitaab: ConnKO - tryConnect"); - } - // in primis salvo data ping... - lastPING = DateTime.Now; - // se passa il ping faccio il resto... - if (testPingMachine == IPStatus.Success) - { - string szStatusConnection = ""; - try - { - // ora provo connessione... - parentForm.commPlcActive = true; - - // connessione OK se oltre al PING riesco a leggere la folder di base - if (Directory.Exists(logDirPath)) - { - parentForm.commPlcActive = false; - connectionOk = true; - } - // refresh stato connessione!!! - if (connectionOk) - { - queueInEnabCurr = true; - if (adpRunning) - { - lgInfo($"Connessione OK alla folder {logDirPath}"); - lastReadPLC = DateTime.Now; - } - } - else - { - lgError("Impossibile procedere, connessione mancante..."); - } - } - catch (Exception exc) - { - lgFatal($"Errore nella connessione all'adapter IobFileSoitaab: {szStatusConnection}{Environment.NewLine}{exc}"); - connectionOk = false; - lgInfo($"Eccezione in TryConnect, Adapter IobFileSoitaab NON running, pausa di {utils.CRI("waitRecMSec")} msec prima di ulteriori tentativi di riconnessione"); - } - } - else - { - // loggo no risposta ping ... - connectionOk = false; - B_input = 0; - if (verboseLog || periodicLog) - { - lgInfo($"Attenzione: IobFileSoitaab controllo PING fallito per IP {cIobConf.cncPingAddr}"); - } - } - } - } - else - { - needRefresh = true; - } - } - - public override void tryDisconnect() - { - // registro solo che è disconnesso - connectionOk = false; - queueInEnabCurr = false; - } - - #endregion Public Methods - - #region Protected Fields - - protected bool sendFluxOnRead = false; - protected int vetoReadFileSec = 3; - - #endregion Protected Fields - - #region Protected Properties - -#if false - /// - /// Stato di sync delle tab gestite - /// - protected List elencoSyncState { get; set; } = new List(); -#endif - - #endregion Protected Properties - - #region Protected Methods - - /// - /// Conversione string row in log generico - /// - /// - /// - protected override GenLogRow convertToMachineLog(string dailyLog) - { - GenLogRow answ = new GenLogRow(); - if (!string.IsNullOrEmpty(dailyLog)) - { - // preventivamente: doppio ";;" --> ";" - dailyLog = dailyLog.Replace(";;", ";"); - var sSplit = dailyLog.Split(';'); - answ.dtRif = DateTime.ParseExact($"{sSplit[0]} {sSplit[1]}", "yyyy-M-d HH:mm:ss", null); - answ.valString = $"{sSplit[2]};{sSplit[3]}"; - } - return answ; - } - - /// - /// Recupera file log da analizzare - /// - /// - protected override bool getRemoteLog() - { - bool answ = false; - bool pingOk = testPingMachine == IPStatus.Success; - if (pingOk && Directory.Exists(logDirPath)) - { - string filePath = Path.Combine(logDirPath, $"Report-{DateTime.Today.Day}.txt"); - bool hasDaily = File.Exists(filePath); - // cerco file quotidiano... - if (!hasDaily) - { - var fileList = Directory.GetFiles(logDirPath, "Report-*.txt"); - DateTime lastMod = DateTime.Today.AddYears(-1); - foreach (var cFile in fileList) - { - var tempFile = Path.Combine(logDirPath, cFile); - var lwTime = File.GetLastWriteTime(tempFile); - if (lwTime >= lastMod) - { - lastMod = lwTime; - filePath = tempFile; - } - } - } - // leggo file - string rawVal = File.ReadAllText(Path.Combine(logDirPath, filePath)); - if (!string.IsNullOrEmpty(rawVal)) - { - // salvo in redis - string redKey = redisMan.redHash($"IOB:CurrData:{cIobConf.codIOB}:LogFile:Act"); - redisMan.setRSV(redKey, rawVal); - answ = true; - } - } - return answ; - } - - #endregion Protected Methods - - #region Private Properties - - private string logDirPath { get; set; } = "\\\\ecs900\\Logs"; - - #endregion Private Properties - - #region Private Methods - - private static int decodeSoitaabLog(string val2test) - { - // di default NON EMERGENZA... - int valInt = 128; - switch (val2test) - { - case "START;1": - valInt = 1 + 2 + 128; - break; - - case "END;1": - valInt = 1 + 128; - break; - - case "START;0": - case "END;0": - case "HOLD;": - valInt = 1 + 16 + 128; - break; - - default: - break; - } - - return valInt; - } - - /// - /// Esegue processing + invio dati tab SignLog - /// - /// - /// - private bool processFluxLogTable(DateTime adesso) - { - bool fatto = false; - // leggo eventuali dati di fluxlog ed invio... - if (fluxLogData != null && fluxLogData.Count > 0) - { - string sVal = ""; - foreach (var fLog2send in fluxLogData) - { - var kvpFlux = fLog2send.valString.Split(';'); - if (kvpFlux.Count() > 1) - { - sVal = $"[DYNDATA] |{fLog2send.dtRif:yyyy-MM-dd HH:mm:ss}|{kvpFlux[0]}|{kvpFlux[1]}"; - // chiamo accodamento con dataora corretta... - accodaFLog(sVal, qEncodeFLog(fLog2send.dtRif, kvpFlux[0], kvpFlux[1])); - } - } - // svuoto coda invio fluxlog... - fluxLogData = new List(); - // fatto! - fatto = true; - } - return fatto; - } - - /// - /// Esegue processing + invio dati tab ProdData - /// - /// - /// - private bool processProdDataTable(DateTime adesso) - { - bool fatto = false; - return fatto; - } - - /// - /// Esegue processing + invio dati tab SignLog - /// - /// - /// - private bool processSignLogTable(DateTime adesso) - { - bool fatto = false; - // init oggetto x processing - Dictionary sigLogFromFile = new Dictionary(); - // recupero i dati dai logs files, attuale e nuovo... - string fileAct = redisMan.getRSV(redKeyLogfileAct); - string fileLast = redisMan.getRSV(redKeyLogfileLast); - // confronto con i dati dell'ultimo LOG FILE processato - int lenghtAct = fileAct != null ? fileAct.Length : 0; - int lenghtLast = fileLast != null ? fileLast.Length : 0; - //if (lenghtAct > 0 && lenghtAct != lenghtLast) - if (lenghtAct > 0) - { - List logNew = new List(); - List sigLogData = new List(); - List logLast = getGenLogFromMachineLog(fileLast); - List logAct = getGenLogFromMachineLog(fileAct); - // SE c'è prendo ultima riga inviata x confronto... - var fileLastEnd = logLast.LastOrDefault(); - if (fileLastEnd != null) - { - // ora prendo SOLAMENTE le righe nuove - logNew = logAct - .Where(x => x.dtRif > fileLastEnd.dtRif) - .OrderBy(x => x.dtRif) - .ToList(); - } - else - { - logNew = logAct; - } - // solo SE ho nuovi dati.... - if (logNew.Count > 0) - { - // processo le righe nuove e le accodo in redis come elenco FluxLog da inviare - // (appoggio in redis)... andando ad accodarle... - var currFLD = fluxLogData; - currFLD.AddRange(logNew); - fluxLogData = currFLD; - - // estraggo solo info x sig log - sigLogData = logNew - .Where(x => x.valString.StartsWith("START") || x.valString.StartsWith("HOLD") || x.valString.StartsWith("END")) - .OrderBy(x => x.dtRif) - .ToList(); - - // processo le righe nuove trasformando al volo SOLO eventi... - foreach (var sLog2send in sigLogData) - { - /* ----------------------------------------------------- - * bitmap MAPO STANDARD 60 - * B0: 001 POWER_ON - * B1: 002 RUN - * B2: 004 pzCount - * B3: 008 allarme - * B4: 016 manuale - * B5: 032 slowTC - * B6: 064 WarmUpCoolDown - * B7: 128 EmergArmata - * - ----------------------------------------------------- */ - - int valInt = decodeSoitaabLog(sLog2send.valString); - - string currVal = getEncodSigLog(sLog2send.dtRif, valInt, counterSigIN); - // verifico non sia in veto invio iniziale... - if (queueInEnabCurr) - { - // --> accodo (valore già formattato)! - QueueIN.Enqueue(currVal); - // loggo! - lgTrace(string.Format("[QUEUE-IN] {0}", currVal)); - counterSigIN++; - if (counterSigIN > 9999) - { - counterSigIN = 0; - } - } - else - { - lgDebug($"[VETO FOR QUEUE-IN] | {currVal} - MESSAGE NOT SENT | {adesso:yyyyMMdd_HHmmss}"); - checkVetoQueueIn(); - } - } - - /* ---------------------------------------------------------- - * processo righe x costruire una lista di eventi produzione: - * - elenco di eventi contapezzi - * - lista xODL come articolo + quantità prodotta (_1, _2, ...) - * - eventuale ultimo xODL che resta aperto - * - * successivamente processing + invio info raccolte - * - recupero PODL aperti - * - apertura/chiusura PODL esistenti - * - creazione PODL mancanti - * - dichiarazione contapezzi - * - * ---------------------------------------------------------- */ - - string sVal = ""; - string descrArt = ""; - List elencoProdBatch = new List(); - ProdBatchData lastProdBatch = new ProdBatchData(); - - // ora processo TUTTO x il generico caso fluxLog...... - foreach (var fLog2send in logNew) - { - // separo per ";" - var currData = fLog2send.valString.Split(';'); - if (currData.Length > 1) - { - if (sendFluxOnRead) - { - // per prima cosa fluxLog a prescindere... - sVal = $"[LOGFILE]{currData[0]}|{currData[1]}"; - // ...e chiamo accodamento - accodaFLog(sVal, qEncodeFLog(fLog2send.dtRif, currData[0], currData[1])); - } - - switch (currData[0]) - { - case "END": - // se è un end --> è comunque NON + runnning - isRunningState = false; // chiudo batch precedente + in elenco (SE era valido...) - if (!string.IsNullOrEmpty(lastProdBatch.codArt)) - { - lastProdBatch.dtEnd = fLog2send.dtRif; - elencoProdBatch.Add(lastProdBatch); - } - // reset articolo.. - lastArtDescr = ""; - // nuovo batch VUOTO - lastProdBatch = new ProdBatchData(); - contapezziPLC = 0; - break; - - case "START": - isRunningState = currData[1] == "1"; - break; - - case "PARTCODE": - // inizio confronto articolo con precedente x capire se sia NUOVO - descrArt = currData[1]; - // devo scartare i "doppi percorsi" - if (descrArt != lastArtDescr) - { - // verifico se sia DAVVERO cambiato articolo... prendo - // articolo senza indice (_1, _2, _3, ...) - var artDataLast = lastArtDescr.Split('_'); - var artDataNew = descrArt.Split('_'); - // nuovo articolo (NON vuoto) - if (!string.IsNullOrEmpty(artDataNew[0]) && artDataLast[0] != artDataNew[0]) - { - // chiudo batch precedente + in elenco (SE era valido...) - if (!string.IsNullOrEmpty(lastProdBatch.codArt)) - { - // chiudo prod - lastProdBatch.dtEnd = fLog2send.dtRif; - elencoProdBatch.Add(lastProdBatch); - } - // nuovo batch - lastProdBatch = new ProdBatchData() - { - codArt = artDataNew[0], - dtStart = fLog2send.dtRif, - numPz = 1 - }; - } - // solo nuova copia articolo - else - { - // aumento numPezzi batch - lastProdBatch.numPz++; - } - - // salvo nuovo art processato - lastArtDescr = descrArt; - } - break; - - default: - break; - } - } - } - - // recupero elenco PODL corrente... - List reqPOdlList = MachineNextPodl(); - // adesso processo tutti i prodBatch collezionati x invio - foreach (var item in elencoProdBatch) - { - int currIdxPOdl = 0; - // cerco se articolo sia in elenco PODL - var listPOdl = reqPOdlList - .Where(x => x.CodArticolo.Equals(item.codArt, StringComparison.InvariantCultureIgnoreCase)) - .ToList(); - - // se trovato --> invio start/stop PODL - if (listPOdl != null && listPOdl.Count > 0) - { - var currPodl = listPOdl.FirstOrDefault(); - if (currPodl != null) - { - currIdxPOdl = currPodl.IdxPromessa; - // elimino da elenco PODL - reqPOdlList.Remove(currPodl); - } - } - else - { - // se NON trovato --> creo PODL, poi avvio/chiudo - currIdxPOdl = TryCreatePodl(item.codArt, CodGruppoIob, item.numPz); - } - // se idxPOdl valido - if (currIdxPOdl > 0) - { - // mando apertura PODL - SendStartPodl(currIdxPOdl, item.dtStart); - // chiudo PODL... - if (item.dtEnd != null) - { - // invio pezzi 3 sec prima di chiusura - SendPzIncrAtDate(item.numPz, ((DateTime)item.dtEnd).AddSeconds(-3)); - // chiudo - SendClosePOdl(currIdxPOdl, (DateTime)item.dtEnd); - } - } - } - - // salvo in last il valore di act... - redisMan.setRSV(redKeyLogfileLast, fileAct); - - // calcolo B_input valido - var lastRec = sigLogData.LastOrDefault(); - if (lastRec != null) - { - // salvo in B_input ultimo valore letto... - int lastValInt = decodeSoitaabLog(lastRec.valString); - B_input = lastValInt; - } - } - fatto = true; - } - return fatto; - } - - #endregion Private Methods - } -} \ No newline at end of file diff --git a/IOB-WIN-NEXT/IobSql/IcoelDb.cs b/IOB-WIN-NEXT/IobSql/IcoelDb.cs deleted file mode 100644 index 21cf7cc5..00000000 --- a/IOB-WIN-NEXT/IobSql/IcoelDb.cs +++ /dev/null @@ -1,288 +0,0 @@ -using EgwProxy.Icoel; -using IOB_UT_NEXT; -using MapoSDK; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Net.NetworkInformation; - -namespace IOB_WIN_NEXT.IobSql -{ - /// - /// Adapter specializzato per ICOEL e le chiamate tramite DB per i dati - /// - accettazione lotti prodotto (frontiera / entrata ciliegie) - /// - export (totale per prodotti) - /// - tracciabilità (confezioni - /// - - public class IcoelDb : Iob.GenericNext - { - #region Public Constructors - - /// - /// Costruttore dell'IOB Icoel DB - /// - /// AdapterForm chiamante - /// Configurazione IOB per avvio - public IcoelDb(AdapterFormNext caller, IobConfiguration IOBConf) : base(caller, IOBConf) - { - /* -------------------------------------- - * todo's - * -------------------------------------- - * - init obj comunicazione da conf e nuget - * - lanciare sync e verifica stato sync - */ - - string SyncStateServer = getOptPar("SyncStateServer"); - string SyncStateDb = getOptPar("SyncStateDb"); - string SyncStateUser = getOptPar("SyncStateUser"); - string SyncStatePwd = getOptPar("SyncStatePwd"); - string SyncStateCTout = getOptPar("SyncStateCTout"); - - string connSyncState = $"data source={SyncStateServer};initial catalog={SyncStateDb};persist security info=True;user id={SyncStateUser};password={SyncStatePwd};MultipleActiveResultSets=True;App=IOB-WIN-NEXT"; - - // gestione command timeout da https://erikej.github.io/sqlclient/2020/10/26/sqlclient-commandtimeout-preview.html - if (!string.IsNullOrEmpty(SyncStateCTout)) - { - connSyncState = $"{connSyncState};Command Timeout={SyncStateCTout}"; - } - - // eccezione: NON TROVA EntityFramework 6.0.0 o successivo... why?!? - dbProxy = new DbProxy(connSyncState); - - lastPING = DateTime.Now.AddHours(-1); - } - - #endregion Public Constructors - - #region Public Methods - - /// - /// Implementazione custom esecuzione task specifici - /// - /// - /// - public override Dictionary executeTasks(Dictionary task2exe) - { - // unico task ammissibile: fare un SYNC forzato... - Dictionary taskDone = new Dictionary(); - if (task2exe != null) - { - // controllo se memMap != null... - if (memMap != null) - { - bool taskOk = false; - string taskVal = ""; - // cerco task specifici: se ho startSetup --> imposto bit DBB701.DBB0.4 - foreach (var item in task2exe) - { - taskOk = false; - taskVal = ""; - // converto richiesta in enum... - taskType tName = taskType.nihil; - Enum.TryParse(item.Key, out tName); - // controllo sulla KEY... - switch (tName) - { - case taskType.syncDbData: - lgInfo($"executeTasks --> syncDbData"); - // effettua sync - refreshElencoStati(); - - break; - - default: - taskVal = $"IobIcoelDb | taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC"; - lgInfo($"IobIcoelDb | chiamata senza processing: taskOk: {taskOk} | taskVal: {taskVal}"); - break; - } - } - } - } - lastReadPLC = DateTime.Now; - return taskDone; - } - - /// - /// Recupero dati dinamici... - /// - public override Dictionary getDynData() - { - // valore non presente in vers default... se gestito fare override - Dictionary outVal = new Dictionary(); - // recupero da DB locale stato sync attuale - var elencoSyncStateCurr = dbProxy.DataController.SyncStateGetAll(); - foreach (var item in elencoSyncStateCurr) - { - saveValue(ref outVal, $"{item.TableName}_NumRec", item.NumRec); - saveValue(ref outVal, $"{item.TableName}_NumRecIn", item.NumRecIn); - saveValue(ref outVal, $"{item.TableName}_LastIdx", item.LastIdx); - saveValue(ref outVal, $"{item.TableName}_LastIdxIn", item.LastIdxIn); - } - - // aggiungo anche i campi currData - var currData = dbProxy.DataController.CurrDataGetAll(); - foreach (var item in currData) - { - saveValue(ref outVal, item.Topic, (double)item.CurrVal); - } - - lastReadPLC = DateTime.Now; - return outVal; - } - - /// - /// Effettua processing CUSTOM x Icoel: - /// - recupera elenco batch delle 2 linee - /// - invia al sistema - /// - public override void processCustomTaskLF() - { - lgInfo($"Richiesto processCustomTaskLF"); - // effettua sync - refreshElencoStati(); - lastReadPLC = DateTime.Now; - } - - /// - /// Effettua lettura semafori principale Parametri da - /// aggiornare x display in form - /// - public override void readSemafori(ref newDisplayData currDispData) - { - if (connectionOk) - { - B_input = 1; - currDispData.semIn = Semaforo.SV; - - if (dbProxy != null && elencoSyncState != null && elencoSyncState.Count > 0) - { - B_input += (1 << 1); - } - - // accodo NON emergenza - B_input += (1 << 7); - } - else - { - B_input = 0; - currDispData.semIn = Semaforo.SR; - } - } - - /// - /// Override connessione - /// - public override void tryConnect() - { - if (!connectionOk) - { - // controllo che il ping sia stato tentato almeno pingTestSec fa... - if (DateTime.Now.Subtract(lastPING).TotalSeconds > utils.CRI("pingTestSec")) - { - if (verboseLog || periodicLog) - { - lgInfo("IcoelSoap: ConnKO - tryConnect"); - } - // in primis salvo data ping... - lastPING = DateTime.Now; - // se passa il ping faccio il resto... - if (testPingMachine == IPStatus.Success) - { - string szStatusConnection = ""; - try - { - // ora provo connessione... - parentForm.commPlcActive = true; - if (dbProxy != null) - { - elencoSyncState = dbProxy.DataController.SyncStateDoImportAll(); - - if (elencoSyncState != null && elencoSyncState.Count > 0) - { - parentForm.commPlcActive = false; - connectionOk = true; - } - } - // refresh stato connessione!!! - if (connectionOk) - { - queueInEnabCurr = true; - if (adpRunning) - { - lgInfo("Connessione OK"); - lastReadPLC = DateTime.Now; - } - } - else - { - lgError("Impossibile procedere, connessione mancante..."); - } - } - catch (Exception exc) - { - lgFatal($"Errore nella connessione all'adapter IcoelSoap: {szStatusConnection}{Environment.NewLine}{exc}"); - connectionOk = false; - lgInfo($"Eccezione in TryConnect, Adapter IcoelSoap NON running, pausa di {utils.CRI("waitRecMSec")} msec prima di ulteriori tentativi di riconnessione"); - } - } - else - { - // loggo no risposta ping ... - connectionOk = false; - if (verboseLog || periodicLog) - { - lgInfo($"Attenzione: IcoelSoap controllo PING fallito per IP {cIobConf.cncPingAddr}"); - } - } - } - } - else - { - needRefresh = true; - } - } - - public override void tryDisconnect() - { - // registro solo che è disconnesso - connectionOk = false; - queueInEnabCurr = false; - } - - #endregion Public Methods - - #region Protected Properties - - protected EgwProxy.Icoel.DbProxy dbProxy { get; set; } = null; - - /// - /// Stato di sync delle tab gestite - /// - protected List elencoSyncState { get; set; } = new List(); - - #endregion Protected Properties - - #region Private Methods - - private void refreshElencoStati() - { - Stopwatch sw = new Stopwatch(); - sw.Start(); - elencoSyncState = dbProxy.DataController.SyncStateDoImportAll(); - sw.Stop(); - lastReadPLC = DateTime.Now; - lgInfo($"DB: esecuzione task dbProxy.DataController.SyncStateGetAll() in {sw.ElapsedMilliseconds} ms"); - - if (elencoSyncState != null) - { - foreach (var item in elencoSyncState) - { - lgTrace($"TAB: {item.TableName} | IdxIN / IdxLocal {item.LastIdxIn} / {item.LastIdx} | NumIn / NumLocal {item.NumRecIn} / {item.NumRec}"); - } - } - } - - #endregion Private Methods - } -} \ No newline at end of file diff --git a/IOB-WIN-NEXT/IobSql/SqlServLantek.cs b/IOB-WIN-NEXT/IobSql/SqlServLantek.cs deleted file mode 100644 index 4be0ca31..00000000 --- a/IOB-WIN-NEXT/IobSql/SqlServLantek.cs +++ /dev/null @@ -1,523 +0,0 @@ -using EgwProxy.SqlDb.Controllers; -using EgwProxy.SqlDb.DbModels; -using IOB_UT_NEXT; -using MapoSDK; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Net.NetworkInformation; -using static IOB_UT_NEXT.CustomObj; - -namespace IOB_WIN_NEXT.IobSql -{ - /// - /// Adapter specializzato per LANTEK e le chiamate tramite DB per i dati - /// - PODL (ordini MES --> MACCHINA) - /// - ProdLog (da NestingDaLantek + RigheNestingDaLantek) - /// - - public class SqlServLantek : Iob.GenericNext - { - #region Public Constructors - - /// - /// Costruttore dell'IOB DB LANTEK - /// - /// AdapterForm chiamante - /// Configurazione IOB per avvio - public SqlServLantek(AdapterFormNext caller, IobConfiguration IOBConf) : base(caller, IOBConf) - { - DateTime adesso = DateTime.Now; - string SyncStateServ = getOptPar("SyncStateServer"); - string SyncStateDb = getOptPar("SyncStateDb"); - string SyncStateUser = getOptPar("SyncStateUser"); - string SyncStatePwd = getOptPar("SyncStatePwd"); - string SyncStateCTout = getOptPar("SyncStateCTout"); - string VetoReadSec = getOptPar("VetoReadSec"); - string VetoSyncSec = getOptPar("VetoSyncSec"); - string sFullPodlUrl = getOptPar("FullPodlUrl"); - - setupSpecialParams(); - - string connSyncState = $"data source={SyncStateServ};initial catalog={SyncStateDb};persist security info=True;user id={SyncStateUser};password={SyncStatePwd};MultipleActiveResultSets=True;App=IOB-WIN-NEXT"; - - // gestione command timeout da https://erikej.github.io/sqlclient/2020/10/26/sqlclient-commandtimeout-preview.html - if (!string.IsNullOrEmpty(SyncStateCTout)) - { - connSyncState = $"{connSyncState};Command Timeout={SyncStateCTout}"; - } - if (!string.IsNullOrEmpty(VetoReadSec)) - { - int.TryParse(VetoReadSec, out vetoReadDbSec); - } - if (!string.IsNullOrEmpty(VetoSyncSec)) - { - int.TryParse(VetoSyncSec, out VetoSyncDbSec); - } - if (!string.IsNullOrEmpty(sFullPodlUrl)) - { - bool.TryParse(sFullPodlUrl, out FullPodlUrl); - } - - // avvio DB controller - dbProxy = new DbController(connSyncState); - - lastPING = DateTime.Now.AddHours(-1); - } - - #endregion Public Constructors - - #region Public Methods - - /// - /// Implementazione custom esecuzione task specifici - /// - /// - /// - public override Dictionary executeTasks(Dictionary task2exe) - { - DateTime adesso = DateTime.Now; - // unico task ammissibile: fare un SYNC forzato... - Dictionary taskDone = new Dictionary(); - if (task2exe != null) - { - // controllo se memMap != null... - if (memMap != null) - { - bool taskOk = false; - string taskVal = ""; - // cerco task specifici: se ho startSetup --> imposto bit DBB701.DBB0.4 - foreach (var item in task2exe) - { - taskOk = false; - taskVal = ""; - // converto richiesta in enum... - taskType tName = taskType.nihil; - Enum.TryParse(item.Key, out tName); - // controllo sulla KEY... - switch (tName) - { - case taskType.setComm: - case taskType.syncDbData: - lgInfo($"executeTasks --> {tName}"); - // per prima cosa recupero elenco PODL attivi x la macchina - List listaPODL = new List(); - bool okPodl = false; - var rawListPODL = callUrl(urlGetCurrPODL, false); - if (!string.IsNullOrEmpty(rawListPODL)) - { - try - { - listaPODL = JsonConvert.DeserializeObject>(rawListPODL); - okPodl = listaPODL.Count > 0; - } - catch (Exception exc) - { - lg.Error($"Errore: chiamata elenco PODL ha restituito errore{Environment.NewLine}{exc}"); - } - } - else - { - lg.Error($"Errore: chiamata elenco PODL ({urlGetCurrPODL}) ha restituito valore vuoto"); - } - if (okPodl) - { - //mando elenco PODL... - List CurrPodlReq = listaPODL - .Select(x => new MesPODLReqModel() - { - Attivabile = x.Attivabile, - CodArticolo = x.CodArticolo, - CodCli = x.CodCli, - CodGruppo = x.CodGruppo, - DueDate = x.DueDate ?? DateTime.Now, - IdxMacchina = x.IdxMacchina, - IdxODL = x.IdxOdl, - IdxPromessa = x.IdxPromessa, - InsertDate = x.InsertDate, - KeyBCode = x.KeyBCode, - KeyRichiesta = x.KeyRichiesta, - Note = x.Note, - NumPezzi = x.NumPezzi, - Priorita = x.Priorita, - PzPallet = x.PzPallet, - TCAssegnato = x.Tcassegnato - }) - .ToList(); - // scrivo i record richiesti - bool fatto = dbProxy.MesPodlWriteReq(CurrPodlReq); - if (fatto) - { - taskVal = $"EXECUTED task: {item.Key} / {item.Value}"; - // registro evento chiamata scrittura in syncState... - string tabName = item.Key; - var currSyncState = elencoSyncState.FirstOrDefault(x => x.TableName == tabName); - // verifico x registrare azione - if (currSyncState == null) - { - currSyncState = new SyncStateModel() - { - LastIdx = 0, - LastUpdate = adesso, - TableName = tabName, - Note = "Init" - }; - } - else - { - var lastRec = CurrPodlReq.OrderBy(x => x.IdxPromessa).LastOrDefault(); - currSyncState.LastIdx = lastRec != null ? lastRec.IdxPromessa : -1; - currSyncState.Note = $"Esecuzione {tabName} per {CurrPodlReq.Count} rec | last code: {currSyncState.LastIdx}"; - currSyncState.LastUpdate = adesso; - } - // salvo sync... - dbProxy.SyncStateUpsert(currSyncState); - } - - // effettua sync scrivendo i dati in export (PODL) - execExportAll(); - } - - break; - - default: - taskVal = $"IobSqlServLantek | taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC"; - lgInfo($"IobSqlServLantek | chiamata senza processing: taskOk: {taskOk} | taskVal: {taskVal}"); - break; - } - // aggiungo task! - taskDone.Add(item.Key, taskVal); - } - } - } - lastReadPLC = DateTime.Now; - return taskDone; - } - - /// - /// Recupero dati dinamici... FAKE! - /// - public override Dictionary getDynData() - { - DateTime adesso = DateTime.Now; - - // dizionario vuoto / gestito da altro adapter file-based - Dictionary outVal = new Dictionary(); - - lastReadPLC = DateTime.Now; - return outVal; - } - - /// - /// Effettua processing CUSTOM: - /// - esegue tutti gli import - /// - public override void processCustomTaskLF() - { - lgInfo($"Richiesto processCustomTaskLF"); - // effettua sync - execExportAll(); - execImportAll(); - lastReadPLC = DateTime.Now; - } - - /// - /// Effettua lettura semafori principale Parametri da - /// aggiornare x display in form - /// - public override void readSemafori(ref newDisplayData currDispData) - { - DateTime adesso = DateTime.Now; - if (connectionOk) - { - // controllo veto checkDB - if (adesso > vetoDataRead) - { - // predispongo prox veto... - vetoDataRead = adesso.AddSeconds(vetoReadDbSec); - if (adesso > vetoDataSync) - { - // effettua sync - execImportAll(); - vetoDataSync = adesso.AddSeconds(VetoSyncDbSec); - } - - // semaforo - currDispData.semIn = Semaforo.SV; - // recupero syncState - elencoSyncState = dbProxy.SyncStateGetAll(); - // verifico ProdData e processo - bool sentProdData = processProdDataTable(adesso); - } - } - else - { - B_input = 0; - currDispData.semIn = Semaforo.SR; - } - } - - /// - /// Override connessione - /// - public override void tryConnect() - { - if (!connectionOk) - { - // controllo che il ping sia stato tentato almeno pingTestSec fa... - if (DateTime.Now.Subtract(lastPING).TotalSeconds > utils.CRI("pingTestSec")) - { - if (verboseLog || periodicLog) - { - lgInfo("SqlDb LANTEK: ConnKO - tryConnect"); - } - // in primis salvo data ping... - lastPING = DateTime.Now; - // se passa il ping faccio il resto... - if (testPingMachine == IPStatus.Success) - { - string szStatusConnection = ""; - try - { - // ora provo connessione... - parentForm.commPlcActive = true; - if (dbProxy != null) - { - elencoSyncState = dbProxy.SyncStateDoImportAll(); - - if (elencoSyncState != null && elencoSyncState.Count > 0) - { - parentForm.commPlcActive = false; - connectionOk = true; - } - } - // refresh stato connessione!!! - if (connectionOk) - { - queueInEnabCurr = true; - if (adpRunning) - { - lgInfo("Connessione OK"); - lastReadPLC = DateTime.Now; - } - } - else - { - lgError("Impossibile procedere, connessione mancante..."); - } - } - catch (Exception exc) - { - lgFatal($"Errore nella connessione all'adapter SqlDb LANTEK: {szStatusConnection}{Environment.NewLine}{exc}"); - connectionOk = false; - lgInfo($"Eccezione in TryConnect, Adapter SqlDb LANTEK NON running, pausa di {utils.CRI("waitRecMSec")} msec prima di ulteriori tentativi di riconnessione"); - } - } - else - { - // loggo no risposta ping ... - connectionOk = false; - if (verboseLog || periodicLog) - { - lgInfo($"Attenzione: SqlDb LANTEK controllo PING fallito per IP {cIobConf.cncPingAddr}"); - } - } - } - } - else - { - needRefresh = true; - } - } - - public override void tryDisconnect() - { - // registro solo che è disconnesso - connectionOk = false; - queueInEnabCurr = false; - } - - #endregion Public Methods - - #region Protected Fields - - protected bool FullPodlUrl = false; - protected int vetoReadDbSec = 3; - - protected int VetoSyncDbSec = 20; - - #endregion Protected Fields - - #region Protected Properties - - protected DbController dbProxy { get; set; } = null; - - /// - /// Stato di sync delle tab gestite - /// - protected List elencoSyncState { get; set; } = new List(); - - #endregion Protected Properties - - #region Private Methods - - /// - /// Esegue task EXPORT (MES PODL to MACHINE) - /// - private void execExportAll() - { - Stopwatch sw = new Stopwatch(); - sw.Start(); - elencoSyncState = dbProxy.SyncStateDoExportAll(); - sw.Stop(); - DateTime adesso = DateTime.Now; - lastReadPLC = adesso; - lgInfo($"DB: esecuzione task dbProxy.SyncStateDoExportAll() in {sw.ElapsedMilliseconds} ms"); - - if (elencoSyncState != null) - { - // registro evento chiamata scrittura in syncState... - string tabName = "ExportAll"; - var currSyncState = elencoSyncState.FirstOrDefault(x => x.TableName == tabName); - // verifico x registrare azione - if (currSyncState == null) - { - currSyncState = new SyncStateModel() - { - LastIdx = 0, - LastUpdate = adesso, - TableName = tabName, - Note = "Init" - }; - } - else - { - // calcolo lastIDX valore da datetime - int valInt = -1; - var nowString = $"{adesso:HHmmss}"; - int.TryParse(nowString, out valInt); - currSyncState.LastIdx = valInt; - currSyncState.Note = $"Esecuzione {tabName} | DT code: {currSyncState.LastIdx}"; - currSyncState.LastUpdate = adesso; - } - // salvo sync... - dbProxy.SyncStateUpsert(currSyncState); - foreach (var item in elencoSyncState) - { - lgTrace($"TAB {item.TableName} | LastIdx {item.LastIdx} | Note {item.Note} | Last Upd {item.LastUpdate}"); - } - } - } - - /// - /// Esegue task IMPORT (MES PODL to MACHINE) - /// - private void execImportAll() - { - Stopwatch sw = new Stopwatch(); - sw.Start(); - elencoSyncState = dbProxy.SyncStateDoImportAll(); - sw.Stop(); - lastReadPLC = DateTime.Now; - lgInfo($"DB: esecuzione task dbProxy.SyncStateDoImportAll() in {sw.ElapsedMilliseconds} ms"); - - if (elencoSyncState != null) - { - foreach (var item in elencoSyncState) - { - lgTrace($"TAB {item.TableName} | LastIdx {item.LastIdx} | Note {item.Note} | Last Upd {item.LastUpdate}"); - } - } - } - - /// - /// Esegue processing + invio dati tab ProdData - /// - /// - /// - private bool processProdDataTable(DateTime adesso) - { - bool fatto = false; - string tabNameIn = "ProdData"; - string tabNameOut = "ProdDataToMes"; - // cerco info sui SignLog (ToMes e letti) - var currSignLogRead = elencoSyncState.FirstOrDefault(x => x.TableName == tabNameIn); - // se nullo inizializzo - if (currSignLogRead == null) - { - currSignLogRead = new SyncStateModel() - { - LastIdx = 0, - LastUpdate = adesso, - TableName = tabNameIn, - Note = "Init" - }; - } - var currSignLogSent = elencoSyncState.FirstOrDefault(x => x.TableName == tabNameOut); - // se nullo inizializzo - if (currSignLogSent == null) - { - currSignLogSent = new SyncStateModel() - { - LastIdx = 0, - LastUpdate = adesso, - TableName = tabNameOut, - Note = "Init" - }; - } - // verifica se ci siano dati da trasmettere (sui valori LastIdx) - if (currSignLogRead.LastIdx > currSignLogSent.LastIdx) - { - // recupero i dati dal DB... - var data2send = dbProxy.MachProdDataGetNew(currSignLogSent.LastIdx); - // se ho dati preparo invio - if (data2send != null && data2send.Count > 0) - { - foreach (var sLog2send in data2send) - { - if (sLog2send.Action == "StartOrd") - { - if (FullPodlUrl) - { - // se il record è apertura PODL chiamo apertura - trySetupPODL(sLog2send.IdxPodl, true, sLog2send.DtEve, DateTime.Now); - } - else - { - trySetupPODL(0); - } - } - else if (sLog2send.Action == "EndOrd") - { - // se il record è chiusura PODL chiamo chiusura... DOPO aver cercato - // PODL --> ODL - if (FullPodlUrl) - { - tryClosePODL(sLog2send.IdxPodl, sLog2send.DtEve, DateTime.Now); - } - else - { - tryClosePODL(0); - } - } - } - } - - // aggiorno idx inviato... - currSignLogSent.Note = $"Updated from {currSignLogRead.LastIdx}"; - currSignLogSent.LastUpdate = adesso; - currSignLogSent.LastIdx = currSignLogRead.LastIdx; - fatto = true; - } - - // alla fine aggiorno i dati inviati! - dbProxy.SyncStateUpsert(currSignLogSent); - - return fatto; - } - - #endregion Private Methods - } -} \ No newline at end of file diff --git a/IOB-WIN-NEXT/IobSql/SqlServPama.cs b/IOB-WIN-NEXT/IobSql/SqlServPama.cs deleted file mode 100644 index 4a2db88b..00000000 --- a/IOB-WIN-NEXT/IobSql/SqlServPama.cs +++ /dev/null @@ -1,686 +0,0 @@ -using EgwProxy.SqlDb.Controllers; -using EgwProxy.SqlDb.DbModels; -using IOB_UT_NEXT; -using MapoSDK; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Net.NetworkInformation; -using static IOB_UT_NEXT.CustomObj; - -namespace IOB_WIN_NEXT.IobSql -{ - /// - /// Adapter specializzato per PAMA e le chiamate tramite DB per i dati - /// - PODL (ordini MES --> MACCHINA) - /// - SignLog (da stato macchina) - /// - FluxLog (da stato macchina) - /// - ProdLog (da stato Prod) - /// - public class SqlServPama : Iob.GenericNext - { - #region Public Constructors - - /// - /// Costruttore dell'IOB DB PAMA - /// - /// AdapterForm chiamante - /// Configurazione IOB per avvio - public SqlServPama(AdapterFormNext caller, IobConfiguration IOBConf) : base(caller, IOBConf) - { - string SyncStateServ = getOptPar("SyncStateServer"); - string SyncStateDb = getOptPar("SyncStateDb"); - string SyncStateUser = getOptPar("SyncStateUser"); - string SyncStatePwd = getOptPar("SyncStatePwd"); - string SyncStateCTout = getOptPar("SyncStateCTout"); - string VetoReadSec = getOptPar("VetoReadSec"); - string VetoSyncSec = getOptPar("VetoSyncSec"); - string sFullPodlUrl = getOptPar("FullPodlUrl"); - - string connSyncState = $"data source={SyncStateServ};initial catalog={SyncStateDb};persist security info=True;user id={SyncStateUser};password={SyncStatePwd};MultipleActiveResultSets=True;App=IOB-WIN-NEXT"; - - // gestione command timeout da https://erikej.github.io/sqlclient/2020/10/26/sqlclient-commandtimeout-preview.html - if (!string.IsNullOrEmpty(SyncStateCTout)) - { - connSyncState = $"{connSyncState};Command Timeout={SyncStateCTout}"; - } - if (!string.IsNullOrEmpty(VetoReadSec)) - { - int.TryParse(VetoReadSec, out vetoReadDbSec); - } - if (!string.IsNullOrEmpty(VetoSyncSec)) - { - int.TryParse(VetoSyncSec, out VetoSyncDbSec); - } - if (!string.IsNullOrEmpty(sFullPodlUrl)) - { - bool.TryParse(sFullPodlUrl, out FullPodlUrl); - } - - // eccezione: NON TROVA EntityFramework 6.0.0 o successivo... why?!? - dbProxy = new DbController(connSyncState); - - lastPING = DateTime.Now.AddHours(-1); - } - - #endregion Public Constructors - - #region Public Methods - - /// - /// Implementazione custom esecuzione task specifici - /// - /// - /// - public override Dictionary executeTasks(Dictionary task2exe) - { - DateTime adesso = DateTime.Now; - // unico task ammissibile: fare un SYNC forzato... - Dictionary taskDone = new Dictionary(); - if (task2exe != null) - { - // controllo se memMap != null... - if (memMap != null) - { - bool taskOk = false; - string taskVal = ""; - // cerco task specifici: se ho startSetup --> imposto bit DBB701.DBB0.4 - foreach (var item in task2exe) - { - taskOk = false; - taskVal = ""; - // converto richiesta in enum... - taskType tName = taskType.nihil; - Enum.TryParse(item.Key, out tName); - // controllo sulla KEY... - switch (tName) - { - case taskType.setComm: - case taskType.syncDbData: - lgInfo($"executeTasks --> {tName}"); - // per prima cosa recupero elenco PODL attivi x la macchina - List listaPODL = new List(); - bool okPodl = false; - var rawListPODL = callUrl(urlGetCurrPODL, false); - if (!string.IsNullOrEmpty(rawListPODL)) - { - try - { - listaPODL = JsonConvert.DeserializeObject>(rawListPODL); - okPodl = listaPODL.Count > 0; - } - catch (Exception exc) - { - lg.Error($"Errore: chiamata elenco PODL ha restituito errore{Environment.NewLine}{exc}"); - } - } - else - { - lg.Error($"Errore: chiamata elenco PODL ({urlGetCurrPODL}) ha restituito valore vuoto"); - } - if (okPodl) - { - //mando elenco PODL... - List CurrPodlReq = listaPODL - .Select(x => new MesPODLReqModel() - { - Attivabile = x.Attivabile, - CodArticolo = x.CodArticolo, - CodCli = x.CodCli, - CodGruppo = x.CodGruppo, - DueDate = x.DueDate ?? DateTime.Now, - IdxMacchina = x.IdxMacchina, - IdxODL = x.IdxOdl, - IdxPromessa = x.IdxPromessa, - InsertDate = x.InsertDate, - KeyBCode = x.KeyBCode, - KeyRichiesta = x.KeyRichiesta, - Note = x.Note, - NumPezzi = x.NumPezzi, - Priorita = x.Priorita, - PzPallet = x.PzPallet, - TCAssegnato = x.Tcassegnato - }) - .ToList(); - // scrivo i record richiesti - bool fatto = dbProxy.MesPodlWriteReq(CurrPodlReq); - if (fatto) - { - taskVal = $"EXECUTED task: {item.Key} / {item.Value}"; - // registro evento chiamata scrittura in syncState... - string tabName = item.Key; - var currSyncState = elencoSyncState.FirstOrDefault(x => x.TableName == tabName); - // verifico x registrare azione - if (currSyncState == null) - { - currSyncState = new SyncStateModel() - { - LastIdx = 0, - LastUpdate = adesso, - TableName = tabName, - Note = "Init" - }; - } - else - { - var lastRec = CurrPodlReq.OrderBy(x => x.IdxPromessa).LastOrDefault(); - currSyncState.LastIdx = lastRec != null ? lastRec.IdxPromessa : -1; - currSyncState.Note = $"Esecuzione {tabName} per {CurrPodlReq.Count} rec | last code: {currSyncState.LastIdx}"; - currSyncState.LastUpdate = adesso; - } - // salvo sync... - dbProxy.SyncStateUpsert(currSyncState); - } - - // effettua sync scrivendo i dati in export (PODL) - execExportAll(); - } - - break; - - default: - taskVal = $"IobSqlServPama | taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC"; - lgInfo($"IobSqlServPama | chiamata senza processing: taskOk: {taskOk} | taskVal: {taskVal}"); - break; - } - // aggiungo task! - taskDone.Add(item.Key, taskVal); - } - } - } - lastReadPLC = DateTime.Now; - return taskDone; - } - - /// - /// Recupero dati dinamici... - /// - public override Dictionary getDynData() - { - DateTime adesso = DateTime.Now; - - // dizionario vuoto / faccio direttamente accodamento in FluxLog - Dictionary outVal = new Dictionary(); - - // processo ed accodo! - processFluxLogTable(adesso); - - lastReadPLC = DateTime.Now; - return outVal; - } - - /// - /// Effettua processing CUSTOM: - /// - esegue tutti gli import - /// - public override void processCustomTaskLF() - { - lgInfo($"Richiesto processCustomTaskLF"); - // effettua sync - execImportAll(); - lastReadPLC = DateTime.Now; - } - - /// - /// Effettua lettura semafori principale Parametri da - /// aggiornare x display in form - /// - public override void readSemafori(ref newDisplayData currDispData) - { - DateTime adesso = DateTime.Now; - if (connectionOk) - { - // controllo veto checkDB - if (adesso > vetoDataRead) - { - // predispongo prox veto... - vetoDataRead = adesso.AddSeconds(vetoReadDbSec); - if (adesso > vetoDataSync) - { - // effettua sync - execImportAll(); - vetoDataSync = adesso.AddSeconds(VetoSyncDbSec); - } - - // semaforo - currDispData.semIn = Semaforo.SV; - // recupero syncState - elencoSyncState = dbProxy.SyncStateGetAll(); - // verifico SignLog e processo - bool sentSignLog = processSignLogTable(adesso); - // verifico ProdData e processo - bool sentProdData = processProdDataTable(adesso); - } - } - else - { - B_input = 0; - currDispData.semIn = Semaforo.SR; - } - } - - /// - /// Override connessione - /// - public override void tryConnect() - { - if (!connectionOk) - { - // controllo che il ping sia stato tentato almeno pingTestSec fa... - if (DateTime.Now.Subtract(lastPING).TotalSeconds > utils.CRI("pingTestSec")) - { - if (verboseLog || periodicLog) - { - lgInfo("SqlDb PAMA: ConnKO - tryConnect"); - } - // in primis salvo data ping... - lastPING = DateTime.Now; - // se passa il ping faccio il resto... - if (testPingMachine == IPStatus.Success) - { - string szStatusConnection = ""; - try - { - // ora provo connessione... - parentForm.commPlcActive = true; - if (dbProxy != null) - { - elencoSyncState = dbProxy.SyncStateDoImportAll(); - - if (elencoSyncState != null && elencoSyncState.Count > 0) - { - parentForm.commPlcActive = false; - connectionOk = true; - } - } - // refresh stato connessione!!! - if (connectionOk) - { - queueInEnabCurr = true; - if (adpRunning) - { - lgInfo("Connessione OK"); - lastReadPLC = DateTime.Now; - } - } - else - { - lgError("Impossibile procedere, connessione mancante..."); - } - } - catch (Exception exc) - { - lgFatal($"Errore nella connessione all'adapter SqlDb PAMA: {szStatusConnection}{Environment.NewLine}{exc}"); - connectionOk = false; - lgInfo($"Eccezione in TryConnect, Adapter SqlDb PAMA NON running, pausa di {utils.CRI("waitRecMSec")} msec prima di ulteriori tentativi di riconnessione"); - } - } - else - { - // loggo no risposta ping ... - connectionOk = false; - if (verboseLog || periodicLog) - { - lgInfo($"Attenzione: SqlDb PAMA controllo PING fallito per IP {cIobConf.cncPingAddr}"); - } - } - } - } - else - { - needRefresh = true; - } - } - - public override void tryDisconnect() - { - // registro solo che è disconnesso - connectionOk = false; - queueInEnabCurr = false; - } - - #endregion Public Methods - - #region Protected Fields - - protected bool FullPodlUrl = false; - protected int vetoReadDbSec = 3; - - protected int VetoSyncDbSec = 20; - - #endregion Protected Fields - - #region Protected Properties - - protected DbController dbProxy { get; set; } = null; - - /// - /// Stato di sync delle tab gestite - /// - protected List elencoSyncState { get; set; } = new List(); - - #endregion Protected Properties - - #region Private Methods - - /// - /// Esegue task EXPORT (MES PODL to MACHINE) - /// - private void execExportAll() - { - Stopwatch sw = new Stopwatch(); - sw.Start(); - elencoSyncState = dbProxy.SyncStateDoExportAll(); - sw.Stop(); - DateTime adesso = DateTime.Now; - lastReadPLC = adesso; - lgInfo($"DB: esecuzione task dbProxy.SyncStateDoExportAll() in {sw.ElapsedMilliseconds} ms"); - - if (elencoSyncState != null) - { - // registro evento chiamata scrittura in syncState... - string tabName = "ExportAll"; - var currSyncState = elencoSyncState.FirstOrDefault(x => x.TableName == tabName); - // verifico x registrare azione - if (currSyncState == null) - { - currSyncState = new SyncStateModel() - { - LastIdx = 0, - LastUpdate = adesso, - TableName = tabName, - Note = "Init" - }; - } - else - { - // calcolo lastIDX valore da datetime - int valInt = -1; - var nowString = $"{adesso:HHmmss}"; - int.TryParse(nowString, out valInt); - currSyncState.LastIdx = valInt; - currSyncState.Note = $"Esecuzione {tabName} | DT code: {currSyncState.LastIdx}"; - currSyncState.LastUpdate = adesso; - } - // salvo sync... - dbProxy.SyncStateUpsert(currSyncState); - foreach (var item in elencoSyncState) - { - lgTrace($"TAB {item.TableName} | LastIdx {item.LastIdx} | Note {item.Note} | Last Upd {item.LastUpdate}"); - } - } - } - - /// - /// Esegue task IMPORT (MES PODL to MACHINE) - /// - private void execImportAll() - { - Stopwatch sw = new Stopwatch(); - sw.Start(); - elencoSyncState = dbProxy.SyncStateDoImportAll(); - sw.Stop(); - lastReadPLC = DateTime.Now; - lgInfo($"DB: esecuzione task dbProxy.SyncStateDoImportAll() in {sw.ElapsedMilliseconds} ms"); - - if (elencoSyncState != null) - { - foreach (var item in elencoSyncState) - { - lgTrace($"TAB {item.TableName} | LastIdx {item.LastIdx} | Note {item.Note} | Last Upd {item.LastUpdate}"); - } - } - } - - /// - /// Esegue processing + invio dati tab SignLog - /// - /// - /// - private bool processFluxLogTable(DateTime adesso) - { - bool fatto = false; - string tabNameIn = "FluxLog"; - string tabNameOut = "FluxLogToMes"; - // cerco info sui FluxLog (ToMes e letti) - var currFluxLogRead = elencoSyncState.FirstOrDefault(x => x.TableName == tabNameIn); - // se nullo inizializzo - if (currFluxLogRead == null) - { - currFluxLogRead = new SyncStateModel() - { - LastIdx = 0, - LastUpdate = adesso, - TableName = tabNameIn, - Note = "Init" - }; - } - var currFluxLogSent = elencoSyncState.FirstOrDefault(x => x.TableName == tabNameOut); - // se nullo inizializzo - if (currFluxLogSent == null) - { - currFluxLogSent = new SyncStateModel() - { - LastIdx = 0, - LastUpdate = adesso, - TableName = tabNameOut, - Note = "Init" - }; - } - // verifica se ci siano dati da trasmettere (sui valori LastIdx) - if (currFluxLogRead.LastIdx > currFluxLogSent.LastIdx) - { - // recupero i dati dal DB... - var data2send = dbProxy.MachFluxLogGetNew(currFluxLogSent.LastIdx); - // se ho dati preparo invio - if (data2send != null && data2send.Count > 0) - { - string sVal = ""; - foreach (var fLog2send in data2send) - { - sVal = $"[DYNDATA] |{fLog2send.DtEvento:yyyy-MM-dd HH:mm:ss}|{fLog2send.CodFlux}|{fLog2send.Valore}"; - // chiamo accodamento con dataora corretta... - accodaFLog(sVal, qEncodeFLog(fLog2send.DtEvento, fLog2send.CodFlux, fLog2send.Valore)); - } - fatto = true; - } - - // aggiorno idx inviato... - currFluxLogSent.Note = $"Updated from {currFluxLogRead.LastIdx}"; - currFluxLogSent.LastUpdate = adesso; - currFluxLogSent.LastIdx = currFluxLogRead.LastIdx; - } - - // alla fine aggiorno i dati inviati! - dbProxy.SyncStateUpsert(currFluxLogSent); - - return fatto; - } - - /// - /// Esegue processing + invio dati tab ProdData - /// - /// - /// - private bool processProdDataTable(DateTime adesso) - { - bool fatto = false; - string tabNameIn = "ProdData"; - string tabNameOut = "ProdDataToMes"; - // cerco info sui SignLog (ToMes e letti) - var currSignLogRead = elencoSyncState.FirstOrDefault(x => x.TableName == tabNameIn); - // se nullo inizializzo - if (currSignLogRead == null) - { - currSignLogRead = new SyncStateModel() - { - LastIdx = 0, - LastUpdate = adesso, - TableName = tabNameIn, - Note = "Init" - }; - } - var currSignLogSent = elencoSyncState.FirstOrDefault(x => x.TableName == tabNameOut); - // se nullo inizializzo - if (currSignLogSent == null) - { - currSignLogSent = new SyncStateModel() - { - LastIdx = 0, - LastUpdate = adesso, - TableName = tabNameOut, - Note = "Init" - }; - } - // verifica se ci siano dati da trasmettere (sui valori LastIdx) - if (currSignLogRead.LastIdx > currSignLogSent.LastIdx) - { - // recupero i dati dal DB... - var data2send = dbProxy.MachProdDataGetNew(currSignLogSent.LastIdx); - // se ho dati preparo invio - if (data2send != null && data2send.Count > 0) - { - foreach (var sLog2send in data2send) - { - if (sLog2send.Action == "StartOrd") - { - if (FullPodlUrl) - { - // se il record è apertura PODL chiamo apertura - trySetupPODL(sLog2send.IdxPodl); - //trySetupPODL(sLog2send.IdxPodl, true, sLog2send.DtEve, DateTime.Now); - } - else - { - trySetupPODL(0); - } - } - else if (sLog2send.Action == "EndOrd") - { - // se il record è chiusura PODL chiamo chiusura... DOPO aver cercato - // PODL --> ODL - if (FullPodlUrl) - { - tryClosePODL(sLog2send.IdxPodl); - //tryClosePODL(sLog2send.IdxPodl, sLog2send.DtEve, DateTime.Now); - } - else - { - tryClosePODL(0); - } - } - } - } - - // aggiorno idx inviato... - currSignLogSent.Note = $"Updated from {currSignLogRead.LastIdx}"; - currSignLogSent.LastUpdate = adesso; - currSignLogSent.LastIdx = currSignLogRead.LastIdx; -#if false - var lastRec = data2send.LastOrDefault(); - if (lastRec != null) - { - // salvo in B_input ultimo valore letto... - B_input = lastRec.ValInt; - } -#endif - fatto = true; - } - - // alla fine aggiorno i dati inviati! - dbProxy.SyncStateUpsert(currSignLogSent); - - return fatto; - } - - /// - /// Esegue processing + invio dati tab SignLog - /// - /// - /// - private bool processSignLogTable(DateTime adesso) - { - bool fatto = false; - string tabNameIn = "SignLog"; - string tabNameOut = "SignLogToMes"; - // cerco info sui SignLog (ToMes e letti) - var currSignLogRead = elencoSyncState.FirstOrDefault(x => x.TableName == tabNameIn); - // se nullo inizializzo - if (currSignLogRead == null) - { - currSignLogRead = new SyncStateModel() - { - LastIdx = 0, - LastUpdate = adesso, - TableName = tabNameIn, - Note = "Init" - }; - } - var currSignLogSent = elencoSyncState.FirstOrDefault(x => x.TableName == tabNameOut); - // se nullo inizializzo - if (currSignLogSent == null) - { - currSignLogSent = new SyncStateModel() - { - LastIdx = 0, - LastUpdate = adesso, - TableName = tabNameOut, - Note = "Init" - }; - } - // verifica se ci siano dati da trasmettere (sui valori LastIdx) - if (currSignLogRead.LastIdx > currSignLogSent.LastIdx) - { - // recupero i dati dal DB... - List data2send = dbProxy.MachSigLogGetNew(currSignLogSent.LastIdx); - // se ho dati preparo invio - if (data2send != null && data2send.Count > 0) - { - foreach (var sLog2send in data2send) - { - string currVal = getEncodSigLog(sLog2send.DtEve, sLog2send.ValInt, counterSigIN); - // verifico non sia in veto invio iniziale... - if (queueInEnabCurr) - { - // --> accodo (valore già formattato)! - QueueIN.Enqueue(currVal); - // loggo! - lgTrace(string.Format("[QUEUE-IN] {0}", currVal)); - counterSigIN++; - if (counterSigIN > 9999) - { - counterSigIN = 0; - } - } - else - { - lgDebug($"[VETO FOR QUEUE-IN] | {currVal} - MESSAGE NOT SENT | {adesso:yyyyMMdd_HHmmss}"); - checkVetoQueueIn(); - } - } - } - - // aggiorno idx inviato... - currSignLogSent.Note = $"Updated from {currSignLogRead.LastIdx}"; - currSignLogSent.LastUpdate = adesso; - currSignLogSent.LastIdx = currSignLogRead.LastIdx; - var lastRec = data2send.LastOrDefault(); - if (lastRec != null) - { - // salvo in B_input ultimo valore letto... - B_input = lastRec.ValInt; - } - fatto = true; - } - - // alla fine aggiorno i dati inviati! - dbProxy.SyncStateUpsert(currSignLogSent); - - return fatto; - } - - #endregion Private Methods - } -} \ No newline at end of file