using MapoSDK; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Threading; namespace IOB_WIN_NEXT { /// /// Controllo Siemens specifico x impianti Cosmap /// public class IobSiemensCosmap : IobSiemens { /* -------------------------------------------------------------------------------- * Controlli SIEMENS Cosmap * - basasto su SIEMENS * - S7 vers 1500 * * STRUTTURA MEMORIA DB29: (lettura) 10byte, * G:\Drive condivisi\30_Clienti\Donati\Schemi IOB-WIN\COSMAP * * Si intende lettura/scrittura con DB6.DBxx * * DB6 * CodOdl Array[000..049] of Char DBB0..49 * RicettaRich Array[050..099] of Char DBB50..99 * CodArt Array[100..150] of Char DBB100..149 * RicettaCorr Array[100..150] of Char DBB150..199 * QtaRich DInt 200 * Stato Int 204 (0 = ferma, 1 = produzione, 2 = manuale, 3 = emergenza) * Allarme Int 206 (0 = ok, 1 = macchina in allarme) * Contapezzi DInt 208 * PzCountSet DInt 212 valore che si vuole impostare sul contapezzi * PzCountRes DInt 216 comando di set contapezzi: al fronte di salita (0-->1) imposta contapezzi al valore prec * * -------------------------------------------------------------------------------- */ #region Public Constructors /// /// Classe base con i metodi x Siemens /// /// /// public IobSiemensCosmap(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf) { lgInfo("NEW IOB SIEMENS versione Cosmap"); } #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) * ----------------------------------------------------- */ //bool fatto = false; ushort currStatus = 0; ushort allarme = 0; //ushort valW = 0; var MemInt = new byte[2]; // recupero //fatto = S7ReadBB(ref MemInt, "DB6.DBW204", 2); //valW = S7.Net.Types.Word.FromByteArray(MemInt.ToArray()); //var testalW = S7.Net.Types.Word.FromByteArray(RawInput.Skip(204).Take(2).ToArray()); currStatus = S7.Net.Types.Word.FromByteArray(RawInput.Skip(204).Take(2).ToArray()); //fatto = S7ReadBB(ref MemInt, "DB6.DBW206", 2); //valW = S7.Net.Types.Word.FromByteArray(MemInt.ToArray()); //allarme = valW; allarme = S7.Net.Types.Word.FromByteArray(RawInput.Skip(206).Take(2).ToArray()); int byteSignals = 0; // bit 0 (poweron) imposto a 1 SE connected... if (currPLC.IsConnected) { byteSignals += (1 << 0); } // processo dagli stati + gravi... if (allarme > 0) { byteSignals += (1 << 3); } switch (currStatus) { case 1: byteSignals += (1 << 1); break; case 2: byteSignals += (1 << 4); break; case 3: byteSignals += (1 << 5); break; default: break; } // salvo! B_input = byteSignals; // log opzionale! if (verboseLog) { lgInfo($"Trasformazione dati: Status:{currStatus} | alarm:{allarme} --> 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) { lgInfo($"Chiamata executeTasks specifica IobSiemensCosmap: {task2exe.Count} task ricevuti"); // Verificare il protocollo: dovrebeb togliere SOLO i task eseguiti... Dictionary taskDone = new Dictionary(); 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.forceSetPzCount: case taskType.setProg: case taskType.sendWatchDogMes2Plc: taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC"; break; case taskType.setPzComm: case taskType.setArt: case taskType.setComm: 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]; 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 valInt = 0; short.TryParse(item.Value, out valInt); MemBlock = S7.Net.Types.Int.ToByteArray(valInt); } } else { string rawMemConf = JsonConvert.SerializeObject(memMap, Formatting.Indented); lgError($"Errore: non trovata chiave write in memMap.mMapWrite per {item.Key}{Environment.NewLine}Configurazione memoria R/W:{Environment.NewLine}{rawMemConf}"); } taskVal = item.Value; break; case taskType.forceResetPzCount: // processo scrittura BIT su DB6.DBDW216 MemBlock = new byte[4]; MemBlock = S7.Net.Types.DInt.ToByteArray(1); memAddrWrite = "DB6.DBDW216"; break; case taskType.startSetup: // processo scrittura BIT su DB6.DBDW216 MemBlock = new byte[4]; MemBlock = S7.Net.Types.DInt.ToByteArray(1); memAddrWrite = "DB6.DBDW216"; break; case taskType.stopSetup: // processo scrittura BIT su DB6.DBDW216 MemBlock = new byte[4]; MemBlock = S7.Net.Types.DInt.ToByteArray(0); memAddrWrite = "DB6.DBDW216"; break; case taskType.setParameter: // richiedo da URL i parametri WRITE da popolare lgInfo("setParameter --> processMemWriteRequests"); taskVal = processMemWriteRequests(); // se restituiscce "" faccio altra prova... 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; } lgInfo($"executeTask: {tName} | {taskVal}"); // aggiungo task! taskDone.Add(item.Key, taskVal); if (!string.IsNullOrEmpty(memAddrWrite)) { // scrivo! taskOk = S7WriteBB(ref MemBlock, memAddrWrite); } if (taskOk) { // aggiorno valore memoria... SE presente if (memMap.mMapWrite.ContainsKey(item.Key)) { memMap.mMapWrite[item.Key].value = item.Value; lgInfo($"Aggiornato valore in mMapWrite per {item.Key}"); } lgInfo($"Eseguita con successo S7WriteBB per executeTasks: {item.Key} | {item.Value}"); } else { lgError($"Errore in S7WriteBB durante executeTasks: {item.Key} | {item.Value}"); } } } return taskDone; } #endregion Public Methods } }