using MapoSDK;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace IOB_UT
{
///
/// informazioni di produzione
///
public struct prodData
{
#region Public Fields
public int AccTime;
public bool EmrStop;
public string FuncMode;
public string MessageCode;
public string MessageText;
public string Operator;
public int Power;
public bool Status;
#endregion Public Fields
}
///
/// Gestione Endianness
///
public static class Endian
{
#region Public Methods
///
/// Scambia MSB/LSB per 16bit
///
///
///
public static UInt16 SwapUInt16(UInt16 inValue)
{
return (UInt16)(((inValue & 0xff00) >> 8) |
((inValue & 0x00ff) << 8));
}
///
/// Scambia MSB/LSB per 32bit
///
///
///
public static UInt32 SwapUInt32(UInt32 inValue)
{
return ((inValue & 0xff000000) >> 24) |
((inValue & 0x00ff0000) >> 8) |
((inValue & 0x0000ff00) << 8) |
((inValue & 0x000000ff) << 24);
}
#endregion Public Methods
}
///
/// GEstione dati di timing
///
public static class TimingData
{
#region Public Fields
public static List results = new List();
#endregion Public Fields
#region Public Methods
///
/// aggiorno vettore aggiungendo risultato
///
/// Codice chiamante
/// Codice da registrare (univoco con chiamante)
/// Tempo esecuzione in ticks
public static void addResult(string caller, string codice, long ticks)
{
if (results.Count == 0)
{
results.Add(new TimeRec(caller, codice, ticks));
}
int indice = -1;
for (int i = 0; i < results.Count; i++)
{
// se il codice è quello cercato...
if (results[i].codCall == codice && results[i].classCall == caller)
{
indice = i;
}
}
// se c'è aggiorno...
if (indice >= 0)
{
results[indice].numCall++;
results[indice].totMsec = results[indice].totMsec.Add(new TimeSpan(ticks));
}
// altrimenti aggiungo...
else
{
results.Add(new TimeRec(caller, codice, ticks));
}
}
///
/// Resetta i dati registrati (ad avvio adapter...)
///
public static void resetData()
{
results = new List();
}
#endregion Public Methods
}
///
/// Cache a tempo valori INT
///
public class CachedInt
{
#region Public Properties
public DateTime ValidUntil { get; set; } = DateTime.Now;
public int Value { get; set; } = 0;
#endregion Public Properties
}
///
/// Cache a tempo valori String
///
public class CachedString
{
#region Public Properties
public DateTime ValidUntil { get; set; } = DateTime.Now;
public string Value { get; set; } = "";
#endregion Public Properties
}
///
/// Classe conf x item DynData
///
public class DynDataItem
{
#region Public Fields
///
/// DataOra scadenza invio forzato
///
public DateTime DTScad = DateTime.Now;
#endregion Public Fields
#region Public Properties
///
/// Valore effettivo da salvare
///
public string actVal { get; set; } = "";
public string func { get; set; } = "";
public string key { get; set; } = "";
public string name { get; set; } = "";
public int sPeriod { get; set; } = 60;
public string unit { get; set; } = "";
public string val { get; set; } = "";
#endregion Public Properties
}
///
/// Configurazione per Eventi/Variabili
///
public class EVData
{
#region Public Fields
///
/// DataOra scadenza invio forzato
///
public DateTime DTScad = DateTime.Now;
#endregion Public Fields
#region Public Properties
///
/// Unità di misura
///
public string UM { get; set; } = "num";
///
/// Valore salvato
///
public string Val { get; set; } = "";
#endregion Public Properties
}
///
/// Rappresentazione dello stato corrente dell'IOB
///
public class IobWinStatus
{
#region Public Properties
///
/// ID univoco
///
public string CodIob { get; set; } = "0";
///
/// Contatore IOB
///
public float counterIOB { get; set; } = 0;
///
/// Contatore Macchina
///
public float counterMAC { get; set; } = 0;
///
/// DataOra ultima comunicazione IN (con PLC)
///
public DateTime lastDataIn { get; set; } = DateTime.Now.AddMinutes(-1);
///
/// DataOra ultima comunicazione OUT (con MP Server)
///
public DateTime lastUpdate { get; set; } = DateTime.Now.AddDays(-1);
///
/// Status del SINGOLO IOB
///
public bool online { get; set; } = false;
#if false
///
/// Indica se sia correntemente in setup
///
public bool inSetup { get; set; } = false;
///
/// Semaforo IN (IOB-PLC)
///
public Semaforo SemIn { get; set; } = Semaforo.ND;
///
/// Semaforo OUT (IOB-MPserver)
///
public Semaforo SemOut { get; set; } = Semaforo.ND;
#endif
///
/// Lungh coda ALLARMI in uscita
///
public int queueAlLen { get; set; } = 0;
///
/// Lunghezza coda EVENTI in uscita
///
public int queueEvLen { get; set; } = 0;
///
/// Lunghezza coda FluxLog in uscita
///
public int queueFlLen { get; set; } = 0;
///
/// Lungh coda MESSAGGI in uscita
///
public int queueMsLen { get; set; } = 0;
#endregion Public Properties
#if false
///
/// DataOra ultima comunicazione OUT (con MP Server)
///
public DateTime lastDataOut { get; set; } = DateTime.Now.AddDays(-1);
///
/// Ultimo stato noto dei parametri in memoria letti da PLC
///
public Dictionary currParams { get; set; } = null;
#endif
}
///
/// Elenco oggetti del monitoraggio (DynData, Status) per WPS
///
public class MonitoredItemsConf
{
#region Public Properties
public List DynData { get; set; }
public srvData SrvData { get; set; }
public List Status { get; set; }
#endregion Public Properties
}
///
/// Classe che contiene tutte le NUOVE informazioni da aggiornare sulla form
///
public class newDisplayData
{
#region Public Properties
///
/// Oggetto COUTNER generico (pezzi, portata...)
///
public int counter { get; set; } = -9999;
///
/// Bitmap attuale segnali letti
///
public string currBitmap { get; set; } = "";
///
/// Verifica se contenga valori (NON default/empty)
///
public bool hasData
{
get
{
bool answ = false;
// true se qualcosa NON E' come default
if (!string.IsNullOrWhiteSpace(newInData) || !string.IsNullOrWhiteSpace(newSignalData) || !string.IsNullOrWhiteSpace(newFLogData) || !string.IsNullOrWhiteSpace(newUrlCallData) || !string.IsNullOrWhiteSpace(newLiveLogData) || counter > -9999 || !string.IsNullOrWhiteSpace(currBitmap) || semIn != Semaforo.ND || semOut != Semaforo.ND)
{
answ = true;
}
return answ;
}
}
///
/// Dati tipo FluxLog
///
public string newFLogData { get; set; } = "";
///
/// Dati tipo IN (RAW)
///
public string newInData { get; set; } = "";
///
/// Dati tipo LiveLog
///
public string newLiveLogData { get; set; } = "";
///
/// Dati tipo Signal
///
public string newSignalData { get; set; } = "";
///
/// Dati tipo UrlCall
///
public string newUrlCallData { get; set; } = "";
///
/// Stato semaforo IN verso PLC
///
public Semaforo semIn { get; set; } = Semaforo.ND;
///
/// Stato semaforo OUT verso MES
///
public Semaforo semOut { get; set; } = Semaforo.ND;
#endregion Public Properties
}
///
/// Dato generico (per decodifica)
///
public class otherData
{
#region Public Fields
public string codNum;
public string dataType;
public string memAddr;
public string varName;
#endregion Public Fields
#region Public Constructors
public otherData()
{
codNum = "";
memAddr = "";
varName = "";
dataType = "";
}
public otherData(string _codNum, string _memAddr, string _varName, string _dataType)
{
codNum = _codNum;
memAddr = _memAddr;
varName = _varName;
dataType = _dataType;
}
#endregion Public Constructors
}
///
/// Classe gestione valori campionati su periodo
///
public class sampleVect
{
#region Protected Fields
///
/// vettore valori temporali della serie
///
protected List lTime;
///
/// vettore valoti puntuali della serie
///
protected List lVal;
///
/// Dimensione finestra di campionamento (secondi)
///
protected int windSize;
#endregion Protected Fields
#region Public Constructors
///
/// Inizializzo l'oggetto
///
public sampleVect()
{
// init valori default...
windSize = baseUtils.CRI("countWindSize") > 0 ? baseUtils.CRI("countWindSize") : 60;
lTime = new List();
lVal = new List();
}
#endregion Public Constructors
#region Protected Properties
///
/// Verifica ampiezza finestra valori First-Last
///
protected double flWindSize
{
get
{
double answ = 0;
if (numElem > 1)
{
answ = lTime.Last().Subtract(lTime[0]).TotalSeconds;
}
return answ;
}
}
///
/// Conteggio elementi
///
protected int numElem
{
get
{
int answ = 0;
try
{
answ = lTime.Count;
}
catch
{ }
return answ;
}
}
///
/// Verifica ampiezza finestra valori Second-Last
///
protected double slWindSize
{
get
{
double answ = 0;
if (numElem > 2) // altrimenti SE non ne ho almeno 3 NON posso avere secondo/ultimo...
{
answ = lTime.Last().Subtract(lTime[1]).TotalSeconds;
}
return answ;
}
}
#endregion Protected Properties
#region Public Properties
///
/// Calcola il valore mediano...
///
public double vcMedian
{
get
{
double answ = 0;
// restituisce la mediana SE valida, altrimenti null...
if (numElem > 2 && flWindSize > windSize)
{
try
{
// calcolo mediana!
//answ = Statistics.Median(lVal.ToArray());
// rif: https://blogs.msmvps.com/deborahk/linq-mean-median-and-mode/
var sortedNumbers = lVal.OrderBy(n => n);
int numCount = lVal.Count;
int indice50 = lVal.Count / 2;
if ((numCount % 2) == 0)
{
answ = ((sortedNumbers.ElementAt(indice50) + sortedNumbers.ElementAt(indice50 - 1)) / 2);
}
else
{
answ = sortedNumbers.ElementAt(indice50);
}
}
catch
{ }
}
return answ;
}
}
///
/// Verifica se la vc sia valida (ovvero almeno 2 valori e intervallo > window richiesta)
///
public bool vcValid
{
get
{
return (flWindSize > windSize && numElem > 1);
}
}
#endregion Public Properties
#region Public Methods
///
/// Aggiunge un valore alla serie ed eventualmente elimina i valori superflui a garantirne una finestra temporale valida
///
///
///
public void addValue(DateTime tempo, int valore)
{
lTime.Add(tempo);
lVal.Add(valore);
// verifico se siano da accorciare le serie... ovvero i 2 intervalli ENTRAMBI sono superiori al periodo minimo (in tal caso riduco..
while (flWindSize > windSize && slWindSize > windSize)
{
// elimino i 2 valori + vecchi
lTime.RemoveAt(0);
lVal.RemoveAt(0);
// ora ricontrollo...
}
}
#endregion Public Methods
}
///
/// Classe x descrivere status server MP
///
public class ServerMpStatus
{
#region Public Properties
///
/// IP server
///
public string IP { get; set; }
///
/// DataOra ultima comunicazione OUT (con MP Server)
///
public DateTime lastUpdate { get; set; } = DateTime.Now.AddDays(-1);
///
/// Status del server
///
public bool online { get; set; } = false;
#endregion Public Properties
}
///
/// Classe conf server html
///
public class srvData
{
#region Public Properties
public string baseUri { get; set; } = "";
public string driverName { get; set; } = "";
#endregion Public Properties
}
///
/// Classe conf x decodifica stsatus
///
public class StatusItem : DynDataItem
{
#region Public Fields
public Dictionary codeMapping;
#endregion Public Fields
}
///
/// Oggetto timing x archiviazione dati perfomances
///
public class TimeRec
{
#region Public Fields
///
/// Classe chiamante della funzione (es codice univoco IOB)
///
public string classCall;
///
/// Codice univoco chiamata: tipo R4 (read 4 byte), W2 (write 2 Byte)
///
public string codCall;
///
/// Num chiamate totale
///
public int numCall;
///
/// Totale Msec accumulati
///
public TimeSpan totMsec;
#endregion Public Fields
#region Public Constructors
///
/// Classe record timing
///
public TimeRec()
{
codCall = "";
numCall = 0;
totMsec = new TimeSpan(0);
}
///
/// Classe record timing
///
///
///
///
public TimeRec(string caller, string codice, long nTicks)
{
classCall = caller;
codCall = codice;
numCall = 1;
totMsec = new TimeSpan(nTicks);
}
#endregion Public Constructors
#region Public Properties
///
/// Tempo medio chiamata
///
public double avgMsec
{
get
{
return totMsec.TotalMilliseconds / numCall;
}
}
#endregion Public Properties
}
///
/// Configurazione per Variabili Casuali
///
public class VCData
{
#region Public Fields
///
/// Array dati per calcolo
///
public List dataArray;
///
/// DataOra inizio periodo di elaborazione
///
public DateTime DTStart;
#endregion Public Fields
#region Public Properties
///
/// Tipologia di funzione da applicare
///
public VC_func Funzione { get; set; } = VC_func.POINT;
///
/// Periodo di riferimento
///
public int Period { get; set; } = 60;
#endregion Public Properties
}
}