Merge branch 'release/UpdateBlinkAlarms' into main
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Platforms>AnyCPU;x86;x64</Platforms>
|
||||
<Version>1.2.2210.2018</Version>
|
||||
<Version>1.2.2210.2318</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>MAPO-MONO</i>
|
||||
<h4>Version: 1.2.2210.2018</h4>
|
||||
<h4>Version: 1.2.2210.2318</h4>
|
||||
<br /> Release Note:
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
@@ -1 +1 @@
|
||||
1.2.2210.2018
|
||||
1.2.2210.2318
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>1.2.2210.2018</version>
|
||||
<version>1.2.2210.2318</version>
|
||||
<url>http://nexus.steamware.net/repository/SWS/MP.MONO.ANALYZER/stable/LAST/MP.Mon.zip</url>
|
||||
<changelog>http://nexus.steamware.net/repository/SWS/MP.MONO.ANALYZER/stable/LAST/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
|
||||
@@ -10,7 +10,8 @@ namespace MP.MONO.Core.CONF
|
||||
#region Public Constructors
|
||||
|
||||
public MachDataItem()
|
||||
{ }
|
||||
{
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
@@ -19,32 +20,32 @@ namespace MP.MONO.Core.CONF
|
||||
/// <summary>
|
||||
/// Categoria oggetto
|
||||
/// </summary>
|
||||
public DataItemCategory Category { get; set; }
|
||||
public DataItemCategory Category { get; set; } = DataItemCategory.EVENT;
|
||||
|
||||
/// <summary>
|
||||
/// Nome / descrizione
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
public string Name { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Tipologia specifica
|
||||
/// </summary>
|
||||
public string SubType { get; set; }
|
||||
public string SubType { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Tipologia principale
|
||||
/// </summary>
|
||||
public string Type { get; set; }
|
||||
public string Type { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Unità di misura
|
||||
/// </summary>
|
||||
public string Units { get; set; }
|
||||
public string Units { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// ID generico
|
||||
/// </summary>
|
||||
public string uuid { get; set; }
|
||||
public string uuid { get; set; } = "";
|
||||
|
||||
#endregion Public Properties
|
||||
}
|
||||
|
||||
@@ -43,8 +43,9 @@ namespace MP.MONO.Core
|
||||
public static readonly string ACT_LOG_CURR_KEY = $"{BASE_HASH}:Current:ActivityLog";
|
||||
public static readonly string ALARM_ADAPTER_ACT_KEY = $"{BASE_HASH}:Current:AdapterAlarm";
|
||||
public static readonly string ALARM_ACT_KEY = $"{BASE_HASH}:Current:AlarmsVal";
|
||||
public static readonly string ALARM_CURR_KEY = $"{BASE_HASH}:Current:Alarms";
|
||||
public static readonly string ALARM_BLINK_CURR_KEY = $"{BASE_HASH}:Current:AlarmsBlink";
|
||||
public static readonly string ALARM_CURR_KEY = $"{BASE_HASH}:Current:Alarms";
|
||||
public static readonly string ALARM_RECEIV_KEY = $"{BASE_HASH}:Current:AlarmsReceived";
|
||||
public static readonly string EVENT_LOG_CURR_KEY = $"{BASE_HASH}:Current:EventsLog";
|
||||
public static readonly string MACH_STATS_CURR_KEY = $"{BASE_HASH}:Current:MachStats";
|
||||
public static readonly string MAINT_STATS_CURR_KEY = $"{BASE_HASH}:Current:Maintenance";
|
||||
|
||||
@@ -55,7 +55,12 @@
|
||||
/// <summary>
|
||||
/// Modalità di invio di un elenco di allarmi attivi in un dato istante
|
||||
/// </summary>
|
||||
RawList
|
||||
RawList,
|
||||
|
||||
/// <summary>
|
||||
/// Modalità di invio di un elenco di allarmi attivi in un dato istante con BLINK ogni 10 sec (come amcchina multiax)
|
||||
/// </summary>
|
||||
RawListBlink
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
|
||||
@@ -0,0 +1,325 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using MP.MONO.Core;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
using StackExchange.Redis;
|
||||
|
||||
namespace MP.MONO.DECODER
|
||||
{
|
||||
public class AlarmsBlinkManager
|
||||
{
|
||||
#region Protected Fields
|
||||
|
||||
protected static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private static ConnectionMultiplexer? redisConn = null;
|
||||
private static IDatabase? redisDb = null;
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Public Constructors
|
||||
|
||||
public AlarmsBlinkManager()
|
||||
{
|
||||
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();
|
||||
|
||||
redisConn = ConnectionMultiplexer.Connect(config.GetConnectionString("Redis"));
|
||||
redisDb = redisConn.GetDatabase();
|
||||
|
||||
Log.Info("AlarmsBlinkManager OK");
|
||||
Console.WriteLine("AlarmsBlinkManager OK");
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Funzione chiamata x verifica allarmi:
|
||||
/// - fornisce elenco allarmi correnti aggiornati
|
||||
/// - fornisce elenco dei NUOVI come ref
|
||||
/// - fornisce elenco dei CESSATI come ref
|
||||
/// </summary>
|
||||
/// <param name="alarmListReceived"></param>
|
||||
/// <param name="alarmListCurrent"></param>
|
||||
/// <param name="alarmListAdded"></param>
|
||||
/// <param name="alarmListCeased"></param>
|
||||
/// <returns>Boolean che indica se ci siano state variazioni</returns>
|
||||
public static bool processData(List<string> alarmListReceived, ref List<string> alarmListCurrent, ref List<string> alarmListAdded, ref List<string> alarmListCeased)
|
||||
{
|
||||
bool answ = false;
|
||||
// verifico se sono zero e prima > 0...
|
||||
answ = (alarmListReceived.Count == 0 && alarmListCurrent.Count > 0);
|
||||
// primo step: verifico gli allarmi ricevuti siano > 0 e NON contengano duplicati...
|
||||
List<string> alarmListReceivedOk = new List<string>();
|
||||
if (alarmListReceived.Count > 0)
|
||||
{
|
||||
alarmListReceivedOk = alarmListReceived
|
||||
.GroupBy(x => x)
|
||||
.Select(grp => grp.First())
|
||||
.OrderBy(x => x)
|
||||
.ToList();
|
||||
Log.Info($"Ricezione update allarmi | {alarmListReceived.Count} --> {alarmListReceivedOk.Count} distinct");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Info($"Ricezione ZERO allarmi | {alarmListReceived.Count}");
|
||||
}
|
||||
|
||||
// salvo set allarmi ricevuti...
|
||||
setAlarms("LastReceived", alarmListReceivedOk);
|
||||
Log.Debug($"Salvataggio LastReceived | count {alarmListReceivedOk.Count}");
|
||||
|
||||
// elenco allarmi confermati
|
||||
var alarmListConf = alarmListCurrent.Intersect(alarmListReceivedOk);
|
||||
|
||||
// copio oggetti x allarmi NUOVI e cessati
|
||||
alarmListAdded = new List<string>(alarmListReceivedOk);
|
||||
alarmListCeased = new List<string>(alarmListCurrent);
|
||||
foreach (var item in alarmListConf)
|
||||
{
|
||||
// calcolo allarmi nuovi/cessati eliminando eventuali elementi comuni
|
||||
alarmListAdded.Remove(item);
|
||||
alarmListCeased.Remove(item);
|
||||
}
|
||||
|
||||
// aggiungo i nuovi a current
|
||||
alarmListCurrent.AddRange(alarmListAdded);
|
||||
// riordino
|
||||
alarmListCurrent = alarmListCurrent.OrderBy(x => x).ToList();
|
||||
// ...e salvo subito
|
||||
setAlarms("Current", alarmListCurrent);
|
||||
|
||||
// loggo controllo
|
||||
Log.Debug($"Esito controllo | {alarmListReceivedOk.Count} ricevuti | {alarmListAdded.Count} aggiunti | {alarmListCeased.Count} cessati");
|
||||
#if false
|
||||
// gestione allarmi muted
|
||||
List<AlarmListModel>? mutedAlarmsList = new List<AlarmListModel>();
|
||||
string rawData = redisDb.StringGet(Constants.ALARMS_SETT_RLIST_KEY);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
mutedAlarmsList = JsonConvert.DeserializeObject<List<AlarmListModel>>(rawData);
|
||||
}
|
||||
if (mutedAlarmsList == null)
|
||||
{
|
||||
mutedAlarmsList = dbController.AlarmListGetAll();
|
||||
}
|
||||
|
||||
// rileggo da REDIS la conf attuale allarmi già attivi da area ALARM_CURR_KEY
|
||||
|
||||
// FIXME TODO !!! usare una lista thread safe?!?!?
|
||||
List<string> lastAlarms = getAlarms("Current");
|
||||
List<string> startedAlarms = new List<string>();
|
||||
List<string> ceasedAlarms = new List<string>();
|
||||
string serAlarms = "";
|
||||
|
||||
// ciclo x ogni allarme ricevuto x vedere se sia INIZIATO o vada filtrato x muted
|
||||
if (alarmList != null)
|
||||
{
|
||||
// ciclo x ogni allarme attivo x verificare se si sia CHIUSO
|
||||
foreach (var newAlarm in alarmList)
|
||||
{
|
||||
var currNewAlarm = newAlarm;
|
||||
// se ho valori trim pre/post li applica...
|
||||
if (!string.IsNullOrEmpty(AlarmCleanPre))
|
||||
{
|
||||
currNewAlarm = currNewAlarm.Replace(AlarmCleanPre, "");
|
||||
}
|
||||
if (!string.IsNullOrEmpty(AlarmCleanPost))
|
||||
{
|
||||
currNewAlarm = currNewAlarm.Replace(AlarmCleanPost, "");
|
||||
}
|
||||
// se AlarmIgnoreEmpty=true + vuoto --> salto
|
||||
if (AlarmIgnoreEmpty && string.IsNullOrWhiteSpace(currNewAlarm))
|
||||
{
|
||||
alarmList.Remove(currNewAlarm);
|
||||
alarmList.Remove(newAlarm);
|
||||
}
|
||||
else
|
||||
{
|
||||
// in primis... se è muted --> lo escludo...
|
||||
bool isMuted = false;
|
||||
var maybeMuted = mutedAlarmsList.Where(x => x.FullValue == currNewAlarm).FirstOrDefault();
|
||||
if (maybeMuted != null)
|
||||
{
|
||||
isMuted = maybeMuted.Muted;
|
||||
}
|
||||
// cerco l'allarme nell'elenco degli allarmi dal DB
|
||||
AlarmListModel? foundAlarm = getAlarmModel(currNewAlarm);
|
||||
|
||||
if (!isMuted)
|
||||
{
|
||||
if (!lastAlarms.Contains(currNewAlarm))
|
||||
{
|
||||
if (foundAlarm != null)
|
||||
{
|
||||
// segno come iniziato...
|
||||
AlarmRecModel newAlarmRec = new AlarmRecModel()
|
||||
{
|
||||
MachineId = MachineId,
|
||||
DtStart = adesso,
|
||||
DtEnd = adesso.AddMinutes(-1),
|
||||
AlarmId = foundAlarm.AlarmId
|
||||
};
|
||||
alarmRecList.Add(newAlarmRec);
|
||||
startedAlarms.Add(currNewAlarm);
|
||||
lastAlarms.Add(currNewAlarm);
|
||||
needsWrite = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// rimuovo da alarmList perché muted...
|
||||
alarmList.Remove(currNewAlarm);
|
||||
alarmList.Remove(newAlarm);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// salvo
|
||||
serAlarms = JsonConvert.SerializeObject(lastAlarms);
|
||||
// invio sulla message pipeline corretta TUTTI gli allarmi serializzati
|
||||
alarmsSendPipe.saveAndSendMessage(Constants.ALARM_CURR_KEY, serAlarms);
|
||||
|
||||
// calcolo allarmi cessati...
|
||||
if (lastAlarms != null)
|
||||
{
|
||||
// ciclo x ogni allarme attivo x verificare se si sia CHIUSO
|
||||
foreach (var oldData in lastAlarms)
|
||||
{
|
||||
bool trovato = false;
|
||||
if (alarmList != null)
|
||||
{
|
||||
trovato = alarmList.Contains(oldData);
|
||||
}
|
||||
// se non c'è... segno cessato
|
||||
if (!trovato)
|
||||
{
|
||||
ceasedAlarms.Add(oldData);
|
||||
await Task.Run(async () =>
|
||||
{
|
||||
await checkCeasedAlarm(oldData);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Log.Debug($"Stato lastAlarms | count {lastAlarms.Count}");
|
||||
|
||||
// gli allarmi cessati avvio un task di verifica dopo periodo di blink
|
||||
if (needsWrite)
|
||||
{
|
||||
Log.Debug($"Preparazione AlarmLogRecord | count {lastAlarms.Count}");
|
||||
|
||||
// preparo dati x alarmLog
|
||||
AlarmLogModel newAlarmLog = new AlarmLogModel()
|
||||
{
|
||||
MachineId = MachineId,
|
||||
DtRif = adesso,
|
||||
MemAddress = "ND",
|
||||
Index = 0,
|
||||
// usare alarmList o lastAlarms
|
||||
Status = (uint)alarmList.Count,
|
||||
ValDecoded = alarmList.Count > 0 ? string.Join(", ", alarmList) : "All OK"
|
||||
};
|
||||
alarmLogList.Add(newAlarmLog);
|
||||
}
|
||||
|
||||
if (lastAlarms != null)
|
||||
{
|
||||
lastAlarms = lastAlarms.OrderBy(x => x).ToList();
|
||||
// serializzo l'elenco allarmi...
|
||||
serAlarms = JsonConvert.SerializeObject(lastAlarms);
|
||||
|
||||
// se vuoto metto controllo x chiusura
|
||||
if (lastAlarms.Count() == 0)
|
||||
{
|
||||
await Task.Run(async () =>
|
||||
{
|
||||
await checkCloseAllAlarm();
|
||||
});
|
||||
}
|
||||
|
||||
// invio sulla message pipeline corretta TUTTI gli allarmi serializzati
|
||||
alarmsSendPipe.saveAndSendMessage(Constants.ALARM_CURR_KEY, serAlarms);
|
||||
|
||||
Log.Debug($"Salvataggio/invio allarmi | serAlarms | count {lastAlarms.Count}");
|
||||
}
|
||||
#endif
|
||||
// restituisco esito esecuzione
|
||||
answ = answ || (alarmListAdded.Count > 0 || alarmListCeased.Count > 0);
|
||||
return answ;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Recupero da redis gli allarmi secondo tipo LastReceived / Current
|
||||
/// </summary>
|
||||
private static List<string> getAlarms(string tipo)
|
||||
{
|
||||
// rileggo da REDIS la conf attuale allarmi già attivi da area ALARM_CURR_KEY
|
||||
List<string> lastAlarms = new List<string>();
|
||||
// in base al tipo leggo una chiave redis o l'altra...
|
||||
string rawData = "";
|
||||
if (redisDb != null)
|
||||
{
|
||||
if (tipo == "LastReceived")
|
||||
{
|
||||
rawData = redisDb.StringGet(Constants.ALARM_RECEIV_KEY);
|
||||
}
|
||||
else
|
||||
{
|
||||
rawData = redisDb.StringGet(Constants.ALARM_CURR_KEY);
|
||||
}
|
||||
}
|
||||
// se trovati uso questi...
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
var rawLastAlarms = JsonConvert.DeserializeObject<List<string>>(rawData);
|
||||
lastAlarms = rawLastAlarms != null ? rawLastAlarms : new List<string>();
|
||||
Log.Debug($"Lettura allarmi | tipo: {tipo} | num: {lastAlarms.Count}");
|
||||
}
|
||||
return lastAlarms;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Salvo in redis gli allarmi secondo tipo LastReceived / Sent
|
||||
/// </summary>
|
||||
private static bool setAlarms(string tipo, List<string> listAlarm)
|
||||
{
|
||||
bool fatto = false;
|
||||
string rawData = JsonConvert.SerializeObject(listAlarm);
|
||||
|
||||
if (redisDb != null)
|
||||
{
|
||||
if (tipo == "LastReceived")
|
||||
{
|
||||
fatto = redisDb.StringSet(Constants.ALARM_RECEIV_KEY, rawData);
|
||||
}
|
||||
else
|
||||
{
|
||||
fatto = redisDb.StringSet(Constants.ALARM_CURR_KEY, rawData);
|
||||
}
|
||||
}
|
||||
|
||||
Log.Debug($"Scrittura allarmi | tipo: {tipo} | num: {listAlarm.Count}");
|
||||
return fatto;
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Platforms>AnyCPU;x86;x64</Platforms>
|
||||
<Version>1.2.2210.2018</Version>
|
||||
<Version>1.2.2210.2318</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
+17
-18
@@ -6,29 +6,29 @@
|
||||
throwExceptions="false"
|
||||
internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log">
|
||||
|
||||
<!-- optional, add some variables
|
||||
<!-- optional, add some variables
|
||||
https://github.com/nlog/NLog/wiki/Configuration-file#variables
|
||||
-->
|
||||
<variable name="myvar" value="myvalue" />
|
||||
<variable name="myvar" value="myvalue" />
|
||||
|
||||
<!--
|
||||
<!--
|
||||
See https://github.com/nlog/nlog/wiki/Configuration-file
|
||||
for information on customizing logging rules and outputs.
|
||||
-->
|
||||
<targets>
|
||||
<targets>
|
||||
|
||||
<!--
|
||||
<!--
|
||||
add your targets here
|
||||
See https://github.com/nlog/NLog/wiki/Targets for possible targets.
|
||||
See https://github.com/nlog/NLog/wiki/Layout-Renderers for the possible layout renderers.
|
||||
-->
|
||||
|
||||
<!--
|
||||
<!--
|
||||
Write events to a file with the date in the filename.
|
||||
<target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log"
|
||||
layout="${longdate} ${uppercase:${level}} ${message}" />
|
||||
-->
|
||||
<target xsi:type="File"
|
||||
<target xsi:type="File"
|
||||
name="fileTarget"
|
||||
fileName="${basedir}/logs/${shortdate}.log"
|
||||
layout="${longdate} | ${uppercase:${level}} | ${logger:shortName=false} | ${message}"
|
||||
@@ -37,22 +37,21 @@
|
||||
archiveAboveSize="1024000"
|
||||
maxArchiveFiles="90"
|
||||
enableArchiveFileCompression="true"
|
||||
keepFileOpen="false"
|
||||
/>
|
||||
<target xsi:type="ColoredConsole"
|
||||
keepFileOpen="false" />
|
||||
<target xsi:type="ColoredConsole"
|
||||
name="consoleTarget"
|
||||
layout="${longdate} | ${uppercase:${level}} | ${logger:shortName=true}| ${message}" />
|
||||
</targets>
|
||||
</targets>
|
||||
|
||||
<rules>
|
||||
<!-- add your logging rules here -->
|
||||
<rules>
|
||||
<!-- add your logging rules here -->
|
||||
|
||||
<!--
|
||||
<!--
|
||||
Write all events with minimal level of Debug (So Debug, Info, Warn, Error and Fatal, but not Trace) to "f"
|
||||
<logger name="*" minlevel="Debug" writeTo="f" />
|
||||
-->
|
||||
<!--<logger name="Microsoft.*" maxlevel="Info" final="true" />-->
|
||||
<!--<logger name="*" minlevel="Trace" writeTo="consoleTarget" />-->
|
||||
<logger name="*" minlevel="Info" writeTo="fileTarget" />
|
||||
</rules>
|
||||
<!--<logger name="Microsoft.*" maxlevel="Info" final="true" />-->
|
||||
<logger name="*" minlevel="Info" writeTo="consoleTarget" />
|
||||
<logger name="*" minlevel="Info" writeTo="fileTarget" />
|
||||
</rules>
|
||||
</nlog>
|
||||
+468
-9
@@ -8,6 +8,7 @@ using MP.MONO.Data.DbModels;
|
||||
using MP.MONO.DECODER;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
using Org.BouncyCastle.Asn1.Pkcs;
|
||||
using StackExchange.Redis;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
@@ -92,6 +93,7 @@ bool AlarmIgnoreEmpty = true;
|
||||
string AlarmCleanPre = "";
|
||||
string AlarmCleanPost = "";
|
||||
int DbSampleInt = 60;
|
||||
int BlinkPeriodMSec = 1000;
|
||||
setupConf();
|
||||
|
||||
// datetime dell'inizio esecuzione task... x usare un semaforo di veto doppia esecuzione entro 30 sec
|
||||
@@ -152,6 +154,7 @@ paramsRecvPipe.EA_NewMessage += ParamsValPipe_EA_NewMessage;
|
||||
* --------------------------------*/
|
||||
// init classe gestione allarmi con LUA
|
||||
AlarmsManager alarmsMan = new AlarmsManager();
|
||||
AlarmsBlinkManager alarmsBlinkMan = new AlarmsBlinkManager();
|
||||
// inizializzo gestione messagePipe da Redis x allarmi
|
||||
MessagePipe alarmsSendPipe = new MessagePipe(redisConn, Constants.ALARM_M_QUEUE);
|
||||
MessagePipe alarmsRecvPipe = new MessagePipe(redisConn, Constants.ALARM_RAW_QUEUE);
|
||||
@@ -159,10 +162,189 @@ MessagePipe alarmsRecvPipe = new MessagePipe(redisConn, Constants.ALARM_RAW_QUEU
|
||||
DateTime lastExecAlarms = DateTime.Now.AddHours(-1);
|
||||
// registro gestione eventi
|
||||
alarmsRecvPipe.EA_NewMessage += AlarmsValPipe_EA_NewMessage;
|
||||
setupAlarmState();
|
||||
|
||||
/* --------------------------------
|
||||
* Funzioni / metodi accessori
|
||||
* --------------------------------*/
|
||||
|
||||
/// <summary>
|
||||
/// Setup iniziale allarmi
|
||||
/// </summary>
|
||||
void setupAlarmState()
|
||||
{
|
||||
// setup preliminare allarmi da DB
|
||||
var actAlarmsList = dbController.AlarmRecGetActive().Select(x => x.AlarmListNav.FullValue).Distinct().ToList();
|
||||
setAlarms("Current", actAlarmsList);
|
||||
setAlarms("LastReceived", new List<string>());
|
||||
Log.Debug($"Setup Stato allarmi | act: {actAlarmsList.Count}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupero da redis gli allarmi secondo tipo LastReceived / Sent
|
||||
/// </summary>
|
||||
List<string> getAlarms(string tipo)
|
||||
{
|
||||
// rileggo da REDIS la conf attuale allarmi già attivi da area ALARM_CURR_KEY
|
||||
List<string> lastAlarms = new List<string>();
|
||||
// in base al tipo leggo una chiave redis o l'altra...
|
||||
string rawData = "";
|
||||
if (redisDb != null)
|
||||
{
|
||||
if (tipo == "LastReceived")
|
||||
{
|
||||
rawData = redisDb.StringGet(Constants.ALARM_RECEIV_KEY);
|
||||
}
|
||||
else
|
||||
{
|
||||
rawData = redisDb.StringGet(Constants.ALARM_CURR_KEY);
|
||||
}
|
||||
}
|
||||
// se trovati uso questi...
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
var rawLastAlarms = JsonConvert.DeserializeObject<List<string>>(rawData);
|
||||
lastAlarms = rawLastAlarms != null ? rawLastAlarms : new List<string>();
|
||||
Log.Debug($"Lettura allarmi | tipo: {tipo} | num: {lastAlarms.Count}");
|
||||
}
|
||||
return lastAlarms;
|
||||
}
|
||||
/// <summary>
|
||||
/// Salvo in redis gli allarmi secondo tipo LastReceived / Sent
|
||||
/// </summary>
|
||||
bool setAlarms(string tipo, List<string> listAlarm)
|
||||
{
|
||||
bool fatto = false;
|
||||
string rawData = JsonConvert.SerializeObject(listAlarm);
|
||||
|
||||
if (redisDb != null)
|
||||
{
|
||||
if (tipo == "LastReceived")
|
||||
{
|
||||
fatto = redisDb.StringSet(Constants.ALARM_RECEIV_KEY, rawData);
|
||||
}
|
||||
else
|
||||
{
|
||||
fatto = redisDb.StringSet(Constants.ALARM_CURR_KEY, rawData);
|
||||
}
|
||||
}
|
||||
|
||||
Log.Debug($"Scrittura allarmi | tipo: {tipo} | num: {listAlarm.Count}");
|
||||
return fatto;
|
||||
}
|
||||
|
||||
AlarmListModel? getAlarmModel(string alarmFullCode)
|
||||
{
|
||||
// cerco l'allarme nell'elenco degli allarmi dal DB
|
||||
AlarmListModel? foundAlarm = null;
|
||||
if (alarmsRecorded != null)
|
||||
{
|
||||
foundAlarm = alarmsRecorded
|
||||
.Where(x => x.FullValue == alarmFullCode)
|
||||
.FirstOrDefault();
|
||||
}
|
||||
|
||||
// se non lo trovo --> chiamo procedura che verifica su DB, eventualmente inserisce, restituisce nuovo elenco
|
||||
if (foundAlarm == null)
|
||||
{
|
||||
// salvo sul DB
|
||||
foundAlarm = dbController.AlarmListInsert(alarmFullCode);
|
||||
// ora rileggo ed aggiorno redis e cerco di nuovo record...
|
||||
alarmsRecorded = dbController.AlarmListGetAll();
|
||||
if (redisDb != null)
|
||||
{
|
||||
redisDb.StringSet(Constants.ALARMS_SETT_RLIST_KEY, JsonConvert.SerializeObject(alarmsRecorded));
|
||||
}
|
||||
}
|
||||
|
||||
return foundAlarm;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifica un allarme se sia x caso cessato dopo il periodo di pausa e quindi
|
||||
/// </summary>
|
||||
async Task<bool> checkCeasedAlarm(string alarmFullCode)
|
||||
{
|
||||
bool answ = false;
|
||||
Log.Debug($"checkCeasedAlarm 01 | Verifica scadenza allarmi | cod: {alarmFullCode}");
|
||||
|
||||
// attendo periodo pausa...
|
||||
await Task.Delay(BlinkPeriodMSec);
|
||||
|
||||
// cerco allarme da valore REDIS ultimi ricevuti
|
||||
var alarmListRecev = getAlarms("LastReceived");
|
||||
if (alarmListRecev != null)
|
||||
{
|
||||
// ...SE mancasse
|
||||
if (!alarmListRecev.Contains(alarmFullCode))
|
||||
{
|
||||
Log.Debug($"checkCeasedAlarm 02 | Allarme ancora mancante | cod: {alarmFullCode}");
|
||||
// recupero allarme...
|
||||
// se non lo trovo
|
||||
var foundAlarm = alarmsRecorded
|
||||
.Where(x => x.FullValue == alarmFullCode)
|
||||
.FirstOrDefault();
|
||||
// --> chiudo
|
||||
if (foundAlarm != null)
|
||||
{
|
||||
// salvo sul DB
|
||||
_ = dbController.AlarmRecCloseActive(foundAlarm.AlarmId);
|
||||
Log.Info($"Chiusura allarme | Id: {foundAlarm.AlarmId}");
|
||||
Log.Debug($"checkCeasedAlarm 03 | Chiusura allarme | cod: {alarmFullCode}");
|
||||
}
|
||||
// --> rimuovo da elenco attivi!
|
||||
var alarmListSent = getAlarms("Current");
|
||||
int numPre = alarmListSent.Count();
|
||||
alarmListSent.Remove(alarmFullCode);
|
||||
int numPost = alarmListSent.Count();
|
||||
Log.Debug($"checkCeasedAlarm 04 | Salvataggio Sent alarms | num: {numPre} --> {numPost}");
|
||||
// invio attivi...
|
||||
string serAlarms = JsonConvert.SerializeObject(alarmListSent);
|
||||
// invio sulla message pipeline corretta TUTTI gli allarmi serializzati
|
||||
alarmsSendPipe.saveAndSendMessage(Constants.ALARM_CURR_KEY, serAlarms);
|
||||
}
|
||||
answ = true;
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifica x TUTTI gli allarmi SE siano cessati topo 4 * periodo di controllo... zero ora e zero dopo...
|
||||
/// </summary>
|
||||
async Task<bool> checkCloseAllAlarm()
|
||||
{
|
||||
bool answ = false;
|
||||
Log.Debug($"Verifica checkCloseAllAlarm");
|
||||
// cerco allarme da valore REDIS ultimi ricevuti
|
||||
var alarmSent = getAlarms("Current");
|
||||
if (alarmSent != null)
|
||||
{
|
||||
bool isZero = alarmSent.Count() == 0;
|
||||
// solo SE ora sono zero...
|
||||
if (isZero)
|
||||
{
|
||||
// attendo periodo pausa...
|
||||
await Task.Delay(BlinkPeriodMSec * 2);
|
||||
// rileggo stato
|
||||
alarmSent = getAlarms("Current");
|
||||
isZero = alarmSent.Count() == 0;
|
||||
// ...SE fossero sempre zero
|
||||
if (isZero)
|
||||
{
|
||||
Log.Debug($"Verifica zero allarmi confermata, chiamo chiusura");
|
||||
// chiudo sul DB
|
||||
_ = dbController.AlarmRecCloseStarving();
|
||||
// invio resettati...
|
||||
string serAlarms = JsonConvert.SerializeObject(alarmSent);
|
||||
// invio sulla message pipeline corretta TUTTI gli allarmi serializzati
|
||||
alarmsSendPipe.saveAndSendMessage(Constants.ALARM_CURR_KEY, serAlarms);
|
||||
}
|
||||
}
|
||||
answ = true;
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupero da redis le conf (es modi,stati,allarmi)
|
||||
/// </summary>
|
||||
@@ -179,6 +361,9 @@ void setupConf()
|
||||
bool.TryParse(rConf, out AlarmIgnoreEmpty);
|
||||
AlarmCleanPre = config["OptPar:AlarmCleanPre"];
|
||||
AlarmCleanPost = config["OptPar:AlarmCleanPost"];
|
||||
// gestione blink allarmi
|
||||
rConf = config["OptPar:BlinkPeriodMSec"];
|
||||
int.TryParse(rConf, out BlinkPeriodMSec);
|
||||
// recupero valori e deserializzo
|
||||
string rawData = "";
|
||||
|
||||
@@ -223,6 +408,10 @@ void setupConf()
|
||||
{
|
||||
alarmsRListConf = JsonConvert.DeserializeObject<List<BaseAlarmRawConf>>(rawData);
|
||||
}
|
||||
else if (alarmMode == AlarmReportingMode.RawListBlink)
|
||||
{
|
||||
alarmsRListConf = JsonConvert.DeserializeObject<List<BaseAlarmRawConf>>(rawData);
|
||||
}
|
||||
else
|
||||
{
|
||||
alarmsBankBitConf = JsonConvert.DeserializeObject<List<BaseAlarmBankConf>>(rawData);
|
||||
@@ -233,13 +422,17 @@ void setupConf()
|
||||
/// <summary>
|
||||
/// Gestione evento ricezione messaggi allarmi secondo tipologia attiva...
|
||||
/// </summary>
|
||||
void AlarmsValPipe_EA_NewMessage(object? sender, EventArgs e)
|
||||
async void AlarmsValPipe_EA_NewMessage(object? sender, EventArgs e)
|
||||
{
|
||||
PubSubEventArgs currArgs = (PubSubEventArgs)e;
|
||||
// conversione on-the-fly List<string> --> allarmi
|
||||
if (!string.IsNullOrEmpty(currArgs.newMessage))
|
||||
{
|
||||
DateTime adesso = DateTime.Now;
|
||||
// variabili accessorie x persistenza su DB
|
||||
List<AlarmRecModel> alarmRecList = new List<AlarmRecModel>();
|
||||
List<AlarmLogModel> alarmLogList = new List<AlarmLogModel>();
|
||||
|
||||
if (alarmMode == AlarmReportingMode.RawList)
|
||||
{
|
||||
try
|
||||
@@ -256,9 +449,6 @@ void AlarmsValPipe_EA_NewMessage(object? sender, EventArgs e)
|
||||
.Select(grp => grp.First())
|
||||
.ToList();
|
||||
}
|
||||
|
||||
List<AlarmRecModel> alarmRecList = new List<AlarmRecModel>();
|
||||
List<AlarmLogModel> alarmLogList = new List<AlarmLogModel>();
|
||||
// gestione allarmi muted
|
||||
List<AlarmListModel>? mutedAlarmsList = new List<AlarmListModel>();
|
||||
string rawData = redisDb.StringGet(Constants.ALARMS_SETT_RLIST_KEY);
|
||||
@@ -324,9 +514,11 @@ void AlarmsValPipe_EA_NewMessage(object? sender, EventArgs e)
|
||||
isMuted = maybeMuted.Muted;
|
||||
}
|
||||
// cerco l'allarme nell'elenco degli allarmi dal DB
|
||||
AlarmListModel? foundAlarm = getAlarmModel(currNewAlarm);
|
||||
#if false
|
||||
var foundAlarm = alarmsRecorded
|
||||
.Where(x => x.FullValue == currNewAlarm)
|
||||
.FirstOrDefault();
|
||||
.Where(x => x.FullValue == currNewAlarm)
|
||||
.FirstOrDefault();
|
||||
// se non lo trovo --> chiamo procedura che verifica su DB,
|
||||
// eventualmente inserisce, restituisce nuovo elenco
|
||||
if (foundAlarm == null)
|
||||
@@ -337,6 +529,7 @@ void AlarmsValPipe_EA_NewMessage(object? sender, EventArgs e)
|
||||
alarmsRecorded = dbController.AlarmListGetAll();
|
||||
redisDb.StringSet(Constants.ALARMS_SETT_RLIST_KEY, JsonConvert.SerializeObject(alarmsRecorded));
|
||||
}
|
||||
#endif
|
||||
if (!isMuted)
|
||||
{
|
||||
if (!lastAlarms.Contains(currNewAlarm))
|
||||
@@ -455,8 +648,14 @@ void AlarmsValPipe_EA_NewMessage(object? sender, EventArgs e)
|
||||
alarmsSendPipe.saveAndSendMessage(Constants.ALARM_CURR_KEY, serAlarms);
|
||||
|
||||
// salvo sul DB
|
||||
_ = dbController.AlarmRecInsertMany(alarmRecList).Result;
|
||||
_ = dbController.AlarmLogInsertMany(alarmLogList).Result;
|
||||
if (alarmRecList.Count > 0)
|
||||
{
|
||||
_ = dbController.AlarmRecInsertMany(alarmRecList).Result;
|
||||
}
|
||||
if (alarmLogList.Count > 0)
|
||||
{
|
||||
_ = dbController.AlarmLogInsertMany(alarmLogList).Result;
|
||||
}
|
||||
|
||||
// salvo nuovo elenco allarmi
|
||||
lastAlarms = alarmList;
|
||||
@@ -464,6 +663,266 @@ void AlarmsValPipe_EA_NewMessage(object? sender, EventArgs e)
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
else if (alarmMode == AlarmReportingMode.RawListBlink)
|
||||
{
|
||||
bool needsWrite = false;
|
||||
try
|
||||
{
|
||||
// decodifico allarmi ricevuti
|
||||
var alarmListRaw = JsonConvert.DeserializeObject<List<string>>(currArgs.newMessage);
|
||||
// allarmi correnti
|
||||
List<string> alarmListCurrent = getAlarms("Current");
|
||||
|
||||
// init classi helper
|
||||
List<string> addedAlarms = new List<string>();
|
||||
List<string> ceasedAlarms = new List<string>();
|
||||
// chiamo procedura in blocco...
|
||||
bool fatto = AlarmsBlinkManager.processData(alarmListRaw, ref alarmListCurrent, ref addedAlarms, ref ceasedAlarms);
|
||||
|
||||
// salvo ed invio subito i current...
|
||||
string serAlarms = JsonConvert.SerializeObject(alarmListCurrent);
|
||||
alarmsSendPipe.saveAndSendMessage(Constants.ALARM_CURR_KEY, serAlarms);
|
||||
|
||||
// se cambiato --> preparo record LOG e salvo
|
||||
if (fatto)
|
||||
{
|
||||
// preparo dati x alarmLog
|
||||
AlarmLogModel newAlarmLog = new AlarmLogModel()
|
||||
{
|
||||
MachineId = MachineId,
|
||||
DtRif = adesso,
|
||||
MemAddress = "ND",
|
||||
Index = 0,
|
||||
Status = (uint)alarmListCurrent.Count,
|
||||
ValDecoded = alarmListCurrent.Count > 0 ? string.Join(", ", alarmListCurrent) : "All OK"
|
||||
};
|
||||
alarmLogList.Add(newAlarmLog);
|
||||
_ = dbController.AlarmLogInsertMany(alarmLogList).Result;
|
||||
Log.Info("Inserito Record AlarmLogModel");
|
||||
}
|
||||
|
||||
if (addedAlarms.Count > 0)
|
||||
{
|
||||
// preparo lista NEW x inserimento su DB
|
||||
foreach (var item in addedAlarms)
|
||||
{
|
||||
// cerco l'allarme nell'elenco degli allarmi dal DB
|
||||
AlarmListModel? foundAlarm = getAlarmModel(item);
|
||||
if (foundAlarm != null)
|
||||
{
|
||||
// segno come iniziato...
|
||||
AlarmRecModel newAlarmRec = new AlarmRecModel()
|
||||
{
|
||||
MachineId = MachineId,
|
||||
DtStart = adesso,
|
||||
DtEnd = adesso.AddMinutes(-1),
|
||||
AlarmId = foundAlarm.AlarmId
|
||||
};
|
||||
alarmRecList.Add(newAlarmRec);
|
||||
}
|
||||
}
|
||||
// salvo sul DB
|
||||
_ = dbController.AlarmRecInsertMany(alarmRecList).Result;
|
||||
Log.Info($"Inseriti {alarmRecList.Count} Records AlarmRecModel");
|
||||
}
|
||||
if (ceasedAlarms.Count > 0)
|
||||
{
|
||||
// chiamo task x verifica chiusura ritardata
|
||||
foreach (var item in ceasedAlarms)
|
||||
{
|
||||
await Task.Run(async () =>
|
||||
{
|
||||
await checkCeasedAlarm(item);
|
||||
});
|
||||
await Task.Delay(10);
|
||||
}
|
||||
// Loggo quanto fatto
|
||||
Log.Debug($"Chiamato controllo differito per {ceasedAlarms.Count} allarmi cessati");
|
||||
}
|
||||
|
||||
#if false
|
||||
|
||||
// effettuo selezione dei SOLI allarmi distinct (in caso di cambio posizione...)
|
||||
List<string> alarmList = new List<string>();
|
||||
if (alarmListRaw != null && alarmListRaw.Count > 0)
|
||||
{
|
||||
alarmList = alarmListRaw
|
||||
.GroupBy(x => x)
|
||||
.Select(grp => grp.First())
|
||||
.OrderBy(x => x)
|
||||
.ToList();
|
||||
}
|
||||
Log.Info($"Ricezione update allarmi | {alarmListRaw.Count} --> {alarmList.Count}");
|
||||
|
||||
// salvo set allarmi correnti...
|
||||
setAlarms("LastReceived", alarmList);
|
||||
Log.Debug($"Salvataggio LastReceived | count {alarmList.Count}");
|
||||
|
||||
// gestione allarmi muted
|
||||
List<AlarmListModel>? mutedAlarmsList = new List<AlarmListModel>();
|
||||
string rawData = redisDb.StringGet(Constants.ALARMS_SETT_RLIST_KEY);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
mutedAlarmsList = JsonConvert.DeserializeObject<List<AlarmListModel>>(rawData);
|
||||
}
|
||||
if (mutedAlarmsList == null)
|
||||
{
|
||||
mutedAlarmsList = dbController.AlarmListGetAll();
|
||||
}
|
||||
|
||||
// rileggo da REDIS la conf attuale allarmi già attivi da area ALARM_CURR_KEY
|
||||
|
||||
// FIXME TODO !!! usare una lista thread safe?!?!?
|
||||
List<string> lastAlarms = getAlarms("Current");
|
||||
List<string> startedAlarms = new List<string>();
|
||||
List<string> ceasedAlarms = new List<string>();
|
||||
string serAlarms = "";
|
||||
|
||||
// ciclo x ogni allarme ricevuto x vedere se sia INIZIATO o vada filtrato x muted
|
||||
if (alarmList != null)
|
||||
{
|
||||
// ciclo x ogni allarme attivo x verificare se si sia CHIUSO
|
||||
foreach (var newAlarm in alarmList)
|
||||
{
|
||||
var currNewAlarm = newAlarm;
|
||||
// se ho valori trim pre/post li applica...
|
||||
if (!string.IsNullOrEmpty(AlarmCleanPre))
|
||||
{
|
||||
currNewAlarm = currNewAlarm.Replace(AlarmCleanPre, "");
|
||||
}
|
||||
if (!string.IsNullOrEmpty(AlarmCleanPost))
|
||||
{
|
||||
currNewAlarm = currNewAlarm.Replace(AlarmCleanPost, "");
|
||||
}
|
||||
// se AlarmIgnoreEmpty=true + vuoto --> salto
|
||||
if (AlarmIgnoreEmpty && string.IsNullOrWhiteSpace(currNewAlarm))
|
||||
{
|
||||
alarmList.Remove(currNewAlarm);
|
||||
alarmList.Remove(newAlarm);
|
||||
}
|
||||
else
|
||||
{
|
||||
// in primis... se è muted --> lo escludo...
|
||||
bool isMuted = false;
|
||||
var maybeMuted = mutedAlarmsList.Where(x => x.FullValue == currNewAlarm).FirstOrDefault();
|
||||
if (maybeMuted != null)
|
||||
{
|
||||
isMuted = maybeMuted.Muted;
|
||||
}
|
||||
// cerco l'allarme nell'elenco degli allarmi dal DB
|
||||
AlarmListModel? foundAlarm = getAlarmModel(currNewAlarm);
|
||||
|
||||
if (!isMuted)
|
||||
{
|
||||
if (!lastAlarms.Contains(currNewAlarm))
|
||||
{
|
||||
if (foundAlarm != null)
|
||||
{
|
||||
// segno come iniziato...
|
||||
AlarmRecModel newAlarmRec = new AlarmRecModel()
|
||||
{
|
||||
MachineId = MachineId,
|
||||
DtStart = adesso,
|
||||
DtEnd = adesso.AddMinutes(-1),
|
||||
AlarmId = foundAlarm.AlarmId
|
||||
};
|
||||
alarmRecList.Add(newAlarmRec);
|
||||
startedAlarms.Add(currNewAlarm);
|
||||
lastAlarms.Add(currNewAlarm);
|
||||
needsWrite = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// rimuovo da alarmList perché muted...
|
||||
alarmList.Remove(currNewAlarm);
|
||||
alarmList.Remove(newAlarm);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// salvo
|
||||
serAlarms = JsonConvert.SerializeObject(lastAlarms);
|
||||
// invio sulla message pipeline corretta TUTTI gli allarmi serializzati
|
||||
alarmsSendPipe.saveAndSendMessage(Constants.ALARM_CURR_KEY, serAlarms);
|
||||
|
||||
// calcolo allarmi cessati...
|
||||
if (lastAlarms != null)
|
||||
{
|
||||
// ciclo x ogni allarme attivo x verificare se si sia CHIUSO
|
||||
foreach (var oldData in lastAlarms)
|
||||
{
|
||||
bool trovato = false;
|
||||
if (alarmList != null)
|
||||
{
|
||||
trovato = alarmList.Contains(oldData);
|
||||
}
|
||||
// se non c'è... segno cessato
|
||||
if (!trovato)
|
||||
{
|
||||
ceasedAlarms.Add(oldData);
|
||||
await Task.Run(async () =>
|
||||
{
|
||||
await checkCeasedAlarm(oldData);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Log.Debug($"Stato lastAlarms | count {lastAlarms.Count}");
|
||||
|
||||
// gli allarmi cessati avvio un task di verifica dopo periodo di blink
|
||||
if (needsWrite)
|
||||
{
|
||||
Log.Debug($"Preparazione AlarmLogRecord | count {lastAlarms.Count}");
|
||||
|
||||
// preparo dati x alarmLog
|
||||
AlarmLogModel newAlarmLog = new AlarmLogModel()
|
||||
{
|
||||
MachineId = MachineId,
|
||||
DtRif = adesso,
|
||||
MemAddress = "ND",
|
||||
Index = 0,
|
||||
// usare alarmList o lastAlarms
|
||||
Status = (uint)alarmList.Count,
|
||||
ValDecoded = alarmList.Count > 0 ? string.Join(", ", alarmList) : "All OK"
|
||||
};
|
||||
alarmLogList.Add(newAlarmLog);
|
||||
}
|
||||
|
||||
if (lastAlarms != null)
|
||||
{
|
||||
lastAlarms = lastAlarms.OrderBy(x => x).ToList();
|
||||
// serializzo l'elenco allarmi...
|
||||
serAlarms = JsonConvert.SerializeObject(lastAlarms);
|
||||
|
||||
// se vuoto metto controllo x chiusura
|
||||
if (lastAlarms.Count() == 0)
|
||||
{
|
||||
await Task.Run(async () =>
|
||||
{
|
||||
await checkCloseAllAlarm();
|
||||
});
|
||||
}
|
||||
|
||||
// invio sulla message pipeline corretta TUTTI gli allarmi serializzati
|
||||
alarmsSendPipe.saveAndSendMessage(Constants.ALARM_CURR_KEY, serAlarms);
|
||||
|
||||
Log.Debug($"Salvataggio/invio allarmi | serAlarms | count {lastAlarms.Count}");
|
||||
}
|
||||
|
||||
// salvo sul DB
|
||||
_ = dbController.AlarmRecInsertMany(alarmRecList).Result;
|
||||
_ = dbController.AlarmLogInsertMany(alarmLogList).Result;
|
||||
|
||||
Log.Debug($"Effettuato salvataggio su DB | alarmRecList {alarmRecList.Count} | alarmLogList {alarmLogList.Count}");
|
||||
#endif
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
@@ -474,7 +933,7 @@ void AlarmsValPipe_EA_NewMessage(object? sender, EventArgs e)
|
||||
{
|
||||
// variabili accessorie
|
||||
List<string> activeAlarmList = new List<string>();
|
||||
List<AlarmLogModel> alarmLogList = new 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>MAPO-MONO</i>
|
||||
<h4>Version: 1.2.2210.2018</h4>
|
||||
<h4>Version: 1.2.2210.2318</h4>
|
||||
<br /> Release Note:
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
@@ -1 +1 @@
|
||||
1.2.2210.2018
|
||||
1.2.2210.2318
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>1.2.2210.2018</version>
|
||||
<version>1.2.2210.2318</version>
|
||||
<url>http://nexus.steamware.net/repository/SWS/MP.MONO.DECODER/stable/LAST/MP.Mon.zip</url>
|
||||
<changelog>http://nexus.steamware.net/repository/SWS/MP.MONO.DECODER/stable/LAST/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"AllowedHosts": "*",
|
||||
"ConnectionStrings": {
|
||||
"Redis": "nkcredis.steamware.net:6379,DefaultDatabase=7,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false,password=BtN9Py1wtLfLRvmzWnOPJ7RytDM+CLiVsJ/16zduNTlV8IOPGNrtzJSXPUnImA5PqmUMhKaUqo9NdHIG",
|
||||
"AuthConnection": "Server=localhost;port=3306;database=GWMS;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
|
||||
"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;"
|
||||
@@ -39,7 +39,8 @@
|
||||
"AlarmMode": "RawList",
|
||||
"AlarmRegexp": "^{[\\d\\w\\:\\ \\.\\/\\(\\)]*}",
|
||||
//"AlarmRegexp": "^{.*}",
|
||||
"BlinkCount": 0,
|
||||
"DbSampleInt": 60
|
||||
"BlinkCount": 3,
|
||||
"DbSampleInt": 60,
|
||||
"BlinkPeriodMSec": 3000
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,12 @@
|
||||
}
|
||||
},
|
||||
"OptPar": {
|
||||
"AlarmMode": "RawList"
|
||||
"AlarmCleanPre": "",
|
||||
"AlarmCleanPost": "",
|
||||
"AlarmIgnoreEmpty": true,
|
||||
"AlarmMode": "RawList",
|
||||
"AlarmRegexp": "^{[\\d\\w\\:\\ \\.\\/\\(\\)]*}",
|
||||
"BlinkCount": 10,
|
||||
"DbSampleInt": 60
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ using MP.MONO.Core.DTO;
|
||||
using MP.MONO.Data.DbModels;
|
||||
using MP.MONO.Data.DTO;
|
||||
using NLog;
|
||||
using StackExchange.Redis;
|
||||
using System.Diagnostics;
|
||||
using static MP.MONO.Core.Enums;
|
||||
|
||||
@@ -11,6 +10,12 @@ namespace MP.MONO.Data.Controllers
|
||||
{
|
||||
public class MpDbController : IDisposable
|
||||
{
|
||||
#region Private Fields
|
||||
|
||||
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Public Constructors
|
||||
|
||||
public MpDbController()
|
||||
@@ -127,6 +132,7 @@ namespace MP.MONO.Data.Controllers
|
||||
{
|
||||
dbResult = localDbCtx
|
||||
.DbSetAlarmLog
|
||||
.AsNoTracking()
|
||||
.Where(x => x.MachineId == MachineId)
|
||||
.Include(m => m.MachineNav)
|
||||
.OrderByDescending(x => x.AlarmLogId)
|
||||
@@ -154,6 +160,7 @@ namespace MP.MONO.Data.Controllers
|
||||
{
|
||||
dbResult = localDbCtx
|
||||
.DbSetAlarmLog
|
||||
.AsNoTracking()
|
||||
.Where(x => (x.MachineId == MachineId) && (x.DtRif <= dtRif))
|
||||
.Include(m => m.MachineNav)
|
||||
.OrderByDescending(x => x.AlarmLogId)
|
||||
@@ -194,7 +201,6 @@ namespace MP.MONO.Data.Controllers
|
||||
}
|
||||
return fatto;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Inserimento di una lista record AlarmLog
|
||||
@@ -208,16 +214,19 @@ namespace MP.MONO.Data.Controllers
|
||||
{
|
||||
try
|
||||
{
|
||||
Stopwatch stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
await localDbCtx
|
||||
.DbSetAlarmLog
|
||||
.AddRangeAsync(newItems);
|
||||
await localDbCtx.SaveChangesAsync();
|
||||
fatto = true;
|
||||
stopWatch.Stop();
|
||||
TimeSpan ts = stopWatch.Elapsed;
|
||||
Log.Info($"AlarmLogInsertMany| DB insert | {newItems.Count} rec | {ts.TotalMilliseconds} ms");
|
||||
if (newItems.Count > 0)
|
||||
{
|
||||
Stopwatch stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
await localDbCtx
|
||||
.DbSetAlarmLog
|
||||
.AddRangeAsync(newItems);
|
||||
await localDbCtx.SaveChangesAsync();
|
||||
fatto = true;
|
||||
stopWatch.Stop();
|
||||
TimeSpan ts = stopWatch.Elapsed;
|
||||
Log.Info($"AlarmLogInsertMany| DB insert | {newItems.Count} rec | {ts.TotalMilliseconds} ms");
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
@@ -259,6 +268,63 @@ namespace MP.MONO.Data.Controllers
|
||||
return fatto;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Chiude ultimo record di allarmi aperti (avendo verificato zia zero da un pò...)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> AlarmRecCloseStarving()
|
||||
{
|
||||
bool fatto = false;
|
||||
using (MapoMonoContext localDbCtx = new MapoMonoContext())
|
||||
{
|
||||
try
|
||||
{
|
||||
DateTime adesso = DateTime.Now;
|
||||
var candList = localDbCtx
|
||||
.DbSetAlarmRec
|
||||
.Where(x => x.DtStart >= x.DtEnd)
|
||||
.ToList();
|
||||
foreach (var item in candList)
|
||||
{
|
||||
item.DtEnd = adesso;
|
||||
}
|
||||
await localDbCtx.SaveChangesAsync();
|
||||
fatto = true;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Eccezione durante AlarmRecCloseStarving{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
return fatto;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupero elenco allarmi Rec ATTIVI (non chiusi)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<AlarmRecModel> AlarmRecGetActive()
|
||||
{
|
||||
List<AlarmRecModel> dbResult = new List<AlarmRecModel>();
|
||||
using (MapoMonoContext localDbCtx = new MapoMonoContext())
|
||||
{
|
||||
try
|
||||
{
|
||||
dbResult = localDbCtx
|
||||
.DbSetAlarmRec
|
||||
.AsNoTracking()
|
||||
.Where(x => x.DtStart >= x.DtEnd)
|
||||
.Include(m => m.AlarmListNav)
|
||||
.ToList();
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Eccezione durante AlarmRecGetActive{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupero elenco allarmi Rec (ultimi dato "skip")
|
||||
/// </summary>
|
||||
@@ -275,6 +341,7 @@ namespace MP.MONO.Data.Controllers
|
||||
{
|
||||
dbResult = localDbCtx
|
||||
.DbSetAlarmRec
|
||||
.AsNoTracking()
|
||||
.Where(x => x.MachineId == MachineId)
|
||||
.Include(m => m.MachineNav)
|
||||
.Include(m => m.AlarmListNav)
|
||||
@@ -303,6 +370,7 @@ namespace MP.MONO.Data.Controllers
|
||||
{
|
||||
dbResult = localDbCtx
|
||||
.DbSetAlarmRec
|
||||
.AsNoTracking()
|
||||
.Where(x => (x.MachineId == MachineId) && (x.DtStart <= dtRif))
|
||||
.Include(m => m.MachineNav)
|
||||
.Include(m => m.AlarmListNav)
|
||||
@@ -465,16 +533,54 @@ namespace MP.MONO.Data.Controllers
|
||||
{
|
||||
try
|
||||
{
|
||||
Stopwatch stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
await localDbCtx
|
||||
.DbSetAlarmRec
|
||||
.AddRangeAsync(newItems);
|
||||
await localDbCtx.SaveChangesAsync();
|
||||
fatto = true;
|
||||
stopWatch.Stop();
|
||||
TimeSpan ts = stopWatch.Elapsed;
|
||||
Log.Info($"AlarmRecInsertMany| DB insert | {newItems.Count} rec | {ts.TotalMilliseconds} ms");
|
||||
if (newItems.Count > 0)
|
||||
{
|
||||
Stopwatch stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
// verifico eventuali items già aperti da NON dover aggiungere...
|
||||
List<int>? stillOpenAlarms = localDbCtx
|
||||
.DbSetAlarmRec
|
||||
.Where(x => x.DtStart >= x.DtEnd)
|
||||
.Select(x => x.AlarmId)
|
||||
.ToList();
|
||||
|
||||
// costruisco l'elenco degli ID allarmi da inserire
|
||||
List<int>? listNewId = newItems
|
||||
.Select(x => x.AlarmId)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
var alarm2rem = listNewId.Intersect(stillOpenAlarms).ToList();
|
||||
// andrò ad inserire solo gli item NON già presenti...
|
||||
foreach (var item in alarm2rem)
|
||||
{
|
||||
var item2del = newItems.FirstOrDefault(x => x.AlarmId == item);
|
||||
if (item2del != null)
|
||||
{
|
||||
newItems.Remove(item2del);
|
||||
}
|
||||
}
|
||||
|
||||
if (newItems.Count > 0)
|
||||
{
|
||||
// aggiungo
|
||||
await localDbCtx
|
||||
.DbSetAlarmRec
|
||||
.AddRangeAsync(newItems);
|
||||
// salvo!
|
||||
await localDbCtx.SaveChangesAsync();
|
||||
fatto = true;
|
||||
stopWatch.Stop();
|
||||
TimeSpan ts = stopWatch.Elapsed;
|
||||
Log.Info($"AlarmRecInsertMany| DB insert | {newItems.Count} rec | {ts.TotalMilliseconds} ms");
|
||||
}
|
||||
else
|
||||
{
|
||||
stopWatch.Stop();
|
||||
TimeSpan ts = stopWatch.Elapsed;
|
||||
Log.Info($"Allarmi già presenti non reinseriti | {ts.TotalMilliseconds} ms");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
@@ -836,18 +942,21 @@ namespace MP.MONO.Data.Controllers
|
||||
.DbSetPMTask
|
||||
.Where(x => x.PMTaskId == currRec.PMTaskId)
|
||||
.FirstOrDefault();
|
||||
// se effettivo delete
|
||||
if (forceDelete)
|
||||
if (currVal != null)
|
||||
{
|
||||
localDbCtx
|
||||
.DbSetPMTask
|
||||
.Remove(currVal);
|
||||
// se effettivo delete
|
||||
if (forceDelete)
|
||||
{
|
||||
localDbCtx
|
||||
.DbSetPMTask
|
||||
.Remove(currVal);
|
||||
}
|
||||
else
|
||||
{
|
||||
currVal.IsDisabled = true;
|
||||
}
|
||||
await localDbCtx.SaveChangesAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
currVal.IsDisabled = true;
|
||||
}
|
||||
await localDbCtx.SaveChangesAsync();
|
||||
fatto = true;
|
||||
}
|
||||
catch (Exception exc)
|
||||
@@ -874,12 +983,15 @@ namespace MP.MONO.Data.Controllers
|
||||
.DbSetPMTask
|
||||
.Where(x => x.PMTaskId == currRec.PMTaskId)
|
||||
.FirstOrDefault();
|
||||
// se effettivo delete
|
||||
if (currRec.IsDisabled)
|
||||
if (currVal != null)
|
||||
{
|
||||
currVal.IsDisabled = false;
|
||||
// se effettivo delete
|
||||
if (currRec.IsDisabled)
|
||||
{
|
||||
currVal.IsDisabled = false;
|
||||
}
|
||||
await localDbCtx.SaveChangesAsync();
|
||||
}
|
||||
await localDbCtx.SaveChangesAsync();
|
||||
fatto = true;
|
||||
}
|
||||
catch (Exception exc)
|
||||
@@ -1225,11 +1337,5 @@ namespace MP.MONO.Data.Controllers
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
#endregion Private Fields
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Platforms>AnyCPU;x86;x64</Platforms>
|
||||
<Version>1.2.2210.2018</Version>
|
||||
<Version>1.2.2210.2318</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
+186
-5
@@ -141,6 +141,10 @@ void setupConf()
|
||||
{
|
||||
alarmsRawConf = configManager.getAlarmsRawConf("SimAlarmRawList.json");
|
||||
}
|
||||
else if (alarmMode == AlarmReportingMode.RawListBlink)
|
||||
{
|
||||
alarmsRawConf = configManager.getAlarmsRawConf("SimAlarmRawList.json");
|
||||
}
|
||||
else
|
||||
{
|
||||
alarmsBankBitConf = configManager.getAlarmsBankConf();
|
||||
@@ -255,16 +259,193 @@ void saveAndSendMessage(string memKey, string notifyChannel, string message)
|
||||
}
|
||||
}
|
||||
|
||||
// Effettua salvataggio allarmi attivi
|
||||
void sendActiveAlarm(Dictionary<string, DateTime> CurrActiveAlarm)
|
||||
{
|
||||
// serializzo ed invio l'elenco dei soli allarmi attivi
|
||||
List<string> actAlarmList = CurrActiveAlarm.Select(x => x.Key).OrderBy(x => x).ToList();
|
||||
string rawDataVal = JsonConvert.SerializeObject(actAlarmList);
|
||||
saveAndSendMessage(Constants.ALARM_ACT_KEY, Constants.ALARM_RAW_QUEUE, rawDataVal);
|
||||
}
|
||||
|
||||
void simAlarms()
|
||||
{
|
||||
int minPeriod = 2000;
|
||||
int maxPeriod = 8000;
|
||||
// periodo minimo tra check allarmi
|
||||
int minPeriod = 1000;
|
||||
// periodo massimo tra check allarmi
|
||||
int maxPeriod = 5000;
|
||||
int percAllarmi = config.GetValue<int>("SimPar:PercAllarmi");
|
||||
int MaxAddAllarmi = config.GetValue<int>("SimPar:MaxAddAllarmi");
|
||||
double MaxDurationAllarmi = config.GetValue<int>("SimPar:MaxDurationAllarmi");
|
||||
|
||||
//--------------------------------
|
||||
// Parametri x SIM BLINK
|
||||
//--------------------------------
|
||||
// indica se l'ultimo allarme simulato fosse breve
|
||||
bool lastAlarmWasShort = true;
|
||||
// soglia (sec) tra interruzioni/allarmi
|
||||
int sogliaSecAllarmi = config.GetValue<int>("SimPar:SogliaAllarmi");
|
||||
// periodo (sec) ogni cui fare refresh allarmi (toglie 1:1 e rimette 1:1)
|
||||
int perRefresh = config.GetValue<int>("SimPar:PeriodRefresh");
|
||||
// periodo in secondi dopo cui è si generano allarmi o interruzioni (alternando)
|
||||
int minOkPeriod = config.GetValue<int>("SimPar:PeriodOk");
|
||||
|
||||
// in base alla modalità configurata effettuo la simulazione...
|
||||
if (alarmMode == AlarmReportingMode.RawList)
|
||||
if (alarmMode == AlarmReportingMode.RawListBlink)
|
||||
{
|
||||
// controllo se devo fare (se ho valori da simulare...)
|
||||
if (alarmsRawConf.Count > 0 && alarmsRawConf[0].messages.Count > 0)
|
||||
{
|
||||
DateTime lastOk = DateTime.Now;
|
||||
DateTime lastAlarm = DateTime.Now.AddMilliseconds(-1);
|
||||
int stdPeriod = 1000;
|
||||
|
||||
/* Modalità simulazione blink...
|
||||
* - verifico da quanto non ho allarmi
|
||||
* - se supero soglia minima ok --> simulo allarme o interruzione (alternati)
|
||||
* - vado in simulazione inizio/fine per le interruzioni (brevi)
|
||||
* - vado in simulazione inizio/fine per gli allarmi (che dovranno sparire e tornare ogni 10 sec)
|
||||
*/
|
||||
// Dict allarmi attivi (e da quando)
|
||||
Dictionary<string, DateTime> CurrActiveAlarm = new Dictionary<string, DateTime>();
|
||||
do
|
||||
{
|
||||
DateTime adesso = DateTime.Now;
|
||||
Dictionary<string, DateTime> NewActiveAlarm = new Dictionary<string, DateTime>();
|
||||
|
||||
bool newAlarm = false;
|
||||
// verifico SE ho superato la soglia minima x "tirare i dadi" e simulare allarmi
|
||||
if (adesso.Subtract(lastOk).TotalSeconds > minOkPeriod)
|
||||
{
|
||||
// simulo allarmi insorti
|
||||
foreach (var alarmGroup in alarmsRawConf)
|
||||
{
|
||||
// simulo e limito insorgenza NUOVI allarmi al percAllarmi/100 dei casi
|
||||
newAlarm = rand.Next(0, 100) <= percAllarmi;
|
||||
if (newAlarm)
|
||||
{
|
||||
int numNew = rand.Next(1, MaxAddAllarmi);
|
||||
// ciclo x aggiungere il numero di allarmi indicato
|
||||
for (int i = 0; i < numNew; i++)
|
||||
{
|
||||
// seleziono uno degli allarmi del banco.. dando + peso agli "allarmi bassi"
|
||||
int alarmIndex = 0;
|
||||
int msgBlock = rand.Next(1, 5);
|
||||
switch (msgBlock)
|
||||
{
|
||||
case 1:
|
||||
alarmIndex = rand.Next(0, alarmGroup.messages.Count / 4);
|
||||
break;
|
||||
case 2:
|
||||
alarmIndex = rand.Next(0, alarmGroup.messages.Count / 2);
|
||||
break;
|
||||
case 3:
|
||||
alarmIndex = rand.Next(0, alarmGroup.messages.Count * 3 / 4);
|
||||
break;
|
||||
case 4:
|
||||
default:
|
||||
alarmIndex = rand.Next(0, alarmGroup.messages.Count);
|
||||
break;
|
||||
}
|
||||
string rndNewAlarm = alarmGroup.messages[alarmIndex];
|
||||
if (!NewActiveAlarm.ContainsKey(rndNewAlarm))
|
||||
{
|
||||
NewActiveAlarm.Add(rndNewAlarm, DateTime.Now);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// se ho allarmi...
|
||||
if (NewActiveAlarm.Count > 0)
|
||||
{
|
||||
// verifico ultimo tipo allarmi breve/veloce
|
||||
if (lastAlarmWasShort)
|
||||
{
|
||||
Dictionary<string, DateTime> currAlarm = new Dictionary<string, DateTime>();
|
||||
// aggiungo 1:1 ed invio
|
||||
foreach (var item in NewActiveAlarm)
|
||||
{
|
||||
Thread.Sleep(rand.Next(400, 700));
|
||||
currAlarm.Add(item.Key, item.Value);
|
||||
sendActiveAlarm(currAlarm);
|
||||
}
|
||||
|
||||
// CICLO 01: aspetto periodo blink... tra 80 e 110% periodo
|
||||
Thread.Sleep(rand.Next(800 * perRefresh, 1100 * perRefresh));
|
||||
// tolgo tutti ed invio
|
||||
currAlarm = new Dictionary<string, DateTime>();
|
||||
sendActiveAlarm(currAlarm);
|
||||
// riaggiungo 1:1 ed invio
|
||||
foreach (var item in NewActiveAlarm)
|
||||
{
|
||||
Thread.Sleep(rand.Next(400, 700));
|
||||
currAlarm.Add(item.Key, item.Value);
|
||||
sendActiveAlarm(currAlarm);
|
||||
}
|
||||
Thread.Sleep(rand.Next(800 * perRefresh, 1000 * perRefresh));
|
||||
|
||||
// CICLO 02: aspetto periodo blink... tra 80 e 110% periodo
|
||||
// tolgo tutti ed invio
|
||||
currAlarm = new Dictionary<string, DateTime>();
|
||||
sendActiveAlarm(currAlarm);
|
||||
// riaggiungo 1:1 ed invio
|
||||
foreach (var item in NewActiveAlarm)
|
||||
{
|
||||
Thread.Sleep(rand.Next(400, 700));
|
||||
currAlarm.Add(item.Key, item.Value);
|
||||
sendActiveAlarm(currAlarm);
|
||||
}
|
||||
Thread.Sleep(rand.Next(800 * perRefresh, 1000 * perRefresh));
|
||||
|
||||
|
||||
// CICLO 03: aspetto periodo blink... tra 80 e 110% periodo
|
||||
// tolgo tutti ed invio
|
||||
currAlarm = new Dictionary<string, DateTime>();
|
||||
sendActiveAlarm(currAlarm);
|
||||
// riaggiungo 1:1 ed invio
|
||||
foreach (var item in NewActiveAlarm)
|
||||
{
|
||||
Thread.Sleep(rand.Next(400, 700));
|
||||
currAlarm.Add(item.Key, item.Value);
|
||||
sendActiveAlarm(currAlarm);
|
||||
}
|
||||
Thread.Sleep(rand.Next(800 * perRefresh, 1000 * perRefresh));
|
||||
|
||||
// svuoto
|
||||
NewActiveAlarm = new Dictionary<string, DateTime>();
|
||||
// invio update
|
||||
sendActiveAlarm(NewActiveAlarm);
|
||||
}
|
||||
else
|
||||
{
|
||||
// invio allarmi
|
||||
sendActiveAlarm(NewActiveAlarm);
|
||||
// aspetto poco
|
||||
Thread.Sleep(rand.Next(100, 1000 * sogliaSecAllarmi));
|
||||
// svuoto
|
||||
NewActiveAlarm = new Dictionary<string, DateTime>();
|
||||
// invio update
|
||||
sendActiveAlarm(NewActiveAlarm);
|
||||
}
|
||||
// resetto/svuoto allarmi correnti...
|
||||
NewActiveAlarm = new Dictionary<string, DateTime>();
|
||||
|
||||
// inverto tipo simulato...
|
||||
lastAlarmWasShort = !lastAlarmWasShort;
|
||||
// indico che ora è INIZIATO periodo OK...
|
||||
lastOk = DateTime.Now;
|
||||
}
|
||||
}
|
||||
// copio i nuovi allarmi nella memoria principale...
|
||||
CurrActiveAlarm = NewActiveAlarm;
|
||||
// invio
|
||||
sendActiveAlarm(CurrActiveAlarm);
|
||||
// attesa random
|
||||
Thread.Sleep(rand.Next(minPeriod, maxPeriod));
|
||||
} while (true);
|
||||
}
|
||||
}
|
||||
else if (alarmMode == AlarmReportingMode.RawList)
|
||||
{
|
||||
// controllo se devo fare (se ho valori da simulare...)
|
||||
if (alarmsRawConf.Count > 0 && alarmsRawConf[0].messages.Count > 0)
|
||||
@@ -503,8 +684,8 @@ void simMaint()
|
||||
|
||||
void simTools()
|
||||
{
|
||||
int minPeriod = 3000;
|
||||
int maxPeriod = 10000;
|
||||
int minPeriod = 30000;
|
||||
int maxPeriod = 120000;
|
||||
|
||||
|
||||
// controllo se devo fare (se ho valori da simulare...)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>MAPO-MONO</i>
|
||||
<h4>Version: 1.2.2210.2018</h4>
|
||||
<h4>Version: 1.2.2210.2318</h4>
|
||||
<br /> Release Note:
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
@@ -1 +1 @@
|
||||
1.2.2210.2018
|
||||
1.2.2210.2318
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>1.2.2210.2018</version>
|
||||
<version>1.2.2210.2318</version>
|
||||
<url>http://nexus.steamware.net/repository/SWS/MP.MONO.SIM/stable/LAST/MP.Mon.zip</url>
|
||||
<changelog>http://nexus.steamware.net/repository/SWS/MP.MONO.SIM/stable/LAST/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
|
||||
@@ -39,12 +39,17 @@
|
||||
"SerialNumber": "1521"
|
||||
},
|
||||
"OptPar": {
|
||||
"AlarmMode": "RawList"
|
||||
"AlarmMode": "RawListBlink"
|
||||
},
|
||||
"SimPar": {
|
||||
"MinSaveIntSec": 5,
|
||||
"PercAllarmi": 10,
|
||||
"MaxAddAllarmi": 4,
|
||||
"MaxDurationAllarmi": 10
|
||||
"PercAllarmi": 60,
|
||||
//"PercAllarmi": 20,
|
||||
"MaxAddAllarmi": 6,
|
||||
"MaxDurationAllarmi": 30,
|
||||
"PeriodRefresh": 10,
|
||||
"PeriodOk": 10,
|
||||
//"PeriodOk": 30,
|
||||
"SogliaAllarmi": 4
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,43 +2,43 @@
|
||||
{
|
||||
"source": "NC Alarm",
|
||||
"messages": [
|
||||
"NC Alarm 001",
|
||||
"NC Alarm 002",
|
||||
"NC Alarm 003",
|
||||
"NC Alarm 004",
|
||||
"NC Alarm 005",
|
||||
"NC Alarm 006",
|
||||
"NC Alarm 007",
|
||||
"NC Alarm 008",
|
||||
"NC Alarm 009",
|
||||
"NC Alarm 010",
|
||||
"NC Alarm 011",
|
||||
"NC Alarm 012",
|
||||
"NC Alarm 013",
|
||||
"NC Alarm 014",
|
||||
"NC Alarm 015",
|
||||
"NC Alarm 016"
|
||||
"NC Alarm 001 - this is a long text made for simulate real alarm text data and so create a bad looking UI like on production case",
|
||||
"NC Alarm 002 - this is a long text made for simulate real alarm text data and so create a bad looking UI like on production case",
|
||||
"NC Alarm 003 - this is a long text made for simulate real alarm text data and so create a bad looking UI like on production case",
|
||||
"NC Alarm 004 - this is a long text made for simulate real alarm text data and so create a bad looking UI like on production case",
|
||||
"NC Alarm 005 - this is a long text made for simulate real alarm text data and so create a bad looking UI like on production case",
|
||||
"NC Alarm 006 - this is a long text made for simulate real alarm text data and so create a bad looking UI like on production case",
|
||||
"NC Alarm 007 - this is a long text made for simulate real alarm text data and so create a bad looking UI like on production case",
|
||||
"NC Alarm 008 - this is a long text made for simulate real alarm text data and so create a bad looking UI like on production case",
|
||||
"NC Alarm 009 - this is a long text made for simulate real alarm text data and so create a bad looking UI like on production case",
|
||||
"NC Alarm 010 - this is a long text made for simulate real alarm text data and so create a bad looking UI like on production case",
|
||||
"NC Alarm 011 - this is a long text made for simulate real alarm text data and so create a bad looking UI like on production case",
|
||||
"NC Alarm 012 - this is a long text made for simulate real alarm text data and so create a bad looking UI like on production case",
|
||||
"NC Alarm 013 - this is a long text made for simulate real alarm text data and so create a bad looking UI like on production case",
|
||||
"NC Alarm 014 - this is a long text made for simulate real alarm text data and so create a bad looking UI like on production case",
|
||||
"NC Alarm 015 - this is a long text made for simulate real alarm text data and so create a bad looking UI like on production case",
|
||||
"NC Alarm 016 - this is a long text made for simulate real alarm text data and so create a bad looking UI like on production case"
|
||||
]
|
||||
},
|
||||
{
|
||||
"source": "PLC Alarm",
|
||||
"messages": [
|
||||
"PLC Warning 001",
|
||||
"PLC Warning 002",
|
||||
"PLC Warning 003",
|
||||
"PLC Warning 004",
|
||||
"PLC Warning 005",
|
||||
"PLC Warning 006",
|
||||
"PLC Warning 007",
|
||||
"PLC Warning 008",
|
||||
"PLC Warning 009",
|
||||
"PLC Warning 010",
|
||||
"PLC Warning 011",
|
||||
"PLC Warning 012",
|
||||
"PLC Warning 013",
|
||||
"PLC Warning 014",
|
||||
"PLC Warning 015",
|
||||
"PLC Warning 016"
|
||||
"PLC Warning 001 - this is a medium text made for simulate real warning and create a bad looking UI like on real UI",
|
||||
"PLC Warning 002 - this is a medium text made for simulate real warning and create a bad looking UI like on real UI",
|
||||
"PLC Warning 003 - this is a medium text made for simulate real warning and create a bad looking UI like on real UI",
|
||||
"PLC Warning 004 - this is a medium text made for simulate real warning and create a bad looking UI like on real UI",
|
||||
"PLC Warning 005 - this is a medium text made for simulate real warning and create a bad looking UI like on real UI",
|
||||
"PLC Warning 006 - this is a medium text made for simulate real warning and create a bad looking UI like on real UI",
|
||||
"PLC Warning 007 - this is a medium text made for simulate real warning and create a bad looking UI like on real UI",
|
||||
"PLC Warning 008 - this is a medium text made for simulate real warning and create a bad looking UI like on real UI",
|
||||
"PLC Warning 009 - this is a medium text made for simulate real warning and create a bad looking UI like on real UI",
|
||||
"PLC Warning 010 - this is a medium text made for simulate real warning and create a bad looking UI like on real UI",
|
||||
"PLC Warning 011 - this is a medium text made for simulate real warning and create a bad looking UI like on real UI",
|
||||
"PLC Warning 012 - this is a medium text made for simulate real warning and create a bad looking UI like on real UI",
|
||||
"PLC Warning 013 - this is a medium text made for simulate real warning and create a bad looking UI like on real UI",
|
||||
"PLC Warning 014 - this is a medium text made for simulate real warning and create a bad looking UI like on real UI",
|
||||
"PLC Warning 015 - this is a medium text made for simulate real warning and create a bad looking UI like on real UI",
|
||||
"PLC Warning 016 - this is a medium text made for simulate real warning and create a bad looking UI like on real UI"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -9,18 +9,20 @@
|
||||
{
|
||||
if (@ListRecords.Count == 0)
|
||||
{
|
||||
<div class="alert alert-success text-center display-4">All OK</div>
|
||||
<div class="alert alert-success text-center display-4">All OK</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<ul class="list-group">
|
||||
@foreach (var item in ListRecords)
|
||||
{
|
||||
<li class="list-group-item list-group-item-action">
|
||||
<div class="d-flex w-100 justify-content-between small" title="order">
|
||||
<div class="text-wrap">@item.Title</div>
|
||||
<div class="textConsensed">
|
||||
<b>@item.Value</b>
|
||||
<li class="list-group-item alarms list-group-item-action text-warning bg-danger">
|
||||
<div class="textConsensed w-100 small" title="order">
|
||||
<div class="small">
|
||||
@item.Title
|
||||
</div>
|
||||
<div class="">
|
||||
<span class="text-break">@item.Value</span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
<li class="list-group-item">
|
||||
<div class="d-flex w-100 justify-content-between" title="Current Cycle Time">
|
||||
<div><i class="fa-solid fa-stopwatch fa-2x"></i></div>
|
||||
<div class="h2" title="">
|
||||
<div class="h3" title="">
|
||||
<b>@($"{currProd.CycleTime.Hours:00}:{currProd.CycleTime.Minutes:00}:{currProd.CycleTime.Seconds:00}")</b>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Platforms>AnyCPU;x86;x64</Platforms>
|
||||
<Version>1.2.2210.2018</Version>
|
||||
<Version>1.2.2210.2318</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -128,7 +128,7 @@ namespace MP.MONO.UI.Pages
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
//StartTimer();
|
||||
#if false
|
||||
if (setLogRec)
|
||||
{
|
||||
SearchRecords = await MMDataService.AlarmLogGetFilt(MachineId, 0, MaxRecord);
|
||||
@@ -140,6 +140,7 @@ namespace MP.MONO.UI.Pages
|
||||
SearchRecordsREC = await MMDataService.AlarmRecGetFilt(MachineId, 0, MaxRecord);
|
||||
ListRecordsREC = SearchRecordsREC.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
|
||||
}
|
||||
#endif
|
||||
await ReloadData(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>MAPO-MONO</i>
|
||||
<h4>Version: 1.2.2210.2018</h4>
|
||||
<h4>Version: 1.2.2210.2318</h4>
|
||||
<br /> Release Note:
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
@@ -1 +1 @@
|
||||
1.2.2210.2018
|
||||
1.2.2210.2318
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>1.2.2210.2018</version>
|
||||
<version>1.2.2210.2318</version>
|
||||
<url>http://nexus.steamware.net/repository/SWS/MP.MONO.UI/stable/LAST/MP.Mon.zip</url>
|
||||
<changelog>http://nexus.steamware.net/repository/SWS/MP.MONO.UI/stable/LAST/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
|
||||
Reference in New Issue
Block a user