diff --git a/MP.MONO.ADAPTER/MP.MONO.ADAPTER.csproj b/MP.MONO.ADAPTER/MP.MONO.ADAPTER.csproj
new file mode 100644
index 0000000..249ce4c
--- /dev/null
+++ b/MP.MONO.ADAPTER/MP.MONO.ADAPTER.csproj
@@ -0,0 +1,49 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+ PreserveNewest
+ true
+ PreserveNewest
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+
+
diff --git a/MP.MONO.ADAPTER/Program.cs b/MP.MONO.ADAPTER/Program.cs
new file mode 100644
index 0000000..1346475
--- /dev/null
+++ b/MP.MONO.ADAPTER/Program.cs
@@ -0,0 +1,257 @@
+using Microsoft.Extensions.Configuration;
+using MP.MONO.Core;
+using MP.MONO.Core.CONF;
+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");
+string alarmSimMode = config.GetValue("AlarmSimMode");
+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);
+
+//Create a connection
+ConnectionMultiplexer.SetFeatureFlag("preventthreadtheft", true);
+ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(redisConf);
+ISubscriber sub = redis.GetSubscriber();
+IDatabase? redisDb = redis.GetDatabase();
+
+// salvo configurazioni in redis
+setupConf();
+
+#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
+{
+ 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()
+{
+ // 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));
+ }
+ }
+}
+
+///
+/// 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/appsettings.json b/MP.MONO.ADAPTER/appsettings.json
new file mode 100644
index 0000000..12d7629
--- /dev/null
+++ b/MP.MONO.ADAPTER/appsettings.json
@@ -0,0 +1,35 @@
+{
+ "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"
+ }
+ }
+ }
+}
diff --git a/MP.MONO.ADAPTER/conf/AlarmList.json b/MP.MONO.ADAPTER/conf/AlarmList.json
new file mode 100644
index 0000000..66b658b
--- /dev/null
+++ b/MP.MONO.ADAPTER/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/conf/ModeList.json b/MP.MONO.ADAPTER/conf/ModeList.json
new file mode 100644
index 0000000..c71df53
--- /dev/null
+++ b/MP.MONO.ADAPTER/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/conf/StatusList.json b/MP.MONO.ADAPTER/conf/StatusList.json
new file mode 100644
index 0000000..e374c71
--- /dev/null
+++ b/MP.MONO.ADAPTER/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