diff --git a/IOB-WIN/IOB-WIN.csproj b/IOB-WIN/IOB-WIN.csproj
index e5525b54..c1bab42b 100644
--- a/IOB-WIN/IOB-WIN.csproj
+++ b/IOB-WIN/IOB-WIN.csproj
@@ -254,6 +254,12 @@
Always
+
+ Always
+
+
+ Always
+
Always
diff --git a/IOB-WIN/IobMTC.cs b/IOB-WIN/IobMTC.cs
index 5f20bc02..bf27530b 100644
--- a/IOB-WIN/IobMTC.cs
+++ b/IOB-WIN/IobMTC.cs
@@ -13,1139 +13,1166 @@ using MTConnectStreams = MTConnect.MTConnectStreams;
namespace IOB_WIN
{
- public class IobMTC : IobGeneric
- {
- #region area comune (non modificare)
+ public class IobMTC : IobGeneric
+ {
+ #region area comune (non modificare)
- ///
- /// LookUpTable di decodifica da CNC a segnali tipo bitmap MAPO
- ///
- Dictionary signLUT = new Dictionary();
- ///
- /// Struttura dove vengono memorizzati i dataitem ed i rispettivi valori x processing
- ///
- Dictionary dataItemMem = new Dictionary();
- ///
- /// Oggetto MAIN x connessione MTC
- ///
- protected MTConnectClient MTC_ref;
- ///
- /// Gestione filtraggio dati
- ///
- protected bool enableDataFilter = false;
- ///
- /// Determina se ha effettuata lettura items in memoria x confronto...
- ///
- protected bool hasReadItems = false;
- ///
- /// Veto controllos tatus x log...
- ///
- protected DateTime vetoCheckStatus = DateTime.Now;
- ///
- /// Ultimo current received x gestione update periodico...
- ///
- protected DateTime lastCurrent = DateTime.Now;
- ///
- /// Abilitazione restart (da opt par...)
- ///
- protected bool enableMtcRestart = false;
- ///
- /// URL x salvataggio elenco dataItems MTC
- ///
- protected string urlSaveDataItems
- {
- get
- {
- string answ = "";
- try
+ ///
+ /// Gestione filtraggio dati
+ ///
+ protected bool enableDataFilter = false;
+
+ ///
+ /// Abilitazione restart (da opt par...)
+ ///
+ protected bool enableMtcRestart = false;
+
+ ///
+ /// Determina se ha effettuata lettura items in memoria x confronto...
+ ///
+ protected bool hasReadItems = false;
+
+ ///
+ /// Ultimo current received x gestione update periodico...
+ ///
+ protected DateTime lastCurrent = DateTime.Now;
+
+ ///
+ /// Oggetto MAIN x connessione MTC
+ ///
+ protected MTConnectClient MTC_ref;
+
+ ///
+ /// Veto controllos tatus x log...
+ ///
+ protected DateTime vetoCheckStatus = DateTime.Now;
+
+ ///
+ /// Struttura dove vengono memorizzati i dataitem ed i rispettivi valori x processing
+ ///
+ private Dictionary dataItemMem = new Dictionary();
+
+ ///
+ /// LookUpTable di decodifica da CNC a segnali tipo bitmap MAPO
+ ///
+ private Dictionary signLUT = new Dictionary();
+
+ ///
+ /// Estende l'init della classe base, impiegando il pacchetto Nuget TrackHound
+ /// https://github.com/TrakHound/MTConnect.NET
+ ///
+ ///
+ ///
+ public IobMTC(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf)
{
- string machineName = Environment.MachineName;
- answ = $@"http://{cIobConf.serverData.MPIP}{cIobConf.serverData.MPURL}{cIobConf.serverData.CMDALIVE}/saveDataItems/{cIobConf.codIOB}";
- }
- catch (Exception exc)
- {
- lgError(exc, "Errore in composizione urlSaveDataItems");
- }
- return answ;
- }
- }
- ///
- /// Parametri specifici MTC
- ///
- protected MtcParamConf mtcParams { get; set; }
- ///
- /// Estende l'init della classe base, impiegando il pacchetto Nuget TrackHound
- /// https://github.com/TrakHound/MTConnect.NET
- ///
- ///
- ///
- public IobMTC(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf)
- {
- // gestione invio ritardato contapezzi
- pzCountDelay = utils.CRI("pzCountDelay");
- // gestione data filtering...
- if (!string.IsNullOrEmpty(getOptPar("ENABLE_DATA_FILTER")))
- {
- bool.TryParse(getOptPar("ENABLE_DATA_FILTER"), out enableDataFilter);
- }
- // gestione restart MTC client...
- if (!string.IsNullOrEmpty(getOptPar("ENABLE_MTC_RESTART")))
- {
- bool.TryParse(getOptPar("ENABLE_MTC_RESTART"), out enableMtcRestart);
- }
- // init datetime counters
- DateTime adesso = DateTime.Now;
- lastPzCountSend = adesso;
- lastWarnODL = adesso;
- lastCurrent = adesso;
- // ora leggo il file di conf specifico....
- string jsonFileName = getOptPar("MTC_PARAM_CONF");
- if (!string.IsNullOrEmpty(jsonFileName))
- {
- // leggo il file...
- loadMtcConf(jsonFileName);
- }
- }
- ///
- /// Effettua lettura file di conf specifico MTC da oggetto serializzato json
- /// Nome file da cui leggere i parametri json
- ///
- private void loadMtcConf(string fileName)
- {
- string jsonFullPath = $"{Application.StartupPath}/DATA/CONF/{fileName}";
- lgInfo($"Apertura file {jsonFullPath}");
- StreamReader reader = new StreamReader(jsonFullPath);
- string jsonData = reader.ReadToEnd().Replace("\n", "").Replace("\r", "");
- if (!string.IsNullOrEmpty(jsonData))
- {
- lgInfo($"File json composto da {jsonData.Length} caratteri");
- try
- {
- mtcParams = JsonConvert.DeserializeObject(jsonData);
- lgInfo($"Decodifica aree MtcParamConf: trovati {mtcParams.paramsEndThresh.Count} valori paramsEndThresh");
- }
- catch (Exception exc)
- {
- lgError($"Eccezione in decodifica conf json MTC:{Environment.NewLine}{exc}");
- }
- }
- else
- {
- lgError("Errore in loadMtcConf: file json vuoto!");
- }
- reader.Dispose();
- }
- ///
- /// Processo i task richiesti e li elimino dalla coda 1:1
- ///
- ///
- public override Dictionary executeTasks(Dictionary task2exe)
- {
- // uso metodo base x ora
- return base.executeTasks(task2exe);
- }
- ///
- /// Effettua reset del contapezzi, NON POSSIBILE per MTC (read only)
- ///
- ///
- public override bool resetContapezziCNC()
- {
- bool answ = false;
- return answ;
- }
- ///
- /// Effettua IMPOSTAZIONE FORZATA del contapezzi, NON POSSIBILE per MTC (read only)
- ///
- ///
- public override bool setContapezziCNC(int newPzCount)
- {
- bool answ = false;
- return answ;
- }
- ///
- /// Effettua log di un devices (ed eventualmente dei sub-devices...
- ///
- ///
- protected void logDevicesList(List elencoDevices)
- {
- if (elencoDevices != null)
- {
- // loggo devices principali...
- foreach (var item in elencoDevices)
- {
- lgInfo($"Device data | ID: {item.Id} | Name: {item.Name} | UUID: {item.Uuid} | # items: {item.DataItems.Count}");
- // se ho subItems descrivo pure loro...
- if (item.DataItems.Count > 0)
- {
- logDataItemList(item.DataItems);
- }
- if (item.Components.Components.Count > 0)
- {
- logComponentsList(item.Components.Components);
- }
- }
- }
- }
- ///
- /// Effettua log di un elenco componenti
- ///
- ///
- protected void logComponentsList(List elencoComponenti)
- {
- if (elencoComponenti != null)
- {
- foreach (var item in elencoComponenti)
- {
- lgInfo($"Component data | ID: {item.Id} | Name: {item.Name} | Type: {item.Type} | # items: {item.DataItems.Count}");
- // se ho sottocomponenti richiamo...
- if (item.SubComponents != null)
- {
- if (item.SubComponents.Components.Count > 0)
+ // gestione invio ritardato contapezzi
+ pzCountDelay = utils.CRI("pzCountDelay");
+ // gestione data filtering...
+ if (!string.IsNullOrEmpty(getOptPar("ENABLE_DATA_FILTER")))
{
- logComponentsList(item.SubComponents.Components);
+ bool.TryParse(getOptPar("ENABLE_DATA_FILTER"), out enableDataFilter);
}
- }
- if (item.DataItems.Count > 0)
- {
- logDataItemList(item.DataItems);
- }
- }
- }
- }
- ///
- /// Log elenco DataItems
- ///
- ///
- protected void logDataItemList(List elencoItems)
- {
- if (elencoItems != null)
- {
- // loggo devices principali...
- foreach (var item in elencoItems)
- {
- lgInfo($"Device data | ID: {item.Id} | Name: {item.Name} | Category: {item.Category} | # Type: {item.Type}");
- }
- }
- }
- ///
- /// Vera connessione ad MTC
- ///
- ///
- private short doConnect()
- {
- short esitoLink = 0;
- // reset memoria dataItem..
- dataItemMem = new Dictionary();
- // predisposizione conf oggetto di comunicazione MTC
- short port = 5000;
- short.TryParse(cIobConf.cncPort, out port);
- // test probe!
- try
- {
- var probe = new Probe($"http://{cIobConf.cncIpAddr}:{port}").Execute();
- // se valido loggo!
- if (probe != null)
- {
- lgInfo($"Effettuata correttamente PROBE per device MTC all'URL {probe.Url} | vers: {probe.Version} | send: {probe.Header.Sender}");
- lgInfo($"---------------- Elenco Devices ----------------");
- // loggo devices principali...
- logDevicesList(probe.Devices);
- }
- }
- catch (Exception exc)
- {
- lgError($"Eccezione durante test probe:{Environment.NewLine}{exc}");
- }
- // attendo 1 sec...
- Thread.Sleep(1000);
- // ora avvio
- try
- {
- lgInfo($"Chiamata apertura MTC Client: {cIobConf.cncIpAddr}:{port}");
- MTC_ref = new MTConnectClient($"http://{cIobConf.cncIpAddr}:{port}");
- // Subscribe to the Event handlers to receive the MTConnect documents
- MTC_ref.ProbeReceived += DevicesSuccessful;
- MTC_ref.CurrentReceived += CurrentSuccessful;
- MTC_ref.SampleReceived += StreamsSuccessful;
-
- // attendo 1 sec...
- Thread.Sleep(1000);
- MTC_ref.Start();
- esitoLink = 1;
-
- // fix tempi!
- DateTime adesso = DateTime.Now;
- lastPzCountSend = adesso;
- lastWarnODL = adesso;
- lastCurrent = adesso;
- }
- catch
- { }
- return esitoLink;
- }
- ///
- /// Effettuata discovery iniziale valori CURRENT
- ///
- ///
- ///
- protected void CurrentSuccessful(MTConnectStreams.Document document)
- {
- if (document != null)
- {
- lgInfo($"DiscoverySuccessful: discovery per {document.Url}");
- if (document.DeviceStreams != null)
- {
- lgInfo($"DiscoverySuccessful: trovati {document.DeviceStreams.Count} streams");
- }
- checkAndSend(document, true);
- }
- else
- {
- lgError("StreamsSuccessful ERROR: document è null");
- }
- }
- ///
- /// Ricevuta modifica come stream da campionamenti ricevuti
- ///
- ///
- protected void StreamsSuccessful(MTConnectStreams.Document document)
- {
- checkAndSend(document, false);
- }
- ///
- /// Evento lanciato alla corretta ricezione del PROBE
- ///
- ///
- protected void DevicesSuccessful(MTConnectDevices.Document document)
- {
- lgInfo("STEP 01 DevicesSuccessful reached!");
- MtcDataItemExt currDataItem = null;
- machDataItem currMapoDataItem = null;
- List elencoDataItems = new List();
- int dSamplePeriod = 0;
- int threshDBand = 0;
- string uuid = "";
- if (document != null)
- {
- foreach (var device in document.Devices)
- {
- List dataItems = device.GetDataItems();
- lgInfo($"Inizio STEP 02 per caricare {dataItems.Count} dataItems");
- foreach (var dataItem in dataItems)
- {
-#if false
- string sVal = $"STEP 03 | Category: {dataItem.Category} | Type: {dataItem.Type} | Id: {dataItem.Id} | Name: {dataItem.Name}";
- lgInfo(sVal);
-#endif
- try
+ // gestione restart MTC client...
+ if (!string.IsNullOrEmpty(getOptPar("ENABLE_MTC_RESTART")))
{
- currDataItem = formatDataItem(ref dSamplePeriod, ref threshDBand, ref uuid, dataItem);
- // aggiungo se non c'è...
- if (!dataItemMem.ContainsKey(dataItem.Id))
- {
- dataItemMem.Add(dataItem.Id, currDataItem);
- }
- // salvo oggetto x registrazione su server MP-IO
- currMapoDataItem = new machDataItem()
- {
- uuid = dataItem.Id,
- Category = (DataItemCategory)dataItem.Category,
- Name = dataItem.Name,
- Type = dataItem.Type,
- SubType = dataItem.SubType,
- Units = dataItem.Units
- };
- // aggiungo se non ci fosse
- if (!elencoDataItems.Contains(currMapoDataItem))
- {
- elencoDataItems.Add(currMapoDataItem);
- }
+ bool.TryParse(getOptPar("ENABLE_MTC_RESTART"), out enableMtcRestart);
}
- catch (Exception exc)
- {
- lgError($"Eccezione in DevicesSuccessful / DataItem:{Environment.NewLine}{exc}");
- }
- }
- }
- // invio IN BLOCCO il dataItem serializzati...
- if (elencoDataItems.Count > 0)
- {
- lgInfo($"STEP 04 invio dati di {elencoDataItems.Count} records");
- sendDataItemsList(elencoDataItems);
- }
- hasReadItems = true;
- lgInfo($"STEP 05: memorizzati {dataItemMem.Count} oggetti in memoria");
- }
- else
- {
- lgError("STEP 06 error: document null!");
- }
- }
- ///
- /// Formatta un dataitem da uno stream SAMPLE
- ///
- ///
- ///
- ///
- ///
- ///
- private MtcDataItemExt formatDataItem(ref int dSamplePeriod, ref int threshDBand, ref string uuid, MTConnectStreams.Sample DISample)
- {
- // creo il nuovo dataitem da sample...
- MTConnectDevices.DataItem newDataItem = new MTConnectDevices.DataItem()
- {
- Category = DISample.Category,
- Id = DISample.DataItemId,
- Name = DISample.Name,
- SampleRate = DISample.SampleRate,
- Statistic = DISample.Statistic,
- SubType = DISample.SubType,
- Type = DISample.Type
- };
- return formatDataItem(ref dSamplePeriod, ref threshDBand, ref uuid, newDataItem);
- }
- ///
- /// Formatta un dataitem da uno stream GENERICO
- ///
- ///
- ///
- ///
- ///
- ///
- private MtcDataItemExt formatDataItem(ref int dSamplePeriod, ref int threshDBand, ref string uuid, MTConnectStreams.DataItem DIGen)
- {
- // creo il nuovo dataitem da sample...
- MTConnectDevices.DataItem newDataItem = new MTConnectDevices.DataItem()
- {
- Category = DIGen.Category,
- Id = DIGen.DataItemId,
- Name = DIGen.Name,
- SubType = DIGen.SubType,
- Type = DIGen.Type
- };
- return formatDataItem(ref dSamplePeriod, ref threshDBand, ref uuid, newDataItem);
- }
- ///
- /// Formatta un dataitem x salvataggio in memoria locale
- ///
- ///
- ///
- ///
- ///
- ///
- private MtcDataItemExt formatDataItem(ref int dSamplePeriod, ref int threshDBand, ref string uuid, MTConnectDevices.DataItem dataItem)
- {
- MtcDataItemExt currDataItem;
- // uuid e parametri secondo categoria...
- switch (dataItem.Category)
- {
- case MTConnect.DataItemCategory.CONDITION:
- uuid = $"C_{dataItem.Id}";
- threshDBand = 0;
- dSamplePeriod = 0;
- break;
- case MTConnect.DataItemCategory.EVENT:
- uuid = $"E_{dataItem.Id}";
- threshDBand = 0;
- dSamplePeriod = 0;
- break;
- case MTConnect.DataItemCategory.SAMPLE:
- uuid = $"S_{dataItem.Id}";
- // SOLO SE è abilitato il datafiltering...
- if (enableDataFilter)
- {
- threshDBand = 1;
- // controllo SE ho conf x deadband...
- if (mtcParams.paramsEndThresh.Count > 0)
- {
- // ciclo su tutti i parametri indicati...
- foreach (var item in mtcParams.paramsEndThresh)
- {
- if (dataItem.Id.EndsWith(item.Key))
- {
- threshDBand = item.Value;
- }
- }
- }
- }
- else
- {
- threshDBand = 0;
- }
- dSamplePeriod = 60;
- break;
- default:
- break;
- }
- // salvo oggetto x "uso interno"
- currDataItem = new MtcDataItemExt()
- {
- Id = dataItem.Id,
- Category = dataItem.Category,
- Constraints = dataItem.Constraints,
- CoordinateSystem = dataItem.CoordinateSystem,
- Name = dataItem.Name,
- NativeScale = dataItem.NativeScale,
- NativeUnits = dataItem.NativeUnits,
- SampleRate = dataItem.SampleRate,
- Representation = dataItem.Representation,
- SignificantDigits = dataItem.SignificantDigits,
- Source = dataItem.Source,
- Statistic = dataItem.Statistic,
- SubType = dataItem.SubType,
- Type = dataItem.Type,
- TypePath = dataItem.TypePath,
- Units = dataItem.Units,
- XPath = dataItem.XPath,
- uid = uuid,
- thresholdDeadBand = threshDBand,
- samplePeriod = dSamplePeriod
- };
- // log x capire COME ho chiamato alcune cosette...
- if (dataItem.Id.Contains("EXE_MODE") || dataItem.Id.Contains("RUN_MODE") || dataItem.Id.Contains("POWER") || dataItem.Id.EndsWith("_Status"))
- {
- lgInfo($"DEBUG DATA | dataItem.Id : {dataItem.Id}");
- }
-
- return currDataItem;
- }
- ///
- /// Effettua invio a MP/IO dell'elenco serializzato dei dataItems
- ///
- ///
- private void sendDataItemsList(List dataItems)
- {
- string rawData = JsonConvert.SerializeObject(dataItems);
- utils.callUrlNow($"{urlSaveDataItems}", rawData);
- }
- ///
- /// Effettua traduzione ITEM da LUT parametrica (key: tipo+id) del file di conf, se non trovo uso key
- ///
- ///
- ///
- ///
- protected string itemTranslation(string tipo, string id)
- {
- string answ = "";
- string lemma = $"{tipo}_{id}";
- // cerco nel dizionario delle traduzioni SE esiste un valore e prendo quello, altrimenti uso il lemma...
- if (mtcParams.itemTranslation.ContainsKey(lemma))
- {
- answ = mtcParams.itemTranslation[lemma];
- }
- else
- {
- answ = lemma;
- }
- return answ;
- }
- ///
- /// Verifica / Salva valore generico (NON SAMPLE)
- ///
- ///
- ///
- protected bool checkSaveItem(MTConnectStreams.DataItem newValue)
- {
- bool answ = !enableDataFilter;
-
- if (newValue != null)
- {
- if (isVerboseLog)
- {
- lgInfo($"Richiesta checkSaveItem per {newValue} | id: {newValue.DataItemId} | CDATA: {newValue.CDATA}");
- }
- // verifico in memoria se ho l'oggetto condition ed il suo valore..
- if (dataItemMem.ContainsKey(newValue.DataItemId))
- {
- // salvo sempre!
- dataItemMem[newValue.DataItemId].value = newValue.CDATA;
- dataItemMem[newValue.DataItemId].valueTimestamp = newValue.Timestamp;
- answ = true;
- }
- else
- {
- // registro non trovato da aggiungere...
- lgInfo($"DataItem non trovato in checkSaveItem: {newValue.DataItemId}");
- try
- {
- // provo a creare oggetot in memoria...
- List elencoDataItems = new List();
- int dSamplePeriod = 0;
- int threshDBand = 0;
- string uuid = "";
- var currDataItem = formatDataItem(ref dSamplePeriod, ref threshDBand, ref uuid, newValue);
- // aggiungo
- dataItemMem.Add(newValue.DataItemId, currDataItem);
- // salvo oggetto x registrazione su server MP-IO
- var currMapoDataItem = new machDataItem()
- {
- uuid = newValue.DataItemId,
- Category = (DataItemCategory)newValue.Category,
- Name = newValue.Name,
- Type = newValue.Type,
- SubType = newValue.SubType,
- //Units = newValue.Units
- };
- // aggiungo
- elencoDataItems.Add(currMapoDataItem);
- // invio il dataItem serializzato...
- sendDataItemsList(elencoDataItems);
- }
- catch (Exception exc)
- {
- lgError($"Eccezione in checkSaveSample{Environment.NewLine}{exc}");
- }
- }
- }
- else
- {
- lgError("Attenzione: checkSaveItem con newValue null!");
- }
- return answ;
- }
- ///
- /// Verifica / Salva valore SAMPLE e restitusice SE sia variato (e quindi da inviare...)
- ///
- ///
- ///
- protected bool checkSaveSample(MTConnectStreams.Sample newValue)
- {
- bool answ = !enableDataFilter;
- double oldVal = 0;
- double newVal = 0;
- if (newValue != null)
- {
- if (isVerboseLog)
- {
- lgInfo($"Richiesta checkSaveSample per {newValue} | id: {newValue.DataItemId} | CDATA: {newValue.CDATA}");
- }
- // verifico in memoria se ho l'oggetto condition ed il suo valore..
- if (dataItemMem.ContainsKey(newValue.DataItemId))
- {
- MtcDataItemExt currDataItemMem = dataItemMem[newValue.DataItemId];
- // controllo SE SIA scaduto il tempo massimo...
- if (Math.Abs(dataItemMem[newValue.DataItemId].valueTimestamp.Subtract(newValue.Timestamp).TotalSeconds) > currDataItemMem.samplePeriod)
- {
- answ = true;
- }
- else
- {
- // ALTRIMENTI controllo SE diverso
- if (dataItemMem[newValue.DataItemId].value != newValue.CDATA)
- {
- // controllo SE ho DeadBand...
- if (dataItemMem[newValue.DataItemId].thresholdDeadBand > 0)
- {
- if (isVerboseLog)
- {
- lgInfo($"Test deadband: oldVal: {oldVal} | newVal: {newVal}");
- }
- // recupero i valori e testo DeadBand...
- double.TryParse(dataItemMem[newValue.DataItemId].value.Replace(".", ","), out oldVal);
- double.TryParse(newValue.CDATA.Replace(".", ","), out newVal);
- // test deadband!
- if (Math.Abs(newVal - oldVal) > dataItemMem[newValue.DataItemId].thresholdDeadBand)
- {
- // indico da salvare..
- answ = true;
- }
- }
- }
- }
- if (answ)
- {
- // salvo!
- dataItemMem[newValue.DataItemId].value = newValue.CDATA;
- dataItemMem[newValue.DataItemId].valueTimestamp = newValue.Timestamp;
- }
- }
- else
- {
- // registro non trovato da aggiungere...
- lgInfo($"DataItem non trovato in checkSaveSample: {newValue.DataItemId}");
- // provo a creare oggetto in memoria...
- try
- {
- List elencoDataItems = new List();
- int dSamplePeriod = 0;
- int threshDBand = 0;
- string uuid = "";
- var currDataItem = formatDataItem(ref dSamplePeriod, ref threshDBand, ref uuid, newValue);
- // aggiungo
- dataItemMem.Add(newValue.DataItemId, currDataItem);
- // salvo oggetto x registrazione su server MP-IO
- var currMapoDataItem = new machDataItem()
- {
- uuid = newValue.DataItemId,
- Category = (DataItemCategory)newValue.Category,
- Name = newValue.Name,
- Type = newValue.Type,
- SubType = newValue.SubType,
- //Units = newValue.Units
- };
- // aggiungo
- elencoDataItems.Add(currMapoDataItem);
- // invio il dataItem serializzato...
- sendDataItemsList(elencoDataItems);
- }
- catch (Exception exc)
- {
- lgError($"Eccezione in checkSaveSample{Environment.NewLine}{exc}");
- }
- }
- }
- else
- {
- lgError("Attenzione: checkSaveItem con newValue null!");
- }
- return answ;
- }
- ///
- /// Verifica ed invia variazioni
- ///
- ///
- ///
- private void checkAndSend(MTConnectStreams.Document document, bool forceSend)
- {
- if (document != null)
- {
- foreach (var deviceStream in document.DeviceStreams)
- {
- string sVal = "";
- string descr = "";
- DateTime locTStamp = DateTime.Now;
- // check su Conditions
- try
- {
- // check su dataItems (conditions + events + samples)
- foreach (var dataItem in deviceStream.Conditions)
- {
- descr = itemTranslation("C", dataItem.DataItemId);
- locTStamp = dataItem.Timestamp.ToLocalTime();
- sVal = $"CONDITION: {locTStamp.ToString()} | Id: {dataItem.DataItemId} | | Name: {dataItem.Name} | descr: {descr} | Val: {dataItem.CDATA}";
- // condizion verboso SEMPRE!
- lgInfo(sVal);
- DateTime tStamp = dataItem.Timestamp;
- var time2 = tStamp.ToLocalTime();
- // verifico se salvare
- bool changed = checkSaveItem(dataItem);
- if (changed || forceSend)
- {
- // accodare ed invia nella coda ALARMS (che POI salva in document MongoDB anche ultimi x minuti di FluxLog...)
- accodaAlarmLog(sVal, qEncodeFLog(time2, descr, dataItem.CDATA));
- }
- }
- }
- catch (Exception exc)
- {
- lgError($"Eccezione in decodifica Conditions x StreamSuccesfull{Environment.NewLine}{exc}", false);
- }
- // check su events
- try
- {
- // check su dataItems (conditions + events + samples)
- foreach (var dataItem in deviceStream.Events)
- {
- descr = itemTranslation("E", dataItem.DataItemId);
- locTStamp = dataItem.Timestamp.ToLocalTime();
- sVal = $"EVENT: {locTStamp.ToString()} | descr: {descr} | Id: {dataItem.DataItemId} | Name: {dataItem.Name} | Val: {dataItem.CDATA}";
- if (isVerboseLog)
- {
- lgInfo(sVal);
- }
- DateTime tStamp = dataItem.Timestamp;
- var time2 = tStamp.ToLocalTime();
- // verifico se salvare
- bool changed = checkSaveItem(dataItem);
- if (changed || forceSend)
- {
- accodaFLog(sVal, qEncodeFLog(time2, descr, dataItem.CDATA));
- }
- }
- }
- catch (Exception exc)
- {
- lgError($"Eccezione in decodifica Events x StreamSuccesfull{Environment.NewLine}{exc}", false);
- }
-
- // check su samples
- try
- {
- // check su dataItems (conditions + events + samples)
- foreach (var dataItem in deviceStream.Samples)
- {
- descr = itemTranslation("S", dataItem.DataItemId);
- locTStamp = dataItem.Timestamp.ToLocalTime();
- sVal = $"SAMPLE: {locTStamp.ToString()} | descr: {descr} | Id: {dataItem.DataItemId} | | Name: {dataItem.Name} | Val: {dataItem.CDATA}";
- if (isVerboseLog)
- {
- lgInfo(sVal);
- }
- DateTime tStamp = dataItem.Timestamp;
- var time2 = tStamp.ToLocalTime();
- // verifico se salvare
- bool changed = checkSaveSample(dataItem);
- if (changed || forceSend)
- {
- accodaFLog(sVal, qEncodeFLog(time2, descr, dataItem.CDATA));
- }
- else
- {
- if (isVerboseLog)
- {
- lgInfo($"NON ACCODATO sample poiché verifica variazione SAMPLE ha dato esito negativo", false);
- }
- }
- }
- }
- catch (Exception exc)
- {
- lgError($"Eccezione in decodifica Samples x StreamSuccesfull{Environment.NewLine}{exc}");
- }
- }
- }
- else
- {
- lgError("StreamsSuccessful ERROR: document è null");
- }
- }
- ///
- /// Override disconnessione
- ///
- public override void tryDisconnect()
- {
- if (connectionOk)
- {
- string szStatusConnection = "";
- try
- {
- MTC_ref.Stop();
- connectionOk = false;
- lgInfo(szStatusConnection);
- lgInfo("Effettuata disconnessione adapter MTC!");
- }
- catch (Exception exc)
- {
- lgFatal(exc, "Errore nella disconnessione dall'adapter MTC");
- }
- }
- else
- {
- lgError("IMPOSSIBILE effettuare disconnessione MTC: Connessione non disponibile...");
- }
- }
- ///
- /// Override connessione
- ///
- public override void tryConnect()
- {
- if (!connectionOk)
- {
- // controllo che il ping sia stato tentato almeno pingTestSec fa...
- if (DateTime.Now.Subtract(lastPING).TotalSeconds > utils.CRI("pingTestSec"))
- {
- if (verboseLog || periodicLog)
- {
- lgInfo("MTC: ConnKO - tryConnect");
- }
- // in primis salvo data ping...
- lastPING = DateTime.Now;
- // se passa il ping faccio il resto...
- if (testPingMachine == IPStatus.Success)
- {
- string szStatusConnection = "";
- try
- {
- // ora provo connessione...
- parentForm.commPlcActive = true;
- short esitoLink = doConnect();
- lgInfo($"szStatusConnection MTC, esitoLink: {esitoLink}");
- parentForm.commPlcActive = false;
- connectionOk = true;
- // refresh stato allarmi!!!
- if (connectionOk)
- {
- if (adpRunning)
- {
- lgInfo("Connessione OK");
- }
- }
- else
- {
- lgError("Impossibile procedere, connessione mancante...");
- }
- }
- catch (Exception exc)
- {
- lgFatal($"Errore nella connessione all'adapter MTC: {szStatusConnection}{Environment.NewLine}{exc}");
- connectionOk = false;
- lgInfo($"Eccezione in TryConnect, Adapter MTC NON running, pausa di {utils.CRI("waitRecMSec")} msec prima di ulteriori tentativi di riconnessione");
- }
- }
- else
- {
- // loggo no risposta ping ...
- connectionOk = false;
- if (verboseLog || periodicLog)
- {
- lgInfo($"Attenzione: MTC controllo PING fallito per IP {cIobConf.cncIpAddr}");
- }
- }
- }
- }
- else
- {
- needRefresh = true;
- }
- // se non è ancora connesso faccio procesisng memoria caso disconnesso...
- if (!connectionOk)
- {
- // processo semafori ed invio...
- processMemoryDiscon();
- }
- }
- ///
- /// Recupera uno specifico dataItem
- ///
- ///
- ///
- public string getDataItemValue(string diKey)
- {
- string answ = "";
- try
- {
- var currDataItem = dataItemMem[diKey];
- answ = currDataItem.value;
- }
- catch (Exception exc)
- {
- Logging.Instance.Error($"Errore in getDataItemValue per {diKey}{Environment.NewLine}{exc}");
- }
- return answ;
- }
-
- #endregion
-
- #region Metodi specifici (da verificare/completare in implementazione)
-
- ///
- /// Effettua vero processing contapezzi
- ///
- public override void processContapezzi()
- {
- if (utils.CRB("enableContapezzi"))
- {
- // cerco parametro contapezzi...
- string currPzCount = getDataItemValue(mtcParams.keyPartCount);
-#if false
- string currPzReq = getDataItemValue(mtcParams.keyPartReq);
- string currPartId = getDataItemValue(mtcParams.keyPartId);
- string currProg = getDataItemValue(mtcParams.keyProgName);
-#endif
-
- // se ho un contapezzi... processo...
- if (!string.IsNullOrEmpty(currPzCount))
- {
- int newVal = -1;
- Int32.TryParse(currPzCount, out newVal);
- lastCountCNC = newVal > -1 ? newVal : lastCountCNC;
- }
- }
- }
- ///
- /// Effettua lettura semafori principale
- /// Parametri da aggiornare x display in form
- ///
- public override void readSemafori(ref newDisplayData currDispData)
- {
- base.readSemafori(ref currDispData);
- try
- {
- if (verboseLog)
- {
- lgInfo("inizio read semafori");
- }
-
- currDispData.semIn = Semaforo.SV;
-
- // decodifica e gestione
- decodeToBaseBitmap();
- reportRawInput(ref currDispData);
- }
- catch (Exception exc)
- {
- currDispData.semIn = Semaforo.SR;
- lgError($"Eccezione in readSemafori:{Environment.NewLine}{exc}");
- }
- }
- ///
- /// Verifico se abbia ALMENO un errore...
- ///
- protected bool hasError
- {
- get
- {
- bool answ = false;
- // controllo TUTTE le conditions...
- foreach (var item in dataItemMem)
- {
- // se NON HO GIA' allarmi attivi...
- if (!answ)
- {
- // se è una condition...
- if (item.Value.Category == MTConnect.DataItemCategory.CONDITION)
- {
- // se ha valore !="" --> allarmi attivi
- if (!string.IsNullOrEmpty(item.Value.value))
- {
- answ = true;
- }
- }
- }
- }
- return answ;
- }
- }
- ///
- /// Effettua decodifica aree memoria alla bitmap usata x MAPO
- ///
- private void decodeToBaseBitmap()
- {
- // init a zero...
- B_input = 0;
-
- /* -----------------------------------------------------
- * bitmap MAPO
- * B0: POWER_ON
- * B1: RUN
- * B2: pzCount
- * B3: allarme
- * B4: manuale
- ----------------------------------------------------- */
-
- // Controllo booleano PING e POWERON...
- string currPowerOn = getDataItemValue(mtcParams.condPowerOn.keyName);
- // se valido il check ping lo eseguo... altrimenti lo do x buono
- bool checkPing = !mtcParams.pingAsPowerOn;
- if (!checkPing)
- {
- checkPing = (testPingMachine == IPStatus.Success);
- }
- // verifico da target value richiesto...
- bool checkPowerOn = (currPowerOn == mtcParams.condPowerOn.targetValue);
-
- // bit 0 (poweron) imposto a 1 SE pingo o PowerOn=="ON"...
- B_input = (checkPing || checkPowerOn) ? 1 : 0;
-
-
- // variabili RUN...
- string currRun = getDataItemValue(mtcParams.keyRunMode);
-
- // controllo RUN MODE preliminare... CABLATO poiché è GENERALE x MTC
- if (currRun == "AUTOMATIC" || currRun == "SEMI_AUTO" || currRun == "SEMI_AUTOMATIC")
- {
- int numCond = mtcParams.condWork.Count;
- int numCondOk = 0;
- // cerco nell'elenco delle condizioni che indicano lavora se sono ok faccio +1 conteggio......
- foreach (var item in mtcParams.condWork)
- {
- if (getDataItemValue(item.keyName) == item.targetValue)
- {
- numCondOk++;
- }
- }
- // se tutte condizioni rispettate --> lavora!
- if (numCond == numCondOk)
- {
- // RUN = LAVORA!
- B_input += (1 << 1);
- }
- }
- // se ho almeno 1 allarme E NON SONO IN AUTO --> ALARM!
- else if (hasError)
- {
- B_input += (1 << 3);
- }
- else
- {
- // se ho run mode != auto --> manual
- B_input += (1 << 4);
- }
-
-
- DateTime adesso = DateTime.Now;
- int vFactor = 1;
- // controllo SE HO dati per fare verifiche...
- if (string.IsNullOrEmpty(currRun))
- {
- // se ho parametro x gestione reset...
- if (enableMtcRestart)
- {
- // controllo se ho ricevuto il current da OLTRE 1 minuto...
- if (lastCurrent.AddMinutes(3) < adesso)
- {
+ // init datetime counters
+ DateTime adesso = DateTime.Now;
+ lastPzCountSend = adesso;
+ lastWarnODL = adesso;
lastCurrent = adesso;
- // stop...
- lgInfo("Fermato MTC_ref per mancanza dati current");
- MTC_ref.Stop();
- Thread.Sleep(1000);
- // restart
- lgInfo("Riavviato MTC_ref per mancanza dati current");
- MTC_ref.Start();
- }
+ // ora leggo il file di conf specifico....
+ string jsonFileName = getOptPar("MTC_PARAM_CONF");
+ if (!string.IsNullOrEmpty(jsonFileName))
+ {
+ // leggo il file...
+ loadMtcConf(jsonFileName);
+ }
}
- }
- else
- {
- vFactor = 6;
- }
- // solo se non ho veto check
- if (vetoCheckStatus < adesso)
- {
- lgInfo($"Stato variabili: currRun: {currRun}");
- // imposto veto per vetoSeconds...
- vetoCheckStatus = adesso.AddSeconds(vetoSeconds * vFactor);
- }
- // log opzionale!
- if (verboseLog)
- {
- lgInfo($"Trasformazione B_input: {B_input} | currRun = {currRun}");
- }
+ ///
+ /// Parametri specifici MTC
+ ///
+ protected MtcParamConf mtcParams { get; set; }
+
+ ///
+ /// URL x salvataggio elenco dataItems MTC
+ ///
+ protected string urlSaveDataItems
+ {
+ get
+ {
+ string answ = "";
+ try
+ {
+ string machineName = Environment.MachineName;
+ answ = $@"http://{cIobConf.serverData.MPIP}{cIobConf.serverData.MPURL}{cIobConf.serverData.CMDALIVE}/saveDataItems/{cIobConf.codIOB}";
+ }
+ catch (Exception exc)
+ {
+ lgError(exc, "Errore in composizione urlSaveDataItems");
+ }
+ return answ;
+ }
+ }
+
+ ///
+ /// Processo i task richiesti e li elimino dalla coda 1:1
+ ///
+ ///
+ public override Dictionary executeTasks(Dictionary task2exe)
+ {
+ // uso metodo base x ora
+ return base.executeTasks(task2exe);
+ }
+
+ ///
+ /// Recupera uno specifico dataItem
+ ///
+ ///
+ ///
+ public string getDataItemValue(string diKey)
+ {
+ string answ = "";
+ try
+ {
+ var currDataItem = dataItemMem[diKey];
+ answ = currDataItem.value;
+ }
+ catch (Exception exc)
+ {
+ Logging.Instance.Error($"Errore in getDataItemValue per {diKey}{Environment.NewLine}{exc}");
+ }
+ return answ;
+ }
+
+ ///
+ /// Effettua reset del contapezzi, NON POSSIBILE per MTC (read only)
+ ///
+ ///
+ public override bool resetContapezziCNC()
+ {
+ bool answ = false;
+ return answ;
+ }
+
+ ///
+ /// Effettua IMPOSTAZIONE FORZATA del contapezzi, NON POSSIBILE per MTC (read only)
+ ///
+ ///
+ public override bool setContapezziCNC(int newPzCount)
+ {
+ bool answ = false;
+ return answ;
+ }
+
+ ///
+ /// Override connessione
+ ///
+ public override void tryConnect()
+ {
+ if (!connectionOk)
+ {
+ // controllo che il ping sia stato tentato almeno pingTestSec fa...
+ if (DateTime.Now.Subtract(lastPING).TotalSeconds > utils.CRI("pingTestSec"))
+ {
+ if (verboseLog || periodicLog)
+ {
+ lgInfo("MTC: ConnKO - tryConnect");
+ }
+ // in primis salvo data ping...
+ lastPING = DateTime.Now;
+ // se passa il ping faccio il resto...
+ if (testPingMachine == IPStatus.Success)
+ {
+ string szStatusConnection = "";
+ try
+ {
+ // ora provo connessione...
+ parentForm.commPlcActive = true;
+ short esitoLink = doConnect();
+ lgInfo($"szStatusConnection MTC, esitoLink: {esitoLink}");
+ parentForm.commPlcActive = false;
+ connectionOk = true;
+ // refresh stato allarmi!!!
+ if (connectionOk)
+ {
+ if (adpRunning)
+ {
+ lgInfo("Connessione OK");
+ }
+ }
+ else
+ {
+ lgError("Impossibile procedere, connessione mancante...");
+ }
+ }
+ catch (Exception exc)
+ {
+ lgFatal($"Errore nella connessione all'adapter MTC: {szStatusConnection}{Environment.NewLine}{exc}");
+ connectionOk = false;
+ lgInfo($"Eccezione in TryConnect, Adapter MTC NON running, pausa di {utils.CRI("waitRecMSec")} msec prima di ulteriori tentativi di riconnessione");
+ }
+ }
+ else
+ {
+ // loggo no risposta ping ...
+ connectionOk = false;
+ if (verboseLog || periodicLog)
+ {
+ lgInfo($"Attenzione: MTC controllo PING fallito per IP {cIobConf.cncIpAddr}");
+ }
+ }
+ }
+ }
+ else
+ {
+ needRefresh = true;
+ }
+ // se non è ancora connesso faccio procesisng memoria caso disconnesso...
+ if (!connectionOk)
+ {
+ // processo semafori ed invio...
+ processMemoryDiscon();
+ }
+ }
+
+ ///
+ /// Override disconnessione
+ ///
+ public override void tryDisconnect()
+ {
+ if (connectionOk)
+ {
+ string szStatusConnection = "";
+ try
+ {
+ MTC_ref.Stop();
+ connectionOk = false;
+ lgInfo(szStatusConnection);
+ lgInfo("Effettuata disconnessione adapter MTC!");
+ }
+ catch (Exception exc)
+ {
+ lgFatal(exc, "Errore nella disconnessione dall'adapter MTC");
+ }
+ }
+ else
+ {
+ lgError("IMPOSSIBILE effettuare disconnessione MTC: Connessione non disponibile...");
+ }
+ }
+
+ ///
+ /// Verifica / Salva valore generico (NON SAMPLE)
+ ///
+ ///
+ ///
+ protected bool checkSaveItem(MTConnectStreams.DataItem newValue)
+ {
+ bool answ = !enableDataFilter;
+
+ if (newValue != null)
+ {
+ if (isVerboseLog)
+ {
+ lgInfo($"Richiesta checkSaveItem per {newValue} | id: {newValue.DataItemId} | CDATA: {newValue.CDATA}");
+ }
+ // verifico in memoria se ho l'oggetto condition ed il suo valore..
+ if (dataItemMem.ContainsKey(newValue.DataItemId))
+ {
+ // salvo sempre!
+ dataItemMem[newValue.DataItemId].value = newValue.CDATA;
+ dataItemMem[newValue.DataItemId].valueTimestamp = newValue.Timestamp;
+ answ = true;
+ }
+ else
+ {
+ // registro non trovato da aggiungere...
+ lgInfo($"DataItem non trovato in checkSaveItem: {newValue.DataItemId}");
+ try
+ {
+ // provo a creare oggetot in memoria...
+ List elencoDataItems = new List();
+ int dSamplePeriod = 0;
+ int threshDBand = 0;
+ string uuid = "";
+ var currDataItem = formatDataItem(ref dSamplePeriod, ref threshDBand, ref uuid, newValue);
+ // aggiungo
+ dataItemMem.Add(newValue.DataItemId, currDataItem);
+ // salvo oggetto x registrazione su server MP-IO
+ var currMapoDataItem = new machDataItem()
+ {
+ uuid = newValue.DataItemId,
+ Category = (DataItemCategory)newValue.Category,
+ Name = newValue.Name,
+ Type = newValue.Type,
+ SubType = newValue.SubType,
+ //Units = newValue.Units
+ };
+ // aggiungo
+ elencoDataItems.Add(currMapoDataItem);
+ // invio il dataItem serializzato...
+ sendDataItemsList(elencoDataItems);
+ }
+ catch (Exception exc)
+ {
+ lgError($"Eccezione in checkSaveSample{Environment.NewLine}{exc}");
+ }
+ }
+ }
+ else
+ {
+ lgError("Attenzione: checkSaveItem con newValue null!");
+ }
+ return answ;
+ }
+
+ ///
+ /// Verifica / Salva valore SAMPLE e restitusice SE sia variato (e quindi da inviare...)
+ ///
+ ///
+ ///
+ protected bool checkSaveSample(MTConnectStreams.Sample newValue)
+ {
+ bool answ = !enableDataFilter;
+ double oldVal = 0;
+ double newVal = 0;
+ if (newValue != null)
+ {
+ if (isVerboseLog)
+ {
+ lgInfo($"Richiesta checkSaveSample per {newValue} | id: {newValue.DataItemId} | CDATA: {newValue.CDATA}");
+ }
+ // verifico in memoria se ho l'oggetto condition ed il suo valore..
+ if (dataItemMem.ContainsKey(newValue.DataItemId))
+ {
+ MtcDataItemExt currDataItemMem = dataItemMem[newValue.DataItemId];
+ // controllo SE SIA scaduto il tempo massimo...
+ if (Math.Abs(dataItemMem[newValue.DataItemId].valueTimestamp.Subtract(newValue.Timestamp).TotalSeconds) > currDataItemMem.samplePeriod)
+ {
+ answ = true;
+ }
+ else
+ {
+ // ALTRIMENTI controllo SE diverso
+ if (dataItemMem[newValue.DataItemId].value != newValue.CDATA)
+ {
+ // controllo SE ho DeadBand...
+ if (dataItemMem[newValue.DataItemId].thresholdDeadBand > 0)
+ {
+ if (isVerboseLog)
+ {
+ lgInfo($"Test deadband: oldVal: {oldVal} | newVal: {newVal}");
+ }
+ // recupero i valori e testo DeadBand...
+ double.TryParse(dataItemMem[newValue.DataItemId].value.Replace(".", ","), out oldVal);
+ double.TryParse(newValue.CDATA.Replace(".", ","), out newVal);
+ // test deadband!
+ if (Math.Abs(newVal - oldVal) > dataItemMem[newValue.DataItemId].thresholdDeadBand)
+ {
+ // indico da salvare..
+ answ = true;
+ }
+ }
+ }
+ }
+ if (answ)
+ {
+ // salvo!
+ dataItemMem[newValue.DataItemId].value = newValue.CDATA;
+ dataItemMem[newValue.DataItemId].valueTimestamp = newValue.Timestamp;
+ }
+ }
+ else
+ {
+ // registro non trovato da aggiungere...
+ lgInfo($"DataItem non trovato in checkSaveSample: {newValue.DataItemId}");
+ // provo a creare oggetto in memoria...
+ try
+ {
+ List elencoDataItems = new List();
+ int dSamplePeriod = 0;
+ int threshDBand = 0;
+ string uuid = "";
+ var currDataItem = formatDataItem(ref dSamplePeriod, ref threshDBand, ref uuid, newValue);
+ // aggiungo
+ dataItemMem.Add(newValue.DataItemId, currDataItem);
+ // salvo oggetto x registrazione su server MP-IO
+ var currMapoDataItem = new machDataItem()
+ {
+ uuid = newValue.DataItemId,
+ Category = (DataItemCategory)newValue.Category,
+ Name = newValue.Name,
+ Type = newValue.Type,
+ SubType = newValue.SubType,
+ //Units = newValue.Units
+ };
+ // aggiungo
+ elencoDataItems.Add(currMapoDataItem);
+ // invio il dataItem serializzato...
+ sendDataItemsList(elencoDataItems);
+ }
+ catch (Exception exc)
+ {
+ lgError($"Eccezione in checkSaveSample{Environment.NewLine}{exc}");
+ }
+ }
+ }
+ else
+ {
+ lgError("Attenzione: checkSaveItem con newValue null!");
+ }
+ return answ;
+ }
+
+ ///
+ /// Effettuata discovery iniziale valori CURRENT
+ ///
+ ///
+ ///
+ protected void CurrentSuccessful(MTConnectStreams.Document document)
+ {
+ if (document != null)
+ {
+ lgInfo($"DiscoverySuccessful: discovery per {document.Url}");
+ if (document.DeviceStreams != null)
+ {
+ lgInfo($"DiscoverySuccessful: trovati {document.DeviceStreams.Count} streams");
+ }
+ checkAndSend(document, true);
+ }
+ else
+ {
+ lgError("StreamsSuccessful ERROR: document è null");
+ }
+ }
+
+ ///
+ /// Evento lanciato alla corretta ricezione del PROBE
+ ///
+ ///
+ protected void DevicesSuccessful(MTConnectDevices.Document document)
+ {
+ lgInfo("STEP 01 DevicesSuccessful reached!");
+ MtcDataItemExt currDataItem = null;
+ machDataItem currMapoDataItem = null;
+ List elencoDataItems = new List();
+ int dSamplePeriod = 0;
+ int threshDBand = 0;
+ string uuid = "";
+ if (document != null)
+ {
+ foreach (var device in document.Devices)
+ {
+ List dataItems = device.GetDataItems();
+ lgInfo($"Inizio STEP 02 per caricare {dataItems.Count} dataItems");
+ foreach (var dataItem in dataItems)
+ {
+ try
+ {
+ currDataItem = formatDataItem(ref dSamplePeriod, ref threshDBand, ref uuid, dataItem);
+ // aggiungo se non c'è...
+ if (!dataItemMem.ContainsKey(dataItem.Id))
+ {
+ dataItemMem.Add(dataItem.Id, currDataItem);
+ }
+ // salvo oggetto x registrazione su server MP-IO
+ currMapoDataItem = new machDataItem()
+ {
+ uuid = dataItem.Id,
+ Category = (DataItemCategory)dataItem.Category,
+ Name = dataItem.Name,
+ Type = dataItem.Type,
+ SubType = dataItem.SubType,
+ Units = dataItem.Units
+ };
+ // aggiungo se non ci fosse
+ if (!elencoDataItems.Contains(currMapoDataItem))
+ {
+ elencoDataItems.Add(currMapoDataItem);
+ }
+ }
+ catch (Exception exc)
+ {
+ lgError($"Eccezione in DevicesSuccessful / DataItem:{Environment.NewLine}{exc}");
+ }
+ }
+ }
+ // invio IN BLOCCO il dataItem serializzati...
+ if (elencoDataItems.Count > 0)
+ {
+ lgInfo($"STEP 04 invio dati di {elencoDataItems.Count} records");
+ sendDataItemsList(elencoDataItems);
+ }
+ hasReadItems = true;
+ lgInfo($"STEP 05: memorizzati {dataItemMem.Count} oggetti in memoria");
+ }
+ else
+ {
+ lgError("STEP 06 error: document null!");
+ }
+ }
+
+ ///
+ /// Effettua traduzione ITEM da LUT parametrica (key: tipo+id) del file di conf, se non trovo uso key
+ ///
+ ///
+ ///
+ ///
+ protected string itemTranslation(string tipo, string id)
+ {
+ string answ = "";
+ string lemma = $"{tipo}_{id}";
+ // cerco nel dizionario delle traduzioni SE esiste un valore e prendo quello, altrimenti uso il lemma...
+ if (mtcParams.itemTranslation.ContainsKey(lemma))
+ {
+ answ = mtcParams.itemTranslation[lemma];
+ }
+ else
+ {
+ answ = lemma;
+ }
+ return answ;
+ }
+
+ ///
+ /// Effettua log di un elenco componenti
+ ///
+ ///
+ protected void logComponentsList(List elencoComponenti)
+ {
+ if (elencoComponenti != null)
+ {
+ foreach (var item in elencoComponenti)
+ {
+ lgInfo($"Component data | ID: {item.Id} | Name: {item.Name} | Type: {item.Type} | # items: {item.DataItems.Count}");
+ // se ho sottocomponenti richiamo...
+ if (item.SubComponents != null)
+ {
+ if (item.SubComponents.Components.Count > 0)
+ {
+ logComponentsList(item.SubComponents.Components);
+ }
+ }
+ if (item.DataItems.Count > 0)
+ {
+ logDataItemList(item.DataItems);
+ }
+ }
+ }
+ }
+
+ ///
+ /// Log elenco DataItems
+ ///
+ ///
+ protected void logDataItemList(List elencoItems)
+ {
+ if (elencoItems != null)
+ {
+ // loggo devices principali...
+ foreach (var item in elencoItems)
+ {
+ lgInfo($"Device data | ID: {item.Id} | Name: {item.Name} | Category: {item.Category} | # Type: {item.Type}");
+ }
+ }
+ }
+
+ ///
+ /// Effettua log di un devices (ed eventualmente dei sub-devices...
+ ///
+ ///
+ protected void logDevicesList(List elencoDevices)
+ {
+ if (elencoDevices != null)
+ {
+ // loggo devices principali...
+ foreach (var item in elencoDevices)
+ {
+ lgInfo($"Device data | ID: {item.Id} | Name: {item.Name} | UUID: {item.Uuid} | # items: {item.DataItems.Count}");
+ // se ho subItems descrivo pure loro...
+ if (item.DataItems.Count > 0)
+ {
+ logDataItemList(item.DataItems);
+ }
+ if (item.Components.Components.Count > 0)
+ {
+ logComponentsList(item.Components.Components);
+ }
+ }
+ }
+ }
+
+ ///
+ /// Ricevuta modifica come stream da campionamenti ricevuti
+ ///
+ ///
+ protected void StreamsSuccessful(MTConnectStreams.Document document)
+ {
+ checkAndSend(document, false);
+ }
+
+ ///
+ /// Verifica ed invia variazioni
+ ///
+ ///
+ ///
+ private void checkAndSend(MTConnectStreams.Document document, bool forceSend)
+ {
+ if (document != null)
+ {
+ foreach (var deviceStream in document.DeviceStreams)
+ {
+ string sVal = "";
+ string descr = "";
+ DateTime locTStamp = DateTime.Now;
+ // check su Conditions
+ try
+ {
+ // check su dataItems (conditions + events + samples)
+ foreach (var dataItem in deviceStream.Conditions)
+ {
+ descr = itemTranslation("C", dataItem.DataItemId);
+ locTStamp = dataItem.Timestamp.ToLocalTime();
+ sVal = $"CONDITION: {locTStamp.ToString()} | Id: {dataItem.DataItemId} | | Name: {dataItem.Name} | descr: {descr} | Val: {dataItem.CDATA}";
+ // condizion verboso SEMPRE!
+ lgInfo(sVal);
+ DateTime tStamp = dataItem.Timestamp;
+ var time2 = tStamp.ToLocalTime();
+ // verifico se salvare
+ bool changed = checkSaveItem(dataItem);
+ if (changed || forceSend)
+ {
+ // accodare ed invia nella coda ALARMS (che POI salva in document MongoDB anche ultimi x minuti di FluxLog...)
+ accodaAlarmLog(sVal, qEncodeFLog(time2, descr, dataItem.CDATA));
+ }
+ }
+ }
+ catch (Exception exc)
+ {
+ lgError($"Eccezione in decodifica Conditions x StreamSuccesfull{Environment.NewLine}{exc}", false);
+ }
+ // check su events
+ try
+ {
+ // check su dataItems (conditions + events + samples)
+ foreach (var dataItem in deviceStream.Events)
+ {
+ descr = itemTranslation("E", dataItem.DataItemId);
+ locTStamp = dataItem.Timestamp.ToLocalTime();
+ sVal = $"EVENT: {locTStamp.ToString()} | descr: {descr} | Id: {dataItem.DataItemId} | Name: {dataItem.Name} | Val: {dataItem.CDATA}";
+ if (isVerboseLog)
+ {
+ lgInfo(sVal);
+ }
+ DateTime tStamp = dataItem.Timestamp;
+ var time2 = tStamp.ToLocalTime();
+ // verifico se salvare
+ bool changed = checkSaveItem(dataItem);
+ if (changed || forceSend)
+ {
+ accodaFLog(sVal, qEncodeFLog(time2, descr, dataItem.CDATA));
+ }
+ }
+ }
+ catch (Exception exc)
+ {
+ lgError($"Eccezione in decodifica Events x StreamSuccesfull{Environment.NewLine}{exc}", false);
+ }
+
+ // check su samples
+ try
+ {
+ // check su dataItems (conditions + events + samples)
+ foreach (var dataItem in deviceStream.Samples)
+ {
+ descr = itemTranslation("S", dataItem.DataItemId);
+ locTStamp = dataItem.Timestamp.ToLocalTime();
+ sVal = $"SAMPLE: {locTStamp.ToString()} | descr: {descr} | Id: {dataItem.DataItemId} | | Name: {dataItem.Name} | Val: {dataItem.CDATA}";
+ if (isVerboseLog)
+ {
+ lgInfo(sVal);
+ }
+ DateTime tStamp = dataItem.Timestamp;
+ var time2 = tStamp.ToLocalTime();
+ // verifico se salvare
+ bool changed = checkSaveSample(dataItem);
+ if (changed || forceSend)
+ {
+ accodaFLog(sVal, qEncodeFLog(time2, descr, dataItem.CDATA));
+ }
+ else
+ {
+ if (isVerboseLog)
+ {
+ lgInfo($"NON ACCODATO sample poiché verifica variazione SAMPLE ha dato esito negativo", false);
+ }
+ }
+ }
+ }
+ catch (Exception exc)
+ {
+ lgError($"Eccezione in decodifica Samples x StreamSuccesfull{Environment.NewLine}{exc}");
+ }
+ }
+ }
+ else
+ {
+ lgError("StreamsSuccessful ERROR: document è null");
+ }
+ }
+
+ ///
+ /// Vera connessione ad MTC
+ ///
+ ///
+ private short doConnect()
+ {
+ short esitoLink = 0;
+ // reset memoria dataItem..
+ dataItemMem = new Dictionary();
+ // predisposizione conf oggetto di comunicazione MTC
+ short port = 5000;
+ short.TryParse(cIobConf.cncPort, out port);
+ // test probe!
+ try
+ {
+ var probe = new Probe($"http://{cIobConf.cncIpAddr}:{port}").Execute();
+ // se valido loggo!
+ if (probe != null)
+ {
+ lgInfo($"Effettuata correttamente PROBE per device MTC all'URL {probe.Url} | vers: {probe.Version} | send: {probe.Header.Sender}");
+ lgInfo($"---------------- Elenco Devices ----------------");
+ // loggo devices principali...
+ logDevicesList(probe.Devices);
+ }
+ }
+ catch (Exception exc)
+ {
+ lgError($"Eccezione durante test probe:{Environment.NewLine}{exc}");
+ }
+ // attendo 1 sec...
+ Thread.Sleep(1000);
+ // ora avvio
+ try
+ {
+ lgInfo($"Chiamata apertura MTC Client: {cIobConf.cncIpAddr}:{port}");
+ MTC_ref = new MTConnectClient($"http://{cIobConf.cncIpAddr}:{port}");
+ // Subscribe to the Event handlers to receive the MTConnect documents
+ MTC_ref.ProbeReceived += DevicesSuccessful;
+ MTC_ref.CurrentReceived += CurrentSuccessful;
+ MTC_ref.SampleReceived += StreamsSuccessful;
+
+ // attendo 1 sec...
+ Thread.Sleep(1000);
+ MTC_ref.Start();
+ esitoLink = 1;
+
+ // fix tempi!
+ DateTime adesso = DateTime.Now;
+ lastPzCountSend = adesso;
+ lastWarnODL = adesso;
+ lastCurrent = adesso;
+ }
+ catch
+ { }
+ return esitoLink;
+ }
+
+ ///
+ /// Formatta un dataitem da uno stream SAMPLE
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private MtcDataItemExt formatDataItem(ref int dSamplePeriod, ref int threshDBand, ref string uuid, MTConnectStreams.Sample DISample)
+ {
+ // creo il nuovo dataitem da sample...
+ MTConnectDevices.DataItem newDataItem = new MTConnectDevices.DataItem()
+ {
+ Category = DISample.Category,
+ Id = DISample.DataItemId,
+ Name = DISample.Name,
+ SampleRate = DISample.SampleRate,
+ Statistic = DISample.Statistic,
+ SubType = DISample.SubType,
+ Type = DISample.Type
+ };
+ return formatDataItem(ref dSamplePeriod, ref threshDBand, ref uuid, newDataItem);
+ }
+
+ ///
+ /// Formatta un dataitem da uno stream GENERICO
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private MtcDataItemExt formatDataItem(ref int dSamplePeriod, ref int threshDBand, ref string uuid, MTConnectStreams.DataItem DIGen)
+ {
+ // creo il nuovo dataitem da sample...
+ MTConnectDevices.DataItem newDataItem = new MTConnectDevices.DataItem()
+ {
+ Category = DIGen.Category,
+ Id = DIGen.DataItemId,
+ Name = DIGen.Name,
+ SubType = DIGen.SubType,
+ Type = DIGen.Type
+ };
+ return formatDataItem(ref dSamplePeriod, ref threshDBand, ref uuid, newDataItem);
+ }
+
+ ///
+ /// Formatta un dataitem x salvataggio in memoria locale
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private MtcDataItemExt formatDataItem(ref int dSamplePeriod, ref int threshDBand, ref string uuid, MTConnectDevices.DataItem dataItem)
+ {
+ MtcDataItemExt currDataItem;
+ // uuid e parametri secondo categoria...
+ switch (dataItem.Category)
+ {
+ case MTConnect.DataItemCategory.CONDITION:
+ uuid = $"C_{dataItem.Id}";
+ threshDBand = 0;
+ dSamplePeriod = 0;
+ break;
+
+ case MTConnect.DataItemCategory.EVENT:
+ uuid = $"E_{dataItem.Id}";
+ threshDBand = 0;
+ dSamplePeriod = 0;
+ break;
+
+ case MTConnect.DataItemCategory.SAMPLE:
+ uuid = $"S_{dataItem.Id}";
+ // SOLO SE è abilitato il datafiltering...
+ if (enableDataFilter)
+ {
+ threshDBand = 1;
+ // controllo SE ho conf x deadband...
+ if (mtcParams.paramsEndThresh.Count > 0)
+ {
+ // ciclo su tutti i parametri indicati...
+ foreach (var item in mtcParams.paramsEndThresh)
+ {
+ if (dataItem.Id.EndsWith(item.Key))
+ {
+ threshDBand = item.Value;
+ }
+ }
+ }
+ }
+ else
+ {
+ threshDBand = 0;
+ }
+ dSamplePeriod = 60;
+ break;
+
+ default:
+ break;
+ }
+ // salvo oggetto x "uso interno"
+ currDataItem = new MtcDataItemExt()
+ {
+ Id = dataItem.Id,
+ Category = dataItem.Category,
+ Constraints = dataItem.Constraints,
+ CoordinateSystem = dataItem.CoordinateSystem,
+ Name = dataItem.Name,
+ NativeScale = dataItem.NativeScale,
+ NativeUnits = dataItem.NativeUnits,
+ SampleRate = dataItem.SampleRate,
+ Representation = dataItem.Representation,
+ SignificantDigits = dataItem.SignificantDigits,
+ Source = dataItem.Source,
+ Statistic = dataItem.Statistic,
+ SubType = dataItem.SubType,
+ Type = dataItem.Type,
+ TypePath = dataItem.TypePath,
+ Units = dataItem.Units,
+ XPath = dataItem.XPath,
+ uid = uuid,
+ thresholdDeadBand = threshDBand,
+ samplePeriod = dSamplePeriod
+ };
+ // log x capire COME ho chiamato alcune cosette...
+ if (dataItem.Id.Contains("EXE_MODE") || dataItem.Id.Contains("RUN_MODE") || dataItem.Id.Contains("POWER") || dataItem.Id.EndsWith("_Status"))
+ {
+ lgInfo($"DEBUG DATA | dataItem.Id : {dataItem.Id}");
+ }
+
+ return currDataItem;
+ }
+
+ ///
+ /// Effettua lettura file di conf specifico MTC da oggetto serializzato json
+ /// Nome file da cui leggere i parametri json
+ ///
+ private void loadMtcConf(string fileName)
+ {
+ string jsonFullPath = $"{Application.StartupPath}/DATA/CONF/{fileName}";
+ lgInfo($"Apertura file {jsonFullPath}");
+ StreamReader reader = new StreamReader(jsonFullPath);
+ string jsonData = reader.ReadToEnd().Replace("\n", "").Replace("\r", "");
+ if (!string.IsNullOrEmpty(jsonData))
+ {
+ lgInfo($"File json composto da {jsonData.Length} caratteri");
+ try
+ {
+ mtcParams = JsonConvert.DeserializeObject(jsonData);
+ lgInfo($"Decodifica aree MtcParamConf: trovati {mtcParams.paramsEndThresh.Count} valori paramsEndThresh");
+ }
+ catch (Exception exc)
+ {
+ lgError($"Eccezione in decodifica conf json MTC:{Environment.NewLine}{exc}");
+ }
+ }
+ else
+ {
+ lgError("Errore in loadMtcConf: file json vuoto!");
+ }
+ reader.Dispose();
+ }
+
+ ///
+ /// Effettua invio a MP/IO dell'elenco serializzato dei dataItems
+ ///
+ ///
+ private void sendDataItemsList(List dataItems)
+ {
+ string rawData = JsonConvert.SerializeObject(dataItems);
+ utils.callUrlNow($"{urlSaveDataItems}", rawData);
+ }
+
+ #endregion area comune (non modificare)
+
+ #region Metodi specifici (da verificare/completare in implementazione)
+
+ ///
+ /// Verifico se abbia ALMENO un errore...
+ ///
+ protected bool hasError
+ {
+ get
+ {
+ bool answ = false;
+ // controllo TUTTE le conditions...
+ foreach (var item in dataItemMem)
+ {
+ // se NON HO GIA' allarmi attivi...
+ if (!answ)
+ {
+ // se è una condition...
+ if (item.Value.Category == MTConnect.DataItemCategory.CONDITION)
+ {
+ // se ha valore !="" --> allarmi attivi
+ if (!string.IsNullOrEmpty(item.Value.value))
+ {
+ answ = true;
+ }
+ }
+ }
+ }
+ return answ;
+ }
+ }
+
+ ///
+ /// Recupero dati dinamici...
+ ///
+ public override Dictionary getDynData()
+ {
+ // valore non presente in vers default... se gestito fare override
+ Dictionary outVal = new Dictionary();
+ return outVal;
+ }
+
+ ///
+ /// Effettua vero processing contapezzi
+ ///
+ public override void processContapezzi()
+ {
+ if (utils.CRB("enableContapezzi"))
+ {
+ // cerco parametro contapezzi...
+ string currPzCount = getDataItemValue(mtcParams.keyPartCount);
+
+ // se ho un contapezzi... processo...
+ if (!string.IsNullOrEmpty(currPzCount))
+ {
+ int newVal = -1;
+ Int32.TryParse(currPzCount, out newVal);
+ lastCountCNC = newVal > -1 ? newVal : lastCountCNC;
+ }
+ }
+ }
+
+ ///
+ /// Effettua lettura semafori principale
+ /// Parametri da aggiornare x display in form
+ ///
+ public override void readSemafori(ref newDisplayData currDispData)
+ {
+ base.readSemafori(ref currDispData);
+ try
+ {
+ if (verboseLog)
+ {
+ lgInfo("inizio read semafori");
+ }
+
+ currDispData.semIn = Semaforo.SV;
+
+ // decodifica e gestione
+ decodeToBaseBitmap();
+ reportRawInput(ref currDispData);
+ }
+ catch (Exception exc)
+ {
+ currDispData.semIn = Semaforo.SR;
+ lgError($"Eccezione in readSemafori:{Environment.NewLine}{exc}");
+ }
+ }
+
+ ///
+ /// Verifica un DataItem e se il valore corrisponde a quello indicato come "true value" restituisce true
+ ///
+ ///
+ ///
+ ///
+ protected bool checkDataItem(string itemName, string trueVal)
+ {
+ bool answ = false;
+ MtcDataItemExt currValue = null;
+ try
+ {
+ currValue = dataItemMem[itemName];
+ answ = (currValue.value.Equals(trueVal));
+ }
+ catch
+ {
+ lgError($"Errore in decodifica valore per {itemName} rispetto a {trueVal} | recuperato {currValue} / {currValue.value}");
+ }
+ return answ;
+ }
+
+ ///
+ /// Effettua decodifica aree memoria alla bitmap usata x MAPO
+ ///
+ private void decodeToBaseBitmap()
+ {
+ // init a zero...
+ B_input = 0;
+
+ /* -----------------------------------------------------
+ * bitmap MAPO
+ * B0: POWER_ON
+ * B1: RUN
+ * B2: pzCount
+ * B3: allarme
+ * B4: manuale
+ ----------------------------------------------------- */
+
+ // Controllo booleano PING e POWERON...
+ string currPowerOn = getDataItemValue(mtcParams.condPowerOn.keyName);
+ // se valido il check ping lo eseguo... altrimenti lo do x buono
+ bool checkPing = !mtcParams.pingAsPowerOn;
+ if (!checkPing)
+ {
+ checkPing = (testPingMachine == IPStatus.Success);
+ }
+ // verifico da target value richiesto...
+ bool checkPowerOn = (currPowerOn == mtcParams.condPowerOn.targetValue);
+
+ // bit 0 (poweron) imposto a 1 SE pingo o PowerOn=="ON"...
+ B_input = (checkPing || checkPowerOn) ? 1 : 0;
+
+ // variabili RUN...
+ string currRun = getDataItemValue(mtcParams.keyRunMode);
+
+ // controllo RUN MODE preliminare... CABLATO poiché è GENERALE x MTC
+ if (currRun == "AUTOMATIC" || currRun == "SEMI_AUTO" || currRun == "SEMI_AUTOMATIC")
+ {
+ int numCond = mtcParams.condWork.Count;
+ int numCondOk = 0;
+ // cerco nell'elenco delle condizioni che indicano lavora se sono ok faccio +1 conteggio......
+ foreach (var item in mtcParams.condWork)
+ {
+ if (getDataItemValue(item.keyName) == item.targetValue)
+ {
+ numCondOk++;
+ }
+ }
+ // se tutte condizioni rispettate --> lavora!
+ if (numCond == numCondOk)
+ {
+ // RUN = LAVORA!
+ B_input += (1 << 1);
+ }
+ }
+ // se ho almeno 1 allarme E NON SONO IN AUTO --> ALARM!
+ else if (hasError)
+ {
+ B_input += (1 << 3);
+ }
+ else
+ {
+ // se ho run mode != auto --> manual
+ B_input += (1 << 4);
+ }
+
+ DateTime adesso = DateTime.Now;
+ int vFactor = 1;
+ // controllo SE HO dati per fare verifiche...
+ if (string.IsNullOrEmpty(currRun))
+ {
+ // se ho parametro x gestione reset...
+ if (enableMtcRestart)
+ {
+ // controllo se ho ricevuto il current da OLTRE 1 minuto...
+ if (lastCurrent.AddMinutes(3) < adesso)
+ {
+ lastCurrent = adesso;
+ // stop...
+ lgInfo("Fermato MTC_ref per mancanza dati current");
+ MTC_ref.Stop();
+ Thread.Sleep(1000);
+ // restart
+ lgInfo("Riavviato MTC_ref per mancanza dati current");
+ MTC_ref.Start();
+ }
+ }
+ }
+ else
+ {
+ vFactor = 6;
+ }
+
+ // solo se non ho veto check
+ if (vetoCheckStatus < adesso)
+ {
+ lgInfo($"Stato variabili: currRun: {currRun}");
+ // imposto veto per vetoSeconds...
+ vetoCheckStatus = adesso.AddSeconds(vetoSeconds * vFactor);
+ }
+ // log opzionale!
+ if (verboseLog)
+ {
+ lgInfo($"Trasformazione B_input: {B_input} | currRun = {currRun}");
+ }
+ }
+
+ #endregion Metodi specifici (da verificare/completare in implementazione)
}
- ///
- /// Verifica un DataItem e se il valore corrisponde a quello indicato come "true value" restituisce true
- ///
- ///
- ///
- ///
- protected bool checkDataItem(string itemName, string trueVal)
- {
- bool answ = false;
- MtcDataItemExt currValue = null;
- try
- {
- currValue = dataItemMem[itemName];
- answ = (currValue.value.Equals(trueVal));
- }
- catch
- {
- lgError($"Errore in decodifica valore per {itemName} rispetto a {trueVal} | recuperato {currValue} / {currValue.value}");
- }
- return answ;
- }
-
- ///
- /// Recupero dati dinamici...
- ///
- public override Dictionary getDynData()
- {
- // valore non presente in vers default... se gestito fare override
- Dictionary outVal = new Dictionary();
- return outVal;
- }
-
- #endregion
-
- }
-}
+}
\ No newline at end of file
diff --git a/IOB-WIN/IobSiemensLasco.cs b/IOB-WIN/IobSiemensLasco.cs
index 695836d6..6a272a22 100644
--- a/IOB-WIN/IobSiemensLasco.cs
+++ b/IOB-WIN/IobSiemensLasco.cs
@@ -7,540 +7,547 @@ using System.Text.RegularExpressions;
namespace IOB_WIN
{
- ///
- /// Controllo Siemens specifico x impianti Lasco (Pressa bilancere Valvital)
- ///
- public class IobSiemensLasco : IobSiemens
- {
- /* --------------------------------------------------------------------------------
- * Controlli SIEMENS LASCO (Pressa principale in VALVITAL)
- * - basasto su SIEMENS
- * - S7 vers 1500
- *
- * STRUTTURA MEMORIA DB1001 READ: 68 byte lettura, DB1002 68 byte byte scrittura, vedere doc allegato
- * G:\Drive condivisi\30_Clienti\Valvital\Comunicazione PLC\LASCO
- *
- * !!!RISCRIVERE!!!
- * - parametri processo
- * - DBD00: Watchdog INT SAET Alive ( 1-9999 )
- *
- * - DB60.DBD6: pressione camera filtrante (salvataggio del MAX ogni minuto) | var testVal = S7.Net.Types.Double.FromByteArray(memByteRead.Skip(0).Take(4).ToArray());
- * - DB60.DBD10: pressione linea utenze (salvataggio del MAX ogni minuto)
- * - DB60.DBD14: temperatura acqua pulita (salvataggio del MAX ogni minuto)
- *
- * - BIT di stato
- * - DBX2.1: READY TO RUN in AUTOMATICO
- * - DBX2.3: Macchina in LAVORAZIONE
- * - DBX2.4: WARNING Differenza tra Part Code MES - Saet (blu)
- * - DBX2.5: se 1 --> LAMPADA ROSSA (allarmi almeno 1 attivo)
- *
- * PartCounter DINT 4.0 Conteggio Parziale di pezzi "OK" prodotti dalla macchina
- * NumberCode String [12] 8.0 Valore numerico associato alla ricetta di produzione attualmente utilizzata dalla macchina
- * NewCode INT 22.0 "1= Avvenuta ricezione del segnale ""richiesta nuovo ordine di produzione (NEW CODE)""
- * ricevuto dal server,impostabile su 1 solo quando la macchina NON è in produzione attiva"
- * Potenza utilizzata ST.1 REAL 24 Potenza utilizzata dalla stazione di riscaldo 1 [kW]
- * Potenza utilizzata ST.2 REAL 28 Potenza utilizzata dalla stazione di riscaldo 2 [kW]
- * Potenza utilizzata ST.3 REAL 32 Potenza utilizzata dalla stazione di riscaldo 3 [kW]
- * Potenza utilizzata ST.4 REAL 36 Potenza utilizzata dalla stazione di riscaldo 4 [kW]
- * Lettura Pirometro ST.1 REAL 40 Lettura Pirometro della stazione di riscaldo 1 [°C]
- * Lettura Pirometro ST.2 REAL 44 Lettura Pirometro della stazione di riscaldo 2 [°C]
- * Lettura Pirometro ST.3 REAL 48 Lettura Pirometro della stazione di riscaldo 3 [°C]
- * Lettura Pirometro ST.4 REAL 52 Lettura Pirometro della stazione di riscaldo 4 [°C]
- * Temperatura Acqua Raff Conv. ST.1 REAL 56 Temperarura Acqua di Raffreddamento Convertitore Stazione di Riscaldo 1 [°C]
- * Temperatura Acqua Raff Conv. ST.2 REAL 60 Temperarura Acqua di Raffreddamento Convertitore Stazione di Riscaldo 2 [°C]
- * Temperatura Acqua Raff Conv. ST.3 REAL 64 Temperarura Acqua di Raffreddamento Convertitore Stazione di Riscaldo 3 [°C]
- * Temperatura Acqua Raff Conv. ST.4 REAL 68 Temperarura Acqua di Raffreddamento Convertitore Stazione di Riscaldo 4 [°C]
- * Part_Status ST.1 INT 72 Stato Pezzo Stazione di Riscaldo 1 (0=Assente 1=Grezzo 10=OK 11=NOK)
- * Part_Status ST.2 INT 74 Stato Pezzo Stazione di Riscaldo 2 (0=Assente 1=Grezzo 10=OK 11=NOK)
- * Part_Status ST.3 INT 76 Stato Pezzo Stazione di Riscaldo 3 (0=Assente 1=Grezzo 10=OK 11=NOK)
- * Part_Status ST.4 INT 78 Stato Pezzo Stazione di Riscaldo 4 (0=Assente 1=Grezzo 10=OK 11=NOK)
- * Reserve_12 REAL 80 Riserva
- * Reserve_13 REAL 84 Riserva
- * Reserve_14 REAL 88 Riserva
-
- * -------------------------------------------------------------------------------- */
-
- protected DateTime lastPLCWatchDog;
- protected int counterMes2Plc = 0;
- protected int counterPlc2Mes = 0;
- protected int counterPlc2MesWrote = 0;
-
- protected bool useNewSend = false;
-
///
- /// Classe base con i metodi x Siemens
+ /// Controllo Siemens specifico x impianti Lasco (Pressa bilancere Valvital)
///
- ///
- ///
- public IobSiemensLasco(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf)
+ public class IobSiemensLasco : IobSiemens
{
- lgInfo("NEW IOB SIEMENS versione LASCO");
- lastPLCWatchDog = DateTime.Now.AddMinutes(-1);
- useNewSend = string.IsNullOrWhiteSpace(getOptPar("USE_NEW_EXE_TASK")) ? false : true;
- // imposto i parametri speciali x calcolo...
- var chiaviTSVC = findOptPar("TSVC");
- if (chiaviTSVC.Count > 0)
- {
- lgInfo($"Trovate {chiaviTSVC.Count} chiavi TSVC");
- string[] codVal;
- VCData currConf;
- int periodo = 0;
- VC_func funz = VC_func.POINT;
- // accodo nella conf...
- foreach (var item in chiaviTSVC)
+ /* --------------------------------------------------------------------------------
+ * Controlli SIEMENS LASCO (Pressa principale in VALVITAL)
+ * - basasto su SIEMENS
+ * - S7 vers 1500
+ *
+ * STRUTTURA MEMORIA DB1001 READ: 68 byte lettura, DB1002 68 byte byte scrittura, vedere doc allegato
+ * G:\Drive condivisi\30_Clienti\Valvital\Comunicazione PLC\LASCO
+ *
+ * !!!RISCRIVERE!!!
+ * - parametri processo
+ * - DBD00: Watchdog INT SAET Alive ( 1-9999 )
+ *
+ * - DB60.DBD6: pressione camera filtrante (salvataggio del MAX ogni minuto) | var testVal = S7.Net.Types.Double.FromByteArray(memByteRead.Skip(0).Take(4).ToArray());
+ * - DB60.DBD10: pressione linea utenze (salvataggio del MAX ogni minuto)
+ * - DB60.DBD14: temperatura acqua pulita (salvataggio del MAX ogni minuto)
+ *
+ * - BIT di stato
+ * - DBX2.1: READY TO RUN in AUTOMATICO
+ * - DBX2.3: Macchina in LAVORAZIONE
+ * - DBX2.4: WARNING Differenza tra Part Code MES - Saet (blu)
+ * - DBX2.5: se 1 --> LAMPADA ROSSA (allarmi almeno 1 attivo)
+ *
+ * PartCounter DINT 4.0 Conteggio Parziale di pezzi "OK" prodotti dalla macchina
+ * NumberCode String [12] 8.0 Valore numerico associato alla ricetta di produzione attualmente utilizzata dalla macchina
+ * NewCode INT 22.0 "1= Avvenuta ricezione del segnale ""richiesta nuovo ordine di produzione (NEW CODE)""
+ * ricevuto dal server,impostabile su 1 solo quando la macchina NON è in produzione attiva"
+ * Potenza utilizzata ST.1 REAL 24 Potenza utilizzata dalla stazione di riscaldo 1 [kW]
+ * Potenza utilizzata ST.2 REAL 28 Potenza utilizzata dalla stazione di riscaldo 2 [kW]
+ * Potenza utilizzata ST.3 REAL 32 Potenza utilizzata dalla stazione di riscaldo 3 [kW]
+ * Potenza utilizzata ST.4 REAL 36 Potenza utilizzata dalla stazione di riscaldo 4 [kW]
+ * Lettura Pirometro ST.1 REAL 40 Lettura Pirometro della stazione di riscaldo 1 [°C]
+ * Lettura Pirometro ST.2 REAL 44 Lettura Pirometro della stazione di riscaldo 2 [°C]
+ * Lettura Pirometro ST.3 REAL 48 Lettura Pirometro della stazione di riscaldo 3 [°C]
+ * Lettura Pirometro ST.4 REAL 52 Lettura Pirometro della stazione di riscaldo 4 [°C]
+ * Temperatura Acqua Raff Conv. ST.1 REAL 56 Temperarura Acqua di Raffreddamento Convertitore Stazione di Riscaldo 1 [°C]
+ * Temperatura Acqua Raff Conv. ST.2 REAL 60 Temperarura Acqua di Raffreddamento Convertitore Stazione di Riscaldo 2 [°C]
+ * Temperatura Acqua Raff Conv. ST.3 REAL 64 Temperarura Acqua di Raffreddamento Convertitore Stazione di Riscaldo 3 [°C]
+ * Temperatura Acqua Raff Conv. ST.4 REAL 68 Temperarura Acqua di Raffreddamento Convertitore Stazione di Riscaldo 4 [°C]
+ * Part_Status ST.1 INT 72 Stato Pezzo Stazione di Riscaldo 1 (0=Assente 1=Grezzo 10=OK 11=NOK)
+ * Part_Status ST.2 INT 74 Stato Pezzo Stazione di Riscaldo 2 (0=Assente 1=Grezzo 10=OK 11=NOK)
+ * Part_Status ST.3 INT 76 Stato Pezzo Stazione di Riscaldo 3 (0=Assente 1=Grezzo 10=OK 11=NOK)
+ * Part_Status ST.4 INT 78 Stato Pezzo Stazione di Riscaldo 4 (0=Assente 1=Grezzo 10=OK 11=NOK)
+ * Reserve_12 REAL 80 Riserva
+ * Reserve_13 REAL 84 Riserva
+ * Reserve_14 REAL 88 Riserva
+
+ * -------------------------------------------------------------------------------- */
+
+ protected int counterMes2Plc = 0;
+ protected int counterPlc2Mes = 0;
+ protected int counterPlc2MesWrote = 0;
+ protected DateTime lastPLCWatchDog;
+ protected bool useNewSend = false;
+
+ ///
+ /// Classe base con i metodi x Siemens
+ ///
+ ///
+ ///
+ public IobSiemensLasco(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf)
{
- codVal = item.Value.Split(':');
- Enum.TryParse(codVal[0], out funz);
- int.TryParse(codVal[1], out periodo);
- currConf = new VCData()
- {
- Funzione = funz,
- Period = periodo,
- DTStart = DateTime.Now.AddHours(-1),
- dataArray = new List()
- };
- TSVC_Data.Add(item.Key.Replace("TSVC_", ""), currConf);
- }
- // documento...
- foreach (var item in TSVC_Data)
- {
- lgInfo($"TSVC: {item.Key} | periodo: {item.Value.Period} | funz: {item.Value.Funzione}");
- // salvo i valori PREC...
- LastTSVC.Add(item.Key, 0);
- }
- }
- }
-
- #region Metodi specifici (da verificare/completare in implementazione)
-
- ///
- /// Effettua processing del recupero delle OVERRIDE (spindle, feedrate, rapid)
- ///
- public override void processOverride()
- {
- }
-
- public override void processWhatchDog()
- {
- // scrive nel primo byte, ultimo bit, il watchdog, mentre scrive nel primo 1 = setup, 0 = run
- // scrivo 1 volta al secondo il contatore incrementale su area apposita
- DateTime adesso = DateTime.Now;
- if (adesso.Subtract(lastPLCWatchDog).TotalSeconds > 1)
- {
- // incremento
- counterMes2Plc++;
- // se > 1 --> 0 (balla solo 0..1)
- if (counterMes2Plc > 1) counterMes2Plc = 0;
- // salvo su DB
- Dictionary task2exe = new Dictionary();
- Dictionary taskDone = new Dictionary();
- task2exe.Add("sendWatchDogMes2Plc", counterMes2Plc.ToString());
- taskDone = executeTasks(task2exe);
- // salvo watchdog PLC
- lastPLCWatchDog = adesso;
- }
- }
-
- ///
- /// 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 = "";
- string memAddrWrite = "";
- if (task2exe != null)
- {
- // inizio VUOTO
- byte[] MemBlock = new byte[parametri.memSizeWrite];
-
- // controllo su OPT_PAR se usare nuovo metodo exe task...
- if (useNewSend)
- {
- // 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)
+ lgInfo("NEW IOB SIEMENS versione LASCO");
+ lastPLCWatchDog = DateTime.Now.AddMinutes(-1);
+ useNewSend = string.IsNullOrWhiteSpace(getOptPar("USE_NEW_EXE_TASK")) ? false : true;
+ // imposto i parametri speciali x calcolo...
+ var chiaviTSVC = findOptPar("TSVC");
+ if (chiaviTSVC.Count > 0)
{
- case taskType.nihil:
- case taskType.fixStopSetup:
- case taskType.forceResetPzCount:
- case taskType.forceSetPzCount:
- case taskType.setProg:
- taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC";
- break;
- case taskType.setArt:
- case taskType.setComm:
- case taskType.setPzComm:
- saveProdData(item);
- int byteSize = 0;
- // recupero dati da memMap... altrimenti NULLA
- if (memMap.mMapWrite.ContainsKey(item.Key))
+ lgInfo($"Trovate {chiaviTSVC.Count} chiavi TSVC");
+ string[] codVal;
+ VCData currConf;
+ int periodo = 0;
+ VC_func funz = VC_func.POINT;
+ // accodo nella conf...
+ foreach (var item in chiaviTSVC)
{
- 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);
- }
+ codVal = item.Value.Split(':');
+ Enum.TryParse(codVal[0], out funz);
+ int.TryParse(codVal[1], out periodo);
+ currConf = new VCData()
+ {
+ Funzione = funz,
+ Period = periodo,
+ DTStart = DateTime.Now.AddHours(-1),
+ dataArray = new List()
+ };
+ TSVC_Data.Add(item.Key.Replace("TSVC_", ""), currConf);
}
- taskVal = item.Value;
- break;
- case taskType.sendWatchDogMes2Plc:
- // processo scrittura BIT su DB150.DBX4.0
- MemBlock = new byte[1];
- memAddrWrite = "DB1002.DBB0";
- // compogo in byte... primo bit è setup/run, ultimo è watchdog
- int valore = inSetup ? 1 : 0;
- valore += (byte)(counterMes2Plc << 7);
- MemBlock[0] = (byte)valore;
- taskVal = $"VALUE DB1002.92 --> {valore} | counter interno {counterMes2Plc}";
- 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))
+ // documento...
+ foreach (var item in TSVC_Data)
{
- // 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";
- }
+ lgInfo($"TSVC: {item.Key} | periodo: {item.Value.Period} | funz: {item.Value.Funzione}");
+ // salvo i valori PREC...
+ LastTSVC.Add(item.Key, 0);
}
- break;
- case taskType.startSetup:
- // salvo che SONO IN SETUP!
- inSetup = true;
- break;
- case taskType.stopSetup:
- // salvo che SONO FUORI DAL SETUP!
- inSetup = false;
- break;
- default:
- taskVal = "SKIPPED | NO EXEC";
- break;
}
- // aggiungo task!
- taskDone.Add(item.Key, taskVal);
- // scrivo comunque!
- taskOk = S7WriteBB(ref MemBlock, memAddrWrite);
- if (!taskOk)
+ }
+
+ #region Metodi specifici (da verificare/completare in implementazione)
+
+ ///
+ /// 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 = "";
+ string memAddrWrite = "";
+ if (task2exe != null)
{
- lgError($"Errore in S7WriteBB durante executeTasks: {item.Key} | {item.Value}");
- }
- }
- }
- else
- {
- // cerco task specifici: se ho startSetup --> imposto bit DBB701.DBB0.4
- 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.startSetup:
- case taskType.stopSetup:
- taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC";
- break;
- case taskType.setArt:
- case taskType.setComm:
- case taskType.setProg:
- saveProdData(item);
- taskVal = item.Value;
- break;
- case taskType.sendWatchDogMes2Plc:
- // compogo in byte... primo bit è setup/run, ultimo è watchdog
- int valore = inSetup ? 1 : 0;
- valore += (byte)(counterMes2Plc << 7);
- MemBlock[0] = (byte)valore;
- taskVal = $"VALUE DB1002.92 --> {counterMes2Plc}";
- break;
+ // inizio VUOTO
+ byte[] MemBlock = new byte[parametri.memSizeWrite];
- 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))
+ // controllo su OPT_PAR se usare nuovo metodo exe task...
+ if (useNewSend)
{
- // 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";
- }
+ // 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:
+ taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC";
+ break;
+
+ case taskType.setArt:
+ case taskType.setComm:
+ case taskType.setPzComm:
+ 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 valDInt = 0;
+ short.TryParse(item.Value, out valDInt);
+ MemBlock = S7.Net.Types.Int.ToByteArray(valDInt);
+ }
+ }
+ taskVal = item.Value;
+ break;
+
+ case taskType.sendWatchDogMes2Plc:
+ // processo scrittura BIT su DB150.DBX4.0
+ MemBlock = new byte[1];
+ memAddrWrite = "DB1002.DBB0";
+ // compogo in byte... primo bit è setup/run, ultimo è watchdog
+ int valore = inSetup ? 1 : 0;
+ valore += (byte)(counterMes2Plc << 7);
+ MemBlock[0] = (byte)valore;
+ taskVal = $"VALUE DB1002.92 --> {valore} | counter interno {counterMes2Plc}";
+ 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))
+ {
+ // 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;
+
+ case taskType.startSetup:
+ // salvo che SONO IN SETUP!
+ inSetup = true;
+ break;
+
+ case taskType.stopSetup:
+ // salvo che SONO FUORI DAL SETUP!
+ inSetup = false;
+ break;
+
+ default:
+ taskVal = "SKIPPED | NO EXEC";
+ break;
+ }
+ // aggiungo task!
+ taskDone.Add(item.Key, taskVal);
+ // scrivo comunque!
+ taskOk = S7WriteBB(ref MemBlock, memAddrWrite);
+ if (!taskOk)
+ {
+ lgError($"Errore in S7WriteBB durante executeTasks: {item.Key} | {item.Value}");
+ }
+ }
+ }
+ else
+ {
+ // cerco task specifici: se ho startSetup --> imposto bit DBB701.DBB0.4
+ 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.startSetup:
+ case taskType.stopSetup:
+ taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC";
+ break;
+
+ case taskType.setArt:
+ case taskType.setComm:
+ case taskType.setProg:
+ saveProdData(item);
+ taskVal = item.Value;
+ break;
+
+ case taskType.sendWatchDogMes2Plc:
+ // compogo in byte... primo bit è setup/run, ultimo è watchdog
+ int valore = inSetup ? 1 : 0;
+ valore += (byte)(counterMes2Plc << 7);
+ MemBlock[0] = (byte)valore;
+ taskVal = $"VALUE DB1002.92 --> {counterMes2Plc}";
+ 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))
+ {
+ // 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);
+ }
+ // controllo SE HO da scrivere articolo/commessa/programma
+ saveStringOnMemBlock(ref MemBlock, "setArt", 2, 22);
+ saveStringOnMemBlock(ref MemBlock, "setComm", 24, 22);
+ saveStringOnMemBlock(ref MemBlock, "setProg", 46, 22);
+
+ // scrivo comunque!
+ taskOk = S7WriteBB(ref MemBlock);
}
- break;
- default:
- taskVal = "SKIPPED | NO EXEC";
- break;
}
- // aggiungo task!
- taskDone.Add(item.Key, taskVal);
- }
- // controllo SE HO da scrivere articolo/commessa/programma
- saveStringOnMemBlock(ref MemBlock, "setArt", 2, 22);
- saveStringOnMemBlock(ref MemBlock, "setComm", 24, 22);
- saveStringOnMemBlock(ref MemBlock, "setProg", 46, 22);
-
- // scrivo comunque!
- taskOk = S7WriteBB(ref MemBlock);
+ return taskDone;
}
- }
- return taskDone;
- }
-
- ///
- /// Recupero dati dinamici in formato dictionary
- ///
- ///
- public override Dictionary getDynData()
- {
- Dictionary outVal = new Dictionary();
- // processing
- try
- {
- // le 3 posizioni sono in 1/10 mm x cui vanno divise x 10... x avere MM
- double RamPosition = S7.Net.Types.Int.FromByteArray(RawInput.Skip(18).Take(2).ToArray()) / 10;
- double LowerEjectorPosition = S7.Net.Types.Int.FromByteArray(RawInput.Skip(20).Take(2).ToArray()) / 10;
- double UpperTool = S7.Net.Types.Int.FromByteArray(RawInput.Skip(22).Take(2).ToArray()) / 10;
- // temp in °C
- int TempMainMotorU = S7.Net.Types.Int.FromByteArray(RawInput.Skip(24).Take(2).ToArray());
- int TempMainMotorV = S7.Net.Types.Int.FromByteArray(RawInput.Skip(26).Take(2).ToArray());
- int TempMainMotorW = S7.Net.Types.Int.FromByteArray(RawInput.Skip(28).Take(2).ToArray());
- int TempSpindleNut = S7.Net.Types.Int.FromByteArray(RawInput.Skip(30).Take(2).ToArray());
- int TempMotoModule = S7.Net.Types.Int.FromByteArray(RawInput.Skip(32).Take(2).ToArray());
- int TempOilCirculation = S7.Net.Types.Int.FromByteArray(RawInput.Skip(34).Take(2).ToArray());
- int TempHydraulicUnit = S7.Net.Types.Int.FromByteArray(RawInput.Skip(36).Take(2).ToArray());
- // press in BAR
- int PressHydraulicPump = S7.Net.Types.Int.FromByteArray(RawInput.Skip(38).Take(2).ToArray());
- int PressHydraulicAccumulator = S7.Net.Types.Int.FromByteArray(RawInput.Skip(40).Take(2).ToArray());
- int PressCounterforceOil = S7.Net.Types.Int.FromByteArray(RawInput.Skip(42).Take(2).ToArray());
- int PressCounterforceGas = S7.Net.Types.Int.FromByteArray(RawInput.Skip(44).Take(2).ToArray());
- // forze in kN (10^3 Newton)
- int ForcePressureActual = S7.Net.Types.DInt.FromByteArray(RawInput.Skip(46).Take(4).ToArray());
- int ForceOnBushing = S7.Net.Types.Int.FromByteArray(RawInput.Skip(50).Take(2).ToArray());
-
- if (utils.CRB("enableTSVC"))
+ ///
+ /// Recupero dati dinamici in formato dictionary
+ ///
+ ///
+ public override Dictionary getDynData()
{
- bool[] scaduti = new bool[16];
- // salvo in stack le VC rilevate
- scaduti[0] = stackVal_TSVC("RamPosition", RamPosition);
- scaduti[1] = stackVal_TSVC("LowerEjectorPosition", LowerEjectorPosition);
- scaduti[2] = stackVal_TSVC("UpperTool", UpperTool);
- scaduti[3] = stackVal_TSVC("TempMainMotorU", TempMainMotorU);
- scaduti[4] = stackVal_TSVC("TempMainMotorV", TempMainMotorV);
- scaduti[5] = stackVal_TSVC("TempMainMotorW", TempMainMotorW);
- scaduti[6] = stackVal_TSVC("TempSpindleNut", TempSpindleNut);
- scaduti[7] = stackVal_TSVC("TempMotoModule", TempMotoModule);
- scaduti[8] = stackVal_TSVC("TempOilCirculation", TempOilCirculation);
- scaduti[9] = stackVal_TSVC("TempHydraulicUnit", TempHydraulicUnit);
- scaduti[10] = stackVal_TSVC("PressHydraulicPump", PressHydraulicPump);
- scaduti[11] = stackVal_TSVC("PressHydraulicAccumulator", PressHydraulicAccumulator);
- scaduti[12] = stackVal_TSVC("PressCounterforceOil", PressCounterforceOil);
- scaduti[13] = stackVal_TSVC("PressCounterforceGas", PressCounterforceGas);
- scaduti[14] = stackVal_TSVC("ForcePressureActual", ForcePressureActual);
- scaduti[15] = stackVal_TSVC("ForceOnBushing", ForceOnBushing);
+ Dictionary outVal = new Dictionary();
+ // processing
+ try
+ {
+ // le 3 posizioni sono in 1/10 mm x cui vanno divise x 10... x avere MM
+ double RamPosition = S7.Net.Types.Int.FromByteArray(RawInput.Skip(18).Take(2).ToArray()) / 10;
+ double LowerEjectorPosition = S7.Net.Types.Int.FromByteArray(RawInput.Skip(20).Take(2).ToArray()) / 10;
+ double UpperTool = S7.Net.Types.Int.FromByteArray(RawInput.Skip(22).Take(2).ToArray()) / 10;
+ // temp in °C
+ int TempMainMotorU = S7.Net.Types.Int.FromByteArray(RawInput.Skip(24).Take(2).ToArray());
+ int TempMainMotorV = S7.Net.Types.Int.FromByteArray(RawInput.Skip(26).Take(2).ToArray());
+ int TempMainMotorW = S7.Net.Types.Int.FromByteArray(RawInput.Skip(28).Take(2).ToArray());
+ int TempSpindleNut = S7.Net.Types.Int.FromByteArray(RawInput.Skip(30).Take(2).ToArray());
+ int TempMotoModule = S7.Net.Types.Int.FromByteArray(RawInput.Skip(32).Take(2).ToArray());
+ int TempOilCirculation = S7.Net.Types.Int.FromByteArray(RawInput.Skip(34).Take(2).ToArray());
+ int TempHydraulicUnit = S7.Net.Types.Int.FromByteArray(RawInput.Skip(36).Take(2).ToArray());
+ // press in BAR
+ int PressHydraulicPump = S7.Net.Types.Int.FromByteArray(RawInput.Skip(38).Take(2).ToArray());
+ int PressHydraulicAccumulator = S7.Net.Types.Int.FromByteArray(RawInput.Skip(40).Take(2).ToArray());
+ int PressCounterforceOil = S7.Net.Types.Int.FromByteArray(RawInput.Skip(42).Take(2).ToArray());
+ int PressCounterforceGas = S7.Net.Types.Int.FromByteArray(RawInput.Skip(44).Take(2).ToArray());
+ // forze in kN (10^3 Newton)
+ int ForcePressureActual = S7.Net.Types.DInt.FromByteArray(RawInput.Skip(46).Take(4).ToArray());
+ int ForceOnBushing = S7.Net.Types.Int.FromByteArray(RawInput.Skip(50).Take(2).ToArray());
- // verifico SE devo riportare dati VC
- if (baseUtils.CountTrue(scaduti) > 0)
- {
- RamPosition = getVal_TSVC_int("RamPosition", scaduti[0]);
- LowerEjectorPosition = getVal_TSVC_int("LowerEjectorPosition", scaduti[1]);
- UpperTool = getVal_TSVC_int("UpperTool", scaduti[2]);
- TempMainMotorU = getVal_TSVC_int("TempMainMotorU", scaduti[3]);
- TempMainMotorV = getVal_TSVC_int("TempMainMotorV", scaduti[4]);
- TempMainMotorW = getVal_TSVC_int("TempMainMotorW", scaduti[5]);
- TempSpindleNut = getVal_TSVC_int("TempSpindleNut", scaduti[6]);
- TempMotoModule = getVal_TSVC_int("TempMotoModule", scaduti[7]);
- TempOilCirculation = getVal_TSVC_int("TempOilCirculation", scaduti[8]);
- TempHydraulicUnit = getVal_TSVC_int("TempHydraulicUnit", scaduti[9]);
- PressHydraulicPump = getVal_TSVC_int("PressHydraulicPump", scaduti[10]);
- PressHydraulicAccumulator = getVal_TSVC_int("PressHydraulicAccumulator", scaduti[11]);
- PressCounterforceOil = getVal_TSVC_int("PressCounterforceOil", scaduti[12]);
- PressCounterforceGas = getVal_TSVC_int("PressCounterforceGas", scaduti[13]);
- ForcePressureActual = getVal_TSVC_int("ForcePressureActual", scaduti[14]);
- ForceOnBushing = getVal_TSVC_int("ForceOnBushing", scaduti[15]);
- //outVal.Add("DYNDATA", $"RamPosition {RamPosition:N2} | TempMainMotorV {TempMainMotorV:N2} | TempOilCirculation {TempOilCirculation:N2} | PressCounterforceGas {PressCounterforceGas}");
- outVal.Add("RamPosition", $"{RamPosition:N1}");
- outVal.Add("LowerEjectorPosition", $"{LowerEjectorPosition:N1}");
- outVal.Add("UpperTool", $"{UpperTool:N1}");
- outVal.Add("TempMainMotorU", $"{TempMainMotorU}");
- outVal.Add("TempMainMotorV", $"{TempMainMotorV}");
- outVal.Add("TempMainMotorW", $"{TempMainMotorW}");
- outVal.Add("TempSpindleNut", $"{TempSpindleNut}");
- outVal.Add("TempMotoModule", $"{TempMotoModule}");
- outVal.Add("TempOilCirculation", $"{TempOilCirculation}");
- outVal.Add("TempHydraulicUnit", $"{TempHydraulicUnit}");
- outVal.Add("PressHydraulicPump", $"{PressHydraulicPump}");
- outVal.Add("PressHydraulicAccumulator", $"{PressHydraulicAccumulator}");
- outVal.Add("PressCounterforceOil", $"{PressCounterforceOil}");
- outVal.Add("PressCounterforceGas", $"{PressCounterforceGas}");
- outVal.Add("ForcePressureActual", $"{ForcePressureActual}");
- outVal.Add("ForceOnBushing", $"{ForceOnBushing}");
+ if (utils.CRB("enableTSVC"))
+ {
+ bool[] scaduti = new bool[16];
+ // salvo in stack le VC rilevate
+ scaduti[0] = stackVal_TSVC("RamPosition", RamPosition);
+ scaduti[1] = stackVal_TSVC("LowerEjectorPosition", LowerEjectorPosition);
+ scaduti[2] = stackVal_TSVC("UpperTool", UpperTool);
+ scaduti[3] = stackVal_TSVC("TempMainMotorU", TempMainMotorU);
+ scaduti[4] = stackVal_TSVC("TempMainMotorV", TempMainMotorV);
+ scaduti[5] = stackVal_TSVC("TempMainMotorW", TempMainMotorW);
+ scaduti[6] = stackVal_TSVC("TempSpindleNut", TempSpindleNut);
+ scaduti[7] = stackVal_TSVC("TempMotoModule", TempMotoModule);
+ scaduti[8] = stackVal_TSVC("TempOilCirculation", TempOilCirculation);
+ scaduti[9] = stackVal_TSVC("TempHydraulicUnit", TempHydraulicUnit);
+ scaduti[10] = stackVal_TSVC("PressHydraulicPump", PressHydraulicPump);
+ scaduti[11] = stackVal_TSVC("PressHydraulicAccumulator", PressHydraulicAccumulator);
+ scaduti[12] = stackVal_TSVC("PressCounterforceOil", PressCounterforceOil);
+ scaduti[13] = stackVal_TSVC("PressCounterforceGas", PressCounterforceGas);
+ scaduti[14] = stackVal_TSVC("ForcePressureActual", ForcePressureActual);
+ scaduti[15] = stackVal_TSVC("ForceOnBushing", ForceOnBushing);
- // salvo!
- LastTSVC["RamPosition"] = RamPosition;
- LastTSVC["LowerEjectorPosition"] = LowerEjectorPosition;
- LastTSVC["UpperTool"] = UpperTool;
- LastTSVC["TempMainMotorU"] = TempMainMotorU;
- LastTSVC["TempMainMotorV"] = TempMainMotorV;
- LastTSVC["TempMainMotorW"] = TempMainMotorW;
- LastTSVC["TempSpindleNut"] = TempSpindleNut;
- LastTSVC["TempMotoModule"] = TempMotoModule;
- LastTSVC["TempOilCirculation"] = TempOilCirculation;
- LastTSVC["TempHydraulicUnit"] = TempHydraulicUnit;
- LastTSVC["PressHydraulicPump"] = PressHydraulicPump;
- LastTSVC["PressHydraulicAccumulator"] = PressHydraulicAccumulator;
- LastTSVC["PressCounterforceOil"] = PressCounterforceOil;
- LastTSVC["PressCounterforceGas"] = PressCounterforceGas;
- LastTSVC["ForcePressureActual"] = ForcePressureActual;
- LastTSVC["ForceOnBushing"] = ForceOnBushing;
- }
- else
- {
- outVal.Add("DYNDATA", $"RamPosition {LastTSVC["RamPosition"]:N1} | ForcePressureActual {LastTSVC["ForcePressureActual"]} | ForceOnBushing {LastTSVC["ForceOnBushing"]}");
- }
+ // verifico SE devo riportare dati VC
+ if (baseUtils.CountTrue(scaduti) > 0)
+ {
+ RamPosition = getVal_TSVC_int("RamPosition", scaduti[0]);
+ LowerEjectorPosition = getVal_TSVC_int("LowerEjectorPosition", scaduti[1]);
+ UpperTool = getVal_TSVC_int("UpperTool", scaduti[2]);
+ TempMainMotorU = getVal_TSVC_int("TempMainMotorU", scaduti[3]);
+ TempMainMotorV = getVal_TSVC_int("TempMainMotorV", scaduti[4]);
+ TempMainMotorW = getVal_TSVC_int("TempMainMotorW", scaduti[5]);
+ TempSpindleNut = getVal_TSVC_int("TempSpindleNut", scaduti[6]);
+ TempMotoModule = getVal_TSVC_int("TempMotoModule", scaduti[7]);
+ TempOilCirculation = getVal_TSVC_int("TempOilCirculation", scaduti[8]);
+ TempHydraulicUnit = getVal_TSVC_int("TempHydraulicUnit", scaduti[9]);
+ PressHydraulicPump = getVal_TSVC_int("PressHydraulicPump", scaduti[10]);
+ PressHydraulicAccumulator = getVal_TSVC_int("PressHydraulicAccumulator", scaduti[11]);
+ PressCounterforceOil = getVal_TSVC_int("PressCounterforceOil", scaduti[12]);
+ PressCounterforceGas = getVal_TSVC_int("PressCounterforceGas", scaduti[13]);
+ ForcePressureActual = getVal_TSVC_int("ForcePressureActual", scaduti[14]);
+ ForceOnBushing = getVal_TSVC_int("ForceOnBushing", scaduti[15]);
+ //outVal.Add("DYNDATA", $"RamPosition {RamPosition:N2} | TempMainMotorV {TempMainMotorV:N2} | TempOilCirculation {TempOilCirculation:N2} | PressCounterforceGas {PressCounterforceGas}");
+ outVal.Add("RamPosition", $"{RamPosition:N1}");
+ outVal.Add("LowerEjectorPosition", $"{LowerEjectorPosition:N1}");
+ outVal.Add("UpperTool", $"{UpperTool:N1}");
+ outVal.Add("TempMainMotorU", $"{TempMainMotorU}");
+ outVal.Add("TempMainMotorV", $"{TempMainMotorV}");
+ outVal.Add("TempMainMotorW", $"{TempMainMotorW}");
+ outVal.Add("TempSpindleNut", $"{TempSpindleNut}");
+ outVal.Add("TempMotoModule", $"{TempMotoModule}");
+ outVal.Add("TempOilCirculation", $"{TempOilCirculation}");
+ outVal.Add("TempHydraulicUnit", $"{TempHydraulicUnit}");
+ outVal.Add("PressHydraulicPump", $"{PressHydraulicPump}");
+ outVal.Add("PressHydraulicAccumulator", $"{PressHydraulicAccumulator}");
+ outVal.Add("PressCounterforceOil", $"{PressCounterforceOil}");
+ outVal.Add("PressCounterforceGas", $"{PressCounterforceGas}");
+ outVal.Add("ForcePressureActual", $"{ForcePressureActual}");
+ outVal.Add("ForceOnBushing", $"{ForceOnBushing}");
+
+ // salvo!
+ LastTSVC["RamPosition"] = RamPosition;
+ LastTSVC["LowerEjectorPosition"] = LowerEjectorPosition;
+ LastTSVC["UpperTool"] = UpperTool;
+ LastTSVC["TempMainMotorU"] = TempMainMotorU;
+ LastTSVC["TempMainMotorV"] = TempMainMotorV;
+ LastTSVC["TempMainMotorW"] = TempMainMotorW;
+ LastTSVC["TempSpindleNut"] = TempSpindleNut;
+ LastTSVC["TempMotoModule"] = TempMotoModule;
+ LastTSVC["TempOilCirculation"] = TempOilCirculation;
+ LastTSVC["TempHydraulicUnit"] = TempHydraulicUnit;
+ LastTSVC["PressHydraulicPump"] = PressHydraulicPump;
+ LastTSVC["PressHydraulicAccumulator"] = PressHydraulicAccumulator;
+ LastTSVC["PressCounterforceOil"] = PressCounterforceOil;
+ LastTSVC["PressCounterforceGas"] = PressCounterforceGas;
+ LastTSVC["ForcePressureActual"] = ForcePressureActual;
+ LastTSVC["ForceOnBushing"] = ForceOnBushing;
+ }
+ else
+ {
+ outVal.Add("DYNDATA", $"RamPosition {LastTSVC["RamPosition"]:N1} | ForcePressureActual {LastTSVC["ForcePressureActual"]} | ForceOnBushing {LastTSVC["ForceOnBushing"]}");
+ }
+ }
+ else
+ {
+ outVal.Add("DYNDATA", $"RamPosition {LastTSVC["RamPosition"]:N1} | ForcePressureActual {LastTSVC["ForcePressureActual"]} | ForceOnBushing {LastTSVC["ForceOnBushing"]}");
+ }
+ }
+ catch (Exception exc)
+ {
+ lgError(exc, "Errore in getDynData x Siemens Aprochim");
+ }
+ return outVal;
}
- else
+
+ public override string getPrgName()
{
- outVal.Add("DYNDATA", $"RamPosition {LastTSVC["RamPosition"]:N1} | ForcePressureActual {LastTSVC["ForcePressureActual"]} | ForceOnBushing {LastTSVC["ForceOnBushing"]}");
+ string answ = "";
+ try
+ {
+ string rawProdCode = S7.Net.Types.String.FromByteArray(RawInput.Skip(54).Take(12).ToArray());
+ // primi due char sono \f e \n avanzamento carta e nuova linea...
+ answ = Regex.Replace(rawProdCode, @"\t|\n|\r|\f", "");
+ }
+ catch (Exception exc)
+ {
+ lgError($"Errore in decodifica product code{Environment.NewLine}{exc}");
+ }
+ return answ;
}
- }
- catch (Exception exc)
- {
- lgError(exc, "Errore in getDynData x Siemens Aprochim");
- }
- return outVal;
+
+ ///
+ /// Effettua processing del recupero delle OVERRIDE (spindle, feedrate, rapid)
+ ///
+ public override void processOverride()
+ {
+ }
+
+ public override void processWhatchDog()
+ {
+ // scrive nel primo byte, ultimo bit, il watchdog, mentre scrive nel primo 1 = setup, 0 = run
+ // scrivo 1 volta al secondo il contatore incrementale su area apposita
+ DateTime adesso = DateTime.Now;
+ if (adesso.Subtract(lastPLCWatchDog).TotalSeconds > 1)
+ {
+ // incremento
+ counterMes2Plc++;
+ // se > 1 --> 0 (balla solo 0..1)
+ if (counterMes2Plc > 1) counterMes2Plc = 0;
+ // salvo su DB
+ Dictionary task2exe = new Dictionary();
+ Dictionary taskDone = new Dictionary();
+ task2exe.Add("sendWatchDogMes2Plc", counterMes2Plc.ToString());
+ taskDone = executeTasks(task2exe);
+ // salvo watchdog PLC
+ lastPLCWatchDog = adesso;
+ }
+ }
+
+ ///
+ /// 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
+ *
+ *
+ * - BIT di stato
+ * - DBX0.0: RUN STATE
+ * - DBX0.1: CYCLE
+ * - DBX0.2: MANUAL MODE
+ * - DBX0.3: GENERAL ALARM
+ * - DBX0.4: ESTOP (1=OK, 0 = emergency)
+ * - DBX0.5: SAFETY DOORS
+ ----------------------------------------------------- */
+
+ byte mainData = RawInput[0];
+
+ int byteSignals = 0;
+ // bit 0 (poweron) imposto a 1 SE connected...
+ if (currPLC.IsConnected)
+ {
+ byteSignals += (1 << 0);
+ }
+ if ((mainData & (1 << 0)) == 1)
+ {
+ byteSignals += (1 << 1);
+ }
+
+ // EMERGENZA
+ if ((mainData & (1 << 5)) == 1)
+ {
+ byteSignals += (1 << 5);
+ }
+ // ALLARME
+ if ((mainData & (1 << 3)) == 1)
+ {
+ byteSignals += (1 << 3);
+ }
+
+ // MANUALE ...
+ if ((mainData & (1 << 2)) == 1)
+ {
+ byteSignals += (1 << 4);
+ }
+
+ // salvo!
+ B_input = byteSignals;
+
+ // log opzionale!
+ if (verboseLog)
+ {
+ lgInfo(string.Format($"Trasformazione dati: RawInput:{RawInput[3]} --> B_input: {B_input}"));
+ }
+ }
+
+ #endregion Metodi specifici (da verificare/completare in implementazione)
}
-
- ///
- /// 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
- *
- *
- * - BIT di stato
- * - DBX0.0: RUN STATE
- * - DBX0.1: CYCLE
- * - DBX0.2: MANUAL MODE
- * - DBX0.3: GENERAL ALARM
- * - DBX0.4: ESTOP (1=OK, 0 = emergency)
- * - DBX0.5: SAFETY DOORS
- ----------------------------------------------------- */
-
- byte mainData = RawInput[0];
-
- int byteSignals = 0;
- // bit 0 (poweron) imposto a 1 SE connected...
- if (currPLC.IsConnected)
- {
- byteSignals += (1 << 0);
- }
- if ((mainData & (1 << 0)) == 1)
- {
- byteSignals += (1 << 1);
- }
-
- // EMERGENZA
- if ((mainData & (1 << 5)) == 1)
- {
- byteSignals += (1 << 5);
- }
- // ALLARME
- if ((mainData & (1 << 3)) == 1)
- {
- byteSignals += (1 << 3);
- }
-
- // MANUALE ...
- if ((mainData & (1 << 2)) == 1)
- {
- byteSignals += (1 << 4);
- }
-
- // salvo!
- B_input = byteSignals;
-
- // log opzionale!
- if (verboseLog)
- {
- lgInfo(string.Format($"Trasformazione dati: RawInput:{RawInput[3]} --> B_input: {B_input}"));
- }
- }
-
- public override string getPrgName()
- {
- string answ = "";
- try
- {
- string rawProdCode = S7.Net.Types.String.FromByteArray(RawInput.Skip(54).Take(12).ToArray());
- // primi due char sono \f e \n avanzamento carta e nuova linea...
- answ = Regex.Replace(rawProdCode, @"\t|\n|\r|\f", "");
- }
- catch (Exception exc)
- {
- lgError($"Errore in decodifica product code{Environment.NewLine}{exc}");
- }
- return answ;
- }
-
- #endregion
- }
-}
+}
\ No newline at end of file
diff --git a/IOB-WIN/IobSiemensSaet.cs b/IOB-WIN/IobSiemensSaet.cs
index 9f59f653..4bc73024 100644
--- a/IOB-WIN/IobSiemensSaet.cs
+++ b/IOB-WIN/IobSiemensSaet.cs
@@ -170,17 +170,19 @@ namespace IOB_WIN
break;
case taskType.startSetup:
- // processo scrittura BIT x richeista nuovo ordine a FINE setup
+ // processo scrittura BIT x richiesta nuovo ordine a FINE setup
MemBlock = new byte[1];
MemBlock[0] = (byte)1;
memAddrWrite = "DB1275.DBB94";
+ lgInfo("Chiamata startSetup");
break;
case taskType.stopSetup:
- // processo scrittura BIT x richeista nuovo ordine a FINE setup
+ // processo scrittura BIT x richiesta nuovo ordine a FINE setup
MemBlock = new byte[1];
MemBlock[0] = (byte)0;
memAddrWrite = "DB1275.DBB94";
+ lgInfo("Chiamata stopSetup");
break;
default:
@@ -243,6 +245,7 @@ namespace IOB_WIN
* B2: pzCount
* B3: allarme
* B4: manuale
+ * B5: anomalia
*
*
* - BIT di stato
@@ -268,7 +271,13 @@ namespace IOB_WIN
}
// controllo il bit ALLARME
- if (((mainData & (1 << 1)) == 0) || ((mainData & (1 << 5)) != 0))
+ if ((mainData & (1 << 1)) == 0)
+ {
+ byteSignals += (1 << 3);
+ }
+
+ // controllo il bit ANOMALIA
+ if ((mainData & (1 << 5)) != 0)
{
byteSignals += (1 << 3);
}