// See https://aka.ms/new-console-template for more information using MachineSim; using MP.MONO.Core; using MP.MONO.Core.CONF; using Newtonsoft.Json; using StackExchange.Redis; string lineSep = "------------------------------------------------------"; string redisConf = "nkcredis.steamware.net:6379,DefaultDatabase=7,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false,password=nkc.password"; Random rand = new Random(); List? statusList = new List(); List? modeList = new List(); Dictionary LogSimulator = new Dictionary(); DateTime lastLog = DateTime.Now; bool verboseLog = false; bool logWriting = false; 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 string confPath = Path.Combine(Directory.GetCurrentDirectory(), "conf"); // salvo configurazioni in redis setupConf(); var currSimGen = new Simulator(confPath, modeList.Count, statusList.Count); // 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(); /// /// Setup e salvataggio redis delle conf (es modi/stati) /// void setupConf() { // leggo e salvo conf stati string fullPath = Path.Combine(confPath, "ConfStatus.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, "ConfMode.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)); } } } void saveAndSendMessage(string memKey, string value, string notifyChannel, string message) { // effettuo la scrittura nell'area di memoria indicata redisDb.StringSetAsync(memKey, value); //redisDb.SetAdd(memKey, value); // invio notifica tramite il canale richiesto sub.Publish(notifyChannel, message); if (verboseLog) { Console.WriteLine($"[{notifyChannel}] key: {memKey} | val: {value} | message: {message}"); } else { try { if (LogSimulator.ContainsKey(notifyChannel)) { LogSimulator[notifyChannel]++; } else { LogSimulator.Add(notifyChannel, 1); } if (!logWriting) { logWriting = true; // vedo se loggare... DateTime adesso = DateTime.Now; if (adesso.Subtract(lastLog).TotalSeconds > 3) { lastLog = adesso; Console.WriteLine(lineSep); Console.WriteLine($"{adesso:yyyy.MM.dd HH:mm:ss}"); Console.WriteLine(lineSep); foreach (var item in LogSimulator) { Console.WriteLine($"{item.Key}: {item.Value} sim done"); } Console.WriteLine(lineSep); Console.WriteLine(""); } logWriting = false; } } catch (Exception ex) { Console.WriteLine($"ERROR{Environment.NewLine}{ex}"); } } } 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(Constants.ALARM_CURR_KEY, rawData, "alarms", 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(Constants.PARAMS_CURR_KEY, rawData, "parameters", rawData); // attesa random Thread.Sleep(rand.Next(minPeriod, maxPeriod)); } while (true); } void simStatus() { int minPeriod = 1000; int maxPeriod = 5000; do { // recupero uno stato simulato var newStatus = currSimGen.getStatus(); string rawData = JsonConvert.SerializeObject(newStatus); saveAndSendMessage(Constants.STATUS_CURR_KEY, 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(Constants.PROD_CURR_KEY, 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(Constants.MACH_STATS_CURR_KEY, 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(Constants.MAINT_STATS_CURR_KEY, 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(Constants.TOOLS_CURR_KEY, 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(Constants.EVENT_LOG_CURR_KEY, 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(Constants.ACT_LOG_CURR_KEY, rawData, "activitylog", rawData); // attesa random Thread.Sleep(rand.Next(minPeriod, maxPeriod)); } while (true); }