Abbozzato adapter con gestione lettura conf completa
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="appsettings.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="appsettings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="6.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="NLog" Version="4.7.14" />
|
||||
<PackageReference Include="StackExchange.Redis" Version="2.5.43" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\MP.MONO.Core\MP.MONO.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="conf\ModeList.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="conf\AlarmList.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="conf\StatusList.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -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<string>("AlarmSimMode");
|
||||
Logger Log = LogManager.GetCurrentClassLogger();
|
||||
Random rand = new Random();
|
||||
List<MachineStatus>? statusList = new List<MachineStatus>();
|
||||
List<MachineMode>? modeList = new List<MachineMode>();
|
||||
|
||||
// fix numero minimo dei thread pool x evitare collasso chiamate redis
|
||||
ThreadPool.SetMinThreads(10, 10);
|
||||
|
||||
Dictionary<string, int> LogSimulator = new Dictionary<string, int>();
|
||||
Dictionary<string, DateTime> LastSend = new Dictionary<string, DateTime>();
|
||||
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);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// verifica esistenza file oppure lo crea...
|
||||
/// </summary>
|
||||
void checkFilePresent(string filePath)
|
||||
{
|
||||
// verific presenza file log...
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
File.WriteAllText(filePath, $"{filePath} created!");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Setup e salvataggio redis delle conf (es modi/stati)
|
||||
/// </summary>
|
||||
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<MachineStatus>? statusList = JsonConvert.DeserializeObject<List<MachineStatus>>(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<List<MachineMode>>(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<List<BaseAlarmConf>>(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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua log INFO su file e se richiesto su console
|
||||
/// </summary>
|
||||
void logInfo(string msg, bool log2file = true, bool log2console = false)
|
||||
{
|
||||
if (log2console)
|
||||
{
|
||||
Console.WriteLine(msg);
|
||||
}
|
||||
if (log2file)
|
||||
{
|
||||
Log.Info(msg);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Effettua log ERROR su file e se richiesto su console
|
||||
/// </summary>
|
||||
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<string, int>(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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user