diff --git a/IOB-WIN-NEXT/IobSiemensCosmap.cs b/IOB-WIN-NEXT/IobSiemensCosmap.cs
index 5fbcce14..9bc31354 100644
--- a/IOB-WIN-NEXT/IobSiemensCosmap.cs
+++ b/IOB-WIN-NEXT/IobSiemensCosmap.cs
@@ -18,7 +18,7 @@ namespace IOB_WIN_NEXT
* - S7 vers 1500
*
* STRUTTURA MEMORIA DB29: (lettura) 10byte,
- * G:\Drive condivisi\30_Clienti\Donati\Schemi DB\COSMAP
+ * G:\Drive condivisi\30_Clienti\Donati\Schemi IOB-WIN\COSMAP
*
* Si intende lettura/scrittura con DB6.DBxx
*
diff --git a/IOB-WIN-NEXT/IobSiemensRobotService.cs b/IOB-WIN-NEXT/IobSiemensRobotService.cs
new file mode 100644
index 00000000..38039e3b
--- /dev/null
+++ b/IOB-WIN-NEXT/IobSiemensRobotService.cs
@@ -0,0 +1,289 @@
+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 RobotSerice (es Smerigliature DONATI)
+ ///
+ public class IobSiemensRobotService : IobSiemens
+ {
+ /* --------------------------------------------------------------------------------
+ * Controlli SIEMENS RobotService
+ * - basasto su SIEMENS
+ * - S7 vers 1500
+ *
+ * STRUTTURA MEMORIA DB15: (lettura) 10byte,
+ * G:\Drive condivisi\30_Clienti\Donati\Schemi IOB-WIN\RobotService
+ *
+ *
+ * DB15
+ * B0.0 Bit PowerOn
+ * B0.1 Bit Run
+ * B0.2 Bit Contapezzi
+ * B0.3 Bit Allarme
+ * B0.4 Bit Manuale
+ * B0.5 Bit MagOutPieno
+ * B0.6 Bit MagInVuoto
+ * Contapezzi DInt 2
+ * PezziRiman DInt 6
+ *
+ *
+ * STRUTTURA MEMORIA DB14: (scrittura) 520byte,
+ * G:\Drive condivisi\30_Clienti\Donati\Schemi IOB-WIN\RobotService
+ *
+ *
+ * DB14
+ * Commessa Odl String[000..256] String (254)
+ * CodArt String[256..512] String (254)
+ * QtaRich DInt 512 numero pezzi lanciati
+ * PzCountRes Bool/Byte 516 al fronte di salita (0-->1) reset contapezzi e NON CONTA mentre è 1, se 0 conta
+ *
+ * -------------------------------------------------------------------------------- */
+
+ #region Public Constructors
+
+ ///
+ /// Classe base con i metodi x Siemens
+ ///
+ ///
+ ///
+ public IobSiemensRobotService(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf)
+ {
+ lgInfo("NEW IOB SIEMENS versione RobotService");
+ }
+
+ #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...
+ memMap.mMapWrite[item.Key].value = item.Value;
+ 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
+ }
+}
\ No newline at end of file