diff --git a/MP.MONO.ADAPTER.OLD/IobGeneric.cs b/MP.MONO.ADAPTER.OLD/IobGeneric.cs
new file mode 100644
index 0000000..b661ac2
--- /dev/null
+++ b/MP.MONO.ADAPTER.OLD/IobGeneric.cs
@@ -0,0 +1,631 @@
+using Microsoft.Extensions.Configuration;
+using MP.MONO.Core;
+using MP.MONO.Core.CONF;
+using Newtonsoft.Json;
+using NLog;
+using System.Net;
+using System.Net.NetworkInformation;
+using static MP.MONO.Core.CONF.OpcUaParamConf;
+using static MP.MONO.Core.Enums;
+
+namespace MP.MONO.ADAPTER
+{
+ public class IobGeneric
+ {
+ #region Public Fields
+
+ ///
+ /// Data/ora ultimo avvio adapter
+ ///
+ public DateTime dtAvvioAdp = DateTime.Now;
+
+ ///
+ /// Data/ora ultimo spegnimento adapter
+ ///
+ public DateTime dtStopAdp = DateTime.Now;
+
+ ///
+ /// dataOra ultimo log periodico...
+ ///
+ public DateTime lastPeriodicLog;
+
+ ///
+ /// dataOra ultimo PING inviato verso il PLC...
+ ///
+ public DateTime lastPING = DateTime.Now.AddHours(-1);
+
+ ///
+ /// Struttura memoria PLC x lettura/scrittura da JSON file
+ ///
+ public plcMemMap memMap;
+
+ #endregion Public Fields
+
+ #region Public Constructors
+
+ ///
+ /// Avvia generico IOB
+ ///
+ ///
+ ///
+ public IobGeneric(string confPath, IConfigurationRoot? config)
+ {
+ lg = LogManager.GetCurrentClassLogger();
+ connectionOk = false;
+ configPath = confPath;
+ confMan = config;
+ if (confMan != null)
+ {
+ var selection = confMan.GetSection("Endpoint");
+ if (selection.Exists())
+ {
+ // recupero dati endpoint
+ cIobConf = selection.Get();
+ }
+ }
+ }
+
+ #endregion Public Constructors
+
+ #region Public Properties
+
+ ///
+ /// Salva verifica stato connessione OK
+ ///
+ ///
+ public virtual bool connectionOk
+ {
+ get
+ {
+ return _connOk;
+ }
+ set
+ {
+ _connOk = value;
+ }
+ }
+
+ ///
+ /// Verifica SE si debba fare log verboso (verboso + ogni tot letture IN)
+ ///
+ public bool verboseLog
+ {
+ get
+ {
+ bool answ = false;
+ int logEvery = confMan.GetValue("logEvery");
+ if (logEvery < 1)
+ {
+ logEvery = 10;
+ }
+
+ answ = confMan.GetValue("verbose") && (nReadIN % logEvery == 0);
+ return answ;
+ }
+ }
+
+ #endregion Public Properties
+
+ #region Public Methods
+
+ ///
+ /// Esecuzione dei task richiesti e pulizia coda richieste eseguite
+ ///
+ ///
+ public virtual Dictionary executeTasks(Dictionary task2exe)
+ {
+ // Verificare il protocollo: dovrebbe togliere SOLO i task eseguiti...
+ Dictionary taskDone = new Dictionary();
+ if (task2exe != null)
+ {
+ // controllo se memMap != null...
+ if (memMap != null)
+ {
+ bool taskOk = false;
+ string taskVal = "";
+ // 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.setArt:
+ case taskType.setComm:
+ case taskType.setProg:
+ case taskType.setPzComm:
+ // recupero dati da memMap...
+ if (memMap != null && memMap.mMapWrite != null)
+ {
+ if (memMap.mMapWrite.ContainsKey(item.Key))
+ {
+ dataConf currMem = memMap.mMapWrite[item.Key];
+ string addr = currMem.memAddr;
+ taskVal = $"SET task: {item.Key} --> {item.Value} | mem: {currMem.memAddr} - {currMem.size} byte";
+ // salvo il nuovo valore nella memoria... così prox invio lo trasmetterà
+ memMap.mMapWrite[item.Key].value = item.Value;
+ }
+ else
+ {
+ taskVal = $"NO DATA MEM, SET task: {item.Key} --> {item.Value}";
+ }
+ }
+ else
+ {
+ taskVal = $"NO MemMap found, SET task: {item.Key} --> {item.Value}";
+ }
+ // salvo in currProd..
+ saveProdData(new KeyValuePair(item.Key, item.Value));
+
+ break;
+
+ case taskType.forceResetPzCount:
+ // reset contapezzi inizio setup
+ taskOk = resetcontapezziPLC();
+ taskVal = taskOk ? "RESET PZ COUNT OK" : "PZ RESET DISABLED | NO EXEC";
+ lgInfo($"Chiamata forceResetPzCount: taskOk: {taskOk} | taskVal: {taskVal}");
+ break;
+
+ case taskType.startSetup:
+ // reset contapezzi inizio setup
+ taskOk = resetcontapezziPLC();
+ taskVal = taskOk ? "RESET: SETUP START" : "PZ RESET DISABLED | NO EXEC";
+ lgInfo($"Chiamata startSetup: taskOk: {taskOk} | taskVal: {taskVal}");
+ break;
+
+ case taskType.stopSetup:
+ // reset contapezzi fine setup SE ESPLICITAMENTE IMPOSTATO
+ if (confMan.GetValue("ENABLE_PZ_RESET_stopSetup"))
+ {
+ taskOk = resetcontapezziPLC();
+ }
+ taskVal = taskOk ? "RESET: SETUP END" : "PZ RESET DISABLED | NO EXEC";
+ lgInfo($"Chiamata stopSetup: taskOk: {taskOk} | taskVal: {taskVal}");
+ break;
+
+ case taskType.setParameter:
+ // richiedo da URL i parametri WRITE da popolare
+ lgInfo("Chiamata setParameter --> processMemWriteRequests");
+ taskVal = processMemWriteRequests();
+ // se restituiscce "" faccio altra prova...
+ if (string.IsNullOrEmpty(taskVal))
+ {
+ // i parametri me li aspetto come stringa composta paramName|paramvalue
+ if (item.Value.Contains("|"))
+ {
+ string[] paramsJob = item.Value.Split('|');
+ taskVal = $"REQUEST SET PARAMETERS: {paramsJob[0]} --> {paramsJob[1]}";
+ }
+ else
+ {
+ taskVal = $"WRONG REQUEST FOR SET PARAMETERS: {item.Value} doesnt contain pipe for splitting key/value";
+ }
+ }
+ break;
+
+ default:
+ taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC";
+ lgInfo($"Chiamata senza processing: taskOk: {taskOk} | taskVal: {taskVal}");
+ break;
+ }
+ // aggiungo task!
+ taskDone.Add(item.Key, taskVal);
+ }
+ }
+ else
+ {
+ lgError($"Attenzione! memMap è nullo, non posso eseguire task2exe!");
+ }
+ }
+
+ return taskDone;
+ }
+
+ ///
+ /// Metodo generico di reset contapezzi...
+ ///
+ ///
+ public virtual bool resetcontapezziPLC()
+ {
+ return false;
+ }
+
+ ///
+ /// Salva valori indicati in prod data
+ ///
+ /// Item KVP di cui salvare i dati in currProdData come chiave/valore
+ ///
+ public void saveProdData(KeyValuePair item)
+ {
+ // imposto i valori...
+ if (currProdData.ContainsKey(item.Key))
+ {
+ currProdData[item.Key] = item.Value;
+ }
+ else
+ {
+ currProdData.Add(item.Key, item.Value);
+ }
+ }
+
+ ///
+ /// Metodo base connessione...
+ ///
+ public virtual void tryConnect()
+ {
+ dtAvvioAdp = DateTime.Now;
+ }
+
+ #endregion Public Methods
+
+ #region Protected Fields
+
+ ///
+ /// wrapper di log
+ ///
+ protected static Logger lg;
+
+ protected bool _connOk = false;
+
+ ///
+ /// Dizionario valori impostati x produzione
+ ///
+ protected Dictionary currProdData = new Dictionary();
+
+ ///
+ /// Dizionario ultimi valori (double) delle TSVC
+ ///
+ protected Dictionary LastTSVC = new Dictionary();
+
+ ///
+ /// Dizionario di VC da trattare come TimeSeries (con conf decodificata + processing successivo...)
+ ///
+ protected Dictionary TSVC_Data = new Dictionary();
+
+ #endregion Protected Fields
+
+ #region Protected Properties
+
+ ///
+ /// Numero letture IN da avvio
+ ///
+ protected int nReadIN { get; set; }
+
+ ///
+ /// COnfiguraizone Endpoint corrente
+ ///
+ private EndpointData cIobConf { get; set; } = new EndpointData();
+
+ ///
+ /// test ping all'indirizzo PLC/CNC impostato nei parametri
+ ///
+ ///
+ protected IPStatus testPingMachine
+ {
+ get
+ {
+ IPStatus answ = IPStatus.Unknown;
+ // se disabilitato salto...
+ if (pingDisabled)
+ {
+ answ = IPStatus.Success;
+ }
+ else
+ {
+ IPAddress address;
+ PingReply reply;
+ using (Ping pingSender = new Ping())
+ {
+ address = IPAddress.Loopback;
+ int pingMsTimeout = cIobConf.PingMsTimeout;
+ IPAddress.TryParse(cIobConf.IpAddress, out address);
+ try
+ {
+ // se != null --> uso address...
+ if (address != null)
+ {
+ reply = pingSender.Send(address, pingMsTimeout);
+ }
+ else
+ {
+ reply = pingSender.Send(cIobConf.IpAddress, pingMsTimeout);
+ }
+ }
+ catch
+ {
+ reply = pingSender.Send(IPAddress.Loopback, pingMsTimeout);
+ }
+ answ = reply.Status;
+ }
+ }
+ return answ;
+ }
+ }
+ ///
+ /// indica se ping disabilitato da optPar
+ ///
+ public bool pingDisabled
+ {
+ get
+ {
+ bool answ = false;
+ bool.TryParse(confMan.GetValue("NO_PING"), out answ);
+ return answ;
+ }
+ }
+
+ #endregion Protected Properties
+
+ #region Protected Methods
+
+ ///
+ /// Stringa raw dei parametri da scrivere...
+ ///
+ ///
+ protected string getParams2write()
+ {
+ string answ = "";
+ // recuperare da una apposita area REDIS...
+#if false
+ string url2call = $"{urlGetParams2Write}";
+ if (verboseLog)
+ {
+ lgInfo("chiamata URL " + url2call);
+ }
+ answ = utils.callUrlNow(url2call);
+ // se vuoto faccio seconda prova...
+ if (string.IsNullOrEmpty(answ))
+ {
+ answ = utils.callUrlNow(url2call);
+ }
+#endif
+ return answ;
+ }
+
+ ///
+ /// Effettua logging DEBUG corretto impostanto anche la variabile IOB prima di scrivere...
+ ///
+ ///
+ protected void lgDebug(string message)
+ {
+ lg.Debug(message);
+ }
+
+ ///
+ /// Effettua logging DEBUG corretto impostanto anche la variabile IOB prima di scrivere...
+ ///
+ ///
+ ///
+ protected void lgDebug(string message, params object[] args)
+ {
+ lg.Debug(message, args);
+ }
+
+ ///
+ /// Effettua logging ERROR corretto impostanto anche la variabile IOB prima di scrivere...
+ ///
+ ///
+ protected void lgError(string message)
+ {
+ lg.Error(message);
+ }
+
+ ///
+ /// Effettua logging ERROR corretto impostanto anche la variabile IOB prima di scrivere...
+ ///
+ ///
+ ///
+ protected void lgError(string message, params object[] args)
+ {
+ lg.Error(message, args);
+ }
+
+ ///
+ /// Effettua logging ERROR corretto impostanto anche la variabile IOB prima di scrivere...
+ ///
+ ///
+ ///
+ ///
+ protected void lgError(Exception exception, string message, params object[] args)
+ {
+ lg.Error(exception, message, args);
+ }
+
+ ///
+ /// Effettua logging FATAL corretto impostanto anche la variabile IOB prima di scrivere...
+ ///
+ ///
+ protected void lgFatal(string message)
+ {
+ lg.Fatal(message);
+ }
+
+ ///
+ /// Effettua logging FATAL corretto impostanto anche la variabile IOB prima di scrivere...
+ ///
+ ///
+ ///
+ protected void lgFatal(string message, params object[] args)
+ {
+ lg.Fatal(message, args);
+ }
+
+ ///
+ /// Effettua logging FATAL corretto impostanto anche la variabile IOB prima di scrivere...
+ ///
+ ///
+ ///
+ ///
+ protected void lgFatal(Exception exception, string message, params object[] args)
+ {
+ lg.Fatal(exception, message, args);
+ }
+
+ ///
+ /// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere...
+ ///
+ ///
+ protected void lgInfo(string message)
+ {
+ lg.Info(message);
+ }
+
+ ///
+ /// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere...
+ ///
+ ///
+ ///
+ protected void lgInfo(string message, params object[] args)
+ {
+ lg.Info(message, args);
+ }
+
+ ///
+ /// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere...
+ ///
+ ///
+ protected void lgTrace(string message)
+ {
+ lg.Trace(message);
+ }
+
+ ///
+ /// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere...
+ ///
+ ///
+ ///
+ protected void lgTrace(string message, params object[] args)
+ {
+ lg.Trace(message, args);
+ }
+
+ ///
+ /// Metodo da overridare x scrivere DAVVERO i parametri sul PLC
+ ///
+ ///
+ protected virtual void plcWriteParams(ref List updatedPar)
+ {
+ // non faccio nulla di base...
+ }
+
+ ///
+ /// Processa le richieste di scrittura memoria
+ ///
+ ///
+ protected string processMemWriteRequests()
+ {
+ string answ = "";
+ // li salvo nei parametri in memoria locale (ogni adapter DOVREBBE salvare POI sul VERO PLC)
+ List writeList = new List();
+ List updatedPar = new List();
+ // recupero elenco delle cose da fare
+ string resp = getParams2write();
+ if (!string.IsNullOrEmpty(resp))
+ {
+ try
+ {
+ writeList = JsonConvert.DeserializeObject>(resp);
+ // se ho da fare chiamo esecuzione..
+ if (writeList.Count > 0)
+ {
+ foreach (var item in writeList)
+ {
+ // scrivo in memoria
+ if (memMap.mMapWrite.ContainsKey(item.uid))
+ {
+ memMap.mMapWrite[item.uid].value = item.reqValue;
+ // accodo in stringa taskVal...
+ answ += $" | Parameter {item.uid} --> {item.reqValue}";
+ // sistemo valori
+ item.value = item.reqValue;
+ lgInfo($"Richiesta update parametro {item.uid} | actVal = {item.value} | reqVal = {item.reqValue}");
+ item.reqValue = "";
+ // salvo in lista da ritrasmettere
+ updatedPar.Add(item);
+ }
+ else
+ {
+ answ += $" | Error: parameter {item.uid} not found";
+ }
+ }
+ // richiamo scrittura parametri su PLC
+ plcWriteParams(ref updatedPar);
+ // invio su cloud parametri!
+ string rawData = JsonConvert.SerializeObject(updatedPar);
+ lgInfo("Notifica a server scrittura parametri");
+#if false
+ utils.callUrl($"{urlUpdateWriteParams}", rawData);
+#endif
+ }
+ }
+ catch (Exception exc)
+ {
+ lgError($"Eccezione in processMemWriteRequests:{Environment.NewLine}{exc}");
+ }
+ }
+ else
+ {
+ lgError("Non è stata ricevuta risposta x task da eseguire");
+ }
+ return answ;
+ }
+
+ ///
+ /// setup parametri da file di conf
+ ///
+ protected void setupMemMap()
+ {
+ lgInfo($"setupMemMap | trovati {memMap.mMapRead.Count} parametri Read (TSVC)");
+ lgInfo($"setupMemMap | trovati {memMap.mMapWrite.Count} parametri Write");
+ if (confMan.GetValue("verbose"))
+ {
+ string rawMemConf = JsonConvert.SerializeObject(memMap, Formatting.Indented);
+ lgDebug($"setupMemMap | configurazione memoria R/W:{Environment.NewLine}{rawMemConf}");
+ }
+ // se ho variabili read --> genero dati TSVC...
+ if (memMap.mMapRead.Count > 0)
+ {
+ TSVC_Data.Clear();
+ LastTSVC.Clear();
+ VCData currConf;
+ int periodo = 0;
+ VC_func funz = VC_func.POINT;
+ // accodo nella conf...
+ foreach (var item in memMap.mMapRead)
+ {
+ funz = item.Value.func;
+ periodo = item.Value.period;
+ currConf = new VCData()
+ {
+ Funzione = funz,
+ Period = periodo,
+ DTStart = DateTime.Now.AddHours(-1),
+ dataArray = new List()
+ };
+ TSVC_Data.Add(item.Key, currConf);
+ }
+ // documento...
+ foreach (var item in TSVC_Data)
+ {
+ lgTrace($"TSVC: {item.Key} | periodo: {item.Value.Period} | funz: {item.Value.Funzione}");
+ // salvo i valori PREC...
+ LastTSVC.Add(item.Key, 0);
+ }
+ }
+ }
+
+ #endregion Protected Methods
+
+ #region Private Properties
+
+ internal string configPath { get; set; } = "";
+
+ internal IConfigurationRoot? confMan { get; set; } = null!;
+
+ #endregion Private Properties
+ }
+}
\ No newline at end of file
diff --git a/MP.MONO.ADAPTER.OLD/IobOpcUa.cs b/MP.MONO.ADAPTER.OLD/IobOpcUa.cs
new file mode 100644
index 0000000..6a0c2a9
--- /dev/null
+++ b/MP.MONO.ADAPTER.OLD/IobOpcUa.cs
@@ -0,0 +1,1342 @@
+using Microsoft.Extensions.Configuration;
+using MP.MONO.Core;
+using MP.MONO.Core.CONF;
+using Newtonsoft.Json;
+using NLog;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MP.MONO.ADAPTER
+{
+ ///
+ /// Classe di comunicazione OPC-UA
+ ///
+ public class IobOpcUa : IobGeneric
+ {
+ private Logger Log = LogManager.GetCurrentClassLogger();
+
+ ///
+ /// Avvia un oggetto IOB in grado di comunicare con server OPC-UA
+ /// Impiega il pacchetto Nuget OPC-UA foundation https://github.com/OPCFoundation/UA-.NETStandard
+ ///
+ ///
+ public IobOpcUa(string confPath, IConfigurationRoot? config) : base(confPath , config)
+ {
+
+ // gestione data filtering...
+ if (!string.IsNullOrEmpty(config.GetValue("ENABLE_DATA_FILTER")))
+ {
+ bool.TryParse(config.GetValue("ENABLE_DATA_FILTER"), out enableDataFilter);
+ }
+ // gestione restart OpcUa client...
+ if (!string.IsNullOrEmpty(config.GetValue("ENABLE_CLI_RESTART")))
+ {
+ bool.TryParse(config.GetValue("ENABLE_CLI_RESTART"), out enableCliRestart);
+ }
+ // init datetime counters
+ DateTime adesso = DateTime.Now;
+ lastCurrent = adesso;
+ // ora leggo il file di conf specifico....
+ string jsonFileName = config.GetValue("OPC_PARAM_CONF");
+ if (!string.IsNullOrEmpty(jsonFileName))
+ {
+ // leggo il file...
+ loadOpcUaConf(jsonFileName);
+ }
+ }
+
+
+ //#region Public Methods
+
+ ///
+ /// 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 = "";
+ // if (string.IsNullOrEmpty(diKey))
+ // {
+ // lgError($"Attenzione: richiesta chiave vuota in getDataItemValue{Environment.NewLine}StackTrace: {Environment.StackTrace}");
+ // }
+ // else
+ // {
+ // DateTime adesso = DateTime.Now;
+ // if (dataItemMem.Count == 0)
+ // {
+ // numErroriCheck++;
+ // if (vetoCheckStatus < adesso)
+ // {
+ // lgError($"Errore in getDataItemValue per {diKey} | dataItemMem NON contiene valori");
+ // // imposto veto per vetoSeconds...
+ // vetoCheckStatus = adesso.AddSeconds(vetoSeconds * 2);
+ // }
+ // }
+ // else
+ // {
+ // if (!dataItemMem.ContainsKey(diKey))
+ // {
+ // if (vetoCheckStatus < adesso)
+ // {
+ // lgError($"Errore in getDataItemValue per {diKey} | dataItemMem non contiene la chiave richiesta ma altri {dataItemMem.Count} valori");
+ // // imposto veto per vetoSeconds...
+ // vetoCheckStatus = adesso.AddSeconds(vetoSeconds * 2);
+ // }
+ // numErroriCheck++;
+ // }
+ // else
+ // {
+ // try
+ // {
+ // var currDataItem = dataItemMem[diKey];
+ // answ = currDataItem.value;
+ // }
+ // catch (Exception exc)
+ // {
+ // lgError($"Errore in getDataItemValue per {diKey} | dataItemMem contiene {dataItemMem.Count} valori {Environment.NewLine}{exc}");
+ // if (dataItemMem != null)
+ // {
+ // lgError($"dataItemMem contiene {dataItemMem.Count} valori");
+ // int maxNum = 5;
+ // foreach (var item in dataItemMem)
+ // {
+ // maxNum--;
+ // if (maxNum < 0)
+ // {
+ // break;
+ // }
+ // lgInfo($"{item.Key} --> {item.Value.DisplayName} = {item.Value.value}");
+ // }
+ // }
+ // }
+ // }
+ // }
+ // // se supero soglia errori lettura --> disconnetto e resetto
+ // if (numErroriCheck > maxErroriCheck)
+ // {
+ // lgInfo($"numErroriCheck: {numErroriCheck} --> richiesta disconnessione adapter con tryDisconnect");
+
+ // numErroriCheck = 0;
+ // tryDisconnect();
+ // }
+ // }
+
+ // return answ;
+ //}
+
+ /////
+ ///// Recupero dati dinamici...
+ /////
+ //public override Dictionary getDynData()
+ //{
+ // Dictionary outVal = new Dictionary();
+ // return outVal;
+ //}
+
+ /////
+ ///// Effettua vero processing contapezzi
+ /////
+ //public override void processContapezzi()
+ //{
+ // if (utils.CRB("enableContapezzi"))
+ // {
+ // // da ridefinire la gestione base del contapezzi OPC-UA...
+ // }
+ //}
+
+ /////
+ ///// 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;
+
+ // // verifico SE sia necessario forzare la lettura RAW
+ // if (doByteRead)
+ // {
+ // if (DateTime.Now.Subtract(lastCurrent).TotalSeconds > lastCurrentMaxElapsed)
+ // {
+ // // FIXME TODO !!!
+ // foreach (var item in dataItemMem)
+ // {
+ // // restituisce i 115 byte da deserializzare... qui HACK!
+ // var rawVal = UA_ref.ReadNodeRaw(item.Value.StartNodeId);
+ // if (rawVal != null)
+ // {
+ // byteRawData = getByteRaw((DataValue)rawVal);
+ // lastCurrent = DateTime.Now;
+ // currReadErrors = 0;
+ // }
+ // else
+ // {
+ // currReadErrors++;
+ // }
+ // }
+ // }
+ // }
+
+ // // decodifica e gestione
+ // decodeToBaseBitmap();
+ // reportRawInput(ref currDispData);
+ // }
+ // catch (Exception exc)
+ // {
+ // currDispData.semIn = Semaforo.SR;
+ // lgError($"Eccezione in readSemafori:{Environment.NewLine}{exc}");
+ // }
+ // // se > max errori --> disconnetto
+ // if (currReadErrors > maxReadErrors)
+ // {
+ // lgError($"Superato limite errori Read ({currReadErrors}) --> tryDisconnect");
+ // currReadErrors = 0;
+ // tryDisconnect();
+ // }
+ // else
+ // {
+ // // altrimenti pausa forzata
+ // Thread.Sleep(300);
+ // }
+ //}
+
+ /////
+ ///// Effettua reset del contapezzi, NON POSSIBILE in questa versione
+ /////
+ /////
+ //public override bool resetcontapezziPLC()
+ //{
+ // bool answ = false;
+ // return answ;
+ //}
+
+ /////
+ ///// Effettua IMPOSTAZIONE FORZATA del contapezzi, NON POSSIBILE in questa versione
+ /////
+ /////
+ //public override bool setcontapezziPLC(int newPzCount)
+ //{
+ // bool answ = false;
+ // return answ;
+ //}
+
+
+ ///
+ /// Verifica SE si debba fare log periodico (ogni "verboseLogTOut" sec...)
+ ///
+ public bool periodicLog
+ {
+ get
+ {
+ bool answ = false;
+ answ = (DateTime.Now.Subtract(lastPeriodicLog).TotalSeconds > confMan.GetValue("verboseLogTOut"));
+ if (answ)
+ {
+ lastPeriodicLog = DateTime.Now;
+ }
+
+ 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 > confMan.GetValue("pingTestSec"))
+ {
+ if (verboseLog || periodicLog)
+ {
+ lgInfo("OpcUa: ConnKO - tryConnect");
+ }
+ // in primis salvo data ping...
+ lastPING = DateTime.Now;
+ // se passa il ping faccio il resto...
+
+ // completare fixme todo !!!
+#if false
+ if (testPingMachine == IPStatus.Success)
+ {
+ string szStatusConnection = "";
+ try
+ {
+ // ora provo connessione...
+ parentForm.commPlcActive = true;
+ var task = Task.Run(async () =>
+ {
+ return await doConnect().ConfigureAwait(false);
+ });
+ short esitoLink = task.Result; // use returned result from async method here
+ lgInfo($"szStatusConnection OpcUa, 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 OpcUa: {szStatusConnection}{Environment.NewLine}{exc}");
+ connectionOk = false;
+ lgInfo($"Eccezione in TryConnect, Adapter OpcUa 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: OpcUa controllo PING fallito per IP {cIobConf.cncIpAddr}");
+ }
+ }
+#endif
+ }
+ }
+ else
+ {
+
+ // completare fixme todo !!!
+#if false
+ needRefresh = true;
+#endif
+ }
+ // se non è ancora connesso faccio procesisng memoria caso disconnesso...
+ if (!connectionOk)
+ {
+
+ // completare fixme todo !!!
+#if false
+ // processo semafori ed invio...
+ processMemoryDiscon();
+#endif
+ }
+ }
+
+ /////
+ ///// Override disconnessione
+ /////
+ //public override void tryDisconnect()
+ //{
+ // if (connectionOk)
+ // {
+ // if (UA_ref != null)
+ // {
+ // string szStatusConnection = "";
+ // try
+ // {
+ // UA_ref.Disconnect();
+ // connectionOk = false;
+ // lgInfo(szStatusConnection);
+ // lgInfo("Effettuata disconnessione adapter OpcUa!");
+ // }
+ // catch (Exception exc)
+ // {
+ // lgFatal(exc, "Errore nella disconnessione dall'adapter OpcUa");
+ // }
+ // }
+ // else
+ // {
+ // lgDebug("IMPOSSIBILE effettuare disconnessione OpcUa: UA_ref non disponibile...");
+ // }
+ // }
+ // else
+ // {
+ // lgError("IMPOSSIBILE effettuare disconnessione OpcUa: Connessione non disponibile...");
+ // }
+ //}
+
+ //#endregion Public Methods
+
+ //#region Internal Methods
+
+ /////
+ ///// Verifica ed invia variazioni
+ /////
+ /////
+ /////
+ /////
+ //internal bool checkAndSend(Opc.Ua.Client.MonitoredItem MonIt, string NotifyValue, bool forceSend)
+ //{
+ // bool changed = false;
+ // if (MonIt != null)
+ // {
+ // if (!string.IsNullOrEmpty(NotifyValue))
+ // {
+ // string sVal = "";
+ // string descr = "";
+ // DateTime locTStamp = DateTime.Now;
+ // descr = itemTranslation("OPC", MonIt.DisplayName);
+ // sVal = $"Change: {locTStamp.ToString()} | descr: {descr} | Id: {MonIt.StartNodeId} | Val: {NotifyValue}";
+ // lgInfo(sVal);
+
+ // // verifico se salvare
+ // changed = checkSaveValue(MonIt, NotifyValue, true);
+ // // cerco se non sia un dato filtrato in FLUXLOG...
+ // bool isFiltered = opcUaParams.fluxLogVeto.Contains(MonIt.DisplayName);
+ // if (isFiltered)
+ // {
+ // lgTrace($"NON ACCODATO sample per {MonIt.DisplayName} - trovato VETO in fluxLogVeto", false);
+ // }
+ // else
+ // {
+ // if (changed || forceSend)
+ // {
+ // accodaFLog(sVal, qEncodeFLog(descr, $"{NotifyValue}"));
+ // }
+ // else
+ // {
+ // lgTrace($"NON ACCODATO sample per {MonIt.DisplayName} - verifica variazione ha dato esito negativo", false);
+ // }
+ // }
+ // }
+ // else
+ // {
+ // lgError($"checkAndSend ERROR | MonIt: {MonIt.DisplayName} | NotifyValue Null!!!");
+ // }
+ // }
+ // else
+ // {
+ // lgError("checkAndSend ERROR: MonIt null");
+ // }
+ // return changed;
+ //}
+
+ /////
+ ///// Verifica ed invia variazioni DAL FORMATO RAW data (byte[])
+ /////
+ /////
+ /////
+ /////
+ //internal virtual bool checkAndSendRaw(Opc.Ua.Client.MonitoredItem MonIt, byte[] NotifyValue, bool forceSend)
+ //{
+ // bool changed = false;
+ // if (MonIt != null)
+ // {
+ // if (NotifyValue != null && NotifyValue.Length > 0)
+ // {
+ // // versione base: il valore è la stringa composta da TUTTI i valori in BYTE
+ // // espressi come comma-sep-string
+ // StringBuilder sb = new StringBuilder();
+ // foreach (var bVal in NotifyValue)
+ // {
+ // sb.Append($"{bVal},");
+ // }
+ // string currVal = sb.ToString();
+
+ // string sVal = "";
+ // string descr = "";
+ // DateTime locTStamp = DateTime.Now;
+ // descr = itemTranslation("OPC", MonIt.DisplayName);
+ // sVal = $"Change: {locTStamp.ToString()} | descr: {descr} | Id: {MonIt.StartNodeId} | Val: {currVal}";
+ // lgInfo(sVal);
+
+ // // verifico se salvare
+ // changed = checkSaveValue(MonIt, currVal, true) || forceSend;
+ // // cerco se non sia un dato filtrato in FLUXLOG...
+ // bool isFiltered = opcUaParams.fluxLogVeto.Contains(MonIt.DisplayName);
+ // if (isFiltered)
+ // {
+ // lgTrace($"NON ACCODATO sample per {MonIt.DisplayName} - trovato VETO in fluxLogVeto", false);
+ // }
+ // else
+ // {
+ // if (changed || forceSend)
+ // {
+ // accodaFLog(sVal, qEncodeFLog(descr, $"{NotifyValue}"));
+ // }
+ // else
+ // {
+ // lgTrace($"NON ACCODATO sample per {MonIt.DisplayName} - verifica variazione ha dato esito negativo", false);
+ // }
+ // }
+ // }
+ // else
+ // {
+ // lgError($"checkAndSend ERROR | MonIt: {MonIt.DisplayName} | NotifyValue Null!!!");
+ // }
+ // }
+ // else
+ // {
+ // lgError("checkAndSend ERROR: MonIt null");
+ // }
+ // return changed;
+ //}
+
+ //internal void sendDataItemListToServer(NodeId StartNodeId)
+ //{
+ // // converto gli attuali nell'elenco dataitem...
+ // List elencoDataItems = dataItemMem.Select(d => new machDataItem()
+ // {
+ // uuid = d.Key,
+ // Category = DataItemCategory.EVENT,
+ // Name = d.Value.DisplayName,
+ // Type = $"{d.Value.NodeClass}",
+ // SubType = $"{StartNodeId}"
+ // }
+ // ).ToList();
+
+ // lgInfo($"Richiesta sendDataItemListToServer per {elencoDataItems.Count} dataItems");
+ // // aspetta un tempo random da 10-100 ms...
+ // Random rnd = new Random();
+ // Task.Delay(rnd.Next(10, 100));
+ // // invio il dataItem serializzato...
+ // sendDataItemsList(elencoDataItems);
+ //}
+
+ /////
+ ///// Evento rilevazione modifica valori --> chiamo checkSend
+ /////
+ /////
+ /////
+ //internal virtual void UA_ref_eh_MonItChange(object sender, opcUaMonitItemChange e)
+ //{
+ // string currVal = "";
+ // // da verificare decodifica valore byte...
+ // if (doByteRead)
+ // {
+ // var currNot = e.CurrNotify;
+ // if (currNot != null)
+ // {
+ // byteRawData = getByteRaw((DataValue)currNot.Value);
+ // checkAndSendRaw(e.CurrMonitoredItem, byteRawData, false);
+ // }
+ // }
+ // else
+ // {
+ // currVal = $"{e.CurrNotify.Value}";
+ // checkAndSend(e.CurrMonitoredItem, currVal, false);
+ // }
+ // // aggiorno ultima lettura
+ // lastCurrent = DateTime.Now;
+ //}
+
+ //#endregion Internal Methods
+
+ //#region Protected Fields
+
+ /////
+ ///// Struttura dove vengono memorizzati i dataitem ed i rispettivi valori x processing
+ /////
+ //protected Dictionary dataItemMem = new Dictionary();
+
+ ///
+ /// Abilitazione restart (da opt par...)
+ ///
+ protected bool enableCliRestart = false;
+
+ ///
+ /// Gestione filtraggio dati
+ ///
+ protected bool enableDataFilter = 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 UAClient UA_ref;
+
+ /////
+ ///// Veto controllo status x log...
+ /////
+ //protected DateTime vetoCheckStatus = DateTime.Now;
+
+ //protected int WatchDog = 0;
+
+ //#endregion Protected Fields
+
+ //#region Protected Properties
+
+ /////
+ ///// Area dati raw per lettura encoded (SE presente)
+ /////
+ //protected byte[] byteRawData { get; set; } = new byte[1];
+
+ /////
+ ///// Indica se si debba leggere un area di tipo "encoded" (byte raw --> obj)
+ /////
+ //protected bool doByteRead { get; set; } = false;
+
+ /////
+ ///// Verifico se abbia ALMENO un errore...
+ /////
+ //protected bool hasError
+ //{
+ // get
+ // {
+ // return checkMultiCondition(opcUaParams.condError);
+ // }
+ //}
+
+ /////
+ ///// Indica se abbia emergenza ARMATA (cond normale)
+ /////
+ //protected bool hasEStopArmed
+ //{
+ // get
+ // {
+ // return checkMultiCondition(opcUaParams.condEStop);
+ // }
+ //}
+
+ /////
+ ///// Indica se abbia stato POWER ON (multicondizione)
+ /////
+ //protected virtual bool hasPowerOn
+ //{
+ // get
+ // {
+ // return checkMultiCondition(opcUaParams.condPowerOn);
+ // }
+ //}
+
+ /////
+ ///// Indica se abbia stato MANUAL (condizioni varie, es stopped)
+ /////
+ //protected virtual bool isManual
+ //{
+ // get
+ // {
+ // return checkMultiCondition(opcUaParams.condManual);
+ // }
+ //}
+
+ /////
+ ///// Indica se abbia stato READY (condizioni varie, es ausiliari OK)
+ /////
+ //protected virtual bool isReady
+ //{
+ // get
+ // {
+ // return checkMultiCondition(opcUaParams.condReady);
+ // }
+ //}
+
+ /////
+ ///// Indica se sia in stato Ssetup
+ /////
+ //protected bool isSetup
+ //{
+ // get
+ // {
+ // return checkMultiCondition(opcUaParams.condSetup);
+ // }
+ //}
+
+ /////
+ ///// Indica se sia in stato WarmUp / CoolDown (riscaldamento/raffreddamento)
+ /////
+ //protected bool isWarmUpCoolDown
+ //{
+ // get
+ // {
+ // return checkMultiCondition(opcUaParams.condWarmUpCoolDown);
+ // }
+ //}
+
+ /////
+ ///// Indica se sia in stato Warning
+ /////
+ //protected bool isWarning
+ //{
+ // get
+ // {
+ // return checkMultiCondition(opcUaParams.condWarning);
+ // }
+ //}
+
+ /////
+ ///// Indica se abbia stato READY (condizioni varie, es ausiliari OK)
+ /////
+ //protected bool isWorking
+ //{
+ // get
+ // {
+ // // cerco SE HO cond OPC Ua o classica... nel caso creo e salvo
+ // if (opcUaParams.condWorkOpc.checkList == null || opcUaParams.condWorkOpc.checkList.Count == 0)
+ // {
+ // opcUaParams.condWorkOpc = new diCheckCondSetup()
+ // {
+ // checkList = opcUaParams.condWork,
+ // checkMode = boolCheckMode.AND,
+ // negateValue = false
+ // };
+ // }
+ // return checkMultiCondition(opcUaParams.condWorkOpc);
+ // }
+ //}
+
+ /////
+ ///// Periodo massimo (in sec) per letture dati RAW in mancanza di eventi
+ /////
+ //protected int lastCurrentMaxElapsed { get; set; } = 120;
+
+ ///
+ /// Parametri specifici MTC
+ ///
+ protected OpcUaParamConf opcUaParams { get; set; }
+
+ /////
+ ///// URL x salvataggio elenco dataItems OpcUa
+ /////
+ //protected string urlSaveDataItems
+ //{
+ // get
+ // {
+ // string answ = "";
+ // try
+ // {
+ // string machineName = Environment.MachineName;
+ // answ = $@"{cIobConf.serverData.TRANSP}://{cIobConf.serverData.MPIP}{cIobConf.serverData.MPURL}{cIobConf.serverData.CMDALIVE}/saveDataItems/{cIobConf.codIOB}";
+ // }
+ // catch (Exception exc)
+ // {
+ // lgError(exc, "Errore in composizione urlSaveDataItems");
+ // }
+ // return answ;
+ // }
+ //}
+
+ //#endregion Protected Properties
+
+ //#region Protected Methods
+
+ /////
+ ///// 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;
+ // OpcUaDataItemExt 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;
+ //}
+
+ /////
+ ///// Verifica condizione "multipla" secondo setup json
+ /////
+ ///// Set condizioni da validare
+ /////
+ //protected bool checkMultiCondition(diCheckCondSetup reqCondition)
+ //{
+ // bool answ = false;
+ // int numCondOk = 0;
+ // int numCond = 0;
+ // if (reqCondition.checkList != null && reqCondition.checkList.Count > 0)
+ // {
+ // numCond = reqCondition.checkList.Count;
+ // // cerco nell'elenco delle condizioni che indicano lavora se sono ok faccio +1 conteggio......
+ // foreach (var item in reqCondition.checkList)
+ // {
+ // if (string.IsNullOrEmpty(item.keyName))
+ // {
+ // lgError($"Attenzione: item vuoto in checkMultiCondition{Environment.NewLine}StackTrace: {Environment.StackTrace}");
+ // }
+ // else
+ // {
+ // if (getDataItemValue(item.keyName) == item.targetValue)
+ // {
+ // numCondOk++;
+ // }
+ // }
+ // }
+ // if (reqCondition.checkMode == boolCheckMode.AND)
+ // {
+ // answ = (numCond == numCondOk);
+ // }
+ // else if (reqCondition.checkMode == boolCheckMode.OR)
+ // {
+ // answ = numCondOk > 0;
+ // }
+ // }
+ // else
+ // {
+ // answ = true;
+ // }
+ // // verifico se devo negare il valore...
+ // answ = reqCondition.negateValue ? !answ : answ;
+ // // restituisco
+ // return answ;
+ //}
+
+ /////
+ ///// Verifica / Salva valore e restitusice SE sia variato (e quindi da inviare...)
+ /////
+ /////
+ /////
+ /////
+ /////
+ //protected bool checkSaveValue(Opc.Ua.Client.MonitoredItem dataItem, string NotifyValue, bool sendItemList)
+ //{
+ // bool answ = !enableDataFilter;
+ // double oldVal = 0;
+ // double newVal = 0;
+ // if (dataItem != null)
+ // {
+ // if (!string.IsNullOrEmpty(NotifyValue))
+ // {
+ // lgTrace($"Richiesta checkSaveValue per {dataItem.DisplayName} | id: {dataItem.StartNodeId} | Valore: {NotifyValue}");
+ // // verifico in memoria se ho l'oggetto condition ed il suo valore..
+ // string uuid = $"{dataItem.DisplayName}";
+ // DateTime adesso = DateTime.Now;
+ // if (dataItemMem.ContainsKey(uuid))
+ // {
+ // OpcUaDataItemExt currDataItemMem = dataItemMem[uuid];
+ // // controllo SE SIA scaduto il tempo massimo...
+ // if (Math.Abs(dataItemMem[uuid].valueTimestamp.Subtract(adesso).TotalSeconds) > currDataItemMem.samplePeriod)
+ // {
+ // answ = true;
+ // }
+ // else
+ // {
+ // // ALTRIMENTI controllo SE diverso
+ // if (dataItemMem[uuid].value != $"{NotifyValue}")
+ // {
+ // lgInfo($"Val uuid: {dataItemMem[uuid].value} | NotifyValue: {NotifyValue}");
+ // // controllo SE ho DeadBand...
+ // if (dataItemMem[uuid].thresholdDeadBand > 0)
+ // {
+ // // recupero i valori e testo DeadBand...
+ // bool isNum01 = double.TryParse(dataItemMem[uuid].value.Replace(".", ","), out oldVal);
+ // bool isNum02 = double.TryParse($"{NotifyValue}".Replace(".", ","), out newVal);
+ // // test deadband!
+ // if (!(isNum01 && isNum02))
+ // {
+ // answ = true;
+ // }
+ // else
+ // {
+ // if (Math.Abs(newVal - oldVal) > dataItemMem[uuid].thresholdDeadBand)
+ // {
+ // // indico da salvare..
+ // answ = true;
+ // }
+ // }
+ // lgInfo($"Test deadband: oldVal: {oldVal} | newVal: {newVal}");
+ // }
+ // }
+ // }
+ // if (answ)
+ // {
+ // // salvo!
+ // dataItemMem[uuid].value = $"{NotifyValue}";
+ // dataItemMem[uuid].valueTimestamp = adesso;
+ // }
+ // }
+ // else
+ // {
+ // // registro non trovato da aggiungere...
+ // lgInfo($"DataItem non trovato in checkSaveValue: {dataItem.DisplayName}");
+ // // provo a creare oggetto in memoria...
+ // try
+ // {
+ // int dSamplePeriod = 0;
+ // int threshDBand = 0;
+ // uuid = "";
+ // var currDataItem = formatDataItem(ref dSamplePeriod, ref threshDBand, ref uuid, dataItem);
+ // // sistemo valore/periodo
+ // currDataItem.value = $"{NotifyValue}";
+ // currDataItem.valueTimestamp = adesso;
+ // // aggiungo
+ // dataItemMem.Add(uuid, currDataItem);
+ // if (sendItemList)
+ // {
+ // sendDataItemListToServer(dataItem.StartNodeId);
+ // }
+ // }
+ // catch (Exception exc)
+ // {
+ // lgError($"Eccezione in checkSaveSample{Environment.NewLine}{exc}");
+ // }
+ // }
+ // }
+ // else
+ // {
+ // lgError("Attenzione: checkSaveItem con Notify null!");
+ // }
+ // }
+ // else
+ // {
+ // lgError("Attenzione: checkSaveItem con MonIt null!");
+ // }
+ // return answ;
+ //}
+
+ /////
+ ///// Effettua decodifica aree memoria alla bitmap usata x MAPO
+ /////
+ //protected virtual void decodeToBaseBitmap()
+ //{
+ // DateTime adesso = DateTime.Now;
+ // // init a zero...
+ // B_input = 0;
+
+ // /* -----------------------------------------------------
+ // * STATE MACHINE 60 STD / SIMULA
+ // *------------------------------------------------------
+ // * bitmap MAPO
+ // * B0: POWER_ON
+ // * B1: RUN
+ // * B2: pzCount
+ // * B3: allarme
+ // * B4: manuale
+ // * B5: SlowTC (NON gestito qui)
+ // * B6: warm-up / cool-down
+ // * B7: emergenza
+ // ---------------------------------------------------- */
+
+ // // se valido il check ping lo eseguo... altrimenti lo do x buono
+ // bool checkPing = !opcUaParams.pingAsPowerOn;
+ // string currRun = "";
+ // if (!checkPing)
+ // {
+ // checkPing = (testPingMachine == IPStatus.Success);
+ // }
+ // // bit 0 (poweron) imposto a 1 SE pingo + PowerOn=="ON"...
+ // bool powerOnOk = checkPing && hasPowerOn;
+
+ // // controllo se sono poweroff e se non ho dati buoni da > lastCurrentMaxElapsed --> disconnetto
+ // if (!powerOnOk && adesso.Subtract(lastCurrent).TotalSeconds > lastCurrentMaxElapsed)
+ // {
+ // tryDisconnect();
+ // }
+
+ // // solo se non ho veto check
+ // int vFactor = 2;
+ // if (vetoCheckStatus < adesso)
+ // {
+ // lgTrace($"Stato variabili checkPing: {testPingMachine}");
+ // // imposto veto per vetoSeconds...
+ // vetoCheckStatus = adesso.AddSeconds(vetoSeconds * vFactor);
+ // }
+
+ // // se abilitato watchdog...
+ // if (opcUaParams.WatchDog.IsEnabled)
+ // {
+ // lgTrace("WatchDog 01");
+ // if (adesso.Subtract(lastWatchDogPLC).TotalSeconds > 2)
+ // {
+ // lastWatchDogPLC = adesso;
+ // WatchDog++;
+ // WatchDog = WatchDog > opcUaParams.WatchDog.MaxVal ? 0 : WatchDog;
+
+ // lgTrace($"WatchDog val: {WatchDog}");
+ // try
+ // {
+ // WriteValue commWriteVal = new WriteValue();
+ // commWriteVal.NodeId = new NodeId(opcUaParams.WatchDog.MemConfWrite);
+ // commWriteVal.AttributeId = Attributes.Value;
+ // commWriteVal.Value = new DataValue();
+ // commWriteVal.Value.Value = WatchDog;
+
+ // List nodes2Write = new List();
+ // nodes2Write.Add(commWriteVal);
+ // UA_ref.WriteNodes(nodes2Write);
+ // lgTrace("Effettuata scrittura WatchDog");
+ // }
+ // catch (Exception exc)
+ // {
+ // lgError($"Eccezione in gestione WatchDog, valore attuale {WatchDog}{Environment.NewLine}{exc}");
+ // }
+ // }
+ // }
+ // else
+ // {
+ // lgTrace("WatchDog disabilitato");
+ // }
+
+ // // log opzionale!
+ // if (verboseLog)
+ // {
+ // lgDebug($"Trasformazione checkPing: {checkPing} | hasPowerOn: {hasPowerOn} | B_input: {B_input} | currRun = {currRun}");
+ // }
+ //}
+
+ //protected byte[] getByteRaw(DataValue obj)
+ //{
+ // if (obj == null)
+ // return null;
+
+ // byte[] rawByte = new byte[1];
+ // if (obj != null)
+ // {
+ // try
+ // {
+ // var wrapVal = ((DataValue)obj).WrappedValue;
+ // //rawByte = ObjectToByteArray(rawVal);
+ // var bodyVal = ((Opc.Ua.ExtensionObject)wrapVal.Value).Body;
+ // rawByte = (byte[])bodyVal;
+ // }
+ // catch
+ // { }
+ // }
+ // return rawByte;
+ //}
+
+ /////
+ ///// 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 = id;
+ // if (!string.IsNullOrEmpty(tipo))
+ // {
+ // lemma = $"{tipo}_{id}";
+ // }
+ // // cerco nel dizionario delle traduzioni SE esiste un valore e prendo quello, altrimenti
+ // // uso il lemma...
+ // if (opcUaParams.itemTranslation.ContainsKey(lemma))
+ // {
+ // answ = opcUaParams.itemTranslation[lemma];
+ // }
+ // else
+ // {
+ // answ = lemma;
+ // }
+ // return answ;
+ //}
+
+ ///
+ /// Effettua lettura file di conf specifico OPC-UA da oggetto serializzato json Nome file da cui leggere i parametri json
+ ///
+ protected void loadOpcUaConf(string fileName)
+ {
+ string jsonFullPath = Path.Combine(configPath, fileName);
+ lgInfo($"Apertura file {jsonFullPath}");
+ using (StreamReader reader = new StreamReader(jsonFullPath))
+ {
+ string jsonData = reader.ReadToEnd().Replace("\n", "").Replace("\r", "");
+ if (!string.IsNullOrEmpty(jsonData))
+ {
+ lgDebug($"File json composto da {jsonData.Length} caratteri");
+ try
+ {
+ opcUaParams = JsonConvert.DeserializeObject(jsonData);
+ lgDebug($"Decodifica aree OpcUaParamConf: trovati {opcUaParams.paramsEndThresh.Count} valori paramsEndThresh");
+ // sistemo se ci sono dati memMap...
+ memMap = new plcMemMap();
+ if (opcUaParams.mMapWrite != null)
+ {
+ memMap.mMapWrite = opcUaParams.mMapWrite;
+ }
+ if (opcUaParams.mMapRead != null)
+ {
+ memMap.mMapRead = opcUaParams.mMapRead;
+ }
+ setupMemMap();
+ }
+ catch (Exception exc)
+ {
+ lgError($"Eccezione in decodifica conf json OPC-UA:{Environment.NewLine}{exc}");
+ }
+ }
+ else
+ {
+ lgError("Errore in loadOpcUaConf: file json vuoto!");
+ }
+ }
+ }
+
+ //#endregion Protected Methods
+
+ //#region Private Fields
+
+ /////
+ ///// Elenco degli items da monitorare come risultato del browse iniziale
+ /////
+ //private Dictionary selectedItemList = new Dictionary();
+
+ //#endregion Private Fields
+
+ //#region Private Methods
+
+ /////
+ ///// Vera connessione ad OpcUa
+ /////
+ /////
+ //private async Task doConnect()
+ //{
+ // short esitoLink = 0;
+ // // reset memoria dataItem..
+ // dataItemMem = new Dictionary();
+ // // predisposizione conf oggetto di comunicazione MTC
+ // int port = 4840;
+ // int.TryParse(cIobConf.cncPort, out port);
+ // // ora avvio
+ // try
+ // {
+ // lgInfo("Start init OpcUa Client");
+ // // Define the UA Client application
+ // ApplicationInstance application = new ApplicationInstance();
+ // application.ApplicationName = "Steamware IOB-WIN Client";
+ // application.ApplicationType = ApplicationType.Client;
+
+ // // load the application configuration.
+ // string confPath = $"{Application.StartupPath}\\DATA\\CONF\\IobOpcUaClient.Config.xml";
+ // await application.LoadApplicationConfiguration(confPath, silent: false).ConfigureAwait(false);
+ // // check the application certificate.
+ // await application.CheckApplicationInstanceCertificate(silent: false, minimumKeySize: 0).ConfigureAwait(false);
+
+ // lgInfo($"Chiamata UAClient con configurazione standard: {application.ApplicationConfiguration.ApplicationName}");
+ // UA_ref = new UAClient(application.ApplicationConfiguration, cIobConf.codIOB, opcUaParams.Identity.UserName, opcUaParams.Identity.Passwd, isVerboseLog, ClientBase.ValidateResponse);
+
+ // lgInfo($"Chiamata apertura OpcUa Client: {cIobConf.cncIpAddr}:{port}");
+ // UA_ref.ServerUrl = $"opc.tcp://{cIobConf.cncIpAddr}:{port}";
+
+ // var task = Task.Run(async () =>
+ // {
+ // return await UA_ref.ConnectAsync().ConfigureAwait(false);
+ // });
+ // bool connected = task.Result;
+ // if (connected)
+ // {
+ // // faccio un primo browse dei dati...
+ // Dictionary nodeIdNameList = new Dictionary();
+ // if (!string.IsNullOrEmpty(opcUaParams.BrowseFullVal))
+ // {
+ // try
+ // {
+ // UA_ref.Browse(opcUaParams.BrowseFullVal, opcUaParams.filterItemsNodeId, ref nodeIdNameList);
+ // }
+ // catch
+ // { }
+ // }
+ // else
+ // {
+ // UA_ref.Browse(opcUaParams.BrowseNSIndex, opcUaParams.BrowseValue, opcUaParams.filterItemsNodeId, ref nodeIdNameList);
+ // }
+ // // loggo elenco degli item sottocrivibili...
+ // lgDebug("---------- AVAILABLE FOR SUBSCRIBE ----------");
+ // foreach (var item in nodeIdNameList)
+ // {
+ // lgDebug(item.Key);
+ // }
+ // lgDebug("---------- END LIST ----------");
+
+ // // se ho un insieme non vuoto degli item sottoscritti carico solo quelli
+ // if (opcUaParams.subscribedItems != null && opcUaParams.subscribedItems.Count > 0)
+ // {
+ // // cerco e aggiungo SOLO quelle indicati
+ // foreach (var currItem in opcUaParams.subscribedItems)
+ // {
+ // var foundItems = nodeIdNameList.Where(x => x.Key.Contains(currItem)).ToList();
+ // if (foundItems != null && foundItems.Count > 0)
+ // {
+ // foreach (var fItem in foundItems)
+ // {
+ // // verifico di NON duplicare...
+ // if (!selectedItemList.ContainsKey(fItem.Key))
+ // {
+ // selectedItemList.Add(fItem.Key, fItem.Value);
+ // }
+ // }
+ // }
+ // else
+ // {
+ // lgDebug($"subscribedItems non trovato: {currItem}");
+ // }
+ // }
+ // lgDebug($"Aggiunti {selectedItemList.Count} items!");
+ // }
+ // // altrimenti tutti!
+ // else
+ // {
+ // selectedItemList = nodeIdNameList;
+ // }
+
+ // // loggo elenco degli item sottocrivibili...
+ // lgInfo("---------- SUBSCRIBED NODES ----------");
+ // foreach (var item in selectedItemList)
+ // {
+ // lgInfo(item.Key);
+ // }
+ // lgInfo("---------- END LIST ----------");
+
+ // // sottoscrivo a rilevazione cambio dati solo l'incrocio degli insiemi
+ // List subscribedItems = UA_ref.SubscribeToDataChanges(selectedItemList);
+ // // aggiungo come DataItems
+ // int dSamplePeriod = 0;
+ // int threshDBand = 0;
+ // string uuid = "";
+ // foreach (var item in subscribedItems)
+ // {
+ // bool changed = false;
+ // OpcUaDataItemExt newItem = formatDataItem(ref dSamplePeriod, ref threshDBand, ref uuid, item);
+ // // controllo non sia già stato aggiunto
+ // if (dataItemMem.ContainsKey(uuid))
+ // {
+ // lgDebug($"Item ALREADY subscribed: {uuid} | NOT re-adding");
+ // }
+ // else
+ // {
+ // dataItemMem.Add(uuid, newItem);
+ // lgDebug($"Item subscribed: {uuid}");
+ // // verifico se ho i dati complessi by design
+ // string currVal = "";
+ // if (doByteRead)
+ // {
+ // // restituisce i 115 byte da deserializzare... qui HACK!
+ // var rawVal = UA_ref.ReadNodeRaw(item.StartNodeId);
+ // if (rawVal != null)
+ // {
+ // byteRawData = getByteRaw((DataValue)rawVal);
+ // changed = checkAndSendRaw(item, byteRawData, true);
+ // }
+ // }
+ // else
+ // {
+ // currVal = UA_ref.ReadNode(item.StartNodeId);
+ // changed = checkAndSend(item, currVal, true);
+ // }
+ // }
+ // }
+ // // gestione eventi change
+ // UA_ref.eh_MonItChange += UA_ref_eh_MonItChange;
+ // lgInfo("eh_MonItChange event registered");
+ // }
+
+ // esitoLink = 1;
+
+ // // fix tempi!
+ // DateTime adesso = DateTime.Now;
+ // lastPzCountSend = adesso;
+ // lastWarnODL = adesso;
+ // lastCurrent = adesso;
+ // }
+ // catch (Exception exc)
+ // {
+ // lgError($"Eccezione in doConnect{Environment.NewLine}{exc}");
+ // }
+ // return esitoLink;
+ //}
+
+ /////
+ ///// Formatta un dataitem x salvataggio in memoria locale
+ /////
+ /////
+ /////
+ /////
+ /////
+ /////
+ //private OpcUaDataItemExt formatDataItem(ref int dSamplePeriod, ref int threshDBand, ref string uuid, Opc.Ua.Client.MonitoredItem dataItem)
+ //{
+ // OpcUaDataItemExt currDataItem;
+ // // calcolo parametri
+ // uuid = $"{dataItem.DisplayName}";
+ // // SOLO SE è abilitato il datafiltering...
+ // if (enableDataFilter)
+ // {
+ // threshDBand = 1;
+ // // controllo SE ho conf x deadband...
+ // if (opcUaParams.paramsEndThresh.Count > 0)
+ // {
+ // // ciclo su tutti i parametri indicati...
+ // foreach (var item in opcUaParams.paramsEndThresh)
+ // {
+ // if (uuid.EndsWith(item.Key))
+ // {
+ // threshDBand = item.Value;
+ // }
+ // }
+ // }
+ // }
+ // else
+ // {
+ // threshDBand = 0;
+ // }
+ // dSamplePeriod = 60;
+
+ // // salvo oggetto x "uso interno"
+ // currDataItem = new OpcUaDataItemExt(dataItem)
+ // {
+ // uid = uuid,
+ // thresholdDeadBand = threshDBand,
+ // samplePeriod = dSamplePeriod
+ // };
+
+ // return currDataItem;
+ //}
+
+ /////
+ ///// Effettua invio a MP/IO dell'elenco serializzato dei dataItems
+ /////
+ /////
+ //private void sendDataItemsList(List dataItems)
+ //{
+ // string rawData = JsonConvert.SerializeObject(dataItems);
+ // try
+ // {
+ // utils.callUrlNow($"{urlSaveDataItems}", rawData);
+ // lgInfo($"Effettuata chiamata sendDataItemsList all'url {urlSaveDataItems}");
+ // }
+ // catch (Exception exc)
+ // {
+ // lgError($"Eccezione in sendDataItemsList{Environment.NewLine} - url: {urlSaveDataItems}{Environment.NewLine}- payload:{rawData}{Environment.NewLine}Eccezione:{Environment.NewLine}{exc}");
+ // }
+ //}
+
+ //#endregion Private Methods
+
+ }
+}
diff --git a/MP.MONO.ADAPTER.OLD/MP.MONO.ADAPTER.OLD.csproj b/MP.MONO.ADAPTER.OLD/MP.MONO.ADAPTER.OLD.csproj
new file mode 100644
index 0000000..3531e0d
--- /dev/null
+++ b/MP.MONO.ADAPTER.OLD/MP.MONO.ADAPTER.OLD.csproj
@@ -0,0 +1,59 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+ 1.12206.1410
+
+
+
+
+
+
+
+
+ PreserveNewest
+ true
+ PreserveNewest
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+
+
+
+
diff --git a/MP.MONO.ADAPTER.OLD/Program.cs b/MP.MONO.ADAPTER.OLD/Program.cs
new file mode 100644
index 0000000..5795497
--- /dev/null
+++ b/MP.MONO.ADAPTER.OLD/Program.cs
@@ -0,0 +1,291 @@
+using Microsoft.Extensions.Configuration;
+using MP.MONO.ADAPTER;
+using MP.MONO.Core;
+using MP.MONO.Core.CONF;
+using MP.MONO.Core.DTO;
+using Newtonsoft.Json;
+using NLog;
+using StackExchange.Redis;
+
+// init parte config, vedere https://blog.hildenco.com/2020/05/configuration-in-net-core-console.html
+var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
+var builder = new ConfigurationBuilder()
+ .AddJsonFile($"appsettings.json", true, true)
+ .AddJsonFile($"appsettings.{env}.json", true, true)
+ .AddEnvironmentVariables();
+var config = builder.Build();
+
+// imposto variabili di base
+string lineSep = "---------------------------------------------";
+string redisConf = config.GetConnectionString("Redis");
+string confPath = Path.Combine(Directory.GetCurrentDirectory(), "conf");
+#if false
+string alarmSimMode = config.GetValue("AlarmSimMode");
+#endif
+Logger Log = LogManager.GetCurrentClassLogger();
+Random rand = new Random();
+List? statusList = new List();
+List? modeList = new List();
+
+// fix numero minimo dei thread pool x evitare collasso chiamate redis
+ThreadPool.SetMinThreads(10, 10);
+
+Dictionary LogSimulator = new Dictionary();
+Dictionary LastSend = new Dictionary();
+DateTime lastLog = DateTime.Now.AddMinutes(-1);
+bool verboseLog = false;
+bool logWriting = false;
+
+logInfo(lineSep, true, true);
+logInfo($"Starting Machine ADAPTER", true, true);
+logInfo($"Redis server param: {redisConf.Substring(0, 20)}...", false, true);
+logInfo(lineSep, true, true);
+logInfo("", true, true);
+logInfo("Running - press CTRL-C to stop SIM", false, true);
+logInfo("", false, true);
+
+// Setup REDIS
+ConnectionMultiplexer.SetFeatureFlag("preventthreadtheft", true);
+ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(redisConf);
+ISubscriber sub = redis.GetSubscriber();
+IDatabase? redisDb = redis.GetDatabase();
+
+// salvo configurazioni in redis
+setupConf();
+
+// avvio il vero e proprio programma di comunicaizone OPC-UA
+var currIob = new IobOpcUa(confPath, config);
+
+#if false
+var currSimGen = new Simulator(confPath, modeList.Count, statusList.Count);
+
+// preparo la lista dei contatori invio...
+LogSimulator.Add(Constants.ACT_LOG_M_QUEUE, 0);
+LogSimulator.Add(Constants.ALARM_M_QUEUE, 0);
+LogSimulator.Add(Constants.EVENT_LOG_M_QUEUE, 0);
+LogSimulator.Add(Constants.PARAMS_M_QUEUE, 0);
+LogSimulator.Add(Constants.PROD_M_QUEUE, 0);
+LogSimulator.Add(Constants.MACH_STATS_M_QUEUE, 0);
+LogSimulator.Add(Constants.MAINT_STATS_M_QUEUE, 0);
+LogSimulator.Add(Constants.TOOLS_M_QUEUE, 0);
+
+// avvio tutti i thread...
+Thread threadStatus = new Thread(simStatus);
+Thread threadAlarms = new Thread(simAlarms);
+Thread threadParams = new Thread(simParameters);
+Thread threadProd = new Thread(simProd);
+Thread threadMachStat = new Thread(simMachStat);
+Thread threadMaint = new Thread(simMaint);
+Thread threadTools = new Thread(simTools);
+Thread threadEvHistory = new Thread(simEvents);
+Thread threadActLog = new Thread(simActivityLog);
+
+threadStatus.Start();
+threadAlarms.Start();
+threadParams.Start();
+threadProd.Start();
+threadMachStat.Start();
+threadMaint.Start();
+threadTools.Start();
+threadEvHistory.Start();
+threadActLog.Start();
+#endif
+
+// Ciclo infinito x attesa chiusura con CTRL-C
+do
+{
+ // se non fosse connesso... riprovo la connessione...
+ if (!currIob.connectionOk)
+ {
+ currIob.tryConnect();
+ }
+ // attesa...
+ Thread.Sleep(100);
+} while (true);
+
+
+///
+/// verifica esistenza file oppure lo crea...
+///
+void checkFilePresent(string filePath)
+{
+ // verific presenza file log...
+ if (!File.Exists(filePath))
+ {
+ File.WriteAllText(filePath, $"{filePath} created!");
+ }
+}
+
+///
+/// Setup e salvataggio redis delle conf (es modi/stati)
+///
+void setupConf()
+{
+#if false
+ // leggo e salvo conf stati
+ string fullPath = Path.Combine(confPath, "StatusList.json");
+ if (File.Exists(fullPath))
+ {
+ var rawData = File.ReadAllText(fullPath);
+ if (!string.IsNullOrEmpty(rawData))
+ {
+ List? statusList = JsonConvert.DeserializeObject>(rawData);
+ // salvo in redis!
+ redisDb.StringSetAsync(Constants.STATUS_CONF_KEY, JsonConvert.SerializeObject(statusList));
+ }
+ }
+
+ // leggo e salvo conf modi
+ fullPath = Path.Combine(confPath, "ModeList.json");
+ if (File.Exists(fullPath))
+ {
+ var rawData = File.ReadAllText(fullPath);
+ if (!string.IsNullOrEmpty(rawData))
+ {
+ var localObj = JsonConvert.DeserializeObject>(rawData);
+ // salvo in redis!
+ redisDb.StringSetAsync(Constants.MODE_CONF_KEY, JsonConvert.SerializeObject(localObj));
+ }
+ }
+
+ // leggo e salvo conf allarmi
+ fullPath = Path.Combine(confPath, "AlarmList.json");
+ if (File.Exists(fullPath))
+ {
+ var rawData = File.ReadAllText(fullPath);
+ if (!string.IsNullOrEmpty(rawData))
+ {
+ var localObj = JsonConvert.DeserializeObject>(rawData);
+ if (localObj != null)
+ {
+ // sistemo allarmi
+ foreach (var item in localObj)
+ {
+ item.setupData();
+ // loggo
+ logInfo($"Decodifica aree alarmMap: {item.description} | {item.memAddr} x {item.size} byte | {item.messages.Count} messaggi allarme", true, true);
+ }
+ }
+ // salvo in redis!
+ redisDb.StringSetAsync(Constants.ALARMS_CONF_KEY, JsonConvert.SerializeObject(localObj));
+ }
+ }
+
+ // leggo e salvo conf parametri
+ fullPath = Path.Combine(confPath, "ParamList.json");
+ if (File.Exists(fullPath))
+ {
+ var rawData = File.ReadAllText(fullPath);
+ if (!string.IsNullOrEmpty(rawData))
+ {
+ var localObj = JsonConvert.DeserializeObject>(rawData);
+ // salvo in redis!
+ redisDb.StringSetAsync(Constants.PARAMS_CONF_KEY, JsonConvert.SerializeObject(localObj));
+ }
+ }
+#endif
+
+ ConfigManager configManager = new ConfigManager(redisConf, confPath);
+ _ = configManager.getAlarmsConf();
+ _ = configManager.getMachineModeConf();
+ _ = configManager.getMachineStatusConf();
+ _ = configManager.getParamsConf();
+}
+
+///
+/// Effettua log INFO su file e se richiesto su console
+///
+void logInfo(string msg, bool log2file = true, bool log2console = false)
+{
+ if (log2console)
+ {
+ Console.WriteLine(msg);
+ }
+ if (log2file)
+ {
+ Log.Info(msg);
+ }
+}
+///
+/// Effettua log ERROR su file e se richiesto su console
+///
+void logError(string msg, bool log2file = true, bool log2console = false)
+{
+ if (log2console)
+ {
+ Console.WriteLine(msg);
+ }
+ if (log2file)
+ {
+ Log.Error(msg);
+ }
+}
+
+void saveAndSendMessage(string memKey, string value, string notifyChannel, string message)
+{
+ // effettuo la scrittura nell'area di memoria indicata SE passato intervallo minimo
+ bool doSend = true;
+ if (LastSend.ContainsKey(memKey))
+ {
+ if (DateTime.Now.Subtract(LastSend[memKey]).TotalSeconds < 60)
+ {
+ doSend = false;
+ }
+ }
+ else
+ {
+ LastSend.Add(memKey, DateTime.Now);
+ }
+ if (doSend)
+ {
+ redisDb.StringSetAsync(memKey, value);
+ LastSend[memKey] = DateTime.Now;
+ logInfo($"Redis Cache Key: {memKey}");
+ }
+ //redisDb.SetAdd(memKey, value);
+
+ // invio notifica tramite il canale richiesto
+ sub.Publish(notifyChannel, message);
+ if (verboseLog)
+ {
+ logInfo($"[{notifyChannel}] key: {memKey} | val: {value} | message: {message}");
+ }
+ else
+ {
+ try
+ {
+ if (!logWriting)
+ {
+ if (LogSimulator.ContainsKey(notifyChannel))
+ {
+ LogSimulator[notifyChannel]++;
+ }
+ else
+ {
+ LogSimulator.Add(notifyChannel, 1);
+ }
+ logWriting = true;
+ // vedo se loggare...
+ DateTime adesso = DateTime.Now;
+ if (adesso.Subtract(lastLog).TotalSeconds > 15)
+ {
+ lastLog = adesso;
+ logInfo(lineSep);
+
+ // lavoro su copia...
+ var LogSimulatorCopy = new Dictionary(LogSimulator);
+ foreach (var item in LogSimulatorCopy)
+ {
+ logInfo($"Redis mQueue {item.Key,-20}{item.Value,12}");
+ }
+ logInfo(lineSep);
+ }
+ logWriting = false;
+ }
+ }
+ catch (Exception ex)
+ {
+ logError($"ERROR{Environment.NewLine}{ex}");
+ }
+ }
+}
\ No newline at end of file
diff --git a/MP.MONO.ADAPTER.OLD/Resources/ChangeLog-original.html b/MP.MONO.ADAPTER.OLD/Resources/ChangeLog-original.html
new file mode 100644
index 0000000..3cf89dd
--- /dev/null
+++ b/MP.MONO.ADAPTER.OLD/Resources/ChangeLog-original.html
@@ -0,0 +1,26 @@
+
+ MAPO-MONO
+ Version: {{CURRENT-REL}}
+ Release Note:
+
+
+ Last changes:
+
+
+
+ v.1.0.* →
+
+ Current CORE version
+ Release dotnet6
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MP.MONO.ADAPTER.OLD/Resources/ChangeLog.html b/MP.MONO.ADAPTER.OLD/Resources/ChangeLog.html
new file mode 100644
index 0000000..ecdcea3
--- /dev/null
+++ b/MP.MONO.ADAPTER.OLD/Resources/ChangeLog.html
@@ -0,0 +1,26 @@
+
+ MAPO-MONO
+ Version: 1.12206.1410
+ Release Note:
+
+
+ Last changes:
+
+
+
+ v.1.0.* →
+
+ Current CORE version
+ Release dotnet6
+
+
+
+
+
+
+
+
+
+
diff --git a/MP.MONO.ADAPTER.OLD/Resources/VersNum.txt b/MP.MONO.ADAPTER.OLD/Resources/VersNum.txt
new file mode 100644
index 0000000..3720595
--- /dev/null
+++ b/MP.MONO.ADAPTER.OLD/Resources/VersNum.txt
@@ -0,0 +1 @@
+1.12206.1410
diff --git a/MP.MONO.ADAPTER.OLD/Resources/logoSteamware.png b/MP.MONO.ADAPTER.OLD/Resources/logoSteamware.png
new file mode 100644
index 0000000..0958b50
Binary files /dev/null and b/MP.MONO.ADAPTER.OLD/Resources/logoSteamware.png differ
diff --git a/MP.MONO.ADAPTER.OLD/Resources/manifest-original.xml b/MP.MONO.ADAPTER.OLD/Resources/manifest-original.xml
new file mode 100644
index 0000000..a9269ca
--- /dev/null
+++ b/MP.MONO.ADAPTER.OLD/Resources/manifest-original.xml
@@ -0,0 +1,7 @@
+
+-
+
1.0.0.0
+ http://nexus.steamware.net/repository/SWS/{{DIRNAME}}/{{BRANCHNAME}}/{{PACKNAME}}.zip
+ http://nexus.steamware.net/repository/SWS/{{DIRNAME}}/{{BRANCHNAME}}/ChangeLog.html
+ false
+
diff --git a/MP.MONO.ADAPTER.OLD/Resources/manifest.xml b/MP.MONO.ADAPTER.OLD/Resources/manifest.xml
new file mode 100644
index 0000000..23bb8cd
--- /dev/null
+++ b/MP.MONO.ADAPTER.OLD/Resources/manifest.xml
@@ -0,0 +1,7 @@
+
+-
+
1.12206.1410
+ http://nexus.steamware.net/repository/SWS/MP.MONO.ADAPTER/stable/LAST/MP.Mon.zip
+ http://nexus.steamware.net/repository/SWS/MP.MONO.ADAPTER/stable/LAST/ChangeLog.html
+ false
+
diff --git a/MP.MONO.ADAPTER.OLD/UAClient.cs b/MP.MONO.ADAPTER.OLD/UAClient.cs
new file mode 100644
index 0000000..cd8fb8e
--- /dev/null
+++ b/MP.MONO.ADAPTER.OLD/UAClient.cs
@@ -0,0 +1,1005 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Collections;
+using Opc.Ua;
+using Opc.Ua.Client;
+using NLog;
+
+namespace MP.MONO.ADAPTER
+{
+ ///
+ /// Evento per incapsulare dati x refresh pagina
+ ///
+ public class opcUaMonitItemChange : EventArgs
+ {
+ #region Private Fields
+
+ ///
+ /// Monitored Item da notificare
+ ///
+ private readonly MonitoredItem _monitoredItem;
+
+ ///
+ /// Valore notifica
+ ///
+ private readonly MonitoredItemNotification _notification;
+
+ #endregion Private Fields
+
+ #region Public Constructors
+
+ ///
+ /// salvataggio obj
+ ///
+ ///
+ public opcUaMonitItemChange(MonitoredItem monitoredItem, MonitoredItemNotification notification)
+ {
+ _monitoredItem = monitoredItem;
+ _notification = notification;
+ }
+
+ #endregion Public Constructors
+
+ #region Public Properties
+
+ ///
+ /// Proprietà lettura del MonitoredItem
+ ///
+ public MonitoredItem CurrMonitoredItem
+ {
+ get { return _monitoredItem; }
+ }
+
+ ///
+ /// Proprietà lettura della notifica
+ ///
+ public MonitoredItemNotification CurrNotify
+ {
+ get { return _notification; }
+ }
+
+ #endregion Public Properties
+ }
+ ///
+ /// OPC UA Client with examples of basic functionality.
+ ///
+ public class UAClient
+ {
+ #region Private Fields
+
+ private readonly string currIob;
+ private readonly Action m_validateResponse;
+ private ApplicationConfiguration m_configuration;
+ private Session m_session;
+
+ #endregion Private Fields
+
+ #region Protected Fields
+
+ protected static Logger lg;
+ protected static bool isLogVerbose = false;
+
+
+ ///
+ /// The user identity to use when creating the session.
+ ///
+ public IUserIdentity CurrUserIdentity { get; set; } = new UserIdentity();
+
+ #endregion Protected Fields
+
+ #region Public Constructors
+
+ ///
+ /// Initializes a new instance of the UAClient class.
+ ///
+ public UAClient(ApplicationConfiguration configuration, string codIOB, string user, string pwd, bool verboseLog, Action validateResponse)
+ {
+ m_validateResponse = validateResponse;
+ currIob = codIOB;
+ lg = LogManager.GetCurrentClassLogger();
+ if (!string.IsNullOrEmpty(user) && !string.IsNullOrEmpty(pwd))
+ {
+ CurrUserIdentity = new UserIdentity(user, pwd);
+ }
+ else
+ {
+ CurrUserIdentity = new UserIdentity();
+ }
+ isLogVerbose = verboseLog;
+ m_configuration = configuration;
+ m_configuration.CertificateValidator.CertificateValidation += CertificateValidation;
+ }
+
+ #endregion Public Constructors
+
+ #region Public Events
+
+ ///
+ /// Evento notifica variazione MonitoredItem
+ ///
+ public event EventHandler eh_MonItChange;
+
+ #endregion Public Events
+
+ #region Public Properties
+
+ ///
+ /// Gets or sets the server URL.
+ ///
+ public string ServerUrl { get; set; } = "opc.tcp://localhost:4840";
+
+ ///
+ /// Gets the client session.
+ ///
+ public Session Session => m_session;
+
+ #endregion Public Properties
+
+ #region Private Methods
+
+ ///
+ /// Handles the certificate validation event.
+ /// This event is triggered every time an untrusted certificate is received from the server.
+ ///
+ private void CertificateValidation(CertificateValidator sender, CertificateValidationEventArgs e)
+ {
+ bool certificateAccepted = true;
+
+ // ****
+ // Implement a custom logic to decide if the certificate should be
+ // accepted or not and set certificateAccepted flag accordingly.
+ // The certificate can be retrieved from the e.Certificate field
+ // ***
+
+ ServiceResult error = e.Error;
+ while (error != null)
+ {
+ lgError($"{error.StatusCode} | {error.Code} | {error.LocalizedText}");
+ error = error.InnerResult;
+ }
+
+ if (certificateAccepted)
+ {
+ lgInfo($"Untrusted Certificate accepted. SubjectName = {e.Certificate.SubjectName}");
+ }
+
+ e.AcceptAll = certificateAccepted;
+ }
+
+ ///
+ /// Handle DataChange notifications from Server
+ ///
+ private void OnMonitoredItemNotification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
+ {
+ try
+ {
+ // Log MonitoredItem Notification event
+ MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification;
+
+ // sollevo evento notifica vaziazione MonitoredItem
+ if (eh_MonItChange != null)
+ {
+ eh_MonItChange(this, new opcUaMonitItemChange(monitoredItem, notification));
+ }
+ lgTrace($"Notification Received | Variable: {monitoredItem.DisplayName} | Value: {notification.Value}");
+ }
+ catch (Exception ex)
+ {
+ lgError($"OnMonitoredItemNotification error: {ex.Message}");
+ }
+ }
+
+ #endregion Private Methods
+
+ #region Protected Methods
+
+ ///
+ /// Effettua logging ERROR corretto impostanto anche la variabile IOB prima di scrivere...
+ ///
+ ///
+ protected void lgError(string message)
+ {
+ lg.Factory.Configuration.Variables["codIOB"] = currIob;
+ lg.Error(message);
+ }
+
+ ///
+ /// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere...
+ ///
+ ///
+ protected void lgInfo(string message)
+ {
+ lg.Factory.Configuration.Variables["codIOB"] = currIob;
+ lg.Info(message);
+ }
+
+ ///
+ /// Effettua logging DEBUG corretto impostanto anche la variabile IOB prima di scrivere...
+ ///
+ ///
+ protected void lgDebug(string message)
+ {
+ lg.Factory.Configuration.Variables["codIOB"] = currIob;
+ lg.Info(message);
+ }
+ ///
+ /// Effettua logging TRACE corretto impostanto anche la variabile IOB prima di scrivere...
+ ///
+ ///
+ protected void lgTrace(string message)
+ {
+ lg.Factory.Configuration.Variables["codIOB"] = currIob;
+ lg.Trace(message);
+ }
+
+ #endregion Protected Methods
+
+ #region Public Methods
+
+ ///
+ /// Browse Server nodes
+ ///
+ public bool Browse(ushort startNodeNS, uint startNodeVal, List vetoBrowse, ref Dictionary nodeIdNameList)
+ {
+ bool fatto = false;
+ if (m_session == null || m_session.Connected == false)
+ {
+ lgError("Session not connected!");
+ return false;
+ }
+
+ try
+ {
+ // Create a Browser object
+ Browser browser = new Browser(m_session);
+
+ // Set browse parameters
+ browser.BrowseDirection = BrowseDirection.Forward;
+ browser.NodeClassMask = (int)NodeClass.Object | (int)NodeClass.Variable;
+ browser.ReferenceTypeId = ReferenceTypeIds.HierarchicalReferences;
+
+ //NodeId nodeToBrowse = ObjectIds.Server;
+ //NodeId nodeToBrowse = new NodeId("ns=4,i=5001");
+ NodeId nodeToBrowse = new NodeId(startNodeVal, startNodeNS);
+
+ // Call Browse service
+ lgTrace($"Browsing {nodeToBrowse} node...");
+ ReferenceDescriptionCollection browseResults = browser.Browse(nodeToBrowse);
+
+ // Display the results
+ lgTrace($"Browse returned {browseResults.Count} results:");
+
+ foreach (ReferenceDescription result in browseResults)
+ {
+ lgTrace($" NodeId = {result.NodeId}, TypeId = {result.TypeId}, DisplayName = {result.DisplayName.Text}, NodeClass = {result.NodeClass}, Others: {result.BinaryEncodingId} | {result.BrowseName}");
+ // se NON fa parte dell'elenco dei VETO di filterItems...
+ if (!vetoBrowse.Contains($"{result.NodeId}"))
+ {
+ // se mancasse aggiungo...
+ if (!nodeIdNameList.ContainsKey($"{result.NodeId}"))
+ {
+ nodeIdNameList.Add(result.NodeId.ToString(), result.DisplayName.Text);
+ }
+ }
+ }
+ fatto = true;
+ }
+ catch (Exception ex)
+ {
+ // Log Error
+ lgError($"Browse Error : {ex.Message}");
+ }
+
+ return fatto;
+ }
+
+ ///
+ /// Browse Server nodes
+ ///
+ public bool Browse(string browsePath, List vetoBrowse, ref Dictionary nodeIdNameList)
+ {
+ bool fatto = false;
+ if (m_session == null || m_session.Connected == false)
+ {
+ lgError("Session not connected!");
+ return false;
+ }
+
+ try
+ {
+ // Create a Browser object
+ Browser browser = new Browser(m_session);
+
+ // Set browse parameters
+ browser.BrowseDirection = BrowseDirection.Forward;
+ browser.NodeClassMask = (int)NodeClass.Object | (int)NodeClass.Variable;
+ browser.ReferenceTypeId = ReferenceTypeIds.HierarchicalReferences;
+
+ //NodeId nodeToBrowse = ObjectIds.Server;
+ //NodeId nodeToBrowse = new NodeId("ns=4;i=5001");
+ NodeId nodeToBrowse = new NodeId(browsePath);
+ //nodeToBrowse = ObjectIds.Server;
+ //nodeToBrowse = new NodeId("Calibratrice_L1", 4);
+ //nodeToBrowse = new NodeId("Dati_Mes", 4);
+ //nodeToBrowse = new NodeId(5001, 2);
+ //nodeToBrowse = new NodeId("ns=4;s=NxController");
+ //nodeToBrowse = new NodeId("ns=4;s=Dati_Mes");
+ //nodeToBrowse = new NodeId("NxController.GlobalVars", 4);
+ //nodeToBrowse = new NodeId("Dati_Mes", 4);
+
+ // Call Browse service
+ lgTrace($"Browsing {nodeToBrowse} node...");
+ ReferenceDescriptionCollection browseResults = browser.Browse(nodeToBrowse);
+
+ // Display the results
+ lgTrace($"Browse returned {browseResults.Count} results:");
+
+ foreach (ReferenceDescription result in browseResults)
+ {
+ // se veto --> loggo veto
+ if (vetoBrowse.Contains($"{result.NodeId}"))
+ {
+ lgTrace($"| FILTERED --> NodeId = {result.NodeId}, DisplayName = {result.DisplayName.Text}, NodeClass = {result.NodeClass}, Others: {result.BinaryEncodingId} | {result.BrowseName}");
+ }
+ // se NON fa parte dell'elenco dei VETO di filterItems...
+ else
+ {
+ lgTrace($" NodeId = {result.NodeId}, DisplayName = {result.DisplayName.Text}, NodeClass = {result.NodeClass}, Others: {result.BinaryEncodingId} | {result.BrowseName}");
+ // se mancasse aggiungo...
+ if (!nodeIdNameList.ContainsKey($"{result.NodeId}"))
+ {
+ nodeIdNameList.Add($"{result.NodeId}", result.DisplayName.Text);
+ // se è un nodo object --> faccio sub browse!
+ if (result.NodeClass != NodeClass.Variable)
+ {
+ this.Browse($"{result.NodeId}", vetoBrowse, ref nodeIdNameList);
+ }
+ }
+ }
+ }
+ fatto = true;
+ }
+ catch (Exception ex)
+ {
+ // Log Error
+ lgError($"Browse Error : {ex.Message}");
+ }
+
+ return fatto;
+ }
+
+ ///
+ /// Call UA method
+ ///
+ public void CallMethod()
+ {
+ if (m_session == null || m_session.Connected == false)
+ {
+ lgError("Session not connected!");
+ return;
+ }
+
+ try
+ {
+ // Define the UA Method to call
+ // Parent node - Objects\CTT\Methods
+ // Method node - Objects\CTT\Methods\Add
+ NodeId objectId = new NodeId("ns=2;s=Methods");
+ NodeId methodId = new NodeId("ns=2;s=Methods_Add");
+
+ // Define the method parameters
+ // Input argument requires a Float and an UInt32 value
+ object[] inputArguments = new object[] { (float)10.5, (uint)10 };
+ IList outputArguments = null;
+
+ // Invoke Call service
+ lgDebug($"Calling UAMethod for node {methodId} ...");
+ outputArguments = m_session.Call(objectId, methodId, inputArguments);
+
+ // Display results
+ lgDebug($"Method call returned {outputArguments.Count} output argument(s):");
+
+ foreach (var outputArgument in outputArguments)
+ {
+ lgDebug($" OutputValue = {outputArgument}");
+ }
+ }
+ catch (Exception ex)
+ {
+ lgError($"Method call error: {ex.Message}");
+ }
+ }
+
+ ///
+ /// Creates a session with the UA server
+ ///
+ public async Task ConnectAsync()
+ {
+ try
+ {
+ if (m_session != null && m_session.Connected == true)
+ {
+ lgInfo("Session already connected!");
+ }
+ else
+ {
+ lgInfo("Connecting...");
+
+ // Get the endpoint by connecting to server's discovery endpoint.
+ // Try to find the first endopint without security.
+ EndpointDescription endpointDescription = CoreClientUtils.SelectEndpoint(ServerUrl, false);
+
+ EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(m_configuration);
+ ConfiguredEndpoint endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration);
+
+ // Create the session
+ Session session = await Session.Create(
+ m_configuration,
+ endpoint,
+ false,
+ false,
+ m_configuration.ApplicationName,
+ 30 * 60 * 1000,
+ CurrUserIdentity,
+ null
+ );
+
+ // Assign the created session
+ if (session != null && session.Connected)
+ {
+ m_session = session;
+ }
+
+ // Session created successfully.
+ lgInfo($"New Session Created with SessionName = {m_session.SessionName}");
+ }
+
+ return true;
+ }
+ catch (Exception ex)
+ {
+ // Log Error
+ lgError($"Create Session Error : {ex.Message}");
+ return false;
+ }
+ }
+
+ ///
+ /// Disconnects the session.
+ ///
+ public void Disconnect()
+ {
+ try
+ {
+ if (m_session != null)
+ {
+ lgInfo("Disconnecting...");
+
+ m_session.Close();
+ m_session.Dispose();
+ m_session = null;
+
+ // Log Session Disconnected event
+ lgInfo("Session Disconnected.");
+ }
+ else
+ {
+ lgError("Session not created!");
+ }
+ }
+ catch (Exception ex)
+ {
+ // Log Error
+ lgError($"Disconnect Error : {ex.Message}");
+ }
+ }
+
+ ///
+ /// Read a SINGLE of nodes value from Server
+ ///
+ ///
+ ///
+ public string ReadNode(NodeId reqNodeId)
+ {
+ string answ = "";
+ if (m_session == null || m_session.Connected == false)
+ {
+ lgError("Session not connected!");
+ return answ;
+ }
+
+ try
+ {
+ //#region Read a node by calling the Read Service
+
+ //// build a list of nodes to be read
+ //ReadValueIdCollection nodesToRead = new ReadValueIdCollection()
+ //{
+ // // Value of ServerStatus
+ // new ReadValueId() { NodeId = Variables.Server_ServerStatus, AttributeId = Attributes.Value },
+ // // BrowseName of ServerStatus_StartTime
+ // new ReadValueId() { NodeId = Variables.Server_ServerStatus_StartTime, AttributeId = Attributes.BrowseName },
+ // // Value of ServerStatus_StartTime
+ // new ReadValueId() { NodeId = Variables.Server_ServerStatus_StartTime, AttributeId = Attributes.Value }
+ //};
+
+ //// Read the node attributes
+ //lgInfo("Reading nodes...");
+
+ //// Call Read Service
+ //m_session.Read(
+ // null,
+ // 0,
+ // TimestampsToReturn.Both,
+ // nodesToRead,
+ // out DataValueCollection resultsValues,
+ // out DiagnosticInfoCollection diagnosticInfos);
+
+ //// Validate the results
+ //m_validateResponse(resultsValues, nodesToRead);
+
+ //// Display the results.
+ //foreach (DataValue result in resultsValues)
+ //{
+ // lgInfo("Read Value = {0} , StatusCode = {1}", result.Value, result.StatusCode);
+ //}
+
+ //#endregion Read a node by calling the Read Service
+
+ #region Read the Value attribute of a node by calling the Session.ReadValue method
+
+ try
+ {
+ DataValue resp = m_session.ReadValue(reqNodeId);
+ answ = $"{resp.Value}";
+ }
+ catch (Exception exc)
+ {
+ // Log Error
+ lgError($"ReadValue Error : {Environment.NewLine}{exc}");
+ }
+
+ #endregion Read the Value attribute of a node by calling the Session.ReadValue method
+ }
+ catch (Exception ex)
+ {
+ // Log Error
+ lgError($"Read Nodes Error : {ex.Message}.");
+ }
+ return answ;
+ }
+
+
+ ///
+ /// Read a SINGLE of nodes value (RAW) from Server
+ ///
+ ///
+ ///
+ public object ReadNodeRaw(NodeId reqNodeId)
+ {
+ object answ = null;
+ if (m_session == null || m_session.Connected == false)
+ {
+ lgError("Session not connected!");
+ return answ;
+ }
+
+ try
+ {
+
+ #region Read the Value attribute of a node by calling the Session.ReadValue method
+
+ try
+ {
+ DataValue resp = m_session.ReadValue(reqNodeId);
+ answ = resp;
+ }
+ catch (Exception exc)
+ {
+ // Log Error
+ lgError($"ReadNodeRaw Error 01: {Environment.NewLine}{exc}");
+ }
+
+ #endregion Read the Value attribute of a node by calling the Session.ReadValue method
+ }
+ catch (Exception ex)
+ {
+ // Log Error
+ lgError($"ReadNodeRaw Error 02: {ex.Message}.");
+ }
+ return answ;
+ }
+
+
+
+ ///
+ /// Read a list of nodes from Server
+ ///
+ public void ReadNodes()
+ {
+ if (m_session == null || m_session.Connected == false)
+ {
+ lgError("Session not connected!");
+ return;
+ }
+
+ try
+ {
+ #region Read a node by calling the Read Service
+
+ // build a list of nodes to be read
+ ReadValueIdCollection nodesToRead = new ReadValueIdCollection()
+ {
+ // Value of ServerStatus
+ new ReadValueId() { NodeId = Variables.Server_ServerStatus, AttributeId = Attributes.Value },
+ // BrowseName of ServerStatus_StartTime
+ new ReadValueId() { NodeId = Variables.Server_ServerStatus_StartTime, AttributeId = Attributes.BrowseName },
+ // Value of ServerStatus_StartTime
+ new ReadValueId() { NodeId = Variables.Server_ServerStatus_StartTime, AttributeId = Attributes.Value }
+ };
+
+ // Read the node attributes
+ lgInfo("Reading nodes...");
+
+ // Call Read Service
+ m_session.Read(
+ null,
+ 0,
+ TimestampsToReturn.Both,
+ nodesToRead,
+ out DataValueCollection resultsValues,
+ out DiagnosticInfoCollection diagnosticInfos);
+
+ // Validate the results
+ m_validateResponse(resultsValues, nodesToRead);
+
+ // Display the results.
+ foreach (DataValue result in resultsValues)
+ {
+ lgTrace($"Read Value = {result.Value} , StatusCode = {result.StatusCode}");
+ }
+
+ #endregion Read a node by calling the Read Service
+
+ #region Read the Value attribute of a node by calling the Session.ReadValue method
+
+ // Read Server NamespaceArray
+ lgTrace("Reading Value of NamespaceArray node...");
+ DataValue namespaceArray = m_session.ReadValue(Variables.Server_NamespaceArray);
+ // Display the result
+ lgTrace($"NamespaceArray Value = {namespaceArray}");
+
+ #endregion Read the Value attribute of a node by calling the Session.ReadValue method
+ }
+ catch (Exception ex)
+ {
+ // Log Error
+ lgError($"Read Nodes Error : {ex.Message}.");
+ }
+ }
+
+ ///
+ /// Create Subscription and MonitoredItems for DataChanges
+ ///
+ public List SubscribeToDataChanges(Dictionary DataList)
+ {
+ List monItList = new List();
+ if (m_session == null || m_session.Connected == false)
+ {
+ lgError("Session not connected!");
+ return monItList;
+ }
+
+ try
+ {
+ // Create a subscription for receiving data change notifications
+
+ // Define Subscription parameters
+ Subscription subscription = new Subscription(m_session.DefaultSubscription);
+
+ subscription.DisplayName = "Steamware IOB-WIN Subscription";
+ subscription.PublishingEnabled = true;
+ subscription.PublishingInterval = 1000;
+
+ m_session.AddSubscription(subscription);
+
+ // Create the subscription on Server side
+ subscription.Create();
+ lgInfo($"New Subscription created with SubscriptionId = {subscription.Id}");
+
+ // Create MonitoredItems for data changes
+ foreach (var item in DataList)
+ {
+ MonitoredItem currMonIt = new MonitoredItem(subscription.DefaultItem);
+ // Int32 Node - Objects\CTT\Scalar\Simulation\Int32
+ currMonIt.StartNodeId = new NodeId(item.Key);
+ currMonIt.AttributeId = Attributes.Value;
+ currMonIt.DisplayName = item.Value;
+ currMonIt.SamplingInterval = 1000;
+ currMonIt.Notification += OnMonitoredItemNotification;
+ subscription.AddItem(currMonIt);
+ monItList.Add(currMonIt);
+ }
+
+#if false
+ MonitoredItem IO_120_00_MonitoredItem = new MonitoredItem(subscription.DefaultItem);
+ // Int32 Node - Objects\CTT\Scalar\Simulation\Int32
+ IO_120_00_MonitoredItem.StartNodeId = new NodeId("ns=4;s=IO_120.00");
+ IO_120_00_MonitoredItem.AttributeId = Attributes.Value;
+ IO_120_00_MonitoredItem.DisplayName = "IO_120 Variable";
+ IO_120_00_MonitoredItem.SamplingInterval = 1000;
+ IO_120_00_MonitoredItem.Notification += OnMonitoredItemNotification;
+ subscription.AddItem(IO_120_00_MonitoredItem);
+
+ MonitoredItem IO_120_01_MonitoredItem = new MonitoredItem(subscription.DefaultItem);
+ // Int32 Node - Objects\CTT\Scalar\Simulation\Int32
+ IO_120_01_MonitoredItem.StartNodeId = new NodeId("ns=4;s=IO_120.01");
+ IO_120_01_MonitoredItem.AttributeId = Attributes.Value;
+ IO_120_01_MonitoredItem.DisplayName = "IO_120_01 Variable";
+ IO_120_01_MonitoredItem.SamplingInterval = 1000;
+ IO_120_01_MonitoredItem.Notification += OnMonitoredItemNotification;
+ subscription.AddItem(IO_120_01_MonitoredItem);
+
+ MonitoredItem IO_130_MonitoredItem = new MonitoredItem(subscription.DefaultItem);
+ // Int32 Node - Objects\CTT\Scalar\Simulation\Int32
+ IO_130_MonitoredItem.StartNodeId = new NodeId("ns=4;s=IO_130");
+ IO_130_MonitoredItem.AttributeId = Attributes.Value;
+ IO_130_MonitoredItem.DisplayName = "IO_130 Variable";
+ IO_130_MonitoredItem.SamplingInterval = 1000;
+ IO_130_MonitoredItem.Notification += OnMonitoredItemNotification;
+ subscription.AddItem(IO_130_MonitoredItem);
+
+ MonitoredItem IO_135_MonitoredItem = new MonitoredItem(subscription.DefaultItem);
+ // Int32 Node - Objects\CTT\Scalar\Simulation\Int32
+ IO_135_MonitoredItem.StartNodeId = new NodeId("ns=4;s=IO_135");
+ IO_135_MonitoredItem.AttributeId = Attributes.Value;
+ IO_135_MonitoredItem.DisplayName = "IO_135 Variable";
+ IO_135_MonitoredItem.SamplingInterval = 1000;
+ IO_135_MonitoredItem.Notification += OnMonitoredItemNotification;
+ subscription.AddItem(IO_135_MonitoredItem);
+
+ MonitoredItem IO_140_MonitoredItem = new MonitoredItem(subscription.DefaultItem);
+ // Int32 Node - Objects\CTT\Scalar\Simulation\Int32
+ IO_140_MonitoredItem.StartNodeId = new NodeId("ns=4;s=IO_140");
+ IO_140_MonitoredItem.AttributeId = Attributes.Value;
+ IO_140_MonitoredItem.DisplayName = "IO_140 Variable";
+ IO_140_MonitoredItem.SamplingInterval = 1000;
+ IO_140_MonitoredItem.Notification += OnMonitoredItemNotification;
+ subscription.AddItem(IO_140_MonitoredItem);
+
+ //MonitoredItem intMonitoredItem = new MonitoredItem(subscription.DefaultItem);
+ //// Int32 Node - Objects\CTT\Scalar\Simulation\Int32
+ //intMonitoredItem.StartNodeId = new NodeId("ns=2;s=Scalar_Simulation_Int32");
+ //intMonitoredItem.AttributeId = Attributes.Value;
+ //intMonitoredItem.DisplayName = "Int32 Variable";
+ //intMonitoredItem.SamplingInterval = 1000;
+ //intMonitoredItem.Notification += OnMonitoredItemNotification;
+
+ //subscription.AddItem(intMonitoredItem);
+
+ //MonitoredItem floatMonitoredItem = new MonitoredItem(subscription.DefaultItem);
+ //// Float Node - Objects\CTT\Scalar\Simulation\Float
+ //floatMonitoredItem.StartNodeId = new NodeId("ns=2;s=Scalar_Simulation_Float");
+ //floatMonitoredItem.AttributeId = Attributes.Value;
+ //floatMonitoredItem.DisplayName = "Float Variable";
+ //floatMonitoredItem.SamplingInterval = 1000;
+ //floatMonitoredItem.Notification += OnMonitoredItemNotification;
+
+ //subscription.AddItem(floatMonitoredItem);
+
+ //MonitoredItem stringMonitoredItem = new MonitoredItem(subscription.DefaultItem);
+ //// String Node - Objects\CTT\Scalar\Simulation\String
+ //stringMonitoredItem.StartNodeId = new NodeId("ns=2;s=Scalar_Simulation_String");
+ //stringMonitoredItem.AttributeId = Attributes.Value;
+ //stringMonitoredItem.DisplayName = "String Variable";
+ //stringMonitoredItem.SamplingInterval = 1000;
+ //stringMonitoredItem.Notification += OnMonitoredItemNotification;
+
+ //subscription.AddItem(stringMonitoredItem);
+#endif
+
+ // Create the monitored items on Server side
+ subscription.ApplyChanges();
+ lgInfo($"MonitoredItems created for SubscriptionId = {subscription.Id}");
+ }
+ catch (Exception ex)
+ {
+ lgError($"Subscribe error: {ex.Message}");
+ }
+ return monItList;
+ }
+
+ /// Write a list of nodes to the Server
+ ///
+ public void WriteNodes(List node2Write)
+ {
+ if (m_session == null || m_session.Connected == false)
+ {
+ lgError("Session not connected!");
+ return;
+ }
+
+ try
+ {
+ // Write the configured nodes
+ WriteValueCollection nodesToWrite = new WriteValueCollection();
+ nodesToWrite.AddRange(node2Write);
+
+ // Write the node attributes
+ StatusCodeCollection results = null;
+ DiagnosticInfoCollection diagnosticInfos;
+ lgDebug("Writing nodes...");
+
+ // Call Write Service
+ m_session.Write(null,
+ nodesToWrite,
+ out results,
+ out diagnosticInfos);
+
+ // Validate the response
+ m_validateResponse(results, nodesToWrite);
+
+ // Display the results.
+ lgDebug("Write Results :");
+
+ foreach (StatusCode writeResult in results)
+ {
+ lgDebug($" {writeResult}");
+ }
+ }
+ catch (Exception ex)
+ {
+ // Log Error
+ lgError($"Write Nodes Error : {ex.Message}");
+ }
+ }
+
+ ///
+ /// Write a list of nodes to the Server
+ ///
+ public void WriteSingleNode(WriteValue node2Write)
+ {
+ if (m_session == null || m_session.Connected == false)
+ {
+ lgError("Session not connected!");
+ return;
+ }
+
+ try
+ {
+ // Write the configured nodes
+ WriteValueCollection nodesToWrite = new WriteValueCollection();
+
+ nodesToWrite.Add(node2Write);
+
+ // Write the node attributes
+ StatusCodeCollection results = null;
+ DiagnosticInfoCollection diagnosticInfos;
+ lgDebug("Writing nodes...");
+
+ // Call Write Service
+ m_session.Write(null,
+ nodesToWrite,
+ out results,
+ out diagnosticInfos);
+
+ // Validate the response
+ m_validateResponse(results, nodesToWrite);
+
+ // Display the results.
+ lgDebug("Write Results :");
+
+ foreach (StatusCode writeResult in results)
+ {
+ lgDebug(" {writeResult}");
+ }
+ }
+ catch (Exception ex)
+ {
+ // Log Error
+ lgError($"Write Nodes Error : {ex.Message}");
+ }
+ }
+
+ ///
+ /// Write a list of nodes to the Server
+ ///
+ public void WriteTestNodes()
+ {
+ if (m_session == null || m_session.Connected == false)
+ {
+ lgError("Session not connected!");
+ return;
+ }
+
+ try
+ {
+ // scrivo vaslori a caso.. hhmm odierni
+ int hhmm = 9876;
+ int.TryParse(DateTime.Now.ToString("HHmm"), out hhmm);
+ // Write the configured nodes
+ WriteValueCollection nodesToWrite = new WriteValueCollection();
+
+ // Int32 Node - Objects\CTT\Scalar\Scalar_Static\Int32
+ WriteValue commWriteVal = new WriteValue();
+ commWriteVal.NodeId = new NodeId("ns=4;s=IO_151");
+ commWriteVal.AttributeId = Attributes.Value;
+ commWriteVal.Value = new DataValue();
+ commWriteVal.Value.Value = (int)hhmm - 10;
+ nodesToWrite.Add(commWriteVal);
+
+ WriteValue artWriteVal = new WriteValue();
+ artWriteVal.NodeId = new NodeId("ns=4;s=IO_151");
+ artWriteVal.AttributeId = Attributes.Value;
+ artWriteVal.Value = new DataValue();
+ artWriteVal.Value.Value = (int)hhmm;
+ nodesToWrite.Add(artWriteVal);
+
+ WriteValue qtyWriteVal = new WriteValue();
+ qtyWriteVal.NodeId = new NodeId("ns=4;s=IO_153");
+ qtyWriteVal.AttributeId = Attributes.Value;
+ qtyWriteVal.Value = new DataValue();
+ qtyWriteVal.Value.Value = (int)hhmm + 10;
+ nodesToWrite.Add(qtyWriteVal);
+
+#if false
+ //// Int32 Node - Objects\CTT\Scalar\Scalar_Static\Int32
+ //WriteValue intWriteVal = new WriteValue();
+ //intWriteVal.NodeId = new NodeId("ns=2;s=Scalar_Static_Int32");
+ //intWriteVal.AttributeId = Attributes.Value;
+ //intWriteVal.Value = new DataValue();
+ //intWriteVal.Value.Value = (int)100;
+ //nodesToWrite.Add(intWriteVal);
+
+ //// Float Node - Objects\CTT\Scalar\Scalar_Static\Float
+ //WriteValue floatWriteVal = new WriteValue();
+ //floatWriteVal.NodeId = new NodeId("ns=2;s=Scalar_Static_Float");
+ //floatWriteVal.AttributeId = Attributes.Value;
+ //floatWriteVal.Value = new DataValue();
+ //floatWriteVal.Value.Value = (float)100.5;
+ //nodesToWrite.Add(floatWriteVal);
+
+ //// String Node - Objects\CTT\Scalar\Scalar_Static\String
+ //WriteValue stringWriteVal = new WriteValue();
+ //stringWriteVal.NodeId = new NodeId("ns=2;s=Scalar_Static_String");
+ //stringWriteVal.AttributeId = Attributes.Value;
+ //stringWriteVal.Value = new DataValue();
+ //stringWriteVal.Value.Value = "String Test";
+ //nodesToWrite.Add(stringWriteVal);
+#endif
+
+ // Write the node attributes
+ StatusCodeCollection results = null;
+ DiagnosticInfoCollection diagnosticInfos;
+ lgDebug("Writing nodes...");
+
+ // Call Write Service
+ m_session.Write(null,
+ nodesToWrite,
+ out results,
+ out diagnosticInfos);
+
+ // Validate the response
+ m_validateResponse(results, nodesToWrite);
+
+ // Display the results.
+ lgDebug("Write Results :");
+
+ foreach (StatusCode writeResult in results)
+ {
+ lgDebug($" {writeResult}");
+ }
+ }
+ catch (Exception ex)
+ {
+ // Log Error
+ lgError($"Write Nodes Error : {ex.Message}.");
+ }
+ }
+
+ #endregion Public Methods
+ }
+}
diff --git a/MP.MONO.ADAPTER.OLD/appsettings.json b/MP.MONO.ADAPTER.OLD/appsettings.json
new file mode 100644
index 0000000..8958138
--- /dev/null
+++ b/MP.MONO.ADAPTER.OLD/appsettings.json
@@ -0,0 +1,47 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ },
+ "AllowedHosts": "*",
+ "ConnectionStrings": {
+ "Redis": "nkcredis.steamware.net:6379,DefaultDatabase=7,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false,password=nkc.password",
+ "AuthConnection": "Server=localhost;port=3306;database=GWMS;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
+ "DefaultConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
+ "AdminConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=root;pwd=Egalware_24068!;sslmode=None;",
+ "MP.MONO.Data": "Server=localhost;port=3306;database=MAPO.MONO;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;"
+ },
+ "DbConfig": {
+ "Server": "10.74.82.230",
+ "nKey": "MONO",
+ "sKey": "Calcium0xide-CaO"
+ },
+ "MachineId": 1,
+ "maxRecord": 15,
+ "ExternalProviders": {
+ "MailKit": {
+ "SMTP": {
+ "Address": "smtp.gmail.com",
+ "Port": "465",
+ "Account": "steamwarebot@gmail.com",
+ "Password": "drmfsls16",
+ "SenderEmail": "steamwarebot@gmail.com",
+ "SenderName": "Steamware Email BOT"
+ }
+ }
+ },
+ "Endpoint": {
+ "IpAddress": "192.168.0.2",
+ "Port": "4840",
+ "PingMsTimeout": 1500
+ },
+ "ENABLE_DATA_FILTER": true,
+ "ENABLE_CLI_RESTART": true,
+ "logEvery": 10,
+ "OPC_PARAM_CONF": "MULTIAX.json",
+ "pingTestSec": 5,
+ "verbose": false,
+ "verboseLogTOut": 60
+}
diff --git a/MP.MONO.ADAPTER.OLD/conf/AlarmList.json b/MP.MONO.ADAPTER.OLD/conf/AlarmList.json
new file mode 100644
index 0000000..47037b0
--- /dev/null
+++ b/MP.MONO.ADAPTER.OLD/conf/AlarmList.json
@@ -0,0 +1,52 @@
+[
+ {
+ "description": "General Alarm",
+ "tipoMem": "DInt",
+ "memAddr": "40901",
+ "index": 901,
+ "size": 2,
+ "messages": [
+ "Alarm 001",
+ "Alarm 002",
+ "Alarm 003",
+ "Alarm 004",
+ "Alarm 005",
+ "Alarm 006",
+ "Alarm 007",
+ "Alarm 008",
+ "Alarm 009",
+ "Alarm 010",
+ "Alarm 011",
+ "Alarm 012",
+ "##Alarm 013",
+ "##Alarm 014",
+ "##Alarm 015",
+ "##Alarm 016"
+ ]
+ },
+ {
+ "description": "Secondary Alarm",
+ "tipoMem": "DInt",
+ "memAddr": "40907",
+ "index": 907,
+ "size": 2,
+ "messages": [
+ "Warning 001",
+ "Warning 002",
+ "Warning 003",
+ "Warning 004",
+ "Warning 005",
+ "Warning 006",
+ "Warning 007",
+ "Warning 008",
+ "##Warning 009",
+ "##Warning 010",
+ "##Warning 011",
+ "##Warning 012",
+ "Warning 013",
+ "Warning 014",
+ "Warning 015",
+ "Warning 016"
+ ]
+ }
+]
\ No newline at end of file
diff --git a/MP.MONO.ADAPTER.OLD/conf/MULTIAX.json b/MP.MONO.ADAPTER.OLD/conf/MULTIAX.json
new file mode 100644
index 0000000..3c73c68
--- /dev/null
+++ b/MP.MONO.ADAPTER.OLD/conf/MULTIAX.json
@@ -0,0 +1,129 @@
+{
+ "BrowseFullVal": "ns=1;s=OSAI-PLC",
+ "BrowseNSIndex": 4,
+ "BrowseValue": 5001,
+ "keyPartCount": "50_2_COUNTER CYCLE",
+ "keyPartReq": "",
+ "keyPartId": "",
+ "keyProgName": "",
+ "keyRunMode": "51_1_MODE",
+ "pingAsPowerOn": true,
+ "condWork": [
+ {
+ "keyName": "1_1_MACHINE STATUS",
+ "targetValue": "ON"
+ }
+ ],
+ "condPowerOn": {
+ "checkMode": "AND",
+ "checkList": [
+ {
+ "keyName": "1_1_MACHINE STATUS",
+ "targetValue": "ON"
+ },
+ {
+ "keyName": "51_1_MODE",
+ "targetValue": "AUTO"
+ },
+ {
+ "keyName": "50_1_STATUS",
+ "targetValue": "RUN"
+ }
+ ]
+ },
+ "condReady": {
+ "checkMode": "AND",
+ "checkList": [
+ {
+ "keyName": "51_1_MODE",
+ "targetValue": "AUTO"
+ }
+ ]
+ },
+ "condManual": {
+ "checkMode": "AND",
+ "checkList": [
+ {
+ "keyName": "51_1_MODE",
+ "targetValue": "HOLD"
+ }
+ ]
+ },
+ "condEStop": {
+ "checkMode": "AND",
+ "checkList": [
+ {
+ "keyName": "IO_121.02",
+ "targetValue": "True"
+ }
+ ]
+ },
+ "condError": {
+ "checkMode": "AND",
+ "checkList": [
+ {
+ "keyName": "IO_120.08",
+ "targetValue": "True"
+ }
+ ]
+ },
+ "condCountEnabled": {
+ "checkMode": "AND",
+ "checkList": []
+ },
+ "condWarmUpCoolDown": {
+ "checkMode": "OR",
+ "checkList": [
+ {
+ "keyName": "IO_120.04",
+ "targetValue": "True"
+ },
+ {
+ "keyName": "IO_120.05",
+ "targetValue": "True"
+ }
+ ]
+ },
+ "fluxLogVeto": [
+ "L2p1CommonVariable"
+ ],
+ "itemTranslation": {
+ "avail": "Machine Available",
+ "rstat": "Execution Mode",
+ "mode": "Controller Mode",
+ "ncprog": "Program Name",
+ "IO_150": "Qta Prodotta (metri)",
+ "lpremain": "Qta Richiesta",
+ "fdovrd": "PATH FEED OVERRIDE",
+ "rovrd": "PATH RAPID OVERRIDE"
+ },
+ "paramsEndThresh": {
+ "InvDDone": 50
+ },
+ "mMapWrite": {
+ "setPzComm": {
+ "name": "setPzComm",
+ "description": "Qty",
+ "tipoMem": "Int",
+ "memAddr": "ns=4;s=IO_153",
+ "index": 0,
+ "size": -1
+ },
+ "setComm": {
+ "name": "setComm",
+ "description": "Commessa",
+ "tipoMem": "String",
+ "memAddr": "ns=4;s=ST80",
+ "index": 0,
+ "size": 20
+ },
+ "setArt": {
+ "name": "setArt",
+ "description": "Articolo",
+ "tipoMem": "String",
+ "memAddr": "ns=4;s=ST80",
+ "index": 20,
+ "size": 20
+ }
+ }
+}
\ No newline at end of file
diff --git a/MP.MONO.ADAPTER.OLD/conf/ModeList.json b/MP.MONO.ADAPTER.OLD/conf/ModeList.json
new file mode 100644
index 0000000..c71df53
--- /dev/null
+++ b/MP.MONO.ADAPTER.OLD/conf/ModeList.json
@@ -0,0 +1,58 @@
+[
+ {
+ "MModeID": 0,
+ "Description": "UNDEFINED",
+ "Css": "bg-dark text-light",
+ "Priority": 1,
+ "Group": "POWEROFF"
+ },
+ {
+ "MModeID": 1,
+ "Description": "EXE",
+ "Css": "bg-success text-light",
+ "Priority": 2,
+ "Group": "RUN"
+ },
+ {
+ "MModeID": 2,
+ "Description": "READY",
+ "Css": "bg-primary text-light",
+ "Priority": 3,
+ "Group": "MANUAL"
+ },
+ {
+ "MModeID": 3,
+ "Description": "HOLD",
+ "Css": "bg-warning text-light",
+ "Priority": 3,
+ "Group": "MANUAL"
+ },
+ {
+ "MModeID": 4,
+ "Description": "FEED_HOLD",
+ "Css": "bg-warning text-light",
+ "Priority": 3,
+ "Group": "MANUAL"
+ },
+ {
+ "MModeID": 5,
+ "Description": "OPTIONAL_STOP",
+ "Css": "bg-danger text-warning",
+ "Priority": 3,
+ "Group": "ERROR"
+ },
+ {
+ "MModeID": 6,
+ "Description": "PROGRAM_STOPPED",
+ "Css": "bg-warning text-light",
+ "Priority": 3,
+ "Group": "MANUAL"
+ },
+ {
+ "MModeID": 7,
+ "Description": "DONE",
+ "Css": "bg-primary text-light",
+ "Priority": 3,
+ "Group": "MANUAL"
+ }
+]
\ No newline at end of file
diff --git a/MP.MONO.ADAPTER.OLD/conf/ParamList.json b/MP.MONO.ADAPTER.OLD/conf/ParamList.json
new file mode 100644
index 0000000..a5fa40e
--- /dev/null
+++ b/MP.MONO.ADAPTER.OLD/conf/ParamList.json
@@ -0,0 +1,125 @@
+[
+ {
+ "Order": 3,
+ "Type": "SPEED-5000-10000",
+ "Title": "SPEED",
+ "Value": "4000",
+ "ValueNum": 4000,
+ "MinVal": 1000,
+ "MaxVal": 10000,
+ "DisplFormat": "N0",
+ "IsNumeric": true,
+ "EnablePlot": true,
+ "ShowBar": true,
+ "CssIcon": "fa-solid fa-gauge-high",
+ "SamplePeriod": 180,
+ "VcFunc": "MEDIAN"
+ },
+ {
+ "Order": 2,
+ "Type": "FEED-3000-5000",
+ "Title": "FEED",
+ "Value": "2500",
+ "ValueNum": 2500,
+ "MinVal": 1000,
+ "MaxVal": 5000,
+ "DisplFormat": "N0",
+ "IsNumeric": true,
+ "EnablePlot": true,
+ "ShowBar": true,
+ "CssIcon": "fa-solid fa-gauge-high",
+ "SamplePeriod": 180,
+ "VcFunc": "MEDIAN"
+ },
+ {
+ "Order": 1,
+ "Type": "LOAD",
+ "Title": "SPINDLE LOAD",
+ "Value": "30",
+ "ValueNum": 30,
+ "MinVal": 0,
+ "MaxVal": 100,
+ "DisplFormat": "N1",
+ "IsNumeric": true,
+ "EnablePlot": true,
+ "ShowBar": true,
+ "CssIcon": "fa-solid fa-bolt",
+ "SamplePeriod": 180,
+ "VcFunc": "MEDIAN"
+ },
+ {
+ "Order": 4,
+ "Type": "POS",
+ "Title": "X POS",
+ "Value": "1500",
+ "ValueNum": 1500,
+ "MinVal": 0,
+ "MaxVal": 5000,
+ "DisplFormat": "N2",
+ "IsNumeric": true,
+ "EnablePlot": true,
+ "CssIcon": "fa-solid fa-ruler-horizontal",
+ "SamplePeriod": 180,
+ "VcFunc": "MEDIAN"
+ },
+ {
+ "Order": 5,
+ "Type": "POS",
+ "Title": "Y POS",
+ "Value": "5000",
+ "ValueNum": 5000,
+ "MinVal": 0,
+ "MaxVal": 10000,
+ "DisplFormat": "N2",
+ "IsNumeric": true,
+ "EnablePlot": true,
+ "CssIcon": "fa-solid fa-ruler-horizontal",
+ "SamplePeriod": 180,
+ "VcFunc": "MEDIAN"
+ },
+ {
+ "Order": 6,
+ "Type": "POS",
+ "Title": "Z POS",
+ "Value": "-1500",
+ "ValueNum": -1500,
+ "MinVal": -3000,
+ "MaxVal": 0,
+ "DisplFormat": "N2",
+ "IsNumeric": true,
+ "EnablePlot": true,
+ "CssIcon": "fa-solid fa-ruler-horizontal",
+ "SamplePeriod": 180,
+ "VcFunc": "MEDIAN"
+ },
+ {
+ "Order": 7,
+ "Type": "POS",
+ "Title": "A POS",
+ "Value": "150",
+ "ValueNum": 150,
+ "MinVal": 0,
+ "MaxVal": 360,
+ "DisplFormat": "N3",
+ "IsNumeric": true,
+ "EnablePlot": true,
+ "CssIcon": "fa-solid fa-rotate-right",
+ "SamplePeriod": 180,
+ "VcFunc": "MEDIAN"
+ },
+ {
+ "Order": 8,
+ "Type": "POS",
+ "Title": "B POS",
+ "Value": "150",
+ "ValueNum": 150,
+ "MinVal": 0,
+ "MaxVal": 360,
+ "DisplFormat": "N3",
+ "IsNumeric": true,
+ "EnablePlot": true,
+ "CssIcon": "fa-solid fa-rotate-right",
+ "SamplePeriod": 180,
+ "VcFunc": "MEDIAN"
+ }
+]
\ No newline at end of file
diff --git a/MP.MONO.ADAPTER.OLD/conf/StatusList.json b/MP.MONO.ADAPTER.OLD/conf/StatusList.json
new file mode 100644
index 0000000..e374c71
--- /dev/null
+++ b/MP.MONO.ADAPTER.OLD/conf/StatusList.json
@@ -0,0 +1,58 @@
+[
+ {
+ "MStatusID": 0,
+ "Description": "UNDEFINED",
+ "Css": "bg-dark text-light",
+ "Priority": 1,
+ "Group": "POWEROFF"
+ },
+ {
+ "MStatusID": 1,
+ "Description": "POWEROFF",
+ "Css": "bg-secondary text-light",
+ "Priority": 1,
+ "Group": "POWEROFF"
+ },
+ {
+ "MStatusID": 2,
+ "Description": "AUTOMATIC",
+ "Css": "bg-success text-light",
+ "Priority": 2,
+ "Group": "RUN"
+ },
+ {
+ "MStatusID": 3,
+ "Description": "EDIT",
+ "Css": "bg-warning text-light",
+ "Priority": 3,
+ "Group": "MANUAL"
+ },
+ {
+ "MStatusID": 4,
+ "Description": "SEMIAUTOMATIC",
+ "Css": "bg-warning text-light",
+ "Priority": 3,
+ "Group": "MANUAL"
+ },
+ {
+ "MStatusID": 5,
+ "Description": "MANUAL_JOG",
+ "Css": "bg-warning text-light",
+ "Priority": 3,
+ "Group": "MANUAL"
+ },
+ {
+ "MStatusID": 6,
+ "Description": "ALARM",
+ "Css": "bg-danger text-warning",
+ "Priority": 3,
+ "Group": "ERROR"
+ },
+ {
+ "MStatusID": 7,
+ "Description": "ESTOP",
+ "Css": "bg-danger text-light",
+ "Priority": 3,
+ "Group": "ERROR"
+ }
+]
\ No newline at end of file
diff --git a/MP.MONO.ADAPTER.OLD/post-build.ps1 b/MP.MONO.ADAPTER.OLD/post-build.ps1
new file mode 100644
index 0000000..d89d097
--- /dev/null
+++ b/MP.MONO.ADAPTER.OLD/post-build.ps1
@@ -0,0 +1,32 @@
+param([string]$ProjectDir, [string]$ProjectPath);
+
+$FileMajMin = "..\MajMin.vers"
+$FileVers = "Resources\VersNum.txt"
+$FileManIn = "Resources\manifest-original.xml"
+$FileManOut = "Resources\manifest.xml"
+$FileCLogIn = "Resources\ChangeLog-original.html"
+$FileCLogOut = "Resources\ChangeLog.html"
+$MajMin = Get-Content $FileMajMin
+$currentDate = get-date -format yyMM;
+$currentTime = get-date -format dHH;
+$find = "(.|\n)*? ";
+$currRelNum = $MajMin + $currentDate +"." + $currentTime
+$replace = "" + $MajMin + $currentDate +"." + $currentTime + " ";
+$csproj = Get-Content $ProjectPath
+$csprojUpdated = $csproj -replace $find, $replace
+
+Set-Content -Path $ProjectPath -Value $csprojUpdated
+Set-Content -Path $FileVers -Value $currRelNum
+
+# replace x manifest
+$manData = Get-Content $FileManIn
+$manData = $manData -replace "1.0.0.0", $currRelNum
+$manData = $manData -replace "{{DIRNAME}}", "MP.MONO.ADAPTER"
+$manData = $manData -replace "{{BRANCHNAME}}", "stable/LAST"
+$manData = $manData -replace "{{PACKNAME}}", "MP.Mon"
+Set-Content -Path $FileManOut -Value $manData
+
+# replace x ChangeLog
+$clogData = Get-Content $FileCLogIn
+$clogData = $clogData -replace "{{CURRENT-REL}}", $currRelNum
+Set-Content -Path $FileCLogOut -Value $clogData