using MapoSDK; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; namespace IOB_UT_NEXT { /// /// Classe gestione configurazione parametri di base x allarmi /// public class BaseAlarmConf { #region Public Fields /// /// valore di aprtenza x un segnale di blink in caso di inizio variazione /// public int blinkVal = 30; #endregion Public Fields #region Public Properties /// /// Elenco dei contatori blink (x gestione caso frponte salita/discesa segnale hce blinka) /// public int[] alarmsBlinkCounter { get; set; } /// /// BitMask 16bit (1 = valido, 0 = filtro) degli allarmi silenziati/disabilitati (se iniziano per ##) come valore da sottrarre x check /// public uint[] alarmsMask { get; set; } /// /// Array dei valori allarme correnti /// public uint[] alarmsState { get; set; } /// /// Descrizione area allarmi /// public string description { get; set; } = ""; /// /// Indice nell'area di memoria (da valore iniziale = 0) /// public int index { get; set; } = 0; /// /// Nome "assoluto" della posizione nell'area di memoria (anche diverso da indice) /// public string memAddr { get; set; } = ""; /// /// Elenco allarmi configurati x la bitmap /// public List messages { get; set; } = new List(); /// /// Size in byte /// public int size { get; set; } = 0; /// /// Tipo di dato /// [JsonConverter(typeof(StringEnumConverter))] public plcDataType tipoMem { get; set; } = plcDataType.Boolean; #endregion Public Properties #region Public Methods /// /// Calcola il filtro da condizioen blink (ovvero maschera per valori indicati blinking) /// /// /// public uint blinkFilter(int num) { uint answ = 0; int idx = 16 * num; for (int i = 0; i < 16; i++) { if (alarmsBlinkCounter[idx + i] > 0) { answ += (uint)1 << i; } } return answ; } /// /// Effettua il decremento dei contatori blink (se >0) per gestire i segnali alternati sul fronte di discesa /// public void decreaseBlinkCounter() { int idx = 0; foreach (var item in alarmsBlinkCounter) { alarmsBlinkCounter[idx] = item > 0 ? item - 1 : item; idx++; } } /// /// Confronta un valore di stato allarme con lo stato precedentemente salvato considerando blink/veto /// /// Numero/indice del banco di allarme (uint16) /// Valore (bitmap) allarmi come uint16 /// public bool isChanged(int num, uint newValue) { // per prima cosa controllo valori RAW bool answ = !alarmsState[num].Equals(newValue); if (answ) { // controllo valori filtrati (sottraendo BITMASK i valori di filtro) answ = ((alarmsState[num] & alarmsMask[num]) != (newValue & alarmsMask[num])); // se fossero ancora differenti controllo ulteriore mask dato il counter dei blink: if (answ) { var blinkFilt = blinkFilter(num); answ = ((alarmsState[num] & (alarmsMask[num] | blinkFilt)) != (newValue & (alarmsMask[num] | blinkFilt))); } } return answ; } /// /// Inizializzazione classe con valori calcolati /// public void setupData() { // inizializzo vettore valore allarmi x banco int16 alarmsState = new uint[size / 2]; alarmsMask = new uint[size / 2]; // 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("##")) { alarmsBlinkCounter[idx] = -999; } else { alarmsMask[bank] += (uint)1 << idx; } idx++; // sistemo bank/indice if (idx > 15) { bank++; idx = 0; } } } /// /// Imposta il valore dello status attuale allarme impostando eventuale valore blink x le variazioni /// /// /// public void updStatusVal(int num, uint newStatus) { // calcola la maschera di variazione da valore precedente var variations = newStatus ^ alarmsState[num]; // ciclo sui 16 bit... for (int i = 0; i < 16; i++) { if ((variations & (1 << i)) == (1 << i)) { alarmsBlinkCounter[num * 16 + i] = blinkVal; } } // salvo nuovo valore alarmsState[num] = newStatus; } #endregion Public Methods } #if false /// /// Struttura della conf memoria ModBus /// public class BaseModbusConf { public enum DataType { ND = 0, BIT, INT, REAL } public enum MemType { ND = 0, DiscreteInput = 1, Coil = 2, InputRegister = 3, HoldingRegister = 4 } /// /// Elenco aree memoria ModBus in lettura /// public List mMapRead { get; set; } = new List(); /// /// Elenco aree memoria ModBus in scrittura /// public List mMapWrite { get; set; } = new List(); /// /// struttura di base memoria ModBus /// public class ModbusMemArea { public ushort BaseAddr { get; set; } = 0; public string RawAddr { get; set; } = ""; public ushort Size { get; set; } = 0; [JsonConverter(typeof(StringEnumConverter))] public MemType Type { get; set; } = MemType.ND; public List VarList { get; set; } = new List(); } public class VarConf { public string description { get; set; } = ""; public int factor { get; set; } = 1; public bool hasRange { get { return !this.minVal.Equals(this.maxVal); } } public ushort index { get; set; } = 0; public int maxVal { get; set; } = 0; public string memAddr { get; set; } = ""; public int minVal { get; set; } = 0; public string name { get; set; } = "none"; public ushort size { get; set; } = 0; [JsonConverter(typeof(StringEnumConverter))] public DataType tipoMem { get; set; } = DataType.ND; public string value { get; set; } = ""; } } #endif /// /// Classe gestione configurazione parametri di base x configuraizone estesa (es MTConnect, OPC-UA, ...) /// public class BaseParamConf { #region Public Properties /// /// Struttura dati x check condizione LAVORA / Green /// public List condWork { get; set; } = new List(); /// /// Elenco items FILTRATI da invio come dynData --> FluxLog (events o samples) /// public List fluxLogVeto { get; set; } = new List(); /// /// Array degli elementi di traduzione item /// public Dictionary itemTranslation { get; set; } = new Dictionary(); /// /// Nome variabile x EmergencyStop /// public string keyEStop { get; set; } = ""; /// /// Nome variabile x pezzi FATTI /// public string keyPartCount { get; set; } = ""; /// /// Nome variabile x Codice Articolo /// public string keyPartId { get; set; } = ""; /// /// Nome variabile x pezzi RICHIESTI /// public string keyPartReq { get; set; } = ""; /// /// Nome variabile x NOME PROGRAMMA /// public string keyProgName { get; set; } = ""; /// /// Nome variabile x RunMode /// public string keyRunMode { get; set; } = ""; /// /// Dictionary dei nomi da cercare come "endsWith" a cui applicare la soglia indicata /// public Dictionary paramsEndThresh { get; set; } = new Dictionary(); /// /// Indica se il ping sia un criterio valido x determinare powerON impianto /// public bool pingAsPowerOn { get; set; } = true; #endregion Public Properties } /// /// Classe per rappresentare oggetti chaive/valore target x controlo condizioni multiple /// public class diCheckCondition { #region Public Properties /// /// nome variabile /// public string keyName { get; set; } = ""; /// /// valore target per esito richeisto /// public string targetValue { get; set; } = ""; #endregion Public Properties } /// /// Classe per rappresentare una lista di oggetti chaive/valore target x controlo condizioni multiple + indicazione modalità di controllo (AND/OR/...) /// public class diCheckCondSetup { #region Public Properties /// /// Elenco condizioni /// public List checkList { get; set; } = new List(); /// /// Modalità verifica condizioni /// public boolCheckMode checkMode { get; set; } = boolCheckMode.AND; #endregion Public Properties } /// /// Classe gestione configurazione parametri specifici MTC da BaseParamConf /// public class MtcParamConf : BaseParamConf { #region Public Properties /// /// Struttura dati x check condizione PowerOn /// public diCheckCondition condPowerOn { get; set; } = new diCheckCondition(); #endregion Public Properties } /// /// Classe gestione configurazione parametri specifici OPC-UA da BaseParamConf /// public class OpcUaParamConf : BaseParamConf { #region Public Properties /// /// Identificativo nodo iniziale /// public string BrowseFullVal { get; set; } = "ns=2;s=Scalar_Static"; /// /// Indice NS da cui fare il browse dei file /// public ushort BrowseNSIndex { get; set; } = 4; /// /// ID del nodo da cui partire x il browse di identificazione nodi iniziale /// public uint BrowseValue { get; set; } = 5001; /// /// Struttura dati x check condizione Contapezzi Abilitato (se vuoto = sempre abilitato) /// public diCheckCondSetup condCountEnabled { get; set; } = new diCheckCondSetup(); /// /// Struttura dati x check condizione Errore /// public diCheckCondSetup condError { get; set; } = new diCheckCondSetup(); /// /// Struttura dati x check condizione Emergenza /// public diCheckCondSetup condEStop { get; set; } = new diCheckCondSetup(); /// /// Struttura dati x check condizione Manual /// public diCheckCondSetup condManual { get; set; } = new diCheckCondSetup(); /// /// Struttura dati x check condizione PowerOn /// public diCheckCondSetup condPowerOn { get; set; } = new diCheckCondSetup(); /// /// Struttura dati x check condizione READY /// public diCheckCondSetup condReady { get; set; } = new diCheckCondSetup(); /// /// Struttura dati x check condizione WarmUp - CoolDown /// public diCheckCondSetup condWarmUpCoolDown { get; set; } = new diCheckCondSetup(); /// /// Aree di memoria lettura /// public Dictionary mMapRead { get; set; } = new Dictionary(); /// /// Aree di memoria scrittura /// public Dictionary mMapWrite { get; set; } = new Dictionary(); #endregion Public Properties } }