Files
mapo-mono/MP.MONO.DECODER/Program.cs
T
2022-03-21 12:02:24 +01:00

393 lines
13 KiB
C#

using NLua;
using MP.MONO.DECODER;
using MP.MONO.Data;
using MP.MONO.Core;
using StackExchange.Redis;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using MP.MONO.Core.DTO;
using MP.MONO.Data.Controllers;
using NLog;
using MP.MONO.Data.DbModels;
using MP.MONO.Core.CONF;
// See https://aka.ms/new-console-template for more information
// 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();
// init LOG
Logger Log = LogManager.GetCurrentClassLogger();
// initi va di base
string lineSep = "---------------------------------------------";
Console.WriteLine(lineSep);
Console.WriteLine("Start DECODER with LUA integration!");
Console.WriteLine("");
Console.WriteLine("Running - press CTRL-C to stop");
Console.WriteLine(lineSep);
Console.WriteLine("");
// init DB
// init info x DB
string dbServerAddr = config["DbConfig:Server"];
string nKey = config["DbConfig:nKey"];
string sKey = config["DbConfig:sKey"];
DbConfig.InitDb(dbServerAddr, nKey, sKey);
// inizializzo il DB e creo (se necessario) l'utente
DbConfig.CheckUser(nKey, sKey);
// verifico se serve applicazione migrazioni
DbConfig.ExecMigrationMain();
//DbConfig.ExecMigrationIdentity();
// altri parametri per check vari
string connStringDB = DbConfig.CONNECTION_STRING;
MpDbController dbController = null!;
if (string.IsNullOrEmpty(connStringDB))
{
Log.Error("ConnString empty!");
}
else
{
dbController = new MpDbController();
Log.Info("DbController OK");
Console.WriteLine("DbController OK");
}
// init info di base
int MachineId = 1;
int.TryParse(config.GetValue<string>("MachineId"), out MachineId);
// init oggetti REDIS + messagePipe...
ConnectionMultiplexer.SetFeatureFlag("preventthreadtheft", true);
ConnectionMultiplexer redisConn = ConnectionMultiplexer.Connect(config.GetConnectionString("Redis"));
IDatabase? redisDb = redisConn.GetDatabase();
// preparo oggetti da configurare
List<BaseAlarmConf>? alarmsConf = new List<BaseAlarmConf>();
List<MachineMode>? machineModeConf = new List<MachineMode>();
List<MachineStatus>? machineStatusConf = new List<MachineStatus>();
// gestione configurazioni da redis
setupConf();
// inizializzo gestione messagePipe da Redis
MessagePipe alarmPipe = new MessagePipe(redisConn, Constants.ALARM_M_QUEUE);
MessagePipe alarmValPipe = new MessagePipe(redisConn, Constants.ALARM_ACT_VAL);
// registro gestione eventi
alarmValPipe.EA_NewMessage += AlarmValPipe_EA_NewMessage;
/// <summary>
/// Recupero da redis le conf (es modi,stati,allarmi)
/// </summary>
void setupConf()
{
// recupero valori e deserializzo
string rawData = "";
// machine conf
rawData = redisDb.StringGet(Constants.STATUS_CONF_KEY);
if (!string.IsNullOrEmpty(rawData))
{
machineStatusConf = JsonConvert.DeserializeObject<List<MachineStatus>>(rawData);
}
// machine mode
rawData = redisDb.StringGet(Constants.MODE_CONF_KEY);
if (!string.IsNullOrEmpty(rawData))
{
machineModeConf = JsonConvert.DeserializeObject<List<MachineMode>>(rawData);
}
// allarmi, versione base...
rawData = redisDb.StringGet(Constants.ALARMS_CONF_KEY);
if (!string.IsNullOrEmpty(rawData))
{
alarmsConf = JsonConvert.DeserializeObject<List<BaseAlarmConf>>(rawData);
}
}
// init classe gestione allarmi con LUA
AlarmManager alarmMan = new AlarmManager();
void AlarmValPipe_EA_NewMessage(object? sender, EventArgs e)
{
PubSubEventArgs currArgs = (PubSubEventArgs)e;
// conversione on-the-fly List<string> --> allarmi
if (!string.IsNullOrEmpty(currArgs.newMessage))
{
try
{
// verifico codici allarmi ricevuti
var alarmList = JsonConvert.DeserializeObject<Dictionary<string, uint>>(currArgs.newMessage);
if (alarmList != null)
{
// variabili accessorie
List<string> activeAlarmList = new List<string>();
List<AlarmLogModel> alarmLogList = new List<AlarmLogModel>();
// rileggo da REDIS la conf attuale allarmi da area ALARMS_SETT_KEY, altrimenti uso quella letta inizialmente da conf base
List<BaseAlarmConf>? currAlarmsConf = new List<BaseAlarmConf>();
string rawData = redisDb.StringGet(Constants.ALARMS_SETT_KEY);
// se trovati uso questi...
if (!string.IsNullOrEmpty(rawData))
{
currAlarmsConf = JsonConvert.DeserializeObject<List<BaseAlarmConf>>(rawData);
}
// altrimenti uso quelli di default inizialmente letti
else
{
currAlarmsConf = alarmsConf;
}
if (currAlarmsConf != null)
{
// ciclo x ogni bank di allarmi configurato
foreach (var alarmData in currAlarmsConf)
{
// recupero valore allarme
var bankVal = alarmList.FirstOrDefault(x => x.Key == alarmData.memAddr);
uint actVal = !string.IsNullOrEmpty(bankVal.Key) ? bankVal.Value : 0;
// valutare se dividere in 2 da 16... FIXME TODO
var bankAlarmList = AlarmManager.processData(alarmData.memAddr, alarmData.messages, alarmData.silenceMask[0], alarmData.disableMask[0], alarmData.alarmsState[0], ref actVal);
// salvo nuovo valore in oggetto...
if (alarmData.alarmsState[0] != actVal)
{
alarmData.alarmsState[0] = actVal;
// aggiungo...
activeAlarmList.AddRange(bankAlarmList);
AlarmLogModel newAlarm = new AlarmLogModel()
{
MachineId = MachineId,
DtRif = DateTime.Now,
MemAddress = bankVal.Key,
Index = alarmData != null ? alarmData.index : 0,
Status = alarmData != null ? (uint)bankVal.Value & alarmData.silenceMask[0] & alarmData.disableMask[0] : (uint)bankVal.Value,
ValDecoded = bankAlarmList.Count > 0 ? string.Join(", ", bankAlarmList) : "All OK"
};
alarmLogList.Add(newAlarm);
}
}
}
// salvo status aggiornato allarme...
redisDb.StringSet(Constants.ALARMS_SETT_KEY, JsonConvert.SerializeObject(currAlarmsConf));
// serializzo l'elenco allarmi...
string serAlarms = "[]";
serAlarms = JsonConvert.SerializeObject(activeAlarmList);
// invio sulla message pipeline corretta TUTTI gli allarmi serializzati
alarmPipe.saveAndSendMessage(Constants.ALARM_CURR_KEY, serAlarms);
if (dbController != null)
{
// salvo nel DB lo stato dei bank di allarme
foreach (var dbItem in alarmLogList)
{
_ = dbController.AlarmLogInsert(dbItem).Result;
}
}
}
}
catch
{ }
}
}
Lua state;
state = new Lua();
// preparo variabile x avvisare script che il modo è da NLua
state.DoString(" callMode = 'NLua' ");
int numTest = 0;
if (numTest == 1)
{
// inserisco dati in LUA...
List<string> alarmList = new List<string>();
string alarmStatus = "";
bool valueChanged = false;
string luaPath = Path.Combine(Directory.GetCurrentDirectory(), "lua", "AlarmDecoder.lua");
state.NewTable("alarmListTable");
LuaTable tabA = state.GetTable("alarmListTable");
// aggiorno valori
alarmList = new List<string>() { "Allarme01", "Allarme02", "##Allarme03", "Allarme04", "##Allarme05", "Allarme06", "Allarme07", "Allarme08" };
state["alarmList"] = alarmList;
state["numAlarm"] = alarmList.Count;
//state.DoString(@"
//function setupAlarms()
// for i = numAlarm,1, -1
// do
// alarmListTable[i] = alarmList[i-1]
// end
//end
//");
//var scriptFunc = state["setupAlarms"] as LuaFunction;
//var res2 = scriptFunc.Call();
// eseguo
state["lastVal"] = 0;
state["currVal"] = 3;
state.DoFile(luaPath);
alarmStatus = state.GetString("alarmStatus");
bool.TryParse(state.GetString("valueChanged"), out valueChanged);
Console.WriteLine($"Changed: {valueChanged}");
Console.WriteLine(alarmStatus);
//tabA = state.GetTable("alarmListActive");
//foreach (var item in tabA.Values)
//{
// Console.WriteLine(item);
//}
Thread.Sleep(800);
state["currVal"] = 7;
state.DoFile(luaPath);
alarmStatus = state.GetString("alarmStatus");
bool.TryParse(state.GetString("valueChanged"), out valueChanged);
Console.WriteLine($"Changed: {valueChanged}");
Console.WriteLine(alarmStatus);
//tabA = state.GetTable("alarmListActive");
//foreach (var item in tabA.Values)
//{
// Console.WriteLine(item);
//}
Thread.Sleep(800);
state["currVal"] = 15;
state.DoFile(luaPath);
alarmStatus = state.GetString("alarmStatus");
bool.TryParse(state.GetString("valueChanged"), out valueChanged);
Console.WriteLine($"Changed: {valueChanged}");
Console.WriteLine(alarmStatus);
//tabA = state.GetTable("alarmListActive");
//foreach (var item in tabA.Values)
//{
// Console.WriteLine(item);
//}
Thread.Sleep(800);
state["currVal"] = 0;
state.DoFile(luaPath);
alarmStatus = state.GetString("alarmStatus");
bool.TryParse(state.GetString("valueChanged"), out valueChanged);
Console.WriteLine($"Changed: {valueChanged}");
Console.WriteLine(alarmStatus);
//tabA = state.GetTable("alarmListActive");
//foreach (var item in tabA.Values)
//{
// Console.WriteLine(item);
//}
//state.DoString("a={b={c=2}}");
//LuaTable tabA = state.GetTable("a");
//LuaTable tabB = state.GetTable("a.b");
//state.DoString(" print(a) ");
//foreach (var item in tabB)
//{
// Console.WriteLine(item);
//}
//tabA = state.GetTable("alarmListActive");
//foreach (var item in tabA.Values)
//{
// Console.WriteLine(item);
//}
}
else if (numTest == 2)
{
static double Compute(double x)
{
return x * (x - 1);
}
var myobj = new MyClass();
myobj.IntegerProperty = 17;
state["var1"] = "someValue";
state["obj"] = myobj;
state["compute"] = new Func<double, double>(Compute);
// Will print "output: someValue"
state.DoString(" print('output: ' .. var1) ");
// Will print 18
state.DoString(" print(obj.IntegerProperty + 1) ");
// Will print "Doing something: hello"
state.DoString(" obj:DoSomething('hello') ");
state.DoString(" obj:SaveData('redis:key:name','{John = 320, Mary = 340, Bob = 880, Rob = 860}') ");
state.DoString("a={b={c=2}}");
LuaTable tabA = state.GetTable("a");
LuaTable tabB = state.GetTable("a.b");
state.DoString(" print(a) ");
foreach (var item in tabA)
{
Console.WriteLine(item);
}
foreach (var item in tabB)
{
Console.WriteLine(item);
}
// Will print "-0.1875"
state.DoString(" print(compute(0.25)) ");
// Reading values back
state.DoString(" x = compute(0.75) ");
state.DoString(" y = 2.0 * (obj.IntegerProperty * x) ");
double x = state.GetNumber("x");
double y = state.GetNumber("y");
// Will print: x = -0.1875, y = -6.375
Console.WriteLine($"x = {x}, y = {y}");
double val = 12.0;
state["x"] = val; // Create a global value 'x'
var resRaw = state.DoString("return 10 + x*(5 + 2)")[0];
double res = 0;
double.TryParse($"{resRaw}", out res);
Console.WriteLine($"{res}");
state.DoString("y = 10 + x*(4 + 2)");
var rawState = state["y"]; // Retrieve the value of y
double y2 = 0;
double.TryParse($"{rawState}", out y2);
Console.WriteLine($"{y2}");
state.DoString(@"
function ScriptFunc (val1, val2)
if val1 > val2 then
return val1 + 1
else
return val2 - 1
end
end
");
var scriptFunc = state["ScriptFunc"] as LuaFunction;
if (scriptFunc != null)
{
var res2 = (long)scriptFunc.Call(3, 9).First();
Console.WriteLine($"risultato script: {res2}");
}
// LuaFunction.Call will also return a array of objects, since a Lua function
// can return multiple values
}
else if (numTest == 99)
{
string luaPath = Path.Combine(Directory.GetCurrentDirectory(), "lua", "prova.lua");
state.DoFile(luaPath);
}
// Ciclo infinito x attesa chiusura con CTRL-C
do
{
Thread.Sleep(100);
} while (true);