diff --git a/IOB-UT-NEXT/ToMapo.cs b/IOB-UT-NEXT/ToMapo.cs index c9c90d56..f67d2cbf 100644 --- a/IOB-UT-NEXT/ToMapo.cs +++ b/IOB-UT-NEXT/ToMapo.cs @@ -82,11 +82,6 @@ namespace IOB_UT_NEXT [JsonConverter(typeof(StringEnumConverter))] public AlarmLevel blockLevel { get; set; } = AlarmLevel.Alarm; - /// - /// Chiave per contaggio degli items attivi, usato se blockType == AlarmBlockType.ActiveList - /// - public string activeCountKey { get; set; } = ""; - /// /// Elenco KEY codici allarme attivabili /// @@ -192,45 +187,50 @@ namespace IOB_UT_NEXT /// /// Inizializzazione classe con valori calcolati: attenzione si aspetta banchi da 32 bit... + /// ATTENZIONE: eseguita solo se blockType == bitmap /// 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 /// public bool runModeTrad { get; set; } = false; + /// + /// Lista ulteriori configurazioni KeyValuePair + /// + public Dictionary optKVP { get; set; } = new Dictionary(); + #endregion Public Properties } @@ -715,18 +720,6 @@ namespace IOB_UT_NEXT /// public string BaseIdMask { get; set; } = ""; -#if false - /// - /// Base del NameSpace usato per le funzionalità di translate (parametri ACT-SET), da inserire come PRE - /// - public string BaseKeyTranslate { get; set; } = ""; - - /// - /// Dizionario per la traduzione delle ricette (se gestite) tra valori acquisiti in dossier e impostazioni da inviare (ACTual, SETup) - /// - public Dictionary RecipeKeyTranslate { get; set; } = new Dictionary(); -#endif - #endregion Public Properties } diff --git a/IOB-WIN-NEXT/DATA/CONF/STEL_210.json b/IOB-WIN-NEXT/DATA/CONF/STEL_210.json index e33fefc0..007c777d 100644 --- a/IOB-WIN-NEXT/DATA/CONF/STEL_210.json +++ b/IOB-WIN-NEXT/DATA/CONF/STEL_210.json @@ -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, diff --git a/IOB-WIN-NEXT/DATA/CONF/STEL_210_alarm.json b/IOB-WIN-NEXT/DATA/CONF/STEL_210_alarm.json index 64c487e8..194bc532 100644 --- a/IOB-WIN-NEXT/DATA/CONF/STEL_210_alarm.json +++ b/IOB-WIN-NEXT/DATA/CONF/STEL_210_alarm.json @@ -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)", diff --git a/IOB-WIN-NEXT/Iob/BaseObj.cs b/IOB-WIN-NEXT/Iob/BaseObj.cs index 84b92141..b2833a84 100644 --- a/IOB-WIN-NEXT/Iob/BaseObj.cs +++ b/IOB-WIN-NEXT/Iob/BaseObj.cs @@ -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 /// public List alarmMaps = new List(); + /// + /// Tipo di allarmi gestiti + /// rif: BaseAlarmConf.AlarmBlockType.[Bitmap/ActiveList] + /// + public AlarmBlockType alarmType = AlarmBlockType.Bitmap; + + /// + /// Livello minimo allarmi da considerare x invio + /// + public AlarmLevel alarmLevelMin = AlarmLevel.Alarm; + /// /// Conf adapter corrente /// diff --git a/IOB-WIN-NEXT/Iob/Generic.cs b/IOB-WIN-NEXT/Iob/Generic.cs index 87ace825..e97f1c87 100644 --- a/IOB-WIN-NEXT/Iob/Generic.cs +++ b/IOB-WIN-NEXT/Iob/Generic.cs @@ -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 } /// - /// 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 /// 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; } + /// + /// Effettua conversione tra gli allarmi attivi secondo configurazione banco allarmi + /// + /// Configurazione banco allarmi + /// num allarmi attivi + /// + public virtual string getAlarmState(BaseAlarmConf memConf, int numAlarms) + { + string valTransl = ""; + List descAttivi = new List(); + + // FAKE!!!: dovrebbe cercare in aree memoria x ogni valore configurato, vedere implementazione specifica es OpcUa + + // combino string + valTransl = string.Join(",", descAttivi); + return valTransl; + } + /// /// effettua recupero dati ed invio valori modificati... /// @@ -1932,16 +1968,6 @@ namespace IOB_WIN_NEXT.Iob raiseRefresh(currDispData); } - /// - /// Effettua task òettura a bassa velocità - /// - /// - protected virtual bool processSlowDataRead() - { - bool answ = false; - return answ; - } - /// /// Effettua conversione da valore bitmap ai valori configurati /// @@ -2428,12 +2454,6 @@ namespace IOB_WIN_NEXT.Iob } } - /// - /// Abilitazione gestione slow data - /// - protected bool enableSlowData = false; - protected int samplePeriodBase = 600; - /// /// Verifica e processing x gestione ODL automatica /// @@ -4033,11 +4053,6 @@ namespace IOB_WIN_NEXT.Iob /// protected string CodGruppoIob = "ND-00"; - /// - /// Determina se sia prevista gestione PODL (creazione/avvio/chiusura) come Soitaab - /// - protected bool EnabelPodlManFull = false; - /// /// Num errori check alive /// @@ -4068,6 +4083,11 @@ namespace IOB_WIN_NEXT.Iob /// protected bool disablePzCounteByIob = false; + /// + /// Determina se sia prevista gestione PODL (creazione/avvio/chiusura) come Soitaab + /// + protected bool EnabelPodlManFull = false; + /// /// Boolean x indicare contapezzi abilitato a livello di conf apoplicazione /// @@ -4078,11 +4098,46 @@ namespace IOB_WIN_NEXT.Iob /// protected bool enablePzCountByIob = true; + /// + /// Abilitazione gestione slow data + /// + protected bool enableSlowData = false; + /// /// dizionario (opzionale) xz decodifica file da importare /// protected Dictionary FileDecod = new Dictionary(); + /// + /// DeadBand x riduzione dati FluxLog (se 0 non gestita) + /// + protected double fluxLogRedDeadBand = 0; + + /// + /// Determina se sia gestita riduzione dati FluxLog + /// + protected bool fluxLogReduce = false; + + /// + /// Dizionario dei valori FluxLog ultimi verificati x veto + /// + protected Dictionary fluxLogReduceLast = new Dictionary(); + + /// + /// Dizionario dei valori FluxLog ultimi tipo STRING verificati x veto + /// + protected Dictionary fluxLogReduceLastString = new Dictionary(); + + /// + /// Dizionario dei veto send x ogni variabile quando non variata + /// + protected Dictionary fluxLogReduceVeto = new Dictionary(); + + /// + /// Finestra in minuti x invio dati FluxLog quando invariati + /// + protected int fluxLogResendPeriod = 60; + /// /// indica che è richeisto forzatamente reset contapezzi /// @@ -4098,36 +4153,6 @@ namespace IOB_WIN_NEXT.Iob /// protected bool hasRecipe = false; - /// - /// Determina se sia gestita riduzione dati FluxLog - /// - protected bool fluxLogReduce = false; - - /// - /// DeadBand x riduzione dati FluxLog (se 0 non gestita) - /// - protected double fluxLogRedDeadBand = 0; - - /// - /// Finestra in minuti x invio dati FluxLog quando invariati - /// - protected int fluxLogResendPeriod = 60; - - /// - /// Dizionario dei veto send x ogni variabile quando non variata - /// - protected Dictionary fluxLogReduceVeto = new Dictionary(); - - /// - /// Dizionario dei valori FluxLog ultimi verificati x veto - /// - protected Dictionary fluxLogReduceLast = new Dictionary(); - - /// - /// Dizionario dei valori FluxLog ultimi tipo STRING verificati x veto - /// - protected Dictionary fluxLogReduceLastString = new Dictionary(); - /// /// Array dei contatori x segnali blinking /// @@ -4173,6 +4198,11 @@ namespace IOB_WIN_NEXT.Iob /// protected DateTime lastWarnODL; + /// + /// Elenco parametri calcolati da inviare alla macchina (es ricetta con traduzione, RAMA/TFT) + /// + protected List ListaCalcParams = new List(); + /// /// Num massimo di errori in funzionalità check alive /// @@ -4223,6 +4253,8 @@ namespace IOB_WIN_NEXT.Iob /// protected int pzCountDelay; + protected int samplePeriodBase = 600; + /// /// Dizionario di VC da trattare come TimeSeries (con conf decodificata + processing successivo...) /// @@ -4300,6 +4332,11 @@ namespace IOB_WIN_NEXT.Iob } } + /// + /// Folder in cui è presente il tool import excel + file json di conf + /// + protected string exclToolDirPath { get; set; } = ""; + /// /// Folder in cui salvare i file importati (es excel) /// @@ -4310,11 +4347,6 @@ namespace IOB_WIN_NEXT.Iob /// protected string fileImportFolder { get; set; } = ""; - /// - /// Folder in cui è presente il tool import excel + file json di conf - /// - protected string exclToolDirPath { get; set; } = ""; - /// /// Tipologia di files da importare (default excel) /// @@ -4389,11 +4421,6 @@ namespace IOB_WIN_NEXT.Iob /// protected List ListaJobs { get; set; } = new List(); - /// - /// Elenco parametri calcolati da inviare alla macchina (es ricetta con traduzione, RAMA/TFT) - /// - protected List ListaCalcParams = new List(); - /// /// Valore limite MASSIMO di invio di dati come array Json /// @@ -4638,24 +4665,6 @@ namespace IOB_WIN_NEXT.Iob #region Protected Methods - /// - /// Aggiunge o aggiorna kvp ad un Dict - /// - /// - /// - /// - protected void DictUpsert(ref Dictionary currDict, string newKey, string newVal) - { - if (currDict.ContainsKey(newKey)) - { - currDict[newKey] = newVal; - } - else - { - currDict.Add(newKey, newVal); - } - } - /// /// Decodifica file MAP (caso .bit) /// @@ -4826,6 +4835,24 @@ namespace IOB_WIN_NEXT.Iob return answ; } + /// + /// Aggiunge o aggiorna kvp ad un Dict + /// + /// + /// + /// + protected void DictUpsert(ref Dictionary currDict, string newKey, string newVal) + { + if (currDict.ContainsKey(newKey)) + { + currDict[newKey] = newVal; + } + else + { + currDict.Add(newKey, newVal); + } + } + /// /// Imposta eventuali altri valori default /// @@ -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>(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 - /// - /// Traduzione del valore chiave configurato dal dizionario RecipeKeyTranslate + BaseKeyTranslate - /// - /// - /// - protected string RecipeKeyDecod(Dictionary keyDict, string currKey) - { - string answ = currKey; - if (keyDict != null) - { - answ = keyDict[currKey]; - } - return answ; - } -#endif - /// /// Processa le richieste di scrittura memoria /// @@ -5866,6 +5910,33 @@ namespace IOB_WIN_NEXT.Iob return answ; } + /// + /// Effettua task òettura a bassa velocità + /// + /// + protected virtual bool processSlowDataRead() + { + bool answ = false; + return answ; + } + +#if false + /// + /// Traduzione del valore chiave configurato dal dizionario RecipeKeyTranslate + BaseKeyTranslate + /// + /// + /// + protected string RecipeKeyDecod(Dictionary 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()); } - /// - /// Processa avvio PODL 8ed eventuale chiusura precedente) - /// - /// Idx del PODL da avviare - /// DataOra di riferimento evento start - 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; - } - /// /// Invio contapezzi alla dataora indicata /// @@ -6468,6 +6524,21 @@ namespace IOB_WIN_NEXT.Iob return answ; } + /// + /// Processa avvio PODL 8ed eventuale chiusura precedente) + /// + /// Idx del PODL da avviare + /// DataOra di riferimento evento start + 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; + } + /// /// Invia messaggio a logWatcher /// diff --git a/IOB-WIN-NEXT/IobOpc/OpcUa.cs b/IOB-WIN-NEXT/IobOpc/OpcUa.cs index ffec9938..86353a01 100644 --- a/IOB-WIN-NEXT/IobOpc/OpcUa.cs +++ b/IOB-WIN-NEXT/IobOpc/OpcUa.cs @@ -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 } /// - /// 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) /// /// /// @@ -1234,6 +1234,28 @@ namespace IOB_WIN_NEXT.IobOpc return answ; } + + /// + /// Effettua conversione tra gli allarmi attivi secondo configurazione banco allarmi + /// + /// Configurazione banco allarmi + /// num allarmi attivi + /// + public override string getAlarmState(BaseAlarmConf memConf, int numAlarms) + { + string valTransl = ""; + List descAttivi = new List(); + // 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) diff --git a/IOB-WIN-NEXT/IobOpc/OpcUaEwonAdige.cs b/IOB-WIN-NEXT/IobOpc/OpcUaEwonAdige.cs index 4c2aeb47..e63a908c 100644 --- a/IOB-WIN-NEXT/IobOpc/OpcUaEwonAdige.cs +++ b/IOB-WIN-NEXT/IobOpc/OpcUaEwonAdige.cs @@ -100,72 +100,42 @@ namespace IOB_WIN_NEXT.IobOpc #endregion Protected Methods + + /// - /// Verifica presenza eventuali allarmi in modalità BLM/Adige + /// Processing degli allarmi (se presenti e gestiti) /// /// - protected override bool hasAlarms() + public override Dictionary 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 outVal = new Dictionary(); + // 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; } } } \ No newline at end of file