diff --git a/IOB-WIN/IobSiemensFape.cs b/IOB-WIN/IobSiemensFape.cs index 7c9efa76..0f918023 100644 --- a/IOB-WIN/IobSiemensFape.cs +++ b/IOB-WIN/IobSiemensFape.cs @@ -164,35 +164,47 @@ namespace IOB_WIN break; } - string currODL = ""; - try + // procedo SOLO SE è enabled IOB + if (IobOnline) { - currODL = utils.callUrl(urlGetCurrODL); - // solo SE HO un ODL... - if (string.IsNullOrWhiteSpace(currODL) || currODL == "0") + try { - if (periodicLog) + currODL = utils.callUrl(urlGetCurrODL); + // solo SE HO un ODL... + if (string.IsNullOrWhiteSpace(currODL) || currODL == "0") { - lgInfo(string.Format("SiemensFape | Lettura ODL andata a vuoto: currODL: {0}", currODL)); + if (periodicLog) + { + lgInfo(string.Format("SiemensFape | Lettura ODL andata a vuoto: currODL: {0}", currODL)); + } + } + else + { + // se variato o scaduto timeout log... + if (periodicLog || (currIdxODL.ToString() != currODL)) + { + lgInfo(string.Format("SiemensFape | Lettura ODL, currODL: {0} --> currIdxODL prec: {1}", currODL, currIdxODL)); + } + // provo a salvare nuovo ODL + int.TryParse(currODL, out currIdxODL); } } - else + catch (Exception exc) { - // se variato o scaduto timeout log... - if (periodicLog || (currIdxODL.ToString() != currODL)) + if (DateTime.Now.Subtract(lastWarnODL).TotalSeconds > 15) { - lgInfo(string.Format("SiemensFape | Lettura ODL, currODL: {0} --> currIdxODL prec: {1}", currODL, currIdxODL)); + lgError(exc, "Errore in fase di chiamata URL x ODL corrente | URL chiamato: {0}", urlGetCurrODL); + lastWarnODL = DateTime.Now; } - // provo a salvare nuovo ODL - int.TryParse(currODL, out currIdxODL); } } - catch (Exception exc) + else { - if (DateTime.Now.Subtract(lastWarnODL).TotalSeconds > 15) + // imposto currODL a vuoto! + currODL = ""; + if (periodicLog) { - lgError(exc, "Errore in fase di chiamata URL x ODL corrente | URL chiamato: {0}", urlGetCurrODL); - lastWarnODL = DateTime.Now; + lgInfo($"Fanuc | Lettura ODL non effettuata: IobOnline: {IobOnline} | currODL impostato a vuoto"); } } if (!string.IsNullOrWhiteSpace(currODL) && currODL != "0") diff --git a/IOB-WIN/IobSiemensTorri.cs b/IOB-WIN/IobSiemensTorri.cs index 25a6e15d..fadd5832 100644 --- a/IOB-WIN/IobSiemensTorri.cs +++ b/IOB-WIN/IobSiemensTorri.cs @@ -8,15 +8,16 @@ namespace IOB_WIN { public class IobSiemensTorri : IobSiemens { - /* -------------------------------------------------------------------------------- + /* -------------------------------------------------------------------------------- * Controlli SIEMENS TORRI * - basasto su SIEMENS * - S7 vers 1200 - * + * * mod: 2019.01.19: aggiunta gestione segnale test/accensione/spegnimento (DB700.B1.4) --> mod StateMachine! * mod: 2019.04.06: aggiunta indicazione (IOB--> PLC) di stato setup su DB701.B0.4 * -------------------------------------------------------------------------------- */ + #region Public Constructors /// /// estende l'init della classe base con i metodi x Siemens specifici x Torri @@ -28,6 +29,183 @@ namespace IOB_WIN // dovebbe fare init della classe base, VERIFICARE... lgInfo("NEW IOB SIEMENS versione TORRI"); } + + #endregion Public Constructors + + #region Protected Methods + + /// + /// Decodifica il resto dell'area TORRI x i dati accessori (allarmi, ...) + /// + protected override void decodeOtherData() + { + if (verboseLog) + { + } + } + + /// + /// Effettua decodifica aree memoria alla bitmap usata x MAPO + /// + protected override void decodeToBaseBitmap() + { + // init a zero... + B_input = 0; + // TORRI: leggo i primi 8 bit hard coded... + int byteSem = RawInput[0]; + + // azzero powerOn... + byteSem &= ~(1 << 0); + // bit 0 (powerOn) imposto a 1 SE connected... + if (currPLC.IsConnected) + { + byteSem += (1 << 0); + } + + // azzero i bit NON gestiti (2-5-6-7) + byteSem &= ~(1 << 2); + byteSem &= ~(1 << 5); + byteSem &= ~(1 << 6); + byteSem &= ~(1 << 7); + // leggo bit DB700.B1.4 e lo porto al bit 5 --> ciclo test/accensione/spegnimento + if ((RawInput[1] & (1 << 4)) != 0) //se RawInput[1] & 16-- > 5° bit-- > TEST + { + byteSem += (1 << 5); + } + // salvo infine variabile bit x invio + B_input = byteSem; + + // 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($"SiemensTorri | Lettura ODL andata a vuoto: currODL: {currODL}"); + } + } + else + { + // se variato o scaduto timeout log... + if (periodicLog || (currIdxODL.ToString() != currODL)) + { + lgInfo($"SiemensTorri | Lettura ODL, currODL: {currODL} --> currIdxODL prec: {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: {urlGetCurrODL}"); + lastWarnODL = DateTime.Now; + } + } + } + else + { + // imposto currODL a vuoto! + currODL = ""; + if (periodicLog) + { + lgInfo($"Fanuc | Lettura ODL non effettuata: IobOnline: {IobOnline} | currODL impostato a vuoto"); + } + } + if (!string.IsNullOrEmpty(currODL) && currODL != "0") + { + // ora processo il contapezzi... + string retVal = ""; + // controllo se è passato intervallo minimo tra 2 controlli/elaborazioni x distanziare invio e ridurre letture + if (DateTime.Now >= lastPzCountSend.AddMilliseconds(pzCountDelay)) + { + // Salvo il contapezzi della macchina + retVal = utils.callUrlNow(urlSetPzCountMAC + contapezziPLC.ToString()); + // verifica se tutto OK, ovvero conferma i pezzi inviati + if (retVal != contapezziPLC.ToString()) + { + // errore salvataggio contapezzi + lgInfo($"Errore salvataggio Contapezzi PLC SIEMENST-TORRI: {contapezziPLC} | contapezziIOB {contapezziIOB} | Valore tornato: {retVal}"); + // rileggo il counter pezzi da server + pzCntReload(true); + } + + // se sono differenti MOSTRO... + if (contapezziPLC != contapezziIOB) + { + // registro contapezzi + lgInfo($"Differenza Contapezzi: contapezziPLC: {contapezziPLC} | contapezziIOB: {contapezziIOB}"); + } + 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 SIEMENST-TORRI: {contapezziPLC} | contapezziIOB {contapezziIOB}"); + } + + // Salvo il contapezzi della macchina + retVal = utils.callUrlNow(urlSetPzCount + contapezziIOB.ToString()); + // verifica se tutto OK, ovvero conferma i pezzi inviati + if (retVal != contapezziIOB.ToString()) + { + // errore salvataggio contapezzi + lgInfo($"Errore salvataggio contapezziPLC SIEMENST-TORRI: {contapezziPLC} | contapezziIOB {contapezziIOB} | Valore tornato: {retVal}"); + // rileggo il counter pezzi da server + pzCntReload(true); + } + + // verifico se variato contapezzi... e se passato ritardo minimo... + if ((contapezziPLC - contapezziIOB) > minSendPzCountBlock) + { + trySendPzCountBlock(); + } + + // invio a server contapezzi (aggiornato) + retVal = utils.callUrlNow(urlSetPzCount + contapezziIOB.ToString()); + // verifica se tutto OK + if (retVal != contapezziIOB.ToString()) + { + // errore salvataggio contapezzi + lgInfo($"Errore salvataggio Contapezzi SIEMENS-TORRI: 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 SIEMENST-TORRI: {contapezziPLC} | contapezziIOB: {contapezziIOB}"); + // resetto timer... + lastPzCountSend = DateTime.Now; + } + } + + // log opzionale! + if (verboseLog) + { + lgInfo("Trasformazione B_input: {B_input}"); + } + } + + #endregion Protected Methods + + #region Public Methods + /// /// Processo i task richiesti e li elimino dalla coda 1:1 /// @@ -63,19 +241,23 @@ namespace IOB_WIN taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC"; lgInfo($"Chiamata senza processing: taskOk: {taskOk} | taskVal: {taskVal}"); break; + case taskType.fixStopSetup: taskVal = "VALUE DB701.0.4 --> 0"; lgInfo($"Chiamata fixStopSetup: taskOk: {taskOk} | taskVal: {taskVal}"); break; + case taskType.startSetup: MemBlock[0] += (1 << 4); taskVal = "VALUE DB701.0.4 --> 1"; lgInfo($"Chiamata startSetup: taskOk: {taskOk} | taskVal: {taskVal}"); break; + case taskType.stopSetup: taskVal = "VALUE DB701.0.4 --> 0"; lgInfo($"Chiamata stopSetup: taskOk: {taskOk} | taskVal: {taskVal}"); break; + default: taskVal = "SKIPPED | NO EXEC"; lgInfo($"Chiamata default senza processing: taskOk: {taskOk} | taskVal: {taskVal}"); @@ -89,269 +271,24 @@ namespace IOB_WIN return taskDone; } - #region da verificare - /// - /// Recupero dati override in formato dictionary + /// Recupera ULTIMO allarme... /// /// - public override Dictionary getOverrides() - { - Dictionary outVal = new Dictionary(); - uint valDW = 0; - // !!!FARE!!! recuperare da conf memoria, ora HARD CODED - outVal.Add("FEED_OVER", RawInput[19].ToString()); - outVal.Add("RAPID_OVER", RawInput[20].ToString()); - outVal.Add("CURR_MODE", decodeCurrMode(RawInput[21])); - // recupero RPM pezzo/mola !!!FARE!!! cambio nome da config, qui sono 01:conduttrice e 02:operatrice (3013), mentre sono pezzo/mola nella V100 - valDW = S7.Net.Types.DWord.FromByteArray(RawInput.Skip(24).Take(4).ToArray()); - outVal.Add("RPM_01", valDW.ToString()); - valDW = S7.Net.Types.DWord.FromByteArray(RawInput.Skip(28).Take(4).ToArray()); - outVal.Add("RPM_02", valDW.ToString()); - return outVal; - } - - /// - /// Decodifica il resto dell'area TORRI x i dati accessori (allarmi, ...) - /// - protected override void decodeOtherData() - { - if (verboseLog) - { - - } - } - - /// - /// Effettua decodifica aree memoria alla bitmap usata x MAPO - /// - protected override void decodeToBaseBitmap() - { - // init a zero... - B_input = 0; - // TORRI: leggo i primi 8 bit hard coded... - int byteSem = RawInput[0]; - - // azzero powerOn... - byteSem &= ~(1 << 0); - // bit 0 (powerOn) imposto a 1 SE connected... - if (currPLC.IsConnected) - { - byteSem += (1 << 0); - } - - // azzero i bit NON gestiti (2-5-6-7) - byteSem &= ~(1 << 2); - byteSem &= ~(1 << 5); - byteSem &= ~(1 << 6); - byteSem &= ~(1 << 7); - // leggo bit DB700.B1.4 e lo porto al bit 5 --> ciclo test/accensione/spegnimento - if ((RawInput[1] & (1 << 4)) != 0) //se RawInput[1] & 16-- > 5° bit-- > TEST - { - byteSem += (1 << 5); - } - // salvo infine variabile bit x invio - B_input = byteSem; - - - string currODL = ""; - try - { - currODL = utils.callUrl(urlGetCurrODL); - // solo SE HO un ODL... - if (string.IsNullOrEmpty(currODL) || currODL == "0") - { - if (periodicLog) - { - lgInfo($"SiemensTorri | Lettura ODL andata a vuoto: currODL: {currODL}"); - } - } - else - { - // se variato o scaduto timeout log... - if (periodicLog || (currIdxODL.ToString() != currODL)) - { - lgInfo($"SiemensTorri | Lettura ODL, currODL: {currODL} --> currIdxODL prec: {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: {urlGetCurrODL}"); - lastWarnODL = DateTime.Now; - } - } - if (!string.IsNullOrEmpty(currODL) && currODL != "0") - { - // ora processo il contapezzi... - string retVal = ""; - // controllo se è passato intervallo minimo tra 2 controlli/elaborazioni x distanziare invio e ridurre letture - if (DateTime.Now >= lastPzCountSend.AddMilliseconds(pzCountDelay)) - { - // Salvo il contapezzi della macchina - retVal = utils.callUrlNow(urlSetPzCountMAC + contapezziPLC.ToString()); - // verifica se tutto OK, ovvero conferma i pezzi inviati - if (retVal != contapezziPLC.ToString()) - { - // errore salvataggio contapezzi - lgInfo($"Errore salvataggio Contapezzi PLC SIEMENST-TORRI: {contapezziPLC} | contapezziIOB {contapezziIOB} | Valore tornato: {retVal}"); - // rileggo il counter pezzi da server - pzCntReload(true); - } - - // se sono differenti MOSTRO... - if (contapezziPLC != contapezziIOB) - { - // registro contapezzi - lgInfo($"Differenza Contapezzi: contapezziPLC: {contapezziPLC} | contapezziIOB: {contapezziIOB}"); - } - 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 SIEMENST-TORRI: {contapezziPLC} | contapezziIOB {contapezziIOB}"); - } - - // Salvo il contapezzi della macchina - retVal = utils.callUrlNow(urlSetPzCount + contapezziIOB.ToString()); - // verifica se tutto OK, ovvero conferma i pezzi inviati - if (retVal != contapezziIOB.ToString()) - { - // errore salvataggio contapezzi - lgInfo($"Errore salvataggio contapezziPLC SIEMENST-TORRI: {contapezziPLC} | contapezziIOB {contapezziIOB} | Valore tornato: {retVal}"); - // rileggo il counter pezzi da server - pzCntReload(true); - } - - // verifico se variato contapezzi... e se passato ritardo minimo... - if ((contapezziPLC - contapezziIOB) > minSendPzCountBlock) - { - trySendPzCountBlock(); - } - - // invio a server contapezzi (aggiornato) - retVal = utils.callUrlNow(urlSetPzCount + contapezziIOB.ToString()); - // verifica se tutto OK - if (retVal != contapezziIOB.ToString()) - { - // errore salvataggio contapezzi - lgInfo($"Errore salvataggio Contapezzi SIEMENS-TORRI: 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 SIEMENST-TORRI: {contapezziPLC} | contapezziIOB: {contapezziIOB}"); - // resetto timer... - lastPzCountSend = DateTime.Now; - } - } - - // log opzionale! - if (verboseLog) - { - lgInfo("Trasformazione B_input: {B_input}"); - } - } - - - /// - /// Recupero programma in lavorazione - /// - /// - public override string getPrgName() - { - string prgName = ""; -#if false - // recupero NUOVO prgName... - try - { - // recupero nome programma MAIN - prgName = utils.purgedChar2String(FANUC_ref.getPrgNameMain()); - // trimmo path del programma, ovvero "CNCMEMUSERPATH1" - prgName = prgName.Replace(utils.CRS("basePrgMemPath"), ""); - } - catch (Exception exc) - { - lgError(string.Format("Eccezione in recupero PRG NAME MAIN:{0}{1}", Environment.NewLine, exc)); - } -#endif - return prgName; - } - - /// - /// Recupero programma in lavorazione come Dictionary FANUC... - /// - SYSINFO: (prima KEY globale) TUTTI i valori separati da # (x fare check modifica) - /// - altre stringhe: ogni singolo parametro / valore - /// - /// - public override Dictionary getSysInfo() + public override Dictionary getCncAlarms() { Dictionary outVal = new Dictionary(); try { - outVal.Add("CPU", currPLC.CPU.ToString()); - outVal.Add("MAX_PDU", currPLC.MaxPDUSize.ToString()); - outVal.Add("RACK", currPLC.Rack.ToString()); - outVal.Add("SLOT", currPLC.Slot.ToString()); + string almMsg = string.Format("{0} | {1}", currPLC.LastErrorCode.ToString(), currPLC.LastErrorString); + outVal.Add("CNC_ALARM", almMsg); } catch (Exception exc) { - lgError(exc, "Errore in getSysInfo"); + lgError(exc, "Errore in getCncAlarms"); } return outVal; } - /// - /// Esegue processing MODE (e nel contempo recupera altri dati dell'area G) - /// - public override void processMode() - { - if (utils.CRB("enableMode")) - { -#if false - try - { - inizio = DateTime.Now; - // leggo tutto da 0 a 43... - int memIndex = 0; - FanucMemRW(R, FANUC.MemType.G, memIndex, ref MemBlockG); - if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-G-AREA", MemBlockG.Length), DateTime.Now.Subtract(inizio).Ticks); - // verifico modo con valore corrente, se cambia aggiorno... - CNC_MODE newMode = decodeG43(MemBlockG[43]); - if (newMode != currMode) - { - // aggiorno! - currMode = newMode; - // conversione NUM MODE in descrizione da ENUM - string descrMode = Enum.GetName(typeof(CNC_MODE), currMode); - // accodo x invio - string sVal = string.Format("[CNC_MODE]{0}", descrMode); - // chiamo accodamento... - accodaFLog(sVal, qEncodeFLog("CNC_MODE", descrMode)); - } - } - catch (Exception exc) - { - lgError(exc, "Errore in process Mode G43"); - } -#endif - } - } /// /// Recupero dati dinamici... @@ -393,29 +330,115 @@ namespace IOB_WIN catch (Exception exc) { lgError(exc, "Errore in getDynData"); - } + } #endif return outVal; } + /// - /// Recupera ULTIMO allarme... + /// Recupero dati override in formato dictionary /// /// - public override Dictionary getCncAlarms() + public override Dictionary getOverrides() + { + Dictionary outVal = new Dictionary(); + uint valDW = 0; + // !!!FARE!!! recuperare da conf memoria, ora HARD CODED + outVal.Add("FEED_OVER", RawInput[19].ToString()); + outVal.Add("RAPID_OVER", RawInput[20].ToString()); + outVal.Add("CURR_MODE", decodeCurrMode(RawInput[21])); + // recupero RPM pezzo/mola !!!FARE!!! cambio nome da config, qui sono 01:conduttrice e 02:operatrice (3013), mentre sono pezzo/mola nella V100 + valDW = S7.Net.Types.DWord.FromByteArray(RawInput.Skip(24).Take(4).ToArray()); + outVal.Add("RPM_01", valDW.ToString()); + valDW = S7.Net.Types.DWord.FromByteArray(RawInput.Skip(28).Take(4).ToArray()); + outVal.Add("RPM_02", valDW.ToString()); + return outVal; + } + + /// + /// Recupero programma in lavorazione + /// + /// + public override string getPrgName() + { + string prgName = ""; +#if false + // recupero NUOVO prgName... + try + { + // recupero nome programma MAIN + prgName = utils.purgedChar2String(FANUC_ref.getPrgNameMain()); + // trimmo path del programma, ovvero "CNCMEMUSERPATH1" + prgName = prgName.Replace(utils.CRS("basePrgMemPath"), ""); + } + catch (Exception exc) + { + lgError(string.Format("Eccezione in recupero PRG NAME MAIN:{0}{1}", Environment.NewLine, exc)); + } +#endif + return prgName; + } + + /// + /// Recupero programma in lavorazione come Dictionary FANUC... + /// - 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(); try { - string almMsg = string.Format("{0} | {1}", currPLC.LastErrorCode.ToString(), currPLC.LastErrorString); - outVal.Add("CNC_ALARM", almMsg); + outVal.Add("CPU", currPLC.CPU.ToString()); + outVal.Add("MAX_PDU", currPLC.MaxPDUSize.ToString()); + outVal.Add("RACK", currPLC.Rack.ToString()); + outVal.Add("SLOT", currPLC.Slot.ToString()); } catch (Exception exc) { - lgError(exc, "Errore in getCncAlarms"); + lgError(exc, "Errore in getSysInfo"); } return outVal; } + /// + /// Esegue processing MODE (e nel contempo recupera altri dati dell'area G) + /// + public override void processMode() + { + if (utils.CRB("enableMode")) + { +#if false + try + { + inizio = DateTime.Now; + // leggo tutto da 0 a 43... + int memIndex = 0; + FanucMemRW(R, FANUC.MemType.G, memIndex, ref MemBlockG); + if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-G-AREA", MemBlockG.Length), DateTime.Now.Subtract(inizio).Ticks); + // verifico modo con valore corrente, se cambia aggiorno... + CNC_MODE newMode = decodeG43(MemBlockG[43]); + if (newMode != currMode) + { + // aggiorno! + currMode = newMode; + // conversione NUM MODE in descrizione da ENUM + string descrMode = Enum.GetName(typeof(CNC_MODE), currMode); + // accodo x invio + string sVal = string.Format("[CNC_MODE]{0}", descrMode); + // chiamo accodamento... + accodaFLog(sVal, qEncodeFLog("CNC_MODE", descrMode)); + } + } + catch (Exception exc) + { + lgError(exc, "Errore in process Mode G43"); + } +#endif + } + } + /// /// Override salvataggio valori in memoria... /// @@ -424,6 +447,6 @@ namespace IOB_WIN { } - #endregion + #endregion Public Methods } -} +} \ No newline at end of file