Files
mapo-mono/MP.MONO.Core/CONF/BaseAlarmBankConf.cs
Samuele Locatelli 9c424aa40c Modifica SIM
- nuova modalità allarmi RawList attivata
- installo su SIM x sviluppare DECODER nuovo
2022-06-19 17:07:27 +02:00

253 lines
8.8 KiB
C#

using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using static MP.MONO.Core.Enums;
namespace MP.MONO.Core.CONF
{
/// <summary>
/// Classe gestione configurazione parametri di base x allarmi di tipo BankBit
/// </summary>
public class BaseAlarmBankConf
{
#region Public Properties
/// <summary>
/// Segnaposto impiegato x disabilitare gli allarmi (sempre)
/// </summary>
public string disableMark { get; set; } = "##";
/// <summary>
/// Elenco dei contatori blink x gestione caso fronte salita/discesa segnale che blinka
/// </summary>
public int[] alarmsBlinkCounter { get; set; } = null!;
/// <summary>
/// BitMask 16bit (1 = valido, 0 = filtro) degli allarmi silenziati (salvato in redis) come valore da sottrarre x check
/// </summary>
public uint[] silenceMask { get; set; } = null!;
/// <summary>
/// BitMask 16bit (1 = valido, 0 = filtro) degli allarmi DISABILITATI (se iniziano per [disableMark]) come valore da sottrarre x check
/// </summary>
public uint[] disableMask { get; set; } = null!;
/// <summary>
/// Array dei valori allarme correnti
/// </summary>
public uint[] alarmsState { get; set; } = null!;
/// <summary>
/// valore di partenza x un segnale di blink in caso di fine variazione (fronte discesa)
/// </summary>
public int blinkDownVal { get; set; } = 4;
/// <summary>
/// valore di partenza x un segnale di blink in caso di inizio variazione (fronte salita)
/// </summary>
public int blinkUpVal { get; set; } = 3;
/// <summary>
/// Descrizione area allarmi
/// </summary>
public string description { get; set; } = "";
/// <summary>
/// Indice nell'area di memoria (da valore iniziale = 0)
/// </summary>
public int index { get; set; } = 0;
/// <summary>
/// Nome "assoluto" della posizione nell'area di memoria (anche diverso da indice)
/// </summary>
public string memAddr { get; set; } = "";
/// <summary>
/// Elenco allarmi configurati x la bitmap
/// </summary>
public List<string> messages { get; set; } = new List<string>();
/// <summary>
/// Dictionary calcolato allarmi
/// </summary>
public Dictionary<int, string> messagesMap //{ get; set; } = new Dictionary<int, string>();
{
get
{
Dictionary<int, string> map = new Dictionary<int, string>();
if (messages != null)
{
foreach (var item in messages)
{
map.Add(map.Count + 1, item);
}
}
return map;
}
}
public bool isSilenced(int messIndex)
{
//decremento: è base 1 mi serve base 0...
messIndex--;
bool answ = false;
int bank = (messIndex) / 16;
if (silenceMask != null && silenceMask.Length >= bank)
{
var testVal = 1 << messIndex;
answ = !((silenceMask[bank] & testVal) == testVal);
}
return answ;
}
/// <summary>
/// Size in byte
/// </summary>
public int size { get; set; } = 0;
/// <summary>
/// Tipo di dato
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public plcDataType tipoMem { get; set; } = plcDataType.Boolean;
#endregion Public Properties
#region Public Methods
/// <summary>
/// Calcola il filtro da condizione blink (ovvero maschera per valori indicati blinking)
/// </summary>
/// <param name="num"></param>
/// <returns></returns>
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;
}
/// <summary>
/// Effettua update dei contatori blink per gestire i segnali alternati sul fronte di salita/discesa
/// </summary>
/// <param name="num"></param>
/// <param name="newStatus"></param>
public void checkBlinkCounter(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++)
{
// controllo se è variato
if ((variations & (1 << i)) == (1 << i))
{
// se il valore nuovo è 1 --> è in fronte salita
if ((newStatus & (1 << i)) == (1 << i))
{
// cambio SOLO SE il valore blink è zero...
if (alarmsBlinkCounter[num * 16 + i] == 0)
{
alarmsBlinkCounter[num * 16 + i] = blinkUpVal;
}
}
// altrimenti se è fronte discesa
else
{
// cambio SOLO SE il valore blink è zero...
if (alarmsBlinkCounter[num * 16 + i] == 0)
{
alarmsBlinkCounter[num * 16 + i] = blinkDownVal;
}
}
}
}
// decremento contatori blink
int idx = 0;
foreach (var item in alarmsBlinkCounter)
{
alarmsBlinkCounter[idx] = item > 0 ? item - 1 : item;
idx++;
}
}
/// <summary>
/// Confronta un valore di stato allarme con lo stato precedentemente salvato considerando blink/veto
/// </summary>
/// <param name="num">Numero/indice del banco di allarme (uint16)</param>
/// <param name="newValue">Valore (bitmap) allarmi come uint16</param>
/// <returns></returns>
public bool isChanged(int num, uint newValue)
{
// per prima cosa controllo valori RAW
bool answ = !alarmsState[num].Equals(newValue);
if (answ)
{
// controllo valori filtrati x silenziamento temporaneo o definitivo (sottraendo BITMASK dai valori di filtro)
answ = ((alarmsState[num] & disableMask[num] & silenceMask[num]) != (newValue & disableMask[num] & silenceMask[num]));
// se fossero ancora differenti controllo ulteriore mask dato il counter dei blink:
if (answ)
{
var blinkFilt = blinkFilter(num);
answ = ((alarmsState[num] & (disableMask[num] & silenceMask[num] & ~blinkFilt)) != (newValue & (disableMask[num] & silenceMask[num] & ~blinkFilt)));
}
}
return answ;
}
/// <summary>
/// Inizializzazione classe con valori calcolati: attenzione si aspetta banchi da 32 bit...
/// </summary>
public void setupData()
{
// inizializzo vettore valore allarmi x banco int16
alarmsState = new uint[size / 2];
disableMask = new uint[size / 2];
silenceMask = 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(disableMark))
{
alarmsBlinkCounter[idx] = -999;
}
else
{
alarmsBlinkCounter[idx] = 1;
disableMask[bank] += (uint)1 << idx;
}
silenceMask[bank] += (uint)1 << idx;
idx++;
// sistemo bank/indice
if (idx > 15)
{
bank++;
idx = 0;
}
}
}
/// <summary>
/// Imposta il valore dello status attuale allarme impostando eventuale valore blink x le variazioni
/// </summary>
/// <param name="num"></param>
/// <param name="newStatus"></param>
public void updStatusVal(int num, uint newStatus)
{
// salvo nuovo valore
alarmsState[num] = newStatus;
}
#endregion Public Methods
}
}