// See https://aka.ms/new-console-template for more information using MachineSim; using MP.MONO.Core.DTO; using MP.MONO.Data.Controllers; using Newtonsoft.Json; using StackExchange.Redis; string lineSep = "------------------------------------------------------"; string redisConf = "127.0.0.1:6379"; Random rand = new Random(); Console.WriteLine(lineSep); Console.WriteLine($"Starting Machine SIM - redis server on {redisConf}!"); Console.WriteLine(lineSep); Console.WriteLine(""); Console.WriteLine("Running - press CTRL-C to stop SIM"); Console.WriteLine(""); //Create a connection ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(redisConf); ISubscriber sub = redis.GetSubscriber(); IDatabase? redisDb = redis.GetDatabase(); // imposto parametri simulatore var currSimGen = new Simulator(Directory.GetCurrentDirectory()); // 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(); /// /// Hash Redis contenente i dati MP di una specifico TYPE (es StatusMacchina, StateMachineIngressi, ...) /// /// /// string mHash(string dataType) { return $"MAPO-MONO:{dataType}"; } void saveAndSendMessage(string memKey, string value, string notifyChannel, string message) { // effettuo la scrittura nell'area di memoria indicata redisDb.StringSetAsync(memKey, value); ; //redis.GetDatabase().SetAdd(memKey, value); //redis.GetDatabase().StringSetAsync(memKey, value); // invio notifica tramite il canale richiesto sub.Publish(notifyChannel, message); Console.WriteLine($"[{notifyChannel}] key: {memKey} | val: {value} | message: {message}"); } void simAlarms() { int minPeriod = 3000; int maxPeriod = 10000; do { List activeAlarms = new List(); //int alarmCode = rand.Next(0, 255); int alarmCode = rand.Next(0, 160); // se >= 128 --> 0 (no alarm) alarmCode = alarmCode <= 127 ? alarmCode : 0; for (int i = 0; i < 8; i++) { if ((alarmCode & (1 << i)) != 0) { activeAlarms.Add($"Alarm {i:000}"); } } string rawData = JsonConvert.SerializeObject(activeAlarms); // decodifico allarme e lo trasformo in List di allarmi attivi... saveAndSendMessage(mHash("Machine:Alarms:Current"), rawData, "allarms", rawData); // attesa random Thread.Sleep(rand.Next(minPeriod, maxPeriod)); } while (true); } void simParameters() { int minPeriod = 250; int maxPeriod = 500; do { var newParams = currSimGen.getParameters(); string rawData = JsonConvert.SerializeObject(newParams); saveAndSendMessage(mHash("Machine:Parameters:Current"), rawData, "parameters", rawData); // attesa random Thread.Sleep(rand.Next(minPeriod, maxPeriod)); } while (true); } void simStatus() { int minPeriod = 2000; int maxPeriod = 3000; do { // recupero uno stato simulato var newStatus = currSimGen.getStatus(); string rawData = JsonConvert.SerializeObject(newStatus); saveAndSendMessage(mHash("Machine:Status:Current"), rawData, "status", rawData); // attesa random Thread.Sleep(rand.Next(minPeriod, maxPeriod)); } while (true); } void simProd() { int minPeriod = 3000; int maxPeriod = 10000; do { // recupero uno stato simulato var newStatus = currSimGen.getProd(); string rawData = JsonConvert.SerializeObject(newStatus); saveAndSendMessage(mHash("Machine:Production:Current"), rawData, "production", rawData); // attesa random Thread.Sleep(rand.Next(minPeriod, maxPeriod)); } while (true); } void simMachStat() { int minPeriod = 3000; int maxPeriod = 5000; do { // recupero uno stato simulato var newVal = currSimGen.getProdStats(); string rawData = JsonConvert.SerializeObject(newVal); saveAndSendMessage(mHash("Machine:MachStats:Current"), rawData, "machstats", rawData); // attesa random Thread.Sleep(rand.Next(minPeriod, maxPeriod)); } while (true); } void simMaint() { int minPeriod = 3000; int maxPeriod = 5000; do { // recupero uno stato simulato var newVal = currSimGen.getMaint(); string rawData = JsonConvert.SerializeObject(newVal); saveAndSendMessage(mHash("Machine:Maintenance:Current"), rawData, "maintenance", rawData); // attesa random Thread.Sleep(rand.Next(minPeriod, maxPeriod)); } while (true); } void simTools() { int minPeriod = 3000; int maxPeriod = 5000; do { // recupero uno stato simulato var newVal = currSimGen.getTools(); string rawData = JsonConvert.SerializeObject(newVal); saveAndSendMessage(mHash("Machine:Tools:Current"), rawData, "tools", rawData); // attesa random Thread.Sleep(rand.Next(minPeriod, maxPeriod)); } while (true); } void simEvents() { int minPeriod = 4000; int maxPeriod = 8000; do { // recupero uno stato simulato var newVal = currSimGen.getEvents(); string rawData = JsonConvert.SerializeObject(newVal); saveAndSendMessage(mHash("Machine:Events:Current"), rawData, "events", rawData); // attesa random Thread.Sleep(rand.Next(minPeriod, maxPeriod)); } while (true); } void simActivityLog() { int minPeriod = 5000; int maxPeriod = 10000; do { // recupero uno stato simulato var newVal = currSimGen.getActLog(); string rawData = JsonConvert.SerializeObject(newVal); saveAndSendMessage(mHash("Machine:ActivityLog:Current"), rawData, "activitylog", rawData); // attesa random Thread.Sleep(rand.Next(minPeriod, maxPeriod)); } while (true); }