using MapoSDK; using System; using System.Collections.Generic; namespace IOB_WIN_NEXT { /// /// Controllo Siemens specifico x impianti Simec /// public class IobSiemensSimec : IobSiemens { /* -------------------------------------------------------------------------------- * Controlli SIEMENS SIMEC * - basasto su SIEMENS * - S7 vers 1500 * * STRUTTURA MEMORIA DB29: (lettura) 10byte, * G:\Drive condivisi\30_Clienti\Valvital\Comunicazione PLC\26 - SIMEC Taglio\ * * Si intende lettura con DB29.DBxx, scrittura DB30.DBxx * * DB30 blocco dati scritto dal MES * CodArt Array[0..19] of Char DBB0..19 * CodComm Array[0..9] of Char DBB20..29 * CodProgr Array[0..9] of Char DBB30..39 * * DB29 blocco dati letto dal MES Byte Bit * CicloOn Bool 0 0 * MacchOn Bool 0 1 * ManualeOn Bool 0 2 * AllarmiOn Bool 0 3 * EmergenzaOn Bool 0 4 * EmergenzaPremuta Bool 0 5 * b06 Bool 0 6 * b07 Bool 0 7 * b10 Bool 1 0 * b11 Bool 1 1 * b12 Bool 1 2 * b13 Bool 1 3 * b14 Bool 1 4 * b15 Bool 1 5 * b16 Bool 1 6 * b17 Bool 1 7 * ContapezziAssoluto DInt 2 * Comtapezzi parziale DInt 6 * -------------------------------------------------------------------------------- */ #region Public Constructors /// /// Classe base con i metodi x Siemens /// /// /// public IobSiemensSimec(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf) { lgInfo("NEW IOB SIEMENS versione SIMEC"); } #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: emergenza (1=attiva/premuta, 0=armed) * * - BIT di stato * DB29 blocco dati letto dal MES Byte Bit * CicloOn Bool 0 0 * MacchOn Bool 0 1 * ManualeOn Bool 0 2 * AllarmiOn Bool 0 3 * EmergenzaOn Bool 0 4 * EmergenzaPremuta Bool 0 5 * ContapezziAssoluto DInt 2 * Comtapezzi parziale DInt 6 * ----------------------------------------------------- */ byte mainData = RawInput[0]; int byteSignals = 0; // bit 0 (poweron) imposto a 1 SE connected... if (currPLC.IsConnected) { byteSignals += (1 << 0); } // lavora --> bit0 e bit1: cicloOn AND macchOn if ((mainData & (1 << 0)) != 0 && (mainData & (1 << 1)) != 0) { byteSignals += (1 << 1); } // controllo il bit ALARM if ((mainData & (1 << 3)) != 0) { byteSignals += (1 << 3); } // controllo il bit emergenza dello status if ((mainData & (1 << 5)) != 0) { byteSignals += (1 << 5); } // check MANUALE ... if ((mainData & (1 << 2)) != 0) { byteSignals += (1 << 4); } // salvo! B_input = byteSignals; // log opzionale! if (verboseLog) { lgInfo($"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 writeDone = false; bool taskOk = false; string taskVal = ""; // inizio con 1 byte di default byte[] MemBlock = new byte[1]; string memAddrWrite = ""; if (task2exe != null) { // cerco task specifici 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.forceResetPzCount: case taskType.forceSetPzCount: case taskType.setProg: case taskType.sendWatchDogMes2Plc: case taskType.setPzComm: case taskType.startSetup: case taskType.stopSetup: taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC"; lgInfo(taskVal); break; case taskType.setArt: case taskType.setComm: saveProdData(item); int byteSize = 0; // verifico se posso aggiornare valori in memoria... if (memMap != null && memMap.mMapWrite != null) { if (memMap.mMapWrite.ContainsKey(item.Key)) { // 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]; 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); } } taskVal = item.Value; } else { taskVal = $"NO DATA MEM, SET task: {item.Key} --> {item.Value}"; } } else { taskVal = $"NO MemMap found, SET task: {item.Key} --> {item.Value}"; } if (!string.IsNullOrEmpty(memAddrWrite)) { // scrivo! writeDone = true; taskOk = S7WriteBB(ref MemBlock, memAddrWrite); } // se restituiscce "" faccio altra prova... break; case taskType.setParameter: // richiedo da URL i parametri WRITE da popolare lgInfo("Chiamata processMemWriteRequests"); taskVal = processMemWriteRequests(); if (string.IsNullOrEmpty(taskVal)) { // 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"; } } break; default: taskVal = "SKIPPED | NO EXEC"; break; } // aggiungo task! taskDone.Add(item.Key, taskVal); if (!taskOk && writeDone) { lgError($"Errore in S7WriteBB durante executeTasks: {item.Key} | {item.Value}"); } } } return taskDone; } #endregion Public Methods } }