diff --git a/IOB-UT/TCMan.cs b/IOB-UT/TCMan.cs
index 6b163fd8..5007d18b 100644
--- a/IOB-UT/TCMan.cs
+++ b/IOB-UT/TCMan.cs
@@ -17,16 +17,16 @@ namespace IOB_UT
///
protected double _lastTC { get; set; } = 0;
- ///
- /// Contapezzi CNC
- ///
- protected int _pzCountCNC { get; set; } = 0;
-
///
/// Contapezzi IOB
///
protected int _pzCountIOB { get; set; } = 0;
+ ///
+ /// Contapezzi PLC
+ ///
+ protected int _pzCountPLC { get; set; } = 0;
+
///
/// Fattore lambda (innovazione) per calcolo EWMA valore TCiclo corrente
///
@@ -68,7 +68,7 @@ namespace IOB_UT
{
bool answ = false;
// solo se ho dei pezzi rilevati...
- if (pzCountCNC > 0 && pzCountIOB > 0)
+ if (pzCountPLC > 0 && pzCountIOB > 0)
{
answ = (DateTime.Now.Subtract(lastObservedData).TotalSeconds >= limitTC);
}
@@ -110,18 +110,23 @@ namespace IOB_UT
}
///
- /// Contapezzi CNC
+ /// Contapezzi IOB
///
- public int pzCountCNC
+ public int pzCountIOB { get; set; } = 0;
+
+ ///
+ /// Contapezzi PLC
+ ///
+ public int pzCountPLC
{
get
{
- return _pzCountCNC;
+ return _pzCountPLC;
}
set
{
DateTime adesso = DateTime.Now;
- int incrPz = value - _pzCountCNC;
+ int incrPz = value - _pzCountPLC;
if (incrPz > 0)
{
// calcolo lastTC...
@@ -133,15 +138,10 @@ namespace IOB_UT
avgTC = lambda * lastTC + (1 - lambda) * avgTC;
}
}
- _pzCountCNC = value;
+ _pzCountPLC = value;
}
}
- ///
- /// Contapezzi IOB
- ///
- public int pzCountIOB { get; set; } = 0;
-
#endregion contapezzi e TCiclo
}
}
\ No newline at end of file
diff --git a/IOB-WIN/IobGeneric.cs b/IOB-WIN/IobGeneric.cs
index dbd2e35f..064ec765 100644
--- a/IOB-WIN/IobGeneric.cs
+++ b/IOB-WIN/IobGeneric.cs
@@ -32,6 +32,91 @@ namespace IOB_WIN
#region variabili ed oggetti base
+ ///
+ /// wrapper di log
+ ///
+ protected static Logger lg;
+
+ ///
+ /// valore booleano di check se sia in fase di COMUNICAZIONE ATTIVA con il PLC/NC
+ ///
+ protected bool adpCommAct;
+
+ ///
+ /// porta x adapter (x restart)
+ ///
+ protected int adpPortNum;
+
+ ///
+ /// DataOra ultimo avvio adapter x watchdog
+ ///
+ protected DateTime adpStartRun;
+
+ ///
+ /// Vettore 16 BIT valori in ingresso al filtro
+ ///
+ protected int B_input;
+
+ ///
+ /// Vettore 16 BIT valori in uscita dal filtro
+ ///
+ protected int B_output;
+
+ ///
+ /// Vettore 16 BIT valori precedenti
+ ///
+ protected int B_previous;
+
+ ///
+ /// Dizionario valori impostati x produzione
+ ///
+ protected Dictionary currProdData = new Dictionary();
+
+ ///
+ /// Array dei contatori x segnali blinking
+ ///
+ protected int[] i_counters;
+
+ ///
+ /// Indica impianto IN SETUP (fino a quando SMETTE di esserlo...)
+ ///
+ protected bool inSetup = false;
+
+ ///
+ /// Ultimo invio contapezzi (x invio delayed)
+ ///
+ protected DateTime lastPzCountSend;
+
+ ///
+ /// Dizionario ultimi valori (double) delle TSVC
+ ///
+ protected Dictionary LastTSVC = new Dictionary();
+
+ ///
+ /// Ultima registrazione warning x ODL mancante (x scrivere solo ogni 15 secondi)
+ ///
+ protected DateTime lastWarnODL;
+
+ ///
+ /// TImeout x ping al server
+ ///
+ protected int pingServerMsTimeout = utils.CRI("pingMsTimeout");
+
+ ///
+ /// Ritardo minimo x invio contapezzi
+ ///
+ protected int pzCountDelay;
+
+ ///
+ /// Dizionario di VC da trattare come TimeSeries (con conf decodificata + processing successivo...)
+ ///
+ protected Dictionary TSVC_Data = new Dictionary();
+
+ ///
+ /// Dizionario di VARIABILI da trattare come eventi (da inviare quando cambiano oppure a scadenza periodo...)
+ ///
+ protected Dictionary VarArray = new Dictionary();
+
///
/// valore booleano di check se sia stato AVVIATO l'adapter (Running)
///
@@ -50,7 +135,32 @@ namespace IOB_WIN
///
/// Contapezzi attuale
///
- public Int32 contapezziIOB = 0;
+ public Int32 contapezziIOB
+ {
+ get
+ {
+ return tcMan.pzCountIOB;
+ }
+ set
+ {
+ tcMan.pzCountIOB = value;
+ }
+ }
+
+ ///
+ /// Ultima lettura variabile contapezzi da CNC
+ ///
+ public Int32 contapezziPLC
+ {
+ get
+ {
+ return tcMan.pzCountPLC;
+ }
+ set
+ {
+ tcMan.pzCountPLC = value;
+ }
+ }
///
/// Conteggio ATTUALE ore macchina IN LAVORO
@@ -112,11 +222,6 @@ namespace IOB_WIN
///
public bool hasBigEndian = false;
- ///
- /// Ultima lettura variabile contapezzi da CNC
- ///
- public Int32 contapezziPLC = 0;
-
///
/// dataOra ultima verifica CNC disconnesso...
///
@@ -215,7 +320,7 @@ namespace IOB_WIN
///
/// Oggetto gestione TempiCiclo e contapezzi
///
- public TCMan tcMan = new TCMan(0.4, 1.5, 4);
+ public TCMan tcMan = new TCMan(0.5, 1.3, 5);
///
/// Imposta veto chiamata split (durante chiamata, per 60 sec)
@@ -227,96 +332,36 @@ namespace IOB_WIN
///
public bool W = true;
- ///
- /// wrapper di log
- ///
- protected static Logger lg;
-
- ///
- /// valore booleano di check se sia in fase di COMUNICAZIONE ATTIVA con il PLC/NC
- ///
- protected bool adpCommAct;
-
- ///
- /// porta x adapter (x restart)
- ///
- protected int adpPortNum;
-
- ///
- /// DataOra ultimo avvio adapter x watchdog
- ///
- protected DateTime adpStartRun;
-
- ///
- /// Vettore 16 BIT valori in ingresso al filtro
- ///
- protected int B_input;
-
- ///
- /// Vettore 16 BIT valori in uscita dal filtro
- ///
- protected int B_output;
-
- ///
- /// Vettore 16 BIT valori precedenti
- ///
- protected int B_previous;
-
- ///
- /// Dizionario valori impostati x produzione
- ///
- protected Dictionary currProdData = new Dictionary();
-
- ///
- /// Array dei contatori x segnali blinking
- ///
- protected int[] i_counters;
-
- ///
- /// Indica impianto IN SETUP (fino a quando SMETTE di esserlo...)
- ///
- protected bool inSetup = false;
-
- ///
- /// Ultimo invio contapezzi (x invio delayed)
- ///
- protected DateTime lastPzCountSend;
-
- ///
- /// Dizionario ultimi valori (double) delle TSVC
- ///
- protected Dictionary LastTSVC = new Dictionary();
-
- ///
- /// Ultima registrazione warning x ODL mancante (x scrivere solo ogni 15 secondi)
- ///
- protected DateTime lastWarnODL;
-
- ///
- /// TImeout x ping al server
- ///
- protected int pingServerMsTimeout = utils.CRI("pingMsTimeout");
-
- ///
- /// Ritardo minimo x invio contapezzi
- ///
- protected int pzCountDelay;
-
- ///
- /// Dizionario di VC da trattare come TimeSeries (con conf decodificata + processing successivo...)
- ///
- protected Dictionary TSVC_Data = new Dictionary();
-
- ///
- /// Dizionario di VARIABILI da trattare come eventi (da inviare quando cambiano oppure a scadenza periodo...)
- ///
- protected Dictionary VarArray = new Dictionary();
-
///
/// Evento Iob ha subito un refresh
///
public event EventHandler eh_refreshed;
+ ///
+ /// Coda massima ammessa per FLog (se <=0 disattivata...)
+ ///
+ protected int maxQueueFLog { get; set; } = utils.CRI("maxQueueFLog");
+
+ ///
+ /// Numero letture IN da avvio
+ ///
+ protected int nReadFilt { get; set; }
+
+ ///
+ /// Numero letture IN da avvio
+ ///
+ protected int nReadIN { get; set; }
+
+ ///
+ /// Numero invii OUT (svuotamento coda)
+ ///
+ protected int nSendOut { get; set; }
+
+ ///
+ /// Numero simulazioni ammesse...
+ ///
+ protected int numSim { get; set; }
+
///
/// Verifica se sia in modalità DEMO avanzata (campionamento da set di valori ammessi...)
///
@@ -502,31 +547,6 @@ namespace IOB_WIN
}
}
- ///
- /// Coda massima ammessa per FLog (se <=0 disattivata...)
- ///
- protected int maxQueueFLog { get; set; } = utils.CRI("maxQueueFLog");
-
- ///
- /// Numero letture IN da avvio
- ///
- protected int nReadFilt { get; set; }
-
- ///
- /// Numero letture IN da avvio
- ///
- protected int nReadIN { get; set; }
-
- ///
- /// Numero invii OUT (svuotamento coda)
- ///
- protected int nSendOut { get; set; }
-
- ///
- /// Numero simulazioni ammesse...
- ///
- protected int numSim { get; set; }
-
///
/// Aggiunge ai dati da inviare alla parentform i valori di RawInput rilevati
///
@@ -577,15 +597,7 @@ namespace IOB_WIN
#endregion variabili ed oggetti base
- ///
- /// Conf adapter corrente
- ///
- public IobConfiguration cIobConf;
-
- ///
- /// Struttura memoria PLC x lettura/scrittura da JSON file
- ///
- public plcMemMap memMap;
+ #region Protected Fields
///
/// ultimo tentativo connessione...
@@ -602,6 +614,18 @@ namespace IOB_WIN
///
protected AdapterForm parentForm;
+ #endregion Protected Fields
+
+ ///
+ /// Conf adapter corrente
+ ///
+ public IobConfiguration cIobConf;
+
+ ///
+ /// Struttura memoria PLC x lettura/scrittura da JSON file
+ ///
+ public plcMemMap memMap;
+
///
/// inizializzo l'oggetto sulla form SULLA BASE DEL FILE DI CONFIGURAZIONE letto
///
@@ -665,6 +689,51 @@ namespace IOB_WIN
///
protected int vetoSeconds { get; set; } = utils.CRI("vetoSeconds");
+ ///
+ /// Imposta eventuali altri valori default
+ ///
+ private void fixDefaultPar()
+ {
+ // parametro max tentativi PING...
+ string s_maxPingRetry = getOptPar("MAX_PING_RETRY");
+ if (!string.IsNullOrEmpty(s_maxPingRetry))
+ {
+ int numRetry = 5;
+ int.TryParse(s_maxPingRetry, out numRetry);
+ maxPingRetry = numRetry;
+ }
+ }
+
+ ///
+ /// Imposto alcuni valori di default
+ ///
+ /// indica se sia richeisto di SVUOTARE le code delel info
+ private void setDefaults(bool resetQueue)
+ {
+ numSim = utils.CRI("numSim");
+ lastPrgName = "";
+ nReadIN = 0;
+ nReadFilt = 0;
+ nSendOut = 0;
+ currMode = 0;
+ lastAlarm = "";
+ doStartMemDump = utils.CRB("doStartMemDump");
+ doSampleMemory = utils.CRB("doSampleMemory");
+ // svuoto code se richiesto
+ if (resetQueue)
+ {
+ QueueIN = new ConcurrentQueue();
+ QueueFLog = new ConcurrentQueue();
+ QueueAlarm = new ConcurrentQueue();
+ QueueMessages = new ConcurrentQueue();
+ }
+ // imposto contatori blink a zero...
+ i_counters = new int[32];
+ lastPeriodicLog = DateTime.Now;
+ // fix parametri generali...
+ enablePrgName = true;
+ }
+
///
/// Effettua logging ERROR corretto impostanto anche la variabile IOB prima di scrivere...
///
@@ -963,84 +1032,10 @@ namespace IOB_WIN
fixDefaultPar();
}
- ///
- /// Imposta eventuali altri valori default
- ///
- private void fixDefaultPar()
- {
- // parametro max tentativi PING...
- string s_maxPingRetry = getOptPar("MAX_PING_RETRY");
- if (!string.IsNullOrEmpty(s_maxPingRetry))
- {
- int numRetry = 5;
- int.TryParse(s_maxPingRetry, out numRetry);
- maxPingRetry = numRetry;
- }
- }
-
- ///
- /// Imposto alcuni valori di default
- ///
- /// indica se sia richeisto di SVUOTARE le code delel info
- private void setDefaults(bool resetQueue)
- {
- numSim = utils.CRI("numSim");
- lastPrgName = "";
- nReadIN = 0;
- nReadFilt = 0;
- nSendOut = 0;
- currMode = 0;
- lastAlarm = "";
- doStartMemDump = utils.CRB("doStartMemDump");
- doSampleMemory = utils.CRB("doSampleMemory");
- // svuoto code se richiesto
- if (resetQueue)
- {
- QueueIN = new ConcurrentQueue();
- QueueFLog = new ConcurrentQueue();
- QueueAlarm = new ConcurrentQueue();
- QueueMessages = new ConcurrentQueue();
- }
- // imposto contatori blink a zero...
- i_counters = new int[32];
- lastPeriodicLog = DateTime.Now;
- // fix parametri generali...
- enablePrgName = true;
- }
-
#region metodi adapter
protected bool _connOk = false;
- ///
- /// Salva verifica stato connessione OK
- ///
- ///
- public virtual bool connectionOk
- {
- get
- {
- return _connOk || DemoIn;
- }
- set
- {
- _connOk = value;
- }
- }
-
- ///
- /// indica se ping disabilitato da optPar
- ///
- public bool pingDisabled
- {
- get
- {
- bool answ = false;
- bool.TryParse(getOptPar("NO_PING"), out answ);
- return answ;
- }
- }
-
///
/// Max tentativi ping permessi (default: 5)
///
@@ -1077,6 +1072,340 @@ namespace IOB_WIN
}
}
+ ///
+ /// Salva verifica stato connessione OK
+ ///
+ ///
+ public virtual bool connectionOk
+ {
+ get
+ {
+ return _connOk || DemoIn;
+ }
+ set
+ {
+ _connOk = value;
+ }
+ }
+
+ ///
+ /// indica se ping disabilitato da optPar
+ ///
+ public bool pingDisabled
+ {
+ get
+ {
+ bool answ = false;
+ bool.TryParse(getOptPar("NO_PING"), out answ);
+ return answ;
+ }
+ }
+
+ ///
+ /// Verifica e se necessario comprime directory log...
+ ///
+ private void checkShrinkDir()
+ {
+ string path = string.Format("{0}logs\\{1}", AppDomain.CurrentDomain.BaseDirectory, cIobConf.codIOB);
+ baseUtils.shrinkDir(path);
+ }
+
+ private void reportDataProc()
+ {
+ // update valori visualizzazione...
+ parentForm.dataProcLabel = string.Format("RAW: {0} --> IN: {1} --> OUT: {2}", nReadIN, nReadFilt, nSendOut);
+ }
+
+ private void svuotaCodaContapezzi()
+ {
+ // permetto al max 2 tentativi infruttuosi...
+ int maxTry = 2;
+ int oldContapezzi = contapezziIOB;
+ // se ho contapezzi OLTRE limite...
+ while ((MPOnline) && (contapezziPLC > contapezziIOB + minSendPzCountBlock))
+ {
+ lgInfo($"Ciclo svuotaCodaContapezzi --> contapezziPLC: {contapezziPLC} | contapezziIOB: {contapezziIOB}");
+ if (!isMulti)
+ {
+ pzCntReload(true);
+ }
+ // provo invio
+ trySendPzCountBlock();
+ // verifica per evitare loop infinito invio fallito
+ if (oldContapezzi == contapezziIOB)
+ {
+ maxTry--;
+ }
+ else
+ {
+ maxTry = 2;
+ oldContapezzi = contapezziIOB;
+ }
+ // verifico maxTry: se li ho esauriti esco!
+ if (maxTry <= 0)
+ {
+ return;
+ }
+ // aspetto x dare tempo calcolo
+ Thread.Sleep(400);
+ }
+ }
+
+ ///
+ /// Cerca di inviare su un altro thread i vari dati accumulati...
+ ///
+ private void trySendValues()
+ {
+ // init obj display
+ newDisplayData currDispData = new newDisplayData();
+ try
+ {
+ // verifico se risponde il server...
+ if (checkServerAlive)
+ {
+ bool iobOk = false;
+ if (utils.CRB("sendDataByThread"))
+ {
+ Task taskCheck = TaskEx.Run(() => iobOk = checkIobEnabled);
+ }
+ else
+ {
+ iobOk = checkIobEnabled;
+ }
+ // verifico SE posso inviare dati
+ if (iobOk)
+ {
+ currDispData.semOut = Semaforo.SV;
+ // verificare come gestire il task secondario senza interferenza (chiamate update su FORM da thread secondari danno errori)
+ if (utils.CRB("sendDataByThread"))
+ {
+ // invio con thread separato...
+ Task taskSigIN = TaskEx.Run(() => svuotaCodaSignIN());
+ Task taskFlog = TaskEx.Run(() => svuotaCodaFLog());
+ }
+ else
+ {
+ // gestione queue SignalIN (invio, display)
+ svuotaCodaSignIN();
+ currDispData.counter = contapezziIOB;
+ raiseRefresh(currDispData);
+ // provo a svuotare coda contapezzi
+ svuotaCodaContapezzi();
+ currDispData.counter = contapezziIOB;
+ raiseRefresh(currDispData);
+ // gestione queue FluxLog (invio, display)
+ svuotaCodaFLog();
+ raiseRefresh(currDispData);
+ }
+ }
+ else
+ {
+ // mostro VETO-SEND x invio... GIALLO
+ currDispData.semOut = Semaforo.SG;
+ if (periodicLog)
+ {
+ lgInfo("IOB - VETO SEND");
+ }
+ }
+ }
+ else
+ {
+ // mostro SERVER KO x invio... ROSSO
+ currDispData.semOut = Semaforo.SR;
+ if (periodicLog)
+ {
+ lgInfo("IOB - SERVER NOT READY");
+ }
+ }
+ }
+ catch (Exception exc)
+ {
+ lgError($"Errore in fase trySendValues{Environment.NewLine}{exc}");
+ currDispData.semOut = Semaforo.SR;
+ }
+ raiseRefresh(currDispData);
+ }
+
+ ///
+ /// Stringa raw dei parametri da scrivere...
+ ///
+ ///
+ protected string getParams2write()
+ {
+ string answ = "";
+ string url2call = $"{urlGetParams2Write}";
+ if (verboseLog)
+ {
+ lgInfo("chiamata URL " + url2call);
+ }
+ answ = utils.callUrlNow(url2call);
+ // se vuoto faccio seconda prova...
+ if (string.IsNullOrEmpty(answ))
+ {
+ answ = utils.callUrlNow(url2call);
+ }
+ return answ;
+ }
+
+ ///
+ /// Chiede elenco dei task da eseguire
+ /// - formato Json
+ /// - array di KVP / Dictionary
+ /// - formato definito da API x MP/IO/:
+ /// - KEY: task
+ /// - VALUE: array JSon KVP
+ ///
+ protected string getTask2exe()
+ {
+ string answ = "";
+ if (checkServerAlive)
+ {
+ string url2call = $"{urlGetTask2Exe}";
+ if (verboseLog)
+ {
+ lgInfo("chiamata URL " + url2call);
+ }
+ answ = utils.callUrlNow(url2call);
+ }
+ return answ;
+ }
+
+ ///
+ /// Metodo da overridare x scrivere DAVVERO i aprametri sul PLC
+ ///
+ ///
+ protected virtual void plcWriteParams(List updatedPar)
+ {
+ // non faccio nulla di base...
+ }
+
+ ///
+ /// Processa le richieste di scrittura memoria
+ ///
+ ///
+ protected string processMemWriteRequests()
+ {
+ string answ = "";
+ // li salvo nei parametri in memoria locale (ogni adapter DOVREBBE salvare POI sul VERO PLC)
+ List writeList = new List();
+ List updatedPar = new List();
+ // recupero elenco delle cose da fare
+ string resp = getParams2write();
+ if (!string.IsNullOrEmpty(resp))
+ {
+ try
+ {
+ writeList = JsonConvert.DeserializeObject>(resp);
+ // se ho da fare chiamo esecuzione..
+ if (writeList.Count > 0)
+ {
+ foreach (var item in writeList)
+ {
+ // scrivo in memoria
+ if (memMap.mMapWrite.ContainsKey(item.uid))
+ {
+ memMap.mMapWrite[item.uid].value = item.reqValue;
+ // accodo in stringa taskVal...
+ answ += $" | Parameter {item.uid} --> {item.reqValue}";
+ // sistemo valori
+ item.value = item.reqValue;
+ lgInfo($"Effettuato update parametro: actVal = {item.value} | reqVal = {item.reqValue}");
+ item.reqValue = "";
+ // salvo in lista da ritrasmettere
+ updatedPar.Add(item);
+ }
+ else
+ {
+ answ += $" | Error: parameter {item.uid} not found";
+ }
+ }
+ // richiamo scrittura parametri su PLC
+ plcWriteParams(updatedPar);
+ // invio su cloud parametri!
+ string rawData = JsonConvert.SerializeObject(updatedPar);
+ utils.callUrl($"{urlUpdateWriteParams}", rawData);
+ }
+ }
+ catch (Exception exc)
+ {
+ lgError($"Eccezione in processServerRequests:{Environment.NewLine}{exc}");
+ }
+ }
+ else
+ {
+ lgError("Non è stata ricevuta risposta x task da eseguire");
+ }
+ return answ;
+ }
+
+ protected void raiseRefresh(newDisplayData currDispData)
+ {
+ if (currDispData.hasData)
+ {
+ // segnalo refresh!
+ if (eh_refreshed != null)
+ {
+ eh_refreshed(this, new iobRefreshedEventArgs(currDispData));
+ }
+ }
+ }
+
+ ///
+ /// Cancella dal server i task eseguiti
+ ///
+ ///
+ ///
+ ///
+ protected string remTask2exe(string taskName, string esitoTask)
+ {
+ string answ = "";
+ if (checkServerAlive)
+ {
+ string url2call = $"{urlRemTask2Exe}{taskName}";
+ lgInfo($"Task2Exe | {esitoTask} | chiamata URL {url2call}");
+ answ = utils.callUrlNow(url2call);
+ }
+ return answ;
+ }
+
+ ///
+ /// Invia informazioni associazione IOB 2 machine
+ ///
+ protected void sendM2IOB()
+ {
+ if (checkServerAlive)
+ {
+ lgInfo("chiamata URL " + urlSetM2IOB);
+ utils.callUrlNow(urlSetM2IOB);
+ }
+ }
+
+ ///
+ /// Invia al server IO i valori dei parametri opzionali (es counters)
+ ///
+ /// Nome parametro
+ /// Valore parametro
+ protected void sendOptVal(string paramName, string paramValue)
+ {
+ if (checkServerAlive)
+ {
+ string url2call = $"{urlSetOptVal}pName={paramName}&pValue={paramValue}";
+ lgInfo("chiamata URL " + url2call);
+ utils.callUrlNow(url2call);
+ }
+ }
+
+ ///
+ /// Invia al server IO i valori dei parametri opzionali (es counters)
+ ///
+ /// Nome parametro
+ /// Valore parametro INT
+ protected void sendOptVal(string paramName, int paramValueInt)
+ {
+ // override!
+ sendOptVal(paramName, paramValueInt.ToString());
+ }
+
///
/// processa dataLayer e se necessario salva/mostra
///
@@ -1631,311 +1960,6 @@ namespace IOB_WIN
{
}
- ///
- /// Stringa raw dei parametri da scrivere...
- ///
- ///
- protected string getParams2write()
- {
- string answ = "";
- string url2call = $"{urlGetParams2Write}";
- if (verboseLog)
- {
- lgInfo("chiamata URL " + url2call);
- }
- answ = utils.callUrlNow(url2call);
- // se vuoto faccio seconda prova...
- if (string.IsNullOrEmpty(answ))
- {
- answ = utils.callUrlNow(url2call);
- }
- return answ;
- }
-
- ///
- /// Chiede elenco dei task da eseguire
- /// - formato Json
- /// - array di KVP / Dictionary
- /// - formato definito da API x MP/IO/:
- /// - KEY: task
- /// - VALUE: array JSon KVP
- ///
- protected string getTask2exe()
- {
- string answ = "";
- if (checkServerAlive)
- {
- string url2call = $"{urlGetTask2Exe}";
- if (verboseLog)
- {
- lgInfo("chiamata URL " + url2call);
- }
- answ = utils.callUrlNow(url2call);
- }
- return answ;
- }
-
- ///
- /// Metodo da overridare x scrivere DAVVERO i aprametri sul PLC
- ///
- ///
- protected virtual void plcWriteParams(List updatedPar)
- {
- // non faccio nulla di base...
- }
-
- ///
- /// Processa le richieste di scrittura memoria
- ///
- ///
- protected string processMemWriteRequests()
- {
- string answ = "";
- // li salvo nei parametri in memoria locale (ogni adapter DOVREBBE salvare POI sul VERO PLC)
- List writeList = new List();
- List updatedPar = new List();
- // recupero elenco delle cose da fare
- string resp = getParams2write();
- if (!string.IsNullOrEmpty(resp))
- {
- try
- {
- writeList = JsonConvert.DeserializeObject>(resp);
- // se ho da fare chiamo esecuzione..
- if (writeList.Count > 0)
- {
- foreach (var item in writeList)
- {
- // scrivo in memoria
- if (memMap.mMapWrite.ContainsKey(item.uid))
- {
- memMap.mMapWrite[item.uid].value = item.reqValue;
- // accodo in stringa taskVal...
- answ += $" | Parameter {item.uid} --> {item.reqValue}";
- // sistemo valori
- item.value = item.reqValue;
- lgInfo($"Effettuato update parametro: actVal = {item.value} | reqVal = {item.reqValue}");
- item.reqValue = "";
- // salvo in lista da ritrasmettere
- updatedPar.Add(item);
- }
- else
- {
- answ += $" | Error: parameter {item.uid} not found";
- }
- }
- // richiamo scrittura parametri su PLC
- plcWriteParams(updatedPar);
- // invio su cloud parametri!
- string rawData = JsonConvert.SerializeObject(updatedPar);
- utils.callUrl($"{urlUpdateWriteParams}", rawData);
- }
- }
- catch (Exception exc)
- {
- lgError($"Eccezione in processServerRequests:{Environment.NewLine}{exc}");
- }
- }
- else
- {
- lgError("Non è stata ricevuta risposta x task da eseguire");
- }
- return answ;
- }
-
- protected void raiseRefresh(newDisplayData currDispData)
- {
- if (currDispData.hasData)
- {
- // segnalo refresh!
- if (eh_refreshed != null)
- {
- eh_refreshed(this, new iobRefreshedEventArgs(currDispData));
- }
- }
- }
-
- ///
- /// Cancella dal server i task eseguiti
- ///
- ///
- ///
- ///
- protected string remTask2exe(string taskName, string esitoTask)
- {
- string answ = "";
- if (checkServerAlive)
- {
- string url2call = $"{urlRemTask2Exe}{taskName}";
- lgInfo($"Task2Exe | {esitoTask} | chiamata URL {url2call}");
- answ = utils.callUrlNow(url2call);
- }
- return answ;
- }
-
- ///
- /// Invia informazioni associazione IOB 2 machine
- ///
- protected void sendM2IOB()
- {
- if (checkServerAlive)
- {
- lgInfo("chiamata URL " + urlSetM2IOB);
- utils.callUrlNow(urlSetM2IOB);
- }
- }
-
- ///
- /// Invia al server IO i valori dei parametri opzionali (es counters)
- ///
- /// Nome parametro
- /// Valore parametro
- protected void sendOptVal(string paramName, string paramValue)
- {
- if (checkServerAlive)
- {
- string url2call = $"{urlSetOptVal}pName={paramName}&pValue={paramValue}";
- lgInfo("chiamata URL " + url2call);
- utils.callUrlNow(url2call);
- }
- }
-
- ///
- /// Invia al server IO i valori dei parametri opzionali (es counters)
- ///
- /// Nome parametro
- /// Valore parametro INT
- protected void sendOptVal(string paramName, int paramValueInt)
- {
- // override!
- sendOptVal(paramName, paramValueInt.ToString());
- }
-
- ///
- /// Verifica e se necessario comprime directory log...
- ///
- private void checkShrinkDir()
- {
- string path = string.Format("{0}logs\\{1}", AppDomain.CurrentDomain.BaseDirectory, cIobConf.codIOB);
- baseUtils.shrinkDir(path);
- }
-
- private void reportDataProc()
- {
- // update valori visualizzazione...
- parentForm.dataProcLabel = string.Format("RAW: {0} --> IN: {1} --> OUT: {2}", nReadIN, nReadFilt, nSendOut);
- }
-
- private void svuotaCodaContapezzi()
- {
- // permetto al max 2 tentativi infruttuosi...
- int maxTry = 2;
- int oldContapezzi = contapezziIOB;
- // se ho contapezzi OLTRE limite...
- while ((MPOnline) && (contapezziPLC > contapezziIOB + minSendPzCountBlock))
- {
- lgInfo($"Ciclo svuotaCodaContapezzi --> contapezziPLC: {contapezziPLC} | contapezziIOB: {contapezziIOB}");
- if (!isMulti)
- {
- pzCntReload(true);
- }
- // provo invio
- trySendPzCountBlock();
- // verifica per evitare loop infinito invio fallito
- if (oldContapezzi == contapezziIOB)
- {
- maxTry--;
- }
- else
- {
- maxTry = 2;
- oldContapezzi = contapezziIOB;
- }
- // verifico maxTry: se li ho esauriti esco!
- if (maxTry <= 0)
- {
- return;
- }
- // aspetto x dare tempo calcolo
- Thread.Sleep(400);
- }
- }
-
- ///
- /// Cerca di inviare su un altro thread i vari dati accumulati...
- ///
- private void trySendValues()
- {
- // init obj display
- newDisplayData currDispData = new newDisplayData();
- try
- {
- // verifico se risponde il server...
- if (checkServerAlive)
- {
- bool iobOk = false;
- if (utils.CRB("sendDataByThread"))
- {
- Task taskCheck = TaskEx.Run(() => iobOk = checkIobEnabled);
- }
- else
- {
- iobOk = checkIobEnabled;
- }
- // verifico SE posso inviare dati
- if (iobOk)
- {
- currDispData.semOut = Semaforo.SV;
- // verificare come gestire il task secondario senza interferenza (chiamate update su FORM da thread secondari danno errori)
- if (utils.CRB("sendDataByThread"))
- {
- // invio con thread separato...
- Task taskSigIN = TaskEx.Run(() => svuotaCodaSignIN());
- Task taskFlog = TaskEx.Run(() => svuotaCodaFLog());
- }
- else
- {
- // gestione queue SignalIN (invio, display)
- svuotaCodaSignIN();
- currDispData.counter = contapezziIOB;
- raiseRefresh(currDispData);
- // provo a svuotare coda contapezzi
- svuotaCodaContapezzi();
- currDispData.counter = contapezziIOB;
- raiseRefresh(currDispData);
- // gestione queue FluxLog (invio, display)
- svuotaCodaFLog();
- raiseRefresh(currDispData);
- }
- }
- else
- {
- // mostro VETO-SEND x invio... GIALLO
- currDispData.semOut = Semaforo.SG;
- if (periodicLog)
- {
- lgInfo("IOB - VETO SEND");
- }
- }
- }
- else
- {
- // mostro SERVER KO x invio... ROSSO
- currDispData.semOut = Semaforo.SR;
- if (periodicLog)
- {
- lgInfo("IOB - SERVER NOT READY");
- }
- }
- }
- catch (Exception exc)
- {
- lgError($"Errore in fase trySendValues{Environment.NewLine}{exc}");
- currDispData.semOut = Semaforo.SR;
- }
- raiseRefresh(currDispData);
- }
-
#endregion metodi adapter
#region layer persistenza dati
@@ -2127,51 +2151,6 @@ namespace IOB_WIN
#region area lettura configurazioni
- ///
- /// Cerca parametri opzionali in modalità "like" del nome
- ///
- ///
- ///
- public Dictionary findOptPar(string keyStartSearch = "")
- {
- Dictionary answ = new Dictionary();
- // controllo SE keySearch !=""
- if (!string.IsNullOrWhiteSpace(keyStartSearch))
- {
- if (cIobConf.optPar.Count > 0)
- {
- // ciclo su tutti e cerco occorrenze che INIZINO...
- foreach (var item in cIobConf.optPar)
- {
- if (item.Key.StartsWith(keyStartSearch))
- {
- answ.Add(item.Key, item.Value);
- }
- }
- }
- }
- return answ;
- }
-
- ///
- /// Cerca se esiste il parametro opzionale e lo restituisce
- ///
- ///
- ///
- public string getOptPar(string key)
- {
- string answ = "";
- if (cIobConf.optPar.Count > 0)
- {
- // controllo SE HO il parametro
- if (cIobConf.optPar.ContainsKey(key))
- {
- answ = cIobConf.optPar[key];
- }
- }
- return answ;
- }
-
///
/// Decodifica file MAP (caso .bit)
///
@@ -2313,6 +2292,51 @@ namespace IOB_WIN
}
}
+ ///
+ /// Cerca parametri opzionali in modalità "like" del nome
+ ///
+ ///
+ ///
+ public Dictionary findOptPar(string keyStartSearch = "")
+ {
+ Dictionary answ = new Dictionary();
+ // controllo SE keySearch !=""
+ if (!string.IsNullOrWhiteSpace(keyStartSearch))
+ {
+ if (cIobConf.optPar.Count > 0)
+ {
+ // ciclo su tutti e cerco occorrenze che INIZINO...
+ foreach (var item in cIobConf.optPar)
+ {
+ if (item.Key.StartsWith(keyStartSearch))
+ {
+ answ.Add(item.Key, item.Value);
+ }
+ }
+ }
+ }
+ return answ;
+ }
+
+ ///
+ /// Cerca se esiste il parametro opzionale e lo restituisce
+ ///
+ ///
+ ///
+ public string getOptPar(string key)
+ {
+ string answ = "";
+ if (cIobConf.optPar.Count > 0)
+ {
+ // controllo SE HO il parametro
+ if (cIobConf.optPar.ContainsKey(key))
+ {
+ answ = cIobConf.optPar[key];
+ }
+ }
+ return answ;
+ }
+
#endregion area lettura configurazioni
#region IOB METHODS
@@ -2327,6 +2351,155 @@ namespace IOB_WIN
///
public DateTime lastSim;
+ ///
+ /// Verifica se la IOB sia ENABLED (da server o Demo)
+ ///
+ private bool checkIobEnabled
+ {
+ get
+ {
+ bool answ = false;
+ // controllo se ho veto al check...
+ if (dtVetoCheckIOB < DateTime.Now)
+ {
+ if (DemoOut)
+ {
+ answ = (QueueIN.Count + QueueFLog.Count >= nMaxSend);
+ }
+ else
+ {
+ try
+ {
+ // chiamo URL, se restituisce "OK" è enabled!
+ string callResp = callUrl(urlIobEnabled, true);
+ answ = (callResp == "OK");
+ // attesa casuale se necessario
+ var rand = new Random();
+ // primi 2 test
+ int maxTry = 2;
+ while (maxTry > 0 && !answ)
+ {
+ Thread.Sleep(rand.Next(250, 500));
+ callResp = callUrl(urlIobEnabled, true);
+ answ = (callResp == "OK");
+ maxTry--;
+ }
+ // se NON OK riprovo ANCORA 1 volta...
+ if (!answ)
+ {
+ resetWebClients();
+ Thread.Sleep(rand.Next(250, 1000));
+ callResp = callUrl(urlIobEnabled, false);
+ answ = (callResp == "OK");
+ }
+ // altri 2
+ maxTry = 2;
+ while (maxTry > 0 && !answ)
+ {
+ Thread.Sleep(rand.Next(250, 500));
+ callResp = callUrl(urlIobEnabled, false);
+ answ = (callResp == "OK");
+ maxTry--;
+ }
+ // salvo status...
+ IobOnline = answ;
+ // se online imposto veto check a 5 x tempo reinvio...
+ if (answ)
+ {
+ lastIobOnline = DateTime.Now;
+ }
+ dtVetoCheckIOB = DateTime.Now.AddMilliseconds(baseUtils.nextPauseSendMSec * 5);
+ }
+ catch
+ { }
+ }
+ // verifico SE è variato stato online/offline...
+ if (IobOnline != answ)
+ {
+ // se ORA sono online riporto...
+ if (answ)
+ {
+ lgInfo("IOB ONLINE for server MP/IO");
+ }
+ else
+ {
+ lgInfo("IOB OFFLINE for server MP/IO");
+ }
+ }
+ // fix colore
+ if (answ)
+ {
+ parentForm.commSrvActive = 2;
+ }
+ else
+ {
+ parentForm.commSrvActive = 1;
+ }
+ }
+ else
+ {
+ // altrimenti passo ultimo valore noto
+ answ = IobOnline;
+ }
+ return answ;
+ }
+ }
+
+ ///
+ /// test ping all'indirizzo impostato nei parametri
+ ///
+ ///
+ private IPStatus testPingServer
+ {
+ get
+ {
+ IPStatus answ = IPStatus.Unknown; ;
+ IPAddress address;
+ PingReply reply;
+ using (Ping pingSender = new Ping())
+ {
+ address = IPAddress.Loopback;
+ int maxRetry = maxPingRetry + 1;
+ int numRetry = 1; ;
+ string ipAdrr = cIobConf.serverData.MPIP.Replace("http://", "").Replace("https://", "");
+ IPAddress.TryParse(ipAdrr, out address);
+ reply = pingSender.Send(address, pingServerMsTimeout);
+ // se ho timeout riprovo...
+ while (reply.Status != IPStatus.Success && numRetry < maxRetry)
+ {
+ lgInfo($"Ping KO | reply: {reply.Status} --> retry");
+ reply = pingSender.Send(address, pingServerMsTimeout * numRetry / 2);
+ numRetry++;
+ if (reply.Status == IPStatus.Success)
+ {
+ lgInfo("PING OK!");
+ break;
+ }
+ }
+ }
+ answ = reply.Status;
+ return answ;
+ }
+ }
+
+ ///
+ /// Valore del num max invii consecutivi da coda...
+ ///
+ protected static int nMaxSend
+ {
+ get
+ {
+ int answ = 5;
+ try
+ {
+ answ = utils.CRI("nMaxSend");
+ }
+ catch
+ { }
+ return answ;
+ }
+ }
+
///
/// Verifica se il server sia ALIVE (tramite PING)
///
@@ -2830,151 +3003,237 @@ namespace IOB_WIN
}
///
- /// Valore del num max invii consecutivi da coda...
+ /// Esegue filtraggio dati x bit blinking!!!
///
- protected static int nMaxSend
+ private void filterData()
{
- get
+ // effettuo filtraggio dei valori letti... inizializzo OUT!
+ B_output = 0;
+ // in primis verifico SE ci siano bit blinkng... se non ci sono OUT=IN...
+ if (cIobConf.BLINK_FILT == 0)
{
- int answ = 5;
- try
+ B_output = B_input;
+ }
+ else
+ {
+ // incomincio con i valori NON blinking: questi "passano invariati", inizio a sommare nel valore OUT...
+ B_output = B_input & ~cIobConf.BLINK_FILT;
+ // calcolo il valore dei BIT che "passano la maschera"
+ int iBlink = B_input & cIobConf.BLINK_FILT;
+ // ...aggiungo i "bit che passano"
+ B_output += iBlink;
+
+ // calcolo QUALI valori (tra quelli blink) siano PASSATI da 0 a 1 --> init counters...
+ BitArray bBlinkStart = new BitArray(new byte[] { Convert.ToByte(iBlink) });
+ int[] bitsUp = bBlinkStart.Cast().Select(bit => bit ? 1 : 0).ToArray();
+ for (int i = 0; i < bitsUp.Length; i++)
{
- answ = utils.CRI("nMaxSend");
+ // SE 1... impostiamo contatori al MAX
+ if (bitsUp[i] == 1)
+ {
+ // se era zero indico START blink...
+ if (i_counters[i] == 0)
+ {
+ lgInfo("START BLINK: B{0}", i);
+ }
+ // imposto comunque contatore al cambio fronte...
+ i_counters[i] = cIobConf.MAX_COUNTER_BLINK;
+ }
+ }
+
+ // quelli che sono zero... LI RECUPERO E LI PROCESSO...
+ int iZero = ~B_input & cIobConf.BLINK_FILT;
+ BitArray bBlinkEnd = new BitArray(new byte[] { Convert.ToByte(iZero) });
+ int[] bitsDown = bBlinkEnd.Cast().Select(bit => bit ? 1 : 0).ToArray();
+ for (int i = 0; i < bitsDown.Length; i++)
+ {
+ // se era a zero (invertito...)
+ if (bitsDown[i] == 1)
+ {
+ // SE è in corso il conteggio...
+ if (i_counters[i] > 0)
+ {
+ // decremento!
+ i_counters[i] -= 1;
+ // se è zero NON faccio nulla, altrimenti SOMMO...
+ if (i_counters[i] > 0)
+ {
+ B_output += 1 << i;
+ }
+ else
+ {
+ lgInfo("END BLINK: B{0}", i);
+ }
+ }
+ }
}
- catch
- { }
- return answ;
}
}
///
- /// Verifica se la IOB sia ENABLED (da server o Demo)
+ /// Classe fittizia in caso di processing GLOBALE di tutto in 1 solo colpo...
///
- private bool checkIobEnabled
+ private void processAllMemory()
{
- get
+ // init obj display
+ newDisplayData currDispData = new newDisplayData();
+ // in primis SALVO valori previous/precedenti
+ B_previous = B_output;
+ // poi faccio lettura NUOVI valori
+ readAllData(ref currDispData);
+ // eseguo il filtering dei valori (per i bit "blinking")
+ filterData();
+ // effettuo confronto valori vecchi/nuovi... SE trovo variazione OPPURE se è passato + di un timeout di controllo...
+ if (B_output != B_previous)
{
- bool answ = false;
- // controllo se ho veto al check...
- if (dtVetoCheckIOB < DateTime.Now)
+ accodaSigIN(ref currDispData);
+ }
+ raiseRefresh(currDispData);
+ }
+
+ ///
+ /// Effettua gestioen programma: legge e mostra su display...
+ ///
+ private void processProgram()
+ {
+ string currPrgName = "";
+ // se abilitata lettura prgName
+ if (enablePrgName)
+ {
+ if (connectionOk)
{
- if (DemoOut)
- {
- answ = (QueueIN.Count + QueueFLog.Count >= nMaxSend);
- }
- else
- {
- try
- {
- // chiamo URL, se restituisce "OK" è enabled!
- string callResp = callUrl(urlIobEnabled, true);
- answ = (callResp == "OK");
- // attesa casuale se necessario
- var rand = new Random();
- // primi 2 test
- int maxTry = 2;
- while (maxTry > 0 && !answ)
- {
- Thread.Sleep(rand.Next(250, 500));
- callResp = callUrl(urlIobEnabled, true);
- answ = (callResp == "OK");
- maxTry--;
- }
- // se NON OK riprovo ANCORA 1 volta...
- if (!answ)
- {
- resetWebClients();
- Thread.Sleep(rand.Next(250, 1000));
- callResp = callUrl(urlIobEnabled, false);
- answ = (callResp == "OK");
- }
- // altri 2
- maxTry = 2;
- while (maxTry > 0 && !answ)
- {
- Thread.Sleep(rand.Next(250, 500));
- callResp = callUrl(urlIobEnabled, false);
- answ = (callResp == "OK");
- maxTry--;
- }
- // salvo status...
- IobOnline = answ;
- // se online imposto veto check a 5 x tempo reinvio...
- if (answ)
- {
- lastIobOnline = DateTime.Now;
- }
- dtVetoCheckIOB = DateTime.Now.AddMilliseconds(baseUtils.nextPauseSendMSec * 5);
- }
- catch
- { }
- }
- // verifico SE è variato stato online/offline...
- if (IobOnline != answ)
- {
- // se ORA sono online riporto...
- if (answ)
- {
- lgInfo("IOB ONLINE for server MP/IO");
- }
- else
- {
- lgInfo("IOB OFFLINE for server MP/IO");
- }
- }
- // fix colore
- if (answ)
- {
- parentForm.commSrvActive = 2;
- }
- else
- {
- parentForm.commSrvActive = 1;
- }
+ currPrgName = getPrgName();
}
else
{
- // altrimenti passo ultimo valore noto
- answ = IobOnline;
+ lgError("Errore connessione mancante x getPrgName");
}
- return answ;
+ }
+ else
+ {
+ currPrgName = lastPrgName;
+ }
+ // verifico SE sia cambiato il programma...
+ if (lastPrgName != currPrgName)
+ {
+ // salvo!
+ lastPrgName = currPrgName;
+ string sVal = string.Format("[PROG]{0}", currPrgName);
+
+ // chiamo accodamento...
+ accodaFLog(sVal, qEncodeFLog("PROG", currPrgName));
}
}
///
- /// test ping all'indirizzo impostato nei parametri
+ /// Processo lettura dati sysinfo
///
- ///
- private IPStatus testPingServer
+ private void processSysInfo()
{
- get
+ if (utils.CRB("enableSysInfo"))
{
- IPStatus answ = IPStatus.Unknown; ;
- IPAddress address;
- PingReply reply;
- using (Ping pingSender = new Ping())
+ Dictionary currSysInfo = new Dictionary();
+
+ if (connectionOk)
{
- address = IPAddress.Loopback;
- int maxRetry = maxPingRetry + 1;
- int numRetry = 1; ;
- string ipAdrr = cIobConf.serverData.MPIP.Replace("http://", "").Replace("https://", "");
- IPAddress.TryParse(ipAdrr, out address);
- reply = pingSender.Send(address, pingServerMsTimeout);
- // se ho timeout riprovo...
- while (reply.Status != IPStatus.Success && numRetry < maxRetry)
+ currSysInfo = getSysInfo();
+ }
+ else
+ {
+ lgError("Errore connessione mancante x getSysInfo");
+ }
+ // verifico SE sia cambiato il programma...
+ if (lastSysInfo != currSysInfo["SYSINFO"])
+ {
+ // salvo!
+ lastSysInfo = currSysInfo["SYSINFO"];
+ // per ogni valore del dizionario mostro ed accodo!
+ string sVal = "";
+ foreach (var item in currSysInfo)
{
- lgInfo($"Ping KO | reply: {reply.Status} --> retry");
- reply = pingSender.Send(address, pingServerMsTimeout * numRetry / 2);
- numRetry++;
- if (reply.Status == IPStatus.Success)
+ sVal = string.Format("[SYSINFO]{0}|{1}", item.Key, item.Value);
+ // chiamo accodamento...
+ accodaFLog(sVal, qEncodeFLog(item.Key, item.Value));
+ }
+ }
+ }
+ }
+
+ ///
+ /// Processo la coda FLog...
+ ///
+ private void svuotaCodaFLog()
+ {
+ //controllo se è passato oltre watchdog e non ho inviato nulla --> RE-INVIO (ultimo inviato)!!!!
+ if (DateTime.Now.Subtract(lastWatchDog).TotalSeconds > utils.CRI("watchdogMaxSec"))
+ {
+ string wdStatus = "elapsed";
+ string sVal = string.Format("[WDST]{0}", wdStatus);
+ // chiamo accodamento...
+ accodaFLog(sVal, qEncodeFLog("WDST", wdStatus));
+ lastWatchDog = DateTime.Now;
+ }
+ // verifico SE la coda abbia dei valori...
+ if (QueueFLog.Count > 0)
+ {
+ // invio pacchetto di dati (max da conf)
+ for (int i = 0; i < nMaxSend; i++)
+ {
+ // SE ho qualcosa in coda...
+ if (QueueFLog.Count > 0)
+ {
+ string currVal = "";
+ if (MPOnline)
+ {
+ if (IobOnline)
+ {
+ // se ho + di 2 elementi in coda --> uso invio JSON in blocco...
+ if (QueueFLog.Count > 1)
+ {
+ List listaValori = new List();
+ // se ho + di maxJsonData elementi --> invio un set di dati alla volta
+ if (QueueFLog.Count > maxJsonData)
+ {
+ // prendoi primi maxJsonDataValori
+ for (int j = 0; j < maxJsonData; j++)
+ {
+ QueueFLog.TryDequeue(out currVal);
+ listaValori.Add(currVal);
+ }
+ sendDataBlock(urlType.FLog, listaValori);
+ }
+ else
+ {
+ // invio in blocco
+ listaValori = QueueFLog.ToList();
+ // invio
+ sendDataBlock(urlType.FLog, listaValori);
+ // svuoto!
+ QueueFLog = new ConcurrentQueue();
+ }
+ }
+ else
+ {
+ // INVIO SINGOLO...!!!
+ QueueFLog.TryDequeue(out currVal);
+ sendToMoonPro(urlType.FLog, currVal);
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ else
{
- lgInfo("PING OK!");
break;
}
}
+ else
+ {
+ break;
+ }
}
- answ = reply.Status;
- return answ;
}
}
@@ -3861,241 +4120,6 @@ namespace IOB_WIN
return answ;
}
- ///
- /// Esegue filtraggio dati x bit blinking!!!
- ///
- private void filterData()
- {
- // effettuo filtraggio dei valori letti... inizializzo OUT!
- B_output = 0;
- // in primis verifico SE ci siano bit blinkng... se non ci sono OUT=IN...
- if (cIobConf.BLINK_FILT == 0)
- {
- B_output = B_input;
- }
- else
- {
- // incomincio con i valori NON blinking: questi "passano invariati", inizio a sommare nel valore OUT...
- B_output = B_input & ~cIobConf.BLINK_FILT;
- // calcolo il valore dei BIT che "passano la maschera"
- int iBlink = B_input & cIobConf.BLINK_FILT;
- // ...aggiungo i "bit che passano"
- B_output += iBlink;
-
- // calcolo QUALI valori (tra quelli blink) siano PASSATI da 0 a 1 --> init counters...
- BitArray bBlinkStart = new BitArray(new byte[] { Convert.ToByte(iBlink) });
- int[] bitsUp = bBlinkStart.Cast().Select(bit => bit ? 1 : 0).ToArray();
- for (int i = 0; i < bitsUp.Length; i++)
- {
- // SE 1... impostiamo contatori al MAX
- if (bitsUp[i] == 1)
- {
- // se era zero indico START blink...
- if (i_counters[i] == 0)
- {
- lgInfo("START BLINK: B{0}", i);
- }
- // imposto comunque contatore al cambio fronte...
- i_counters[i] = cIobConf.MAX_COUNTER_BLINK;
- }
- }
-
- // quelli che sono zero... LI RECUPERO E LI PROCESSO...
- int iZero = ~B_input & cIobConf.BLINK_FILT;
- BitArray bBlinkEnd = new BitArray(new byte[] { Convert.ToByte(iZero) });
- int[] bitsDown = bBlinkEnd.Cast().Select(bit => bit ? 1 : 0).ToArray();
- for (int i = 0; i < bitsDown.Length; i++)
- {
- // se era a zero (invertito...)
- if (bitsDown[i] == 1)
- {
- // SE è in corso il conteggio...
- if (i_counters[i] > 0)
- {
- // decremento!
- i_counters[i] -= 1;
- // se è zero NON faccio nulla, altrimenti SOMMO...
- if (i_counters[i] > 0)
- {
- B_output += 1 << i;
- }
- else
- {
- lgInfo("END BLINK: B{0}", i);
- }
- }
- }
- }
- }
- }
-
- ///
- /// Classe fittizia in caso di processing GLOBALE di tutto in 1 solo colpo...
- ///
- private void processAllMemory()
- {
- // init obj display
- newDisplayData currDispData = new newDisplayData();
- // in primis SALVO valori previous/precedenti
- B_previous = B_output;
- // poi faccio lettura NUOVI valori
- readAllData(ref currDispData);
- // eseguo il filtering dei valori (per i bit "blinking")
- filterData();
- // effettuo confronto valori vecchi/nuovi... SE trovo variazione OPPURE se è passato + di un timeout di controllo...
- if (B_output != B_previous)
- {
- accodaSigIN(ref currDispData);
- }
- raiseRefresh(currDispData);
- }
-
- ///
- /// Effettua gestioen programma: legge e mostra su display...
- ///
- private void processProgram()
- {
- string currPrgName = "";
- // se abilitata lettura prgName
- if (enablePrgName)
- {
- if (connectionOk)
- {
- currPrgName = getPrgName();
- }
- else
- {
- lgError("Errore connessione mancante x getPrgName");
- }
- }
- else
- {
- currPrgName = lastPrgName;
- }
- // verifico SE sia cambiato il programma...
- if (lastPrgName != currPrgName)
- {
- // salvo!
- lastPrgName = currPrgName;
- string sVal = string.Format("[PROG]{0}", currPrgName);
-
- // chiamo accodamento...
- accodaFLog(sVal, qEncodeFLog("PROG", currPrgName));
- }
- }
-
- ///
- /// Processo lettura dati sysinfo
- ///
- private void processSysInfo()
- {
- if (utils.CRB("enableSysInfo"))
- {
- Dictionary currSysInfo = new Dictionary();
-
- if (connectionOk)
- {
- currSysInfo = getSysInfo();
- }
- else
- {
- lgError("Errore connessione mancante x getSysInfo");
- }
- // verifico SE sia cambiato il programma...
- if (lastSysInfo != currSysInfo["SYSINFO"])
- {
- // salvo!
- lastSysInfo = currSysInfo["SYSINFO"];
- // per ogni valore del dizionario mostro ed accodo!
- string sVal = "";
- foreach (var item in currSysInfo)
- {
- sVal = string.Format("[SYSINFO]{0}|{1}", item.Key, item.Value);
- // chiamo accodamento...
- accodaFLog(sVal, qEncodeFLog(item.Key, item.Value));
- }
- }
- }
- }
-
- ///
- /// Processo la coda FLog...
- ///
- private void svuotaCodaFLog()
- {
- //controllo se è passato oltre watchdog e non ho inviato nulla --> RE-INVIO (ultimo inviato)!!!!
- if (DateTime.Now.Subtract(lastWatchDog).TotalSeconds > utils.CRI("watchdogMaxSec"))
- {
- string wdStatus = "elapsed";
- string sVal = string.Format("[WDST]{0}", wdStatus);
- // chiamo accodamento...
- accodaFLog(sVal, qEncodeFLog("WDST", wdStatus));
- lastWatchDog = DateTime.Now;
- }
- // verifico SE la coda abbia dei valori...
- if (QueueFLog.Count > 0)
- {
- // invio pacchetto di dati (max da conf)
- for (int i = 0; i < nMaxSend; i++)
- {
- // SE ho qualcosa in coda...
- if (QueueFLog.Count > 0)
- {
- string currVal = "";
- if (MPOnline)
- {
- if (IobOnline)
- {
- // se ho + di 2 elementi in coda --> uso invio JSON in blocco...
- if (QueueFLog.Count > 1)
- {
- List listaValori = new List();
- // se ho + di maxJsonData elementi --> invio un set di dati alla volta
- if (QueueFLog.Count > maxJsonData)
- {
- // prendoi primi maxJsonDataValori
- for (int j = 0; j < maxJsonData; j++)
- {
- QueueFLog.TryDequeue(out currVal);
- listaValori.Add(currVal);
- }
- sendDataBlock(urlType.FLog, listaValori);
- }
- else
- {
- // invio in blocco
- listaValori = QueueFLog.ToList();
- // invio
- sendDataBlock(urlType.FLog, listaValori);
- // svuoto!
- QueueFLog = new ConcurrentQueue();
- }
- }
- else
- {
- // INVIO SINGOLO...!!!
- QueueFLog.TryDequeue(out currVal);
- sendToMoonPro(urlType.FLog, currVal);
- }
- }
- else
- {
- break;
- }
- }
- else
- {
- break;
- }
- }
- else
- {
- break;
- }
- }
- }
- }
-
#endregion IOB METHODS
#region gestione VC e postprocessing
@@ -4258,6 +4282,29 @@ namespace IOB_WIN
}
}
+ ///
+ /// Decodifica valore della coda IN nel formato
+ /// answ[0]=dtEve
+ /// answ[1]=valore
+ /// answ[2]=counter
+ ///
+ /// dtEve + '#' + value + '#' + cont
+ ///
+ protected static string[] qDecodeIN(string queueVal)
+ {
+ string[] answ = null;
+ if (!string.IsNullOrEmpty(queueVal))
+ {
+ try
+ {
+ answ = queueVal.Split('#');
+ }
+ catch
+ { }
+ }
+ return answ;
+ }
+
///
/// Accumula in coda i valori ALARM e logga...
///
@@ -4535,33 +4582,25 @@ namespace IOB_WIN
raiseRefresh(currDispData);
}
- ///
- /// Decodifica valore della coda IN nel formato
- /// answ[0]=dtEve
- /// answ[1]=valore
- /// answ[2]=counter
- ///
- /// dtEve + '#' + value + '#' + cont
- ///
- protected static string[] qDecodeIN(string queueVal)
- {
- string[] answ = null;
- if (!string.IsNullOrEmpty(queueVal))
- {
- try
- {
- answ = queueVal.Split('#');
- }
- catch
- { }
- }
- return answ;
- }
-
#endregion gestione code (accumulo, invio)
#region gestione dataMonitor (update visualizzazione valori)
+ ///
+ /// Mostra i dati grezzi letti in esadecimale
+ /// Parametri da aggiornare x display in form
+ ///
+ private void displayRawData(ref newDisplayData currDispData)
+ {
+ // mostro update...
+ string newString = string.Format("{0:X}", B_input);
+ currDispData.newInData = newString;
+#if false
+ // salvo coda debug...
+ QueueDebug.Enqueue(B_input);
+#endif
+ }
+
///
/// Accoda (visualizzando in cima allo stack) la nuova stringa di output per area OTHER DATA
///
@@ -4615,21 +4654,6 @@ namespace IOB_WIN
return newString;
}
- ///
- /// Mostra i dati grezzi letti in esadecimale
- /// Parametri da aggiornare x display in form
- ///
- private void displayRawData(ref newDisplayData currDispData)
- {
- // mostro update...
- string newString = string.Format("{0:X}", B_input);
- currDispData.newInData = newString;
-#if false
- // salvo coda debug...
- QueueDebug.Enqueue(B_input);
-#endif
- }
-
#endregion gestione dataMonitor (update visualizzazione valori)
}
@@ -4638,11 +4662,17 @@ namespace IOB_WIN
///
public class iobRefreshedEventArgs : EventArgs
{
+ #region Private Fields
+
///
/// classe obj privata
///
private readonly newDisplayData _newDisplayData;
+ #endregion Private Fields
+
+ #region Public Constructors
+
///
/// salvataggio obj
///
@@ -4652,6 +4682,10 @@ namespace IOB_WIN
_newDisplayData = newObject;
}
+ #endregion Public Constructors
+
+ #region Public Properties
+
///
/// Proprietà lettura displayData aggiornato
///
@@ -4659,5 +4693,7 @@ namespace IOB_WIN
{
get { return _newDisplayData; }
}
+
+ #endregion Public Properties
}
}
\ No newline at end of file