Completato update conf allarmi (da testare STEL)

This commit is contained in:
Samuele Locatelli
2023-12-20 17:49:45 +01:00
parent 94e5f09577
commit b118851550
7 changed files with 342 additions and 267 deletions
+41 -48
View File
@@ -82,11 +82,6 @@ namespace IOB_UT_NEXT
[JsonConverter(typeof(StringEnumConverter))]
public AlarmLevel blockLevel { get; set; } = AlarmLevel.Alarm;
/// <summary>
/// Chiave per contaggio degli items attivi, usato se blockType == AlarmBlockType.ActiveList
/// </summary>
public string activeCountKey { get; set; } = "";
/// <summary>
/// Elenco KEY codici allarme attivabili
/// </summary>
@@ -192,45 +187,50 @@ namespace IOB_UT_NEXT
/// <summary>
/// Inizializzazione classe con valori calcolati: attenzione si aspetta banchi da 32 bit...
/// ATTENZIONE: eseguita solo se blockType == bitmap
/// </summary>
public void setupData()
{
// inizializzo vettore valore allarmi x banco int8 x iniziare
alarmsState = new uint[size];
alarmsMask = new uint[size];
int bitSize = 8;
// 16/32 bit
if (size > 1)
// verifico si tratti di un tipo allarmi a bitmap... altrimenti salto
if (blockType == AlarmBlockType.Bitmap)
{
// inizializzo vettore valore allarmi x banco int16
alarmsState = new uint[size / 2];
alarmsMask = new uint[size / 2];
bitSize = 16;
}
// inizializzo vettore valore allarmi x banco int8 x iniziare
alarmsState = new uint[size];
alarmsMask = new uint[size];
int bitSize = 8;
// una volta inizializzata la classe di base sistemo vettori allarmi disabilitati ed il
// contatore blink dei fronti di discesa
alarmsBlinkCounter = new int[messages.Count];
int idx = 0;
int bank = 0;
foreach (var item in messages)
{
if (item.StartsWith("##"))
// 16/32 bit
if (size > 1)
{
alarmsBlinkCounter[idx] = -999;
// inizializzo vettore valore allarmi x banco int16
alarmsState = new uint[size / 2];
alarmsMask = new uint[size / 2];
bitSize = 16;
}
else
// una volta inizializzata la classe di base sistemo vettori allarmi disabilitati ed il
// contatore blink dei fronti di discesa
alarmsBlinkCounter = new int[messages.Count];
int idx = 0;
int bank = 0;
foreach (var item in messages)
{
alarmsBlinkCounter[idx] = 1;
alarmsMask[bank] += (uint)1 << idx;
}
idx++;
// sistemo bank/indice
if (idx > bitSize - 1)
{
bank++;
idx = 0;
if (item.StartsWith("##"))
{
alarmsBlinkCounter[idx] = -999;
}
else
{
alarmsBlinkCounter[idx] = 1;
alarmsMask[bank] += (uint)1 << idx;
}
idx++;
// sistemo bank/indice
if (idx > bitSize - 1)
{
bank++;
idx = 0;
}
}
}
}
@@ -401,6 +401,11 @@ namespace IOB_UT_NEXT
/// </summary>
public bool runModeTrad { get; set; } = false;
/// <summary>
/// Lista ulteriori configurazioni KeyValuePair
/// </summary>
public Dictionary<string, string> optKVP { get; set; } = new Dictionary<string, string>();
#endregion Public Properties
}
@@ -715,18 +720,6 @@ namespace IOB_UT_NEXT
/// </summary>
public string BaseIdMask { get; set; } = "";
#if false
/// <summary>
/// Base del NameSpace usato per le funzionalità di translate (parametri ACT-SET), da inserire come PRE
/// </summary>
public string BaseKeyTranslate { get; set; } = "";
/// <summary>
/// Dizionario per la traduzione delle ricette (se gestite) tra valori acquisiti in dossier e impostazioni da inviare (ACTual, SETup)
/// </summary>
public Dictionary<string, string> RecipeKeyTranslate { get; set; } = new Dictionary<string, string>();
#endif
#endregion Public Properties
}
+10 -1
View File
@@ -98,6 +98,10 @@
}
]
},
"optKVP": {
"alarmType": "ActiveList",
"alarmLevelMin": "Warning"
},
"fluxLogVeto": [
"AlarmCode(0)",
"AlarmCode(1)",
@@ -159,6 +163,11 @@
"MessageCode(17)",
"MessageCode(18)",
"MessageCode(19)",
"MessageText(0)",
"MessageText(1)",
"MessageText(2)",
"MessageText(3)",
"MessageText(4)",
"MessageText(5)",
"MessageText(6)",
"MessageText(7)",
@@ -426,7 +435,7 @@
},
"OPC_BladeRotTorque": {
"name": "OPC_BladeRotTorque",
"description": "BladeCoppia % nominale",
"description": "Blade Coppia % nominale",
"tipoMem": "String",
"memAddr": "ns=4;s=BladeRotTorque",
"index": 0,
+3 -5
View File
@@ -2,12 +2,11 @@
{
"description": "Messaggi",
"tipoMem": "UInt",
"memAddr": "Message",
"memAddr": "NumOfMessages",
"index": 0,
"size": 20,
"blockType": "ActiveList",
"blockLevel": "Message",
"activeCountKey": "NumOfMessages",
"blockLevel": "Warning",
"activeKeys": [
"MessageCode(0)",
"MessageCode(1)",
@@ -56,12 +55,11 @@
{
"description": "Allarmi",
"tipoMem": "UInt",
"memAddr": "Alarm",
"memAddr": "NumOfAlarms",
"index": 0,
"size": 20,
"blockType": "ActiveList",
"blockLevel": "Alarm",
"activeCountKey": "NumOfAlarms",
"activeKeys": [
"AlarmCode(0)",
"AlarmCode(1)",
+12
View File
@@ -6,6 +6,7 @@ using System.Diagnostics;
using System.Linq;
using System.Net.NetworkInformation;
using System.Threading;
using static IOB_UT_NEXT.BaseAlarmConf;
namespace IOB_WIN_NEXT.Iob
{
@@ -36,6 +37,17 @@ namespace IOB_WIN_NEXT.Iob
/// </summary>
public List<BaseAlarmConf> alarmMaps = new List<BaseAlarmConf>();
/// <summary>
/// Tipo di allarmi gestiti
/// rif: BaseAlarmConf.AlarmBlockType.[Bitmap/ActiveList]
/// </summary>
public AlarmBlockType alarmType = AlarmBlockType.Bitmap;
/// <summary>
/// Livello minimo allarmi da considerare x invio
/// </summary>
public AlarmLevel alarmLevelMin = AlarmLevel.Alarm;
/// <summary>
/// Conf adapter corrente
/// </summary>
+225 -154
View File
@@ -18,6 +18,7 @@ using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Serialization;
using static IOB_UT_NEXT.BaseAlarmConf;
using static IOB_UT_NEXT.CustomObj;
using static IOB_UT_NEXT.DataModel.Fimat;
using static MapoSDK.WharehouseData;
@@ -498,7 +499,8 @@ namespace IOB_WIN_NEXT.Iob
}
/// <summary>
/// URL per INVIO IN BLOCCO di un INCREMENTO x contapezzi (quelli della macchina: PLC/CNC) in una data SPECIFICA
/// URL per INVIO IN BLOCCO di un INCREMENTO x contapezzi (quelli della macchina: PLC/CNC)
/// in una data SPECIFICA
/// </summary>
public string urlAddPzCountAtDate
{
@@ -1690,9 +1692,25 @@ namespace IOB_WIN_NEXT.Iob
foreach (var item in alarmMaps)
{
bankVal = "";
var currState = currAlarmsState(item);
// calcolo vettore stringa degli allarmi...
bankVal = getAlarmState(item, currState);
// verifico ed eseguo secondo il tipo di allarme gestito...
if (alarmType == AlarmBlockType.Bitmap)
{
var currState = currAlarmsState(item);
// calcolo vettore stringa degli allarmi...
bankVal = getAlarmState(item, currState);
}
else if (alarmType == AlarmBlockType.ActiveList)
{
// cerco se sia superiore al livello minimo da conf
if (item.blockLevel >= alarmLevelMin)
{
int numActive = getAlarmStatus(item);
// calcolo vettore stringa degli allarmi...
bankVal = getAlarmState(item, numActive);
}
}
// sistemo se OK e/o invio
bankVal = string.IsNullOrEmpty(bankVal) ? "OK" : bankVal;
saveAlarmString(ref outVal, bankVal, item.description);
}
@@ -1739,6 +1757,24 @@ namespace IOB_WIN_NEXT.Iob
return valTransl;
}
/// <summary>
/// Effettua conversione tra gli allarmi attivi secondo configurazione banco allarmi
/// </summary>
/// <param name="memConf">Configurazione banco allarmi</param>
/// <param name="numAlarms">num allarmi attivi</param>
/// <returns></returns>
public virtual string getAlarmState(BaseAlarmConf memConf, int numAlarms)
{
string valTransl = "";
List<string> descAttivi = new List<string>();
// FAKE!!!: dovrebbe cercare in aree memoria x ogni valore configurato, vedere implementazione specifica es OpcUa
// combino string
valTransl = string.Join(",", descAttivi);
return valTransl;
}
/// <summary>
/// effettua recupero dati ed invio valori modificati...
/// </summary>
@@ -1932,16 +1968,6 @@ namespace IOB_WIN_NEXT.Iob
raiseRefresh(currDispData);
}
/// <summary>
/// Effettua task òettura a bassa velocità
/// </summary>
/// <returns></returns>
protected virtual bool processSlowDataRead()
{
bool answ = false;
return answ;
}
/// <summary>
/// Effettua conversione da valore bitmap ai valori configurati
/// </summary>
@@ -2428,12 +2454,6 @@ namespace IOB_WIN_NEXT.Iob
}
}
/// <summary>
/// Abilitazione gestione slow data
/// </summary>
protected bool enableSlowData = false;
protected int samplePeriodBase = 600;
/// <summary>
/// Verifica e processing x gestione ODL automatica
/// </summary>
@@ -4033,11 +4053,6 @@ namespace IOB_WIN_NEXT.Iob
/// </summary>
protected string CodGruppoIob = "ND-00";
/// <summary>
/// Determina se sia prevista gestione PODL (creazione/avvio/chiusura) come Soitaab
/// </summary>
protected bool EnabelPodlManFull = false;
/// <summary>
/// Num errori check alive
/// </summary>
@@ -4068,6 +4083,11 @@ namespace IOB_WIN_NEXT.Iob
/// </summary>
protected bool disablePzCounteByIob = false;
/// <summary>
/// Determina se sia prevista gestione PODL (creazione/avvio/chiusura) come Soitaab
/// </summary>
protected bool EnabelPodlManFull = false;
/// <summary>
/// Boolean x indicare contapezzi abilitato a livello di conf apoplicazione
/// </summary>
@@ -4078,11 +4098,46 @@ namespace IOB_WIN_NEXT.Iob
/// </summary>
protected bool enablePzCountByIob = true;
/// <summary>
/// Abilitazione gestione slow data
/// </summary>
protected bool enableSlowData = false;
/// <summary>
/// dizionario (opzionale) xz decodifica file da importare
/// </summary>
protected Dictionary<string, int> FileDecod = new Dictionary<string, int>();
/// <summary>
/// DeadBand x riduzione dati FluxLog (se 0 non gestita)
/// </summary>
protected double fluxLogRedDeadBand = 0;
/// <summary>
/// Determina se sia gestita riduzione dati FluxLog
/// </summary>
protected bool fluxLogReduce = false;
/// <summary>
/// Dizionario dei valori FluxLog ultimi verificati x veto
/// </summary>
protected Dictionary<string, double> fluxLogReduceLast = new Dictionary<string, double>();
/// <summary>
/// Dizionario dei valori FluxLog ultimi tipo STRING verificati x veto
/// </summary>
protected Dictionary<string, string> fluxLogReduceLastString = new Dictionary<string, string>();
/// <summary>
/// Dizionario dei veto send x ogni variabile quando non variata
/// </summary>
protected Dictionary<string, DateTime> fluxLogReduceVeto = new Dictionary<string, DateTime>();
/// <summary>
/// Finestra in minuti x invio dati FluxLog quando invariati
/// </summary>
protected int fluxLogResendPeriod = 60;
/// <summary>
/// indica che è richeisto forzatamente reset contapezzi
/// </summary>
@@ -4098,36 +4153,6 @@ namespace IOB_WIN_NEXT.Iob
/// </summary>
protected bool hasRecipe = false;
/// <summary>
/// Determina se sia gestita riduzione dati FluxLog
/// </summary>
protected bool fluxLogReduce = false;
/// <summary>
/// DeadBand x riduzione dati FluxLog (se 0 non gestita)
/// </summary>
protected double fluxLogRedDeadBand = 0;
/// <summary>
/// Finestra in minuti x invio dati FluxLog quando invariati
/// </summary>
protected int fluxLogResendPeriod = 60;
/// <summary>
/// Dizionario dei veto send x ogni variabile quando non variata
/// </summary>
protected Dictionary<string, DateTime> fluxLogReduceVeto = new Dictionary<string, DateTime>();
/// <summary>
/// Dizionario dei valori FluxLog ultimi verificati x veto
/// </summary>
protected Dictionary<string, double> fluxLogReduceLast = new Dictionary<string, double>();
/// <summary>
/// Dizionario dei valori FluxLog ultimi tipo STRING verificati x veto
/// </summary>
protected Dictionary<string, string> fluxLogReduceLastString = new Dictionary<string, string>();
/// <summary>
/// Array dei contatori x segnali blinking
/// </summary>
@@ -4173,6 +4198,11 @@ namespace IOB_WIN_NEXT.Iob
/// </summary>
protected DateTime lastWarnODL;
/// <summary>
/// Elenco parametri calcolati da inviare alla macchina (es ricetta con traduzione, RAMA/TFT)
/// </summary>
protected List<objItem> ListaCalcParams = new List<objItem>();
/// <summary>
/// Num massimo di errori in funzionalità check alive
/// </summary>
@@ -4223,6 +4253,8 @@ namespace IOB_WIN_NEXT.Iob
/// </summary>
protected int pzCountDelay;
protected int samplePeriodBase = 600;
/// <summary>
/// Dizionario di VC da trattare come TimeSeries (con conf decodificata + processing successivo...)
/// </summary>
@@ -4300,6 +4332,11 @@ namespace IOB_WIN_NEXT.Iob
}
}
/// <summary>
/// Folder in cui è presente il tool import excel + file json di conf
/// </summary>
protected string exclToolDirPath { get; set; } = "";
/// <summary>
/// Folder in cui salvare i file importati (es excel)
/// </summary>
@@ -4310,11 +4347,6 @@ namespace IOB_WIN_NEXT.Iob
/// </summary>
protected string fileImportFolder { get; set; } = "";
/// <summary>
/// Folder in cui è presente il tool import excel + file json di conf
/// </summary>
protected string exclToolDirPath { get; set; } = "";
/// <summary>
/// Tipologia di files da importare (default excel)
/// </summary>
@@ -4389,11 +4421,6 @@ namespace IOB_WIN_NEXT.Iob
/// </summary>
protected List<JobRow> ListaJobs { get; set; } = new List<JobRow>();
/// <summary>
/// Elenco parametri calcolati da inviare alla macchina (es ricetta con traduzione, RAMA/TFT)
/// </summary>
protected List<objItem> ListaCalcParams = new List<objItem>();
/// <summary>
/// Valore limite MASSIMO di invio di dati come array Json
/// </summary>
@@ -4638,24 +4665,6 @@ namespace IOB_WIN_NEXT.Iob
#region Protected Methods
/// <summary>
/// Aggiunge o aggiorna kvp ad un Dict
/// </summary>
/// <param name="currDict"></param>
/// <param name="newKey"></param>
/// <param name="newVal"></param>
protected void DictUpsert(ref Dictionary<string, string> currDict, string newKey, string newVal)
{
if (currDict.ContainsKey(newKey))
{
currDict[newKey] = newVal;
}
else
{
currDict.Add(newKey, newVal);
}
}
/// <summary>
/// Decodifica file MAP (caso <paramref name="ByteNum" />.bit)
/// </summary>
@@ -4826,6 +4835,24 @@ namespace IOB_WIN_NEXT.Iob
return answ;
}
/// <summary>
/// Aggiunge o aggiorna kvp ad un Dict
/// </summary>
/// <param name="currDict"></param>
/// <param name="newKey"></param>
/// <param name="newVal"></param>
protected void DictUpsert(ref Dictionary<string, string> currDict, string newKey, string newVal)
{
if (currDict.ContainsKey(newKey))
{
currDict[newKey] = newVal;
}
else
{
currDict.Add(newKey, newVal);
}
}
/// <summary>
/// Imposta eventuali altri valori default
/// </summary>
@@ -5078,55 +5105,78 @@ namespace IOB_WIN_NEXT.Iob
protected virtual bool hasAlarms()
{
bool answ = false;
int numErrors = 0;
int currStatus = 0;
ushort full16 = 65535;
int[] listInt = new int[2];
if (alarmMaps != null)
// 2023.12.20: aggiunta gestione secondo tipo allarmi come elenco OPC-UA (BLM/Adige)
if (alarmType == AlarmBlockType.Bitmap)
{
// leggo a ciclo le aree degli allarmi CONFIGURATI, se ne trovo --> segnalo allarme...
foreach (var item in alarmMaps)
int numErrors = 0;
int currStatus = 0;
ushort full16 = 65535;
int[] listInt = new int[2];
if (alarmMaps != null)
{
// banchi in array Int16 --> scompongo
for (int i = 0; i < item.size / 2; i++)
// leggo a ciclo le aree degli allarmi CONFIGURATI, se ne trovo --> segnalo allarme...
foreach (var item in alarmMaps)
{
currStatus = getAlarmStatus(item);
// ora filtro x l'i-esimo banco a 16 bit...
if (i == 0)
// banchi in array Int16 --> scompongo
for (int i = 0; i < item.size / 2; i++)
{
currStatus = (ushort)(currStatus & full16);
}
else
{
var temp = currStatus >> 16;
currStatus = (ushort)temp;
}
// aggiornamento blink counters dato nuovo valore
item.checkBlinkCounter(i, (uint)currStatus);
// calcolo indice errori
if ((uint)(item.alarmsMask[i] & currStatus) > 0)
{
numErrors++;
}
// verifico SE sia variato... confronto allarmi filtrato stile blink per bit status:
// - allarmi che iniziano per # IGNORATI
// - altri allarmi con un countdown da MAX_COUNTER_BLINK a 0 per il fronte
// di discesa
if (item.isChanged(i, (uint)currStatus))
{
// registro gli allarmi attivi e trasmetto...
if (sendAlarmVariations(item.memAddr, i, item.alarmsState[i], (uint)(item.alarmsMask[i] & currStatus), item.messages))
currStatus = getAlarmStatus(item);
// ora filtro x l'i-esimo banco a 16 bit...
if (i == 0)
{
// se inviato --> salvo stato da current...
item.updStatusVal(i, (uint)(item.alarmsMask[i] & currStatus));
currStatus = (ushort)(currStatus & full16);
}
else
{
var temp = currStatus >> 16;
currStatus = (ushort)temp;
}
// aggiornamento blink counters dato nuovo valore
item.checkBlinkCounter(i, (uint)currStatus);
// calcolo indice errori
if ((uint)(item.alarmsMask[i] & currStatus) > 0)
{
numErrors++;
}
// verifico SE sia variato... confronto allarmi filtrato stile blink per bit status:
// - allarmi che iniziano per # IGNORATI
// - altri allarmi con un countdown da MAX_COUNTER_BLINK a 0 per il fronte
// di discesa
if (item.isChanged(i, (uint)currStatus))
{
// registro gli allarmi attivi e trasmetto...
if (sendAlarmVariations(item.memAddr, i, item.alarmsState[i], (uint)(item.alarmsMask[i] & currStatus), item.messages))
{
// se inviato --> salvo stato da current...
item.updStatusVal(i, (uint)(item.alarmsMask[i] & currStatus));
}
}
}
}
}
answ = numErrors > 0;
}
// gestione allarmi come elenco
else if (alarmType == AlarmBlockType.ActiveList)
{
// verifico SE ho allarmi
if (alarmMaps != null && alarmMaps.Count > 0)
{
// ciclo x ogni blocco
foreach (var item in alarmMaps)
{
// cerco se sia superiore al livello minimo da conf
if (item.blockLevel >= alarmLevelMin)
{
// controllo variabile counter SE > 0...
int numCount = getAlarmStatus(item);
answ = numCount > 0;
}
}
}
}
answ = numErrors > 0;
return answ;
}
@@ -5491,6 +5541,17 @@ namespace IOB_WIN_NEXT.Iob
lgInfo("loadMemConf | Inizio setup allarmi");
alarmMaps = JsonConvert.DeserializeObject<List<BaseAlarmConf>>(jsonData);
setupAlarmMap();
// leggo il tipo gestione allarmi..
string sAlarmType = getOptJsonKVP("alarmType");
if (!string.IsNullOrEmpty(sAlarmType))
{
alarmType = (AlarmBlockType)Enum.Parse(typeof(AlarmBlockType), sAlarmType);
}
string sAlarmLMin = getOptJsonKVP("alarmLevelMin");
if (!string.IsNullOrEmpty(sAlarmLMin))
{
alarmLevelMin = (AlarmLevel)Enum.Parse(typeof(AlarmLevel), sAlarmLMin);
}
lgInfo("loadMemConf | Fine setup allarmi");
}
catch (Exception exc)
@@ -5675,23 +5736,6 @@ namespace IOB_WIN_NEXT.Iob
return answ;
}
#if false
/// <summary>
/// Traduzione del valore chiave configurato dal dizionario RecipeKeyTranslate + BaseKeyTranslate
/// </summary>
/// <param name="currKey"></param>
/// <returns></returns>
protected string RecipeKeyDecod(Dictionary<string, string> keyDict, string currKey)
{
string answ = currKey;
if (keyDict != null)
{
answ = keyDict[currKey];
}
return answ;
}
#endif
/// <summary>
/// Processa le richieste di scrittura memoria
/// </summary>
@@ -5866,6 +5910,33 @@ namespace IOB_WIN_NEXT.Iob
return answ;
}
/// <summary>
/// Effettua task òettura a bassa velocità
/// </summary>
/// <returns></returns>
protected virtual bool processSlowDataRead()
{
bool answ = false;
return answ;
}
#if false
/// <summary>
/// Traduzione del valore chiave configurato dal dizionario RecipeKeyTranslate + BaseKeyTranslate
/// </summary>
/// <param name="currKey"></param>
/// <returns></returns>
protected string RecipeKeyDecod(Dictionary<string, string> keyDict, string currKey)
{
string answ = currKey;
if (keyDict != null)
{
answ = keyDict[currKey];
}
return answ;
}
#endif
protected void raiseRefresh(newDisplayData currDispData)
{
if (currDispData != null)
@@ -6438,21 +6509,6 @@ namespace IOB_WIN_NEXT.Iob
sendOptVal(paramName, paramValueInt.ToString());
}
/// <summary>
/// Processa avvio PODL 8ed eventuale chiusura precedente)
/// </summary>
/// <param name="idxPOdl">Idx del PODL da avviare</param>
/// <param name="dtRif">DataOra di riferimento evento start</param>
protected bool SendStartPodl(int idxPOdl, DateTime dtRif)
{
bool answ = false;
DateTime dtCurr = DateTime.Now;
// chiamata avvio PODL (a posteriori)
string resp = callUrl($"{urlOdlStartFromPOdl}{idxPOdl}&dtEve={dtRif:yyyyMMddHHmmssfff}&dtCurr={dtCurr:yyyyMMddHHmmssfff}", false);
answ = resp == "OK";
return answ;
}
/// <summary>
/// Invio contapezzi alla dataora indicata
/// </summary>
@@ -6468,6 +6524,21 @@ namespace IOB_WIN_NEXT.Iob
return answ;
}
/// <summary>
/// Processa avvio PODL 8ed eventuale chiusura precedente)
/// </summary>
/// <param name="idxPOdl">Idx del PODL da avviare</param>
/// <param name="dtRif">DataOra di riferimento evento start</param>
protected bool SendStartPodl(int idxPOdl, DateTime dtRif)
{
bool answ = false;
DateTime dtCurr = DateTime.Now;
// chiamata avvio PODL (a posteriori)
string resp = callUrl($"{urlOdlStartFromPOdl}{idxPOdl}&dtEve={dtRif:yyyyMMddHHmmssfff}&dtCurr={dtCurr:yyyyMMddHHmmssfff}", false);
answ = resp == "OK";
return answ;
}
/// <summary>
/// Invia messaggio a logWatcher
/// </summary>
+25 -3
View File
@@ -598,9 +598,9 @@ namespace IOB_WIN_NEXT.IobOpc
// cerco se non sia un dato filtrato in FLUXLOG...
bool isFiltered = opcUaParams.fluxLogVeto.Contains(uuid);
// cerco filtro ANCHE PER solo display name x contains...
if(!isFiltered)
if (!isFiltered)
{
isFiltered = opcUaParams.fluxLogVetoContains.Contains(uuid) || opcUaParams.fluxLogVetoContains.Contains(MonIt.DisplayName) ;
isFiltered = opcUaParams.fluxLogVetoContains.Contains(uuid) || opcUaParams.fluxLogVetoContains.Contains(MonIt.DisplayName);
}
if (isFiltered)
{
@@ -1216,7 +1216,7 @@ namespace IOB_WIN_NEXT.IobOpc
}
/// <summary>
/// Recupero allarmi specifico x OPC-UA
/// Recupero allarmi specifico x OPC-UA, in formato BITMAP (se è gestito a bitmap) o come INT (counter tipo BLM)
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
@@ -1234,6 +1234,28 @@ namespace IOB_WIN_NEXT.IobOpc
return answ;
}
/// <summary>
/// Effettua conversione tra gli allarmi attivi secondo configurazione banco allarmi
/// </summary>
/// <param name="memConf">Configurazione banco allarmi</param>
/// <param name="numAlarms">num allarmi attivi</param>
/// <returns></returns>
public override string getAlarmState(BaseAlarmConf memConf, int numAlarms)
{
string valTransl = "";
List<string> descAttivi = new List<string>();
// dato il num di allarmi leggo i vari messaggi...
int numRead = numAlarms <= memConf.activeKeys.Count() ? numAlarms : memConf.activeKeys.Count();
for (int i = 0; i < numAlarms; i++)
{
descAttivi.Add(getDataItemValue(memConf.activeKeys[i]));
}
// combino string
valTransl = string.Join(",", descAttivi);
return valTransl;
}
protected byte[] getByteRaw(DataValue obj)
{
if (obj == null)
+26 -56
View File
@@ -100,72 +100,42 @@ namespace IOB_WIN_NEXT.IobOpc
#endregion Protected Methods
/// <summary>
/// Verifica presenza eventuali allarmi in modalità BLM/Adige
/// Processing degli allarmi (se presenti e gestiti)
/// </summary>
/// <returns></returns>
protected override bool hasAlarms()
public override Dictionary<string, string> getAlarmData()
{
/*----------------------------------------------
* verifica lo stato allarmi da
* - condizione allarme (key)
* - numero allarmi presenti
* - lettura relative chiavi OPC-UA dei codici
* - lettura relative chiavi OPC-UA del testo allarme
* - verifica variazione dell'insieme dei codici attivi (INT)
* - costruzione della stringa finale allarmi attivi (unico banco)
----------------------------------------------*/
bool answ = false;
int numErrors = 0;
int currStatus = 0;
ushort full16 = 65535;
int[] listInt = new int[2];
if (alarmMaps != null)
Dictionary<string, string> outVal = new Dictionary<string, string>();
// ora aggiungo (se ci fossero) gli allarmi...
if (alarmMaps != null && alarmMaps.Count > 0)
{
// leggo a ciclo le aree degli allarmi CONFIGURATI, se ne trovo --> segnalo allarme...
foreach (var item in alarmMaps)
if (hasAlarms())
{
// banchi in array Int16 --> scompongo
for (int i = 0; i < item.size / 2; i++)
string bankVal = "";
foreach (var item in alarmMaps)
{
currStatus = getAlarmStatus(item);
// ora filtro x l'i-esimo banco a 16 bit...
if (i == 0)
{
currStatus = (ushort)(currStatus & full16);
}
else
{
var temp = currStatus >> 16;
currStatus = (ushort)temp;
}
// aggiornamento blink counters dato nuovo valore
item.checkBlinkCounter(i, (uint)currStatus);
// calcolo indice errori
if ((uint)(item.alarmsMask[i] & currStatus) > 0)
{
numErrors++;
}
// verifico SE sia variato... confronto allarmi filtrato stile blink per bit status:
// - allarmi che iniziano per # IGNORATI
// - altri allarmi con un countdown da MAX_COUNTER_BLINK a 0 per il fronte
// di discesa
if (item.isChanged(i, (uint)currStatus))
{
// registro gli allarmi attivi e trasmetto...
if (sendAlarmVariations(item.memAddr, i, item.alarmsState[i], (uint)(item.alarmsMask[i] & currStatus), item.messages))
{
// se inviato --> salvo stato da current...
item.updStatusVal(i, (uint)(item.alarmsMask[i] & currStatus));
}
}
bankVal = "";
var currState = currAlarmsState(item);
// calcolo vettore stringa degli allarmi...
bankVal = getAlarmState(item, currState);
bankVal = string.IsNullOrEmpty(bankVal) ? "OK" : bankVal;
saveAlarmString(ref outVal, bankVal, item.description);
}
}
}
answ = numErrors > 0;
return answ;
else
{
lgTrace("No alarm found in alarmMaps");
}
if (periodicLog || outVal.Count > 0)
{
lgDebug($"Esito getAlarmData: {outVal.Count} allarmi attivi/validi in outVal");
}
return outVal;
}
}
}