using IOB_UT;
using NLog;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace IOB_WIN
{
public class IobGeneric
{
///
/// Evento Iob ha subito un refresh
///
public event EventHandler eh_refreshed;
///
/// Determina se sia encessario convertire valori little/big endian (SIEMENS=true, OSAI=FALSE)
///
public bool hasBigEndian = false;
///
/// alias booleano false = R
///
public bool R = false;
///
/// alias booleano true = W
///
public bool W = true;
///
/// wrapper di log
///
public static Logger lg;
///
/// dataOra ultimo log periodico...
///
public DateTime lastPeriodicLog;
///
/// Oggetto della coda degli elementi letti (e non ancora trasmessi)
///
public Queue QueueIN = new Queue();
///
/// Coda valori simulazione deterministica...
///
public Queue QueueSIM = new Queue();
///
/// Coda valori letti x DEBUG...
///
public Queue QueueDebug = new Queue();
///
/// valore booleano di check se sia in fase di COMUNICAZIONE ATTIVA con il PLC/NC
///
protected bool adpCommAct;
///
/// valore booleano di check se sia stato AVVIATO l'adapter (Running)
///
public bool adpRunning = false;
///
/// valore booleano di check se l'adapter STIA SALVANDO
///
public bool adpSaving = false;
///
/// valore booleano (richiesta di riavvio automatico)
///
public bool adpTryRestart;
///
/// Ultimo valore watchdog rilevato
///
public bool lastWatchDog = false;
///
/// Verifica se sia in modalità DEMO x dati INPUT
///
public bool DemoIn
{
get
{
return IOB_UT.baseUtils.CRB("DemoIn");
}
}
///
/// Verifica se sia in modalità DEMO avanzata (campionamento da set di valori ammessi...)
///
public bool DemoInSample
{
get
{
return IOB_UT.baseUtils.CRB("DemoInSample");
}
}
///
/// Numero simulazioni ammesse...
///
protected int numSim { get; set; }
///
/// Numero letture IN da avvio
///
protected int nReadIN { get; set; }
///
/// Numero letture IN da avvio
///
protected int nReadFilt { get; set; }
///
/// Numero invii OUT (svuotamento coda)
///
protected int nSendOut { get; set; }
///
/// Verifica se sia in modalità DEMO x dati OUTPUT
///
public bool DemoOut
{
get
{
return utils.CRB("DemoOut");
}
}
///
/// Contatore x invio dati
///
public int counter { get; set; }
///
/// Ultimo URL
///
public string lastUrl { get; set; }
///
/// Array dei contatori x segnali blinking
///
protected int[] i_counters;
///
/// Vettore 16 BIT valori precedenti
///
protected int B_previous;
///
/// Vettore 16 BIT valori in ingresso al filtro
///
protected int B_input;
///
/// Vettore 16 BIT valori in uscita dal filtro
///
protected int B_output;
// 16 byte di strobe (4 word da 32 bit di flags...)
public byte[] RawInput = new byte[4];
///
/// Verifica SE si debba fare log verboso (verboso + ogni tot letture IN)
///
public bool verboseLog
{
get
{
bool answ = false;
int logEvery = utils.CRI("logEvery");
if (logEvery < 1) logEvery = 10;
answ = utils.CRB("verbose") && (nReadIN % logEvery == 0);
return answ;
}
}
///
/// Verifica SE si debba fare log periodico (ogni "verboseLogTOut" sec...)
///
public bool periodicLog
{
get
{
bool answ = false;
answ = (DateTime.Now.Subtract(lastPeriodicLog).TotalSeconds > utils.CRI("verboseLogTOut"));
if (answ) lastPeriodicLog = DateTime.Now;
return answ;
}
}
///
/// Determina se utilizzare blocchi di memoria IOT contigui (e quindi processing "monoblocco" semplificato"=
///
public bool procIotMem = false;
///
/// porta x adapter (x restart)
///
protected int adpPortNum;
///
/// DataOra ultimo avvio adapter x watchdog
///
protected DateTime adpStartRun;
///
/// Data/ora ultimo avvio adapter
///
public DateTime dtAvvioAdp = DateTime.Now;
///
/// Data/ora ultimo spegnimento adapter
///
public DateTime dtStopAdp = DateTime.Now;
///
/// vettore gestione cronometraggi
///
public DateTime inizio;
///
/// Conteggio ATTUALE ore macchina ON
///
public double contOreMaccOn;
///
/// Conteggio ATTUALE ore macchina IN LAVORO
///
public double contOreMaccLav;
///
/// stato Online/Offline della IOB
///
public bool IobOnline;
///
/// stato Online/Offline della IOB
///
public bool MPOnline;
///
/// Form chiamante
///
protected MainForm parentForm;
///
/// Conf adapter corrente
///
public IobConfiguration currIobConf;
///
/// inizializzo l'oggetto sulla form SULLA BASE DEL FILE DI CONFIGURAZIONE letto
///
///
///
public IobGeneric(MainForm caller, IobConfiguration IOBConf)
{
lg = LogManager.GetCurrentClassLogger();
lg.Info("Avvio preliminare AdapterGeneric");
// configurazione...
currIobConf = IOBConf;
// aggiungo altri defaults
setDefaults();
// salvo il form chiamante
parentForm = caller;
// concluso!
lg.Info("Istanziata classe preliminare IOBGeneric");
}
///
/// Imposto alcuni valori di default
///
private void setDefaults()
{
numSim = utils.CRI("numSim");
nReadIN = 0;
nReadFilt = 0;
nSendOut = 0;
// svuoto code...
QueueIN.Clear();
QueueSIM.Clear();
// imposto contatori blink a zero...
i_counters = new int[32];
lastPeriodicLog = DateTime.Now;
}
#region metodi adapter
///
/// lettura file di persistenza
///
public void loadPersData()
{
}
///
/// Avvia l'adapter sulla porta richiesta
///
///
public virtual void startAdapter(int port)
{
lg.Info("Starting adapter...");
parentForm.commPlcActive = false;
adpRunning = true;
dtAvvioAdp = DateTime.Now;
TimingData.resetData();
// aggiungo altri defaults
setDefaults();
adpTryRestart = true;
parentForm.displayTaskAndLog("Adapter Started!");
}
///
/// ferma l'adapter...
///
/// indica se si debba tentare di riavviare l'adapter (con caduta connessione viene fermato in automatico)
public void stopAdapter(bool tryRestart)
{
parentForm.displayTaskAndLog("Svuotamento FORZATO coda invio...");
while (QueueIN.Count > 0)
{
// INVIO SE PERMESSO...!!!
sendToMoonPro(QueueIN.Dequeue());
}
//reportDataProc();
parentForm.displayTaskAndLog("Stopping adapter...");
adpTryRestart = false;
parentForm.displayTaskAndLog("Stopping adapter - last periodic data read...");
// chiudo la connessione all'adapter...
tryDisconnect();
dtStopAdp = DateTime.Now;
adpTryRestart = tryRestart;
adpRunning = false;
// chiudo!
parentForm.resetProgBar();
parentForm.displayTaskAndLog("Adapter Stopped.");
parentForm.commPlcActive = false;
}
///
/// effettua recupero dati ed invio valori modificati...
///
///
public void getAndSend(gatherCycle ciclo)
{
lg.Info("START getAndSend");
// controllo connessione/connettività
if (connectionOk)
{
// controllo non sia già in esecuzione...
if (!adpCommAct)
{
// provo ad avviare
try
{
// imposto flag adapter running..
adpCommAct = true;
adpStartRun = DateTime.Now;
}
catch (Exception exc)
{
parentForm.displayTaskAndLog(string.Format("Adapter NOT STARTED!!!{0}{1}", Environment.NewLine, exc));
adpCommAct = false;
adpStartRun = DateTime.Now;
}
if (adpCommAct)
{
// try / catch generale altrimenti segno che è disconnesso...
try
{
bool showDebugData = false;
lg.Info("STEP 01");
// processing dati memoria (lettura, filtraggio, enqueque)
if (ciclo == gatherCycle.VHF)
{
}
else if (ciclo == gatherCycle.HF)
{
processAllMemory();
}
else if (ciclo == gatherCycle.MF)
{
parentForm.dataMonitor_3 = "";
readPrgName();
}
else if (ciclo == gatherCycle.LF)
{
}
else if (ciclo == gatherCycle.VLF)
{
// recupero dati SETUP (sysinfo e sysinfo_ex)
// eventuale log!
if (utils.CRB("recTime")) logTimeResults();
}
lg.Info("STEP 02");
// gestione queue (invio, display)
svuotaCoda();
reportDataProc();
if (showDebugData)
{
// verifica se debba salvare e mostrare dati
checkSavePersDataLayer();
}
lg.Info("STEP 03");
}
catch (Exception exc)
{
// segnalo eccezione e indico disconnesso...
lg.Error(exc, string.Format("Errore in gestione ciclo principale ADP, fermo adapter{0}{1}", Environment.NewLine, exc));
parentForm.fermaAdapter(true);
}
// tolgo flag running
adpCommAct = false;
}
else
{
if (periodicLog) lg.Info("ADP not running...");
}
}
else
{
// log ADP running
lg.Error("Non eseguo chiamata: ADP ancora in running");
// se è bloccato da oltre maxSec lo sblocco...
if (DateTime.Now.Subtract(adpStartRun).TotalSeconds > utils.CRI("maxAdapterLockSec"))
{
// tolgo flag running
adpCommAct = false;
adpStartRun = DateTime.Now;
}
}
}
else
{
// log connessione KO
lg.Error("getAndSend - Connessione non disponibile, provo a riconnettere");
// provo a riconnettere SE abilitato tryRestart...
if (adpTryRestart && !connectionOk)
{
lg.Info("ConnKO - tryConnect");
tryConnect();
}
}
if (eh_refreshed != null)
{
eh_refreshed(this, new EventArgs());
}
lg.Info("STOP getAndSend");
}
private void reportDataProc()
{
// update valori visualizzazione...
parentForm.dataProcLabel = string.Format("RAW: {0} --> IN: {1} --> OUT: {2}", nReadIN, nReadFilt, nSendOut);
}
///
/// riporta il log di tutti i dati di results temporali registrati
///
public void logTimeResults()
{
if (TimingData.results.Count > 0)
{
lg.Info("{0}--------------- START TIMING DATA ---------------", Environment.NewLine);
int globNumCall = 0;
TimeSpan globAvgMsec = new TimeSpan(0);
foreach (TimeRec item in TimingData.results)
{
lg.Info("Chiamate {0}: effettuate {1}, tempo medio {2:N2} msec | impegno canale {3:P3}", item.codCall, item.numCall, item.avgMsec, item.totMsec.TotalSeconds / DateTime.Now.Subtract(dtAvvioAdp).TotalSeconds);
globNumCall += item.numCall;
globAvgMsec += item.totMsec;
}
// riporto conteggio medio al secondo...
lg.Info("Chiamate GLOBALI: {0}, periodo: {1:N2} minuti.cent, tempo medio {2:N2} msec | impegno canale {3:P3}", globNumCall, DateTime.Now.Subtract(dtAvvioAdp).TotalMinutes, globAvgMsec.TotalMilliseconds / globNumCall, globAvgMsec.TotalSeconds / DateTime.Now.Subtract(dtAvvioAdp).TotalSeconds);
lg.Info("{0}--------------- STOP TIMING DATA ---------------{0}", Environment.NewLine);
// mostro in form statistiche globali!
parentForm.updateComStats(string.Format("Periodo: {0:N2}min | {1} x {2:N2}ms | canale {3:P3}", DateTime.Now.Subtract(dtAvvioAdp).TotalMinutes, globNumCall, globAvgMsec.TotalMilliseconds / globNumCall, globAvgMsec.TotalSeconds / DateTime.Now.Subtract(dtAvvioAdp).TotalSeconds));
}
}
///
/// processa dataLayer e se necessario salva/mostra
///
public void checkSavePersDataLayer()
{
}
public void resetDebugConsole()
{
}
///
/// Metodo base connessione...
///
public virtual void tryConnect()
{
}
///
/// Metodo base disconnessione...
///
public virtual void tryDisconnect()
{
}
protected bool _connOk = false;
///
/// Salva verifica stato connessione OK
///
///
public virtual bool connectionOk
{
get
{
return _connOk;
}
set
{
_connOk = value;
}
}
#endregion
#region layer persistenza dati
///
/// Dizionario di persistenza per i valori da salvare da/su file
///
public Dictionary persistenceLayer;
///
/// recupera valore salvato in persistence layer (se non c'è crea...)
///
///
///
private string getStoredVal(string keyVal)
{
string value = "";
try
{
if (persistenceLayer != null)
{
if (!persistenceLayer.TryGetValue(keyVal, out value))
{
persistenceLayer.Add(keyVal, "0");
}
}
}
catch (Exception exc)
{
lg.Error(string.Format("Eccezione in getStoredVal: {0}{1}", Environment.NewLine, exc));
}
return value;
}
///
/// recupera valore salvato in persistence layer (se non c'è crea...) come UINT
///
///
///
private uint getStoredValUInt(string keyVal)
{
uint answ = 0;
try
{
answ = Convert.ToUInt32(getStoredVal(keyVal));
}
catch (Exception exc)
{
lg.Error(string.Format("Eccezione in getStoredValUInt: {0}{1}", Environment.NewLine, exc));
}
// verifico che il valore sia minore di 9/10 del valore massimo...
answ = (answ < (uint.MaxValue / 10 * 9)) ? answ : 0;
return answ;
}
///
/// recupera valore salvato in persistence layer (se non c'è crea...) come INT
///
///
///
private long getStoredValLong(string keyVal)
{
long answ = 0;
try
{
answ = Convert.ToInt64(getStoredVal(keyVal));
}
catch
{ }
// verifico che il valore sia minore di 9/10 del valore massimo...
answ = (answ < (long.MaxValue / 10 * 9)) ? answ : 0;
return answ;
}
///
/// recupera valore salvato in persistence layer (se non c'è crea...) come double
///
///
///
private double getStoredValDouble(string keyVal)
{
double answ = 0;
try
{
answ = Convert.ToDouble(getStoredVal(keyVal));
}
catch (Exception exc)
{
lg.Error(string.Format("Eccezione in getStoredValDouble: {0}{1}", Environment.NewLine, exc));
}
answ = (answ < (double.MaxValue / 10 * 9)) ? answ : 0;
return answ;
}
///
/// Aggiorna un valore del dizionario in SOSTITUZIONE
///
///
///
///
/// Nuovo valore incrementato
private void updateValString(int i, string newVal, string searchString)
{
// stringa da cercare..
string keyVal = string.Format(searchString, i + 1);
// salvo in ram!
persistenceLayer[keyVal] = newVal;
}
///
/// Aggiorna un valore del dizionario in SOSTITUZIONE e lo restituisce
///
///
///
///
/// Nuovo valore incrementato
private void updateValUInt(int i, uint newVal, string searchString)
{
// stringa da cercare..
string keyVal = string.Format(searchString, i + 1);
// salvo in ram!
persistenceLayer[keyVal] = newVal.ToString();
}
///
/// Aggiorna un valore del dizionario in INCREMENTO e lo restituisce
///
///
///
///
/// Nuovo valore incrementato
private uint updateValUIntByIncr(int i, uint delta, string searchString)
{
// stringa da cercare..
string keyVal = string.Format(searchString, i + 1);
// recupero valore precedente...
uint contAct = getStoredValUInt(keyVal);
// nuovo valore...
contAct += delta;
// salvo in ram!
persistenceLayer[keyVal] = contAct.ToString();
// rendo il valore!
return contAct;
}
///
/// Aggiorna un valore del dizionario in INCREMENTO e lo restituisce
///
///
///
///
/// Nuovo valore incrementato
private long updateValLongByIncr(int i, long delta, string searchString)
{
// stringa da cercare..
string keyVal = string.Format(searchString, i + 1);
// recupero valore precedente...
long contAct = getStoredValLong(keyVal);
// nuovo valore...
contAct += delta;
// salvo in ram!
persistenceLayer[keyVal] = contAct.ToString();
// rendo il valore!
return contAct;
}
///
/// Aggiorna un valore del dizionario in INCREMENTO e lo restituisce
///
///
///
///
/// Nuovo valore incrementato
private double updateValDoubleByIncr(int i, double delta, string searchString)
{
// stringa da cercare..
string keyVal = string.Format(searchString, i + 1);
// recupero valore precedente...
double contAct = getStoredValDouble(keyVal);
// nuovo valore...
contAct += delta;
// salvo in ram!
persistenceLayer[keyVal] = contAct.ToString();
// rendo il valore!
return contAct;
}
#endregion
///
/// effettua ogni log period una rilettura di TUTTI gli allarmi...
///
public virtual void forceAlarmCheck()
{
}
#region IOB METHODS
///
/// Valore del num max invii consecutivi da coda...
///
protected int nMaxSend = 5;
///
/// DateTime Ultimo valore simulazione generato
///
public DateTime lastSim;
///
/// contatore x simulazione valori input
///
public int countSim = 0;
///
/// URL per check alive...
///
public string urlAlive
{
get
{
return string.Format(@"{0}{1}{2}", currIobConf.serverData.MPIP, currIobConf.serverData.MPURL, currIobConf.serverData.CMDALIVE);
}
}
///
/// URL per check alive...
///
public string urlIobEnabled
{
get
{
return string.Format(@"{0}{1}{2}{3}", currIobConf.serverData.MPIP, currIobConf.serverData.MPURL, currIobConf.serverData.CMDENABLED, currIobConf.codIOB);
}
}
///
/// Fornisce URL INPUT per i parametri richiesti
///
/// valore salvato in coda formatodtEve#valore#counter
///
public string urlInput(string queueVal)
{
// URL base x input
string answ = string.Format(@"{0}{1}{2}", currIobConf.serverData.MPIP, currIobConf.serverData.MPURL, currIobConf.serverData.CMDBASE);
// decodifica valore!
string[] valori = qDecodeIN(queueVal);
// aggiungo macchina e valore...
answ += string.Format(@"{0}?valore={1}", currIobConf.codIOB, valori[1]);
// aggiondo dataOra evento e corrente + contatore...
answ += string.Format(@"&&dtEve={0}&&dtCurr={1:yyyyMMddHHmmssfff}&&cnt={2}", valori[0], DateTime.Now, valori[2]);
return answ;
}
///
/// Effettua chaimata URL e restituisce risultato
///
///
///
public string callUrl(string URL)
{
string answ = "";
var client = new WebClient();
answ = client.DownloadString(URL);
// restituisco valore!
return answ;
}
///
/// Verifica se il server sia ALIVE
///
private bool checkServerAlive
{
get
{
bool answ = false;
if (DemoOut)
{
answ = true;
}
else
{
try
{
// chiamo URL, se restituisce "OK" è alive!
answ = (callUrl(urlAlive) == "OK");
}
catch
{ }
// verifico SE è variato stato online/offline...
if (MPOnline != answ)
{
// se ORA sono online riporto...
if (answ)
{
lg.Info("SERVER ONLINE");
}
else
{
lg.Info("SERVER OFFLINE");
}
// salvo nuovo status...
MPOnline = answ;
}
}
return answ;
}
}
///
/// Verifica se la IOB sia ENABLED (da server o Demo)
///
private bool checkIobEnabled
{
get
{
bool answ = false;
if (DemoOut)
{
answ = (QueueIN.Count >= nMaxSend);
}
else
{
try
{
// chiamo URL, se restituisce "OK" è enabled!
answ = (callUrl(urlIobEnabled) == "OK");
}
catch
{ }
}
// verifico SE è variato stato online/offline...
if (IobOnline != answ)
{
// se ORA sono online riporto...
if (answ)
{
lg.Info("IOB ONLINE");
}
else
{
lg.Info("IOB OFFLINE");
}
// salvo nuovo status...
IobOnline = answ;
}
return answ;
}
}
///
/// Processo la coda...
///
private void svuotaCoda()
{
// verifico SE la coda abbia dei valori...
if (QueueIN.Count > 0)
{
// verifico se risponde il server...
if (checkServerAlive)
{
// verifico SE posso inviare dati
if (checkIobEnabled)
{
// invio pacchetto di dati (max da conf)
for (int i = 0; i < nMaxSend; i++)
{
// SE ho qualcosa in coda...
if (QueueIN.Count > 0)
{
// INVIO!!!
sendToMoonPro(QueueIN.Dequeue());
}
}
}
else
{
// mostro VETO-SEND x invio... GIALLO
parentForm.sOUT = Semaforo.SG;
}
}
else
{
// mostro SERVER KO x invio... ROSSO
parentForm.sOUT = Semaforo.SR;
}
}
}
///
/// Classe fittizia in caso di processing GLOBALE di tutto in 1 solo colpo...
///
private void processAllMemory()
{
// in primis SALVO valori previous/precedenti
B_previous = B_output;
// poi faccio lettura NUOVI valori
readAllData();
// eseguo il filtering dei valori (per i bit "blinking")
filterData();
// effettuo confronto valori vecchi/nuovi... SE trovo variazione
if (B_output != B_previous)
{
// mostro dati variati letti...
displayInData();
// --> accodo (valore già formattato)!
QueueIN.Enqueue(qEncodeIN);
nReadFilt++;
// Gestione counter!
counter++;
// se supera 10k resetto...
if (counter > 9999) counter = 0;
}
}
///
/// 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 (currIobConf.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 & ~currIobConf.BLINK_FILT;
// calcolo il valore dei BIT che "passano la maschera"
int iBlink = B_input & currIobConf.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)
{
lg.Info("START BLINK: B{0}", i);
}
// imposto comunque contatore al cambio fronte...
i_counters[i] = currIobConf.MAX_COUNTER_BLINK;
}
}
// quelli che sono zero... LI RECUPERO E LI PROCESSO...
int iZero = ~B_input & currIobConf.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
{
lg.Info("END BLINK: B{0}", i);
}
}
}
}
}
}
///
/// Fornisce il valore letto da BITMAP in formato valido x messa in coda nel formato dtEve#value#cont
///
protected string qEncodeIN
{
get
{
string answ = "";
try
{
answ = string.Format("{0:yyyyMMddHHmmssfff}#{1:X2}#{2}", DateTime.Now, (int)B_output, counter);
}
catch
{ }
return answ;
}
}
///
/// Decodifica valore della coda IN nel formato
/// answ[0]=dtEve
/// answ[1]=valore
/// answ[2]=counter
///
/// dtEve + '#' + value + '#' + cont
///
protected string[] qDecodeIN(string queueVal)
{
return queueVal.Split('#');
}
///
/// Effettua lettura dati
///
public virtual void readAllData()
{
if (!DemoIn)
{
if (connectionOk)
{
readSemafori();
}
else
{
lg.Error("Errore connessione mancante x readSemafori");
}
}
else
{
// segnalo ceh sono in Demo
parentForm.sIN = Semaforo.SS;
// simulo letura
simReadMem();
}
nReadIN++;
// aggiorno valore mostrato...
displayRawData();
}
///
/// lettura programma in esecuzione
///
public virtual void readPrgName()
{
}
///
/// Effettua lettura semafori principale
///
public virtual void readSemafori()
{
}
private void displayRawData()
{
// mostro update......
string newString = string.Format("{0}{1}{2}", (int)B_input, Environment.NewLine, parentForm.dataMonitor_0);
// se num righe superiore a limite trimmo...
if (newString.Split('\n').Length > parentForm.nLine2show)
{
int idx = newString.LastIndexOf(Environment.NewLine);
newString = newString.Substring(0, idx);
}
parentForm.dataMonitor_0 = newString;
// salvo coda debug...
QueueDebug.Enqueue(B_input);
}
///
/// Effettua invio a MoonPro dello status rilevato in HEX
///
public void sendToMoonPro(string queueVal)
{
// recupero e formatto URL dati da coda...
lastUrl = urlInput(queueVal);
// se NON sono in demo effettuo invio!
if (!DemoOut)
{
// chiamo URL!
string answ = callUrl(lastUrl);
// loggo!
lg.Info(string.Format("{0} -> {1}", queueVal, answ));
// se "OK" verde, altrimenti errore --> ROSSO
if (answ == "OK")
{
parentForm.sOUT = Semaforo.SV;
}
else
{
parentForm.sOUT = Semaforo.SR;
}
}
else
{
parentForm.sOUT = Semaforo.SV;
// loggo!
lg.Info(string.Format("{0} -> [SIM]", queueVal));
}
nSendOut++;
// riporto cosa inviato
displayOutData();
}
///
/// Mostra cosa ha/avrebbe inviato
///
public void displayOutData()
{
// mostro update......
string newString = string.Format("{0}{1}{2}", lastUrl, Environment.NewLine, parentForm.dataMonitor_2);
// se num righe superiore a limite trimmo...
if (newString.Split('\n').Length > parentForm.nLine2show)
{
int idx = newString.LastIndexOf(Environment.NewLine);
newString = newString.Substring(0, idx);
}
parentForm.dataMonitor_2 = newString;
}
///
/// Update visualizzaizone BIT in ingresso
///
public void displayInData()
{
// mostro update......
string newString = string.Format("{0:0000}|{1}{2}{3}", counter, utils.IntToBinStr((int)B_output, 8), Environment.NewLine, parentForm.dataMonitor_1);
// se num righe superiore a limite trimmo...
if (newString.Split('\n').Length > parentForm.nLine2show)
{
int idx = newString.LastIndexOf(Environment.NewLine);
newString = newString.Substring(0, idx);
}
parentForm.dataMonitor_1 = newString;
}
public void simReadMem()
{
if (lastSim == null)
{
lastSim = DateTime.Now;
}
// simulazione complessa (basata su samples dei parametri effettivi...)
if (utils.CRB("DemoInSample"))
{
if (numSim >= 0)
{
// verifico se la coda di simulazione sia piena altrimenti la RICARICO...
if (QueueSIM.Count == 0)
{
leggiSimFile();
numSim--;
}
// processo la coda di simulazione (stacco ed accodo 1 valore...)
B_input = QueueSIM.Dequeue();
countSim++;
// ogni 5 loggo...
if (countSim % 5 == 0)
{
lg.Info("Read {0} sim data", countSim);
}
}
else
{
// fermo tutto!
parentForm.sIN = Semaforo.SR;
parentForm.fermaAdapter(false);
}
}
// simulazione semplice (counter crescente)
else
{
// se passato 1 sec genero NUOV num casuale e lo metto nel bit strobe... ogni 2 sec...
if (DateTime.Now.Subtract(lastSim).TotalMilliseconds > 100)
{
countSim++;
if (countSim > 255) countSim = 0;
B_input = countSim;
}
}
lastSim = DateTime.Now;
}
///
/// legge ed accoda file Sim in QueueSIM
///
private void leggiSimFile()
{
int totRighe = 0;
string fileName = utils.simDataFile;
string linea;
totRighe = File.ReadLines(fileName).Count();
lg.Info("File SIM: TROVATE {0} righe", totRighe);
// ora conto righe effettive...
totRighe = 0;
// carica da file...
StreamReader file = new StreamReader(fileName);
// leggo 1 linea alla volta...
int valore = 0;
while ((linea = file.ReadLine()) != null)
{
// SE non è un commento...
if (linea.Substring(0, 1) != ";")
{
//elencoAllarmi[rumRiga] = decodeAlarmLine(linea, ':');
Int32.TryParse(linea, out valore);
QueueSIM.Enqueue(valore);
totRighe++;
}
}
// chiudo file
file.Close();
lg.Info("File SIM: LETTE {0} righe", totRighe);
}
#endregion
}
}