using MapoSDK; using System; using System.Collections.Generic; namespace IOB_WIN_NEXT { /// /// Controllo Siemens specifico x impianti SAET /// public class IobSiemensAt2001 : IobSiemens { /* -------------------------------------------------------------------------------- * Controlli VIPA/SIEMENS (Interclays) di @2001 * - VIPA, COMPATIBILE SIEMENS * - S7 vers 300 * * * -------------------------------------------------------------------------------- */ #region Protected Fields protected int counterMes2Plc = 0; protected int counterPlc2Mes = 0; protected DateTime lastPLCWatchDog; #endregion Protected Fields #region Public Constructors /// /// Classe base con i metodi x Siemens /// /// /// public IobSiemensAt2001(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf) { lgInfo("NEW IOB SIEMENS versione VIPA AT2001"); lastPLCWatchDog = DateTime.Now.AddMinutes(-1); } #endregion Public Constructors #region Protected Methods /// /// Effettua decodifica aree memoria alla bitmap usata x MAPO /// protected override void decodeToBaseBitmap() { // init a zero... B_input = 0; /* ----------------------------------------------------- * bitmap MAPO STANDARD * B0: POWER_ON * B1: RUN * B2: pzCount * B3: allarme * B4: manuale * B5: avvio/spegnimento * B6: emergenza * * * - BYTE di stato * - +0.0 AutoStatus BYTE B#16#0 Valore 0=Fermo/1->3=Avviamento/4=Avviato/5=Pausa/6->8spegnimento/9->10 allarme * - +1.0 Dosatore BYTE B#16#0 Stato (bit0=in avviamento/1=marcia sx/2=marcia dx/3=in allarme/4=by-pass on) * - +2.0 V_Dosatore BYTE B#16#0 Stato (bit0=in avviamento/1=marcia sx/2=marcia dx/3=in allarme/4=by-pass on) * - +3.0 Nas_Lancio BYTE B#16#0 Stato (bit0=in avviamento/1=marcia sx/2=marcia dx/3=in allarme/4=by-pass on) * - +4.0 Cilindro BYTE B#16#0 Stato (bit0=in avviamento/1=marcia sx/2=marcia dx/3=in allarme/4=by-pass on) * - +5.0 Bruciatore BYTE B#16#0 Stato (bit0=in avviamento/1=marcia sx/2=marcia dx/3=in allarme/4=by-pass on) * - +6.0 Aspiratore BYTE B#16#0 Stato (bit0=in avviamento/1=marcia sx/2=marcia dx/3=in allarme/4=by-pass on) * - +7.0 Nas_Raccolta BYTE B#16#0 Stato (bit0=in avviamento/1=marcia sx/2=marcia dx/3=in allarme/4=by-pass on) * - +8.0 Nas_Brandeg BYTE B#16#0 Stato (bit0=in avviamento/1=marcia sx/2=marcia dx/3=in allarme/4=by-pass on) * - +9.0 Coclea_Filtro BYTE B#16#0 Stato (bit0=in avviamento/1=marcia sx/2=marcia dx/3=in allarme/4=by-pass on) * - +10.0 Ciclico_Filtro BYTE B#16#0 Stato (bit0=in avviamento/1=marcia sx/2=marcia dx/3=in allarme/4=by-pass on) ----------------------------------------------------- */ // recupero byte segnali... int byteSignals = RawInput[0]; // bit 0 (poweron) imposto a 1 SE connected... B_input = currPLC.IsConnected ? 1 : 0; // avviamento --> manuale switch (byteSignals) { case 0: B_input = 1; break; case 1: case 2: case 3: B_input += (1 << 5); break; case 4: B_input += (1 << 1); break; case 5: B_input += (1 << 4); break; case 6: case 7: case 8: B_input += (1 << 5); break; case 9: B_input += (1 << 3); break; case 10: B_input += (1 << 6); break; default: break; } // log opzionale! if (verboseLog) { lgInfo(string.Format($"Trasformazione dati: RawInput:{RawInput[0]} --> B_input: {B_input}")); } } #endregion Protected Methods #region Public Methods /// /// Processo i task richiesti e li elimino dalla coda 1:1 /// /// public override Dictionary executeTasks(Dictionary task2exe) { // Verificare il protocollo: dovrebeb togliere SOLO i task eseguiti... Dictionary taskDone = new Dictionary(); bool taskOk = false; string taskVal = ""; // inizio VUOTO byte[] MemBlock = new byte[1]; string memAddrWrite = ""; if (task2exe != null) { // cerco task specifici: se ho startSetup --> imposto bit DBB701.DBB0.4 foreach (var item in task2exe) { taskOk = false; taskVal = ""; memAddrWrite = ""; // 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.forceSetPzCount: case taskType.stopSetup: taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC"; break; case taskType.forceResetPzCount: case taskType.startSetup: // alzo il bit x registrare richiesta reset contapezzi... POI quando ha eseguito abbassa il PLC il bit a zero... MemBlock[0] = 1; memAddrWrite = "DB1001.DBB88"; break; case taskType.setArt: case taskType.setComm: case taskType.setProg: #if false // imposto i valori... if (currProdData.ContainsKey(item.Key)) { currProdData[item.Key] = item.Value; } else { currProdData.Add(item.Key, item.Value); } taskVal = item.Value; #endif saveProdData(item); int byteSize = 0; // recupero dati da memMap... altrimenti NULLA if (memMap.mMapWrite.ContainsKey(item.Key)) { dataConf currMem = memMap.mMapWrite[item.Key]; byteSize = currMem.size; memAddrWrite = currMem.memAddr; MemBlock = new byte[byteSize]; switch (currMem.tipoMem) { case plcDataType.Boolean: break; case plcDataType.Int: saveIntOnMemBlock(ref MemBlock, item.Key, 0); break; case plcDataType.DInt: saveDIntOnMemBlock(ref MemBlock, item.Key, 0); break; case plcDataType.Real: saveRealOnMemBlock(ref MemBlock, item.Key, 0); break; case plcDataType.String: saveStringOnMemBlock(ref MemBlock, item.Key, 0, byteSize); break; default: break; } #if false if (currMem.tipoMem == plcDataType.String) { saveStringOnMemBlock(ref MemBlock, item.Key, 0, byteSize); } else if (currMem.tipoMem == plcDataType.DInt) { int valDInt = 0; int.TryParse(item.Value, out valDInt); MemBlock = S7.Net.Types.DInt.ToByteArray(valDInt); } else if (currMem.tipoMem == plcDataType.Int) { short valDInt = 0; short.TryParse(item.Value, out valDInt); MemBlock = S7.Net.Types.Int.ToByteArray(valDInt); } #endif } taskVal = item.Value; break; case taskType.setParameter: // richiedo da URL i parametri WRITE da popolare lgInfo("Chiamata processMemWriteRequests"); taskVal = processMemWriteRequests(); // se restituiscce "" faccio altra prova... if (!string.IsNullOrEmpty(taskVal)) { taskOk = true; } else { // i parametri me li aspetto come stringa composta paramName|paramvalue if (item.Value.Contains("|")) { string[] paramsJob = item.Value.Split('|'); taskVal = $"REQUEST SET PARAMETERS: {paramsJob[0]} --> {paramsJob[1]}"; } else { taskVal = $"WRONG REQUEST FOR SET PARAMETERS: {item.Value} doesnt contain pipe for splitting key/value"; } } // alzo il bit x registrare RICHEISTA modifica (secondo BIT)... POI quando ha eseguito abbassa il PLC il bit a zero... MemBlock[0] = 2; memAddrWrite = "DB1001.DBB88"; break; case taskType.sendWatchDogMes2Plc: //// compogo in byte... primo bit è setup/run, ultimo è watchdog //int valore = inSetup ? 1 : 0; int valore = counterMes2Plc; MemBlock[68] = (byte)valore; taskVal = $"VALUE DB1001.68 --> {counterMes2Plc}"; break; default: taskVal = "SKIPPED | NO EXEC"; break; } // aggiungo task! taskDone.Add(item.Key, taskVal); if (!string.IsNullOrEmpty(memAddrWrite)) { // scrivo! taskOk = S7WriteBB(ref MemBlock, memAddrWrite); } if (!taskOk) { lgError($"Errore in S7WriteBB durante executeTasks: {item.Key} | {item.Value}"); } } } #if false // controllo SE HO da scrivere articolo/commessa/programma saveStringOnMemBlock(ref MemBlock, "setArt", 0, 20, true); saveStringOnMemBlock(ref MemBlock, "setComm", 22, 20, true); saveStringOnMemBlock(ref MemBlock, "setProg", 44, 20, true); // !!!FIXME!!! rendere parametrico // SE HO un valore ART scrivo... if (currProdData.ContainsKey("setArt")) { if (currProdData["setArt"] != "") { // imposto i valori... upsertKey("kgParz", "1234"); saveIntOnMemBlock(ref MemBlock, "kgParz", 66); upsertKey("set_th", "601"); saveIntOnMemBlock(ref MemBlock, "set_th", 72); upsertKey("set_c", "101"); saveRealOnMemBlock(ref MemBlock, "set_c", 74); upsertKey("aria_1", "1801"); saveIntOnMemBlock(ref MemBlock, "aria_1", 78); upsertKey("aria_2", "1851"); saveIntOnMemBlock(ref MemBlock, "aria_2", 80); upsertKey("setMmH20", "9"); saveRealOnMemBlock(ref MemBlock, "setMmH20", 82); upsertKey("rpmci", "101"); saveIntOnMemBlock(ref MemBlock, "rpmci", 86); } } // fare un controllo x forzare update... // scrivo comunque! taskOk = S7WriteBB(ref MemBlock); #endif return taskDone; } /// /// Effettua processing del recupero delle OVERRIDE (spindle, feedrate, rapid) /// public override void processOverride() { } public override void processWhatchDog() { //NON SERVE!!!! } #endregion Public Methods } }