2239 lines
68 KiB
C#
2239 lines
68 KiB
C#
using IOB_UT;
|
|
using NLog;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Net.NetworkInformation;
|
|
|
|
namespace IOB_WIN
|
|
{
|
|
public class IobGeneric
|
|
{
|
|
#region variabili ed oggetti base
|
|
|
|
/// <summary>
|
|
/// Indicazione VETO invio a server sino alla data-ora indicata
|
|
/// </summary>
|
|
public static DateTime dtVetoPing = DateTime.Now;
|
|
/// <summary>
|
|
/// Contapezzi attuale
|
|
/// </summary>
|
|
protected Int32 contapezzi;
|
|
/// <summary>
|
|
/// Ultima lettura variabile contapezzi da CNC
|
|
/// </summary>
|
|
protected Int32 lastCountCNC;
|
|
/// <summary>
|
|
/// ODL attualmente sulla macchina
|
|
/// </summary>
|
|
public Int32 currIdxODL;
|
|
/// <summary>
|
|
/// Ultimo invio contapezzi (x invio delayed)
|
|
/// </summary>
|
|
protected DateTime lastPzCountSend;
|
|
/// <summary>
|
|
/// Ultima registrazione warning x ODL mancante (x scrivere solo ogni 15 secondi)
|
|
/// </summary>
|
|
protected DateTime lastWarnODL;
|
|
/// <summary>
|
|
/// Ritardo minimo x invio contapezzi
|
|
/// </summary>
|
|
protected int pzCountDelay;
|
|
/// <summary>
|
|
/// Abilitazione lettura PrgName
|
|
/// </summary>
|
|
public bool enablePrgName = true;
|
|
/// <summary>
|
|
/// Indica se si debba leggere e fare DUMP delle aree di memoria (1 volta solo all'avvio x debug...)
|
|
/// </summary>
|
|
public bool doStartMemDump;
|
|
/// <summary>
|
|
/// Indica se sia richiesto campionamento memoria PERIODICO
|
|
/// </summary>
|
|
public bool doSampleMemory;
|
|
/// <summary>
|
|
/// Evento Iob ha subito un refresh
|
|
/// </summary>
|
|
public event EventHandler eh_refreshed;
|
|
/// <summary>
|
|
/// Determina se sia encessario convertire valori little/big endian (SIEMENS=true, OSAI=FALSE)
|
|
/// </summary>
|
|
public bool hasBigEndian = false;
|
|
/// <summary>
|
|
/// alias booleano false = R
|
|
/// </summary>
|
|
public bool R = false;
|
|
/// <summary>
|
|
/// alias booleano true = W
|
|
/// </summary>
|
|
public bool W = true;
|
|
/// <summary>
|
|
/// wrapper di log
|
|
/// </summary>
|
|
protected static Logger lg;
|
|
/// <summary>
|
|
/// ULtimo valore inviato (in caso di disconnessione lo reinvia x garantire watchdog...)
|
|
/// </summary>
|
|
public string lastSignInVal = "";
|
|
/// <summary>
|
|
/// dataOra ultimo log periodico...
|
|
/// </summary>
|
|
public DateTime lastPeriodicLog;
|
|
/// <summary>
|
|
/// dataOra ultimo segnale inviato...
|
|
/// </summary>
|
|
public DateTime lastWatchDog;
|
|
/// <summary>
|
|
/// dataOra ultima verifica CNC disconnesso...
|
|
/// </summary>
|
|
public DateTime lastDisconnCheck;
|
|
/// <summary>
|
|
/// dataOra ultimo PING inviato...
|
|
/// </summary>
|
|
public DateTime lastPING;
|
|
/// <summary>
|
|
/// Oggetto della coda degli elementi letti (e non ancora trasmessi)
|
|
/// </summary>
|
|
public Queue<string> QueueIN = new Queue<string>();
|
|
/// <summary>
|
|
/// Oggetto della coda degli elementi letti di tipo FluxLog (e non ancora trasmessi)
|
|
/// </summary>
|
|
public Queue<string> QueueFLog = new Queue<string>();
|
|
/// <summary>
|
|
/// Coda valori simulazione deterministica...
|
|
/// </summary>
|
|
public Queue<int> QueueSIM = new Queue<int>();
|
|
/// <summary>
|
|
/// Coda valori letti x DEBUG...
|
|
/// </summary>
|
|
public Queue<int> QueueDebug = new Queue<int>();
|
|
|
|
/// <summary>
|
|
/// valore booleano di check se sia in fase di COMUNICAZIONE ATTIVA con il PLC/NC
|
|
/// </summary>
|
|
protected bool adpCommAct;
|
|
/// <summary>
|
|
/// valore booleano di check se sia stato AVVIATO l'adapter (Running)
|
|
/// </summary>
|
|
public bool adpRunning = false;
|
|
/// <summary>
|
|
/// valore booleano di check se l'adapter STIA SALVANDO
|
|
/// </summary>
|
|
public bool adpSaving = false;
|
|
/// <summary>
|
|
/// valore booleano (richiesta di riavvio automatico)
|
|
/// </summary>
|
|
public bool adpTryRestart;
|
|
/// <summary>
|
|
/// Verifica se sia in modalità DEMO --> da tipo IOB SIMULA...
|
|
/// </summary>
|
|
public bool DemoIn
|
|
{
|
|
get
|
|
{
|
|
return (cIobConf.tipoIob == tipoAdapter.SIMULA);// baseUtils.CRB("DemoIn");
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Verifica se sia in modalità DEMO avanzata (campionamento da set di valori ammessi...)
|
|
/// </summary>
|
|
public bool DemoInSample
|
|
{
|
|
get
|
|
{
|
|
return baseUtils.CRB("DemoInSample");
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Numero simulazioni ammesse...
|
|
/// </summary>
|
|
protected int numSim { get; set; }
|
|
/// <summary>
|
|
/// Numero letture IN da avvio
|
|
/// </summary>
|
|
protected int nReadIN { get; set; }
|
|
/// <summary>
|
|
/// Numero letture IN da avvio
|
|
/// </summary>
|
|
protected int nReadFilt { get; set; }
|
|
/// <summary>
|
|
/// Numero invii OUT (svuotamento coda)
|
|
/// </summary>
|
|
protected int nSendOut { get; set; }
|
|
/// <summary>
|
|
/// Verifica se sia in modalità DEMO x dati OUTPUT
|
|
/// </summary>
|
|
public bool DemoOut
|
|
{
|
|
get
|
|
{
|
|
return utils.CRB("DemoOut");
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Contatore x invio dati SignalIN
|
|
/// </summary>
|
|
public int counterSigIN { get; set; }
|
|
/// <summary>
|
|
/// Contatore x invio dati FluxLog
|
|
/// </summary>
|
|
public int counterFLog { get; set; }
|
|
/// <summary>
|
|
/// Ultimo URL
|
|
/// </summary>
|
|
public string lastUrl { get; set; }
|
|
/// <summary>
|
|
/// Ultimo programma letto
|
|
/// </summary>
|
|
public string lastPrgName { get; set; }
|
|
/// <summary>
|
|
/// Ultimo SysInfo letto
|
|
/// </summary>
|
|
public string lastSysInfo { get; set; }
|
|
/// <summary>
|
|
/// Ultimo DynData letto
|
|
/// </summary>
|
|
public string lastDynData { get; set; }
|
|
/// <summary>
|
|
/// Ultimo Alarm letto
|
|
/// </summary>
|
|
public string lastAlarm { get; set; }
|
|
/// <summary>
|
|
/// Ultimo Override set letto
|
|
/// </summary>
|
|
public string lastOverrideFS { get; set; }
|
|
/// <summary>
|
|
/// Ultimo Override set letto
|
|
/// </summary>
|
|
public string lastOverrideRapid { get; set; }
|
|
|
|
/// <summary>
|
|
/// Array dei contatori x segnali blinking
|
|
/// </summary>
|
|
protected int[] i_counters;
|
|
/// <summary>
|
|
/// Vettore 16 BIT valori precedenti
|
|
/// </summary>
|
|
protected int B_previous;
|
|
/// <summary>
|
|
/// Vettore 16 BIT valori in ingresso al filtro
|
|
/// </summary>
|
|
protected int B_input;
|
|
/// <summary>
|
|
/// Vettore 16 BIT valori in uscita dal filtro
|
|
/// </summary>
|
|
protected int B_output;
|
|
/// <summary>
|
|
/// 32 byte input base (es strobe, 8 word da 32 bit di flags...)
|
|
/// </summary>
|
|
public byte[] RawInput = new byte[32];
|
|
/// <summary>
|
|
/// 32 byte output base (es ack, 8 word da 32 bit di flags...)
|
|
/// </summary>
|
|
public byte[] RawOutput = new byte[32];
|
|
/// <summary>
|
|
/// Modo corrente (da classe ENUM)
|
|
/// </summary>
|
|
public CNC_MODE currMode;
|
|
|
|
/// <summary>
|
|
/// Verifica SE si debba fare log verboso (verboso + ogni tot letture IN)
|
|
/// </summary>
|
|
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;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Verifica SE si debba fare log periodico (ogni "verboseLogTOut" sec...)
|
|
/// </summary>
|
|
public bool periodicLog
|
|
{
|
|
get
|
|
{
|
|
bool answ = false;
|
|
answ = (DateTime.Now.Subtract(lastPeriodicLog).TotalSeconds > utils.CRI("verboseLogTOut"));
|
|
if (answ)
|
|
{
|
|
lastPeriodicLog = DateTime.Now;
|
|
}
|
|
|
|
return answ;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determina se utilizzare blocchi di memoria IOT contigui (e quindi processing "monoblocco" semplificato"=
|
|
/// </summary>
|
|
public bool procIotMem = false;
|
|
/// <summary>
|
|
/// porta x adapter (x restart)
|
|
/// </summary>
|
|
protected int adpPortNum;
|
|
/// <summary>
|
|
/// DataOra ultimo avvio adapter x watchdog
|
|
/// </summary>
|
|
protected DateTime adpStartRun;
|
|
/// <summary>
|
|
/// Data/ora ultimo avvio adapter
|
|
/// </summary>
|
|
public DateTime dtAvvioAdp = DateTime.Now;
|
|
/// <summary>
|
|
/// Data/ora ultimo spegnimento adapter
|
|
/// </summary>
|
|
public DateTime dtStopAdp = DateTime.Now;
|
|
/// <summary>
|
|
/// Oggetto cronometro x campionamento durate chiamate
|
|
/// </summary>
|
|
public Stopwatch stopwatch = new Stopwatch();
|
|
/// <summary>
|
|
/// Conteggio ATTUALE ore macchina ON
|
|
/// </summary>
|
|
public double contOreMaccOn;
|
|
/// <summary>
|
|
/// Conteggio ATTUALE ore macchina IN LAVORO
|
|
/// </summary>
|
|
public double contOreMaccLav;
|
|
/// <summary>
|
|
/// stato Online/Offline della IOB
|
|
/// </summary>
|
|
public bool IobOnline;
|
|
/// <summary>
|
|
/// stato Online/Offline della IOB
|
|
/// </summary>
|
|
public bool MPOnline;
|
|
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// Form chiamante
|
|
/// </summary>
|
|
protected AdapterForm parentForm;
|
|
/// <summary>
|
|
/// Conf adapter corrente
|
|
/// </summary>
|
|
public IobConfiguration cIobConf;
|
|
/// <summary>
|
|
/// indica se serva refresh parametri e quindi PLC...
|
|
/// </summary>
|
|
protected bool needRefresh = true;
|
|
/// <summary>
|
|
/// inizializzo l'oggetto sulla form SULLA BASE DEL FILE DI CONFIGURAZIONE letto
|
|
/// </summary>
|
|
/// <param name="caller"></param>
|
|
/// <param name="adpConf"></param>
|
|
public IobGeneric(AdapterForm caller, IobConfiguration IOBConf)
|
|
{
|
|
// configurazione...
|
|
cIobConf = IOBConf;
|
|
|
|
// aggiungo nel logger IDX Macchina
|
|
lg = LogManager.GetCurrentClassLogger();
|
|
|
|
lgInfo("Avvio preliminare AdapterGeneric");
|
|
// aggiungo altri defaults
|
|
setDefaults(true);
|
|
// salvo il form chiamante
|
|
parentForm = caller;
|
|
|
|
// checkLogDir x shrink!
|
|
checkShrinkDir();
|
|
|
|
// concluso!
|
|
lgInfo("Istanziata classe preliminare IOBGeneric");
|
|
}
|
|
/// <summary>
|
|
/// Imposto alcuni valori di default
|
|
/// </summary>
|
|
/// <param name="resetQueue">indica se sia richeisto di SVUOTARE le code delel info</param>
|
|
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.Clear();
|
|
QueueFLog.Clear();
|
|
QueueSIM.Clear();
|
|
}
|
|
// imposto contatori blink a zero...
|
|
i_counters = new int[32];
|
|
lastPeriodicLog = DateTime.Now;
|
|
// fix parametri generali...
|
|
enablePrgName = true;
|
|
}
|
|
/// <summary>
|
|
/// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere...
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
protected void lgInfo(string message)
|
|
{
|
|
lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB;
|
|
lg.Info(message);
|
|
}
|
|
/// <summary>
|
|
/// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere...
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
/// <param name="args"></param>
|
|
protected void lgInfo(string message, params object[] args)
|
|
{
|
|
lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB;
|
|
lg.Info(message, args);
|
|
}
|
|
/// <summary>
|
|
/// Effettua logging ERROR corretto impostanto anche la variabile IOB prima di scrivere...
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
protected void lgError(string message)
|
|
{
|
|
lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB;
|
|
lg.Error(message);
|
|
}
|
|
/// <summary>
|
|
/// Effettua logging ERROR corretto impostanto anche la variabile IOB prima di scrivere...
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
/// <param name="args"></param>
|
|
protected void lgError(string message, params object[] args)
|
|
{
|
|
lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB;
|
|
lg.Error(message, args);
|
|
}
|
|
/// <summary>
|
|
/// Effettua logging ERROR corretto impostanto anche la variabile IOB prima di scrivere...
|
|
/// </summary>
|
|
/// <param name="exception"></param>
|
|
/// <param name="message"></param>
|
|
/// <param name="args"></param>
|
|
protected void lgError(Exception exception, string message, params object[] args)
|
|
{
|
|
lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB;
|
|
lg.Error(exception, message, args);
|
|
}
|
|
/// <summary>
|
|
/// Effettua logging FATAL corretto impostanto anche la variabile IOB prima di scrivere...
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
protected void lgFatal(string message)
|
|
{
|
|
lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB;
|
|
lg.Fatal(message);
|
|
}
|
|
/// <summary>
|
|
/// Effettua logging FATAL corretto impostanto anche la variabile IOB prima di scrivere...
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
/// <param name="args"></param>
|
|
protected void lgFatal(string message, params object[] args)
|
|
{
|
|
lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB;
|
|
lg.Fatal(message, args);
|
|
}
|
|
/// <summary>
|
|
/// Effettua logging FATAL corretto impostanto anche la variabile IOB prima di scrivere...
|
|
/// </summary>
|
|
/// <param name="exception"></param>
|
|
/// <param name="message"></param>
|
|
/// <param name="args"></param>
|
|
protected void lgFatal(Exception exception, string message, params object[] args)
|
|
{
|
|
lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB;
|
|
lg.Fatal(exception, message, args);
|
|
}
|
|
|
|
#region metodi adapter
|
|
|
|
/// <summary>
|
|
/// Invia informazioni associazione IOB 2 machine
|
|
/// </summary>
|
|
protected void sendM2IOB()
|
|
{
|
|
if (checkServerAlive)
|
|
{
|
|
lgInfo("chiamata URL " + urlSetM2IOB);
|
|
utils.callUrl(urlSetM2IOB);
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Effettua rilettura del contapezzi dal server MP/IO
|
|
/// </summary>
|
|
/// <param name="forceCountRec">Forza rilettura da DB tempi ciclo rilevati</param>
|
|
protected void pzCntReload(bool forceCountRec)
|
|
{
|
|
// legge da IO server ULTIMO valore CONTPEZZI al riavvio...
|
|
string currServerCount = "";
|
|
string lastIdxODL = "";
|
|
if (checkServerAlive)
|
|
{
|
|
// se ho valori in coda da trasmettere uso dati REDIS
|
|
if (QueueIN.Count > 0 && !forceCountRec)
|
|
{
|
|
currServerCount = utils.callUrl(urlGetPzCount);
|
|
lgInfo("Lettura contapezzi dall'url {0}", urlGetPzCount);
|
|
}
|
|
// altrimenti uso dati da TCiclo registrati...
|
|
else
|
|
{
|
|
// leggo PRIMA ODL ....
|
|
lastIdxODL = utils.callUrl(urlGetCurrODL);
|
|
lgInfo("Lettura ODL dall'url {0} --> {1}", urlGetPzCountRec, lastIdxODL);
|
|
// POI leggo i pezzi
|
|
currServerCount = utils.callUrl(urlGetPzCountRec);
|
|
lgInfo("Lettura contapezzi da TCiclo dall'url {0} --> num pz: {1}", urlGetPzCountRec, currServerCount);
|
|
}
|
|
// controllo: SE NON HO ODL...
|
|
if (lastIdxODL == "" || lastIdxODL == "0")
|
|
{
|
|
// NON AGGIORNO
|
|
contapezzi = lastCountCNC;
|
|
lgInfo(string.Format("Errore lettura ODL: {0} - uso lastCountCNC --> {1}", lastIdxODL, contapezzi));
|
|
}
|
|
else
|
|
{
|
|
if (currServerCount != "")
|
|
{
|
|
// se "-1" resto a ultimo...
|
|
if (currServerCount != "-1")
|
|
{
|
|
int.TryParse(currServerCount, out contapezzi);
|
|
lgInfo("Ricevuta conferma da server di {0} pezzi registrati per ODL", currServerCount);
|
|
}
|
|
else
|
|
{
|
|
// NON AGGIORNO
|
|
contapezzi = lastCountCNC;
|
|
lgInfo("Errore lettura contapezzi (-1) - uso lastCountCNC --> " + contapezzi);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// registro che ho UN NUOVO ODL
|
|
lgInfo(string.Format("Lettura ODL in pzCntReload, {0} --> {1}", currIdxODL, lastIdxODL));
|
|
// provo a salvare nuovo ODL
|
|
int.TryParse(lastIdxODL, out currIdxODL);
|
|
// segno contapezzi a zero...
|
|
contapezzi = 0;
|
|
lgInfo("RESET contapezzi (ZERO)");
|
|
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// se server NON pronto...
|
|
contapezzi = lastCountCNC;
|
|
lgError("Errore server NON pronto in pzCntReload");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Avvia l'adapter sulla porta richiesta
|
|
/// </summary>
|
|
/// <param name="resetQueue">indica se sia richeisto di SVUOTARE le code delel info</param>
|
|
public virtual void startAdapter(bool resetQueue)
|
|
{
|
|
lgInfo("Starting adapter...");
|
|
parentForm.commPlcActive = false;
|
|
adpRunning = true;
|
|
dtAvvioAdp = DateTime.Now;
|
|
lastWatchDog = dtAvvioAdp;
|
|
lastPING = dtAvvioAdp;
|
|
lastDisconnCheck = dtAvvioAdp;
|
|
TimingData.resetData();
|
|
// aggiungo altri defaults
|
|
setDefaults(resetQueue);
|
|
adpTryRestart = true;
|
|
parentForm.displayTaskAndLog("Adapter Started!");
|
|
}
|
|
|
|
/// <summary>
|
|
/// ferma l'adapter...
|
|
/// </summary>
|
|
/// <param name="tryRestart">indica se si debba tentare di riavviare l'adapter (con caduta connessione viene fermato in automatico)</param>
|
|
/// <param name="forceDequeue">indica se sia richeisto di SVUOTARE le code delel info</param>
|
|
public void stopAdapter(bool tryRestart, bool forceDequeue)
|
|
{
|
|
if (forceDequeue)
|
|
{
|
|
// svuoto le code dei valori letti e non ancora trasmessi...
|
|
parentForm.displayTaskAndLog("Svuotamento FORZATO coda segnali...");
|
|
while (QueueIN.Count > 0)
|
|
{
|
|
// INVIO COMUNQUE...!!!
|
|
sendToMoonPro(urlType.SignIN, QueueIN.Dequeue());
|
|
}
|
|
parentForm.displayTaskAndLog("Svuotamento FORZATO coda FluxLOG...");
|
|
while (QueueFLog.Count > 0)
|
|
{
|
|
// INVIO COMUNQUE...!!!
|
|
sendToMoonPro(urlType.FLog, QueueFLog.Dequeue());
|
|
}
|
|
}
|
|
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.displayTaskAndLog("Adapter Stopped.");
|
|
parentForm.commPlcActive = false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// effettua recupero dati ed invio valori modificati...
|
|
/// </summary>
|
|
/// <param name="ciclo"></param>
|
|
public void getAndSend(gatherCycle ciclo)
|
|
{
|
|
// IN OGNI CASO a prima di tutto EFFETTUO GESTIONE INVII dati da code!!!
|
|
try
|
|
{
|
|
// gestione queue SignalIN (invio, display)
|
|
svuotaCodaSignIN();
|
|
// gestione queue FluxLog (invio, display)
|
|
svuotaCodaFLog();
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgError(exc, "Errore in gestione svuotamento/invio preliminare code memoria");
|
|
}
|
|
// 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;
|
|
if (ciclo == gatherCycle.VHF)
|
|
{
|
|
processVHF();
|
|
}
|
|
// processing dati memoria (lettura, filtraggio, enqueque)
|
|
else if (ciclo == gatherCycle.HF)
|
|
{
|
|
processAllMemory();
|
|
processMode();
|
|
}
|
|
else if (ciclo == gatherCycle.MF)
|
|
{
|
|
processOverride();
|
|
processContapezzi();
|
|
processCncAlarms();
|
|
}
|
|
else if (ciclo == gatherCycle.LF)
|
|
{
|
|
processProgram();
|
|
}
|
|
else if (ciclo == gatherCycle.VLF)
|
|
{
|
|
if (utils.CRB("enableContapezzi"))
|
|
{
|
|
// rilettura contapezzi da server... SE ABILITATA
|
|
pzCntReload(false);
|
|
// refresh associazione Macchina - IOB
|
|
sendM2IOB();
|
|
}
|
|
// dati dinamici
|
|
processDynData();
|
|
// recupero dati SETUP (sysinfo) e li invio/mostro se variati...
|
|
processSysInfo();
|
|
// checkLogDir x shrink!
|
|
checkShrinkDir();
|
|
// eventuale log!
|
|
if (utils.CRB("recTime"))
|
|
{
|
|
logTimeResults();
|
|
}
|
|
}
|
|
// mostra eventuali altri dati di processo...
|
|
reportDataProc();
|
|
if (showDebugData)
|
|
{
|
|
// verifica se debba salvare e mostrare dati
|
|
checkSavePersDataLayer();
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
// segnalo eccezione e indico disconnesso...
|
|
lgError(exc, string.Format("Errore in gestione ciclo principale ADP, fermo adapter{0}{1}", Environment.NewLine, exc));
|
|
parentForm.fermaAdapter(true, false);
|
|
}
|
|
// tolgo flag running
|
|
adpCommAct = false;
|
|
}
|
|
else
|
|
{
|
|
if (periodicLog)
|
|
{
|
|
lgInfo("ADP not running...");
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// log ADP running
|
|
lgError("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
|
|
{
|
|
// provo a riconnettere SE abilitato tryRestart...
|
|
if (adpTryRestart && !connectionOk)
|
|
{
|
|
tryConnect();
|
|
}
|
|
}
|
|
// segnalo refresh!
|
|
if (eh_refreshed != null)
|
|
{
|
|
eh_refreshed(this, new EventArgs());
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Verifica e se necessario comprime directory log...
|
|
/// </summary>
|
|
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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// riporta il log di tutti i dati di results temporali registrati
|
|
/// </summary>
|
|
public void logTimeResults()
|
|
{
|
|
if (TimingData.results.Count > 0)
|
|
{
|
|
lgInfo("{0}--------------- START TIMING DATA ---------------", Environment.NewLine);
|
|
int globNumCall = 0;
|
|
TimeSpan globAvgMsec = new TimeSpan(0);
|
|
foreach (TimeRec item in TimingData.results)
|
|
{
|
|
// loggo SOLO se del mio IOB corrente...
|
|
if (item.classCall == cIobConf.codIOB)
|
|
{
|
|
lgInfo("{4}|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, cIobConf.codIOB);
|
|
globNumCall += item.numCall;
|
|
globAvgMsec += item.totMsec;
|
|
}
|
|
}
|
|
// riporto conteggio medio al secondo...
|
|
lgInfo("{4}|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, cIobConf.codIOB);
|
|
lgInfo("{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));
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// processa dataLayer e se necessario salva/mostra
|
|
/// </summary>
|
|
public void checkSavePersDataLayer()
|
|
{
|
|
}
|
|
public void resetDebugConsole()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Metodo base connessione...
|
|
/// </summary>
|
|
public virtual void tryConnect()
|
|
{
|
|
dtAvvioAdp = DateTime.Now;
|
|
}
|
|
/// <summary>
|
|
/// Metodo base disconnessione...
|
|
/// </summary>
|
|
public virtual void tryDisconnect()
|
|
{
|
|
|
|
}
|
|
protected bool _connOk = false;
|
|
/// <summary>
|
|
/// Salva verifica stato connessione OK
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public virtual bool connectionOk
|
|
{
|
|
get
|
|
{
|
|
return _connOk || DemoIn;
|
|
}
|
|
set
|
|
{
|
|
_connOk = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// test ping all'indirizzo impostato nei parametri
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
protected IPStatus testPing()
|
|
{
|
|
IPStatus answ = IPStatus.Unknown; ;
|
|
IPAddress address;
|
|
PingReply reply;
|
|
Ping pingSender = new Ping();
|
|
address = IPAddress.Loopback;
|
|
IPAddress.TryParse(cIobConf.cncIpAddr, out address);
|
|
int pingMsTimeout = cIobConf.pingMsTimeout;
|
|
reply = pingSender.Send(address, pingMsTimeout);
|
|
answ = reply.Status;
|
|
return answ;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region layer persistenza dati
|
|
|
|
/// <summary>
|
|
/// Dizionario di persistenza per i valori da salvare da/su file
|
|
/// </summary>
|
|
public Dictionary<string, string> persistenceLayer;
|
|
|
|
/// <summary>
|
|
/// recupera valore salvato in persistence layer (se non c'è crea...)
|
|
/// </summary>
|
|
/// <param name="keyVal"></param>
|
|
/// <returns></returns>
|
|
private string getStoredVal(string keyVal)
|
|
{
|
|
string value = "";
|
|
try
|
|
{
|
|
if (persistenceLayer != null)
|
|
{
|
|
if (!persistenceLayer.TryGetValue(keyVal, out value))
|
|
{
|
|
persistenceLayer.Add(keyVal, "0");
|
|
}
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgError(string.Format("Eccezione in getStoredVal: {0}{1}", Environment.NewLine, exc));
|
|
}
|
|
return value;
|
|
}
|
|
/// <summary>
|
|
/// recupera valore salvato in persistence layer (se non c'è crea...) come UINT
|
|
/// </summary>
|
|
/// <param name="keyVal"></param>
|
|
/// <returns></returns>
|
|
private uint getStoredValUInt(string keyVal)
|
|
{
|
|
uint answ = 0;
|
|
try
|
|
{
|
|
answ = Convert.ToUInt32(getStoredVal(keyVal));
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgError(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;
|
|
}
|
|
/// <summary>
|
|
/// recupera valore salvato in persistence layer (se non c'è crea...) come INT
|
|
/// </summary>
|
|
/// <param name="keyVal"></param>
|
|
/// <returns></returns>
|
|
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;
|
|
}
|
|
/// <summary>
|
|
/// recupera valore salvato in persistence layer (se non c'è crea...) come double
|
|
/// </summary>
|
|
/// <param name="keyVal"></param>
|
|
/// <returns></returns>
|
|
private double getStoredValDouble(string keyVal)
|
|
{
|
|
double answ = 0;
|
|
try
|
|
{
|
|
answ = Convert.ToDouble(getStoredVal(keyVal));
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgError(string.Format("Eccezione in getStoredValDouble: {0}{1}", Environment.NewLine, exc));
|
|
}
|
|
answ = (answ < (double.MaxValue / 10 * 9)) ? answ : 0;
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Aggiorna un valore del dizionario in SOSTITUZIONE
|
|
/// </summary>
|
|
/// <param name="i"></param>
|
|
/// <param name="newVal"></param>
|
|
/// <param name="searchString"></param>
|
|
/// <returns>Nuovo valore incrementato</returns>
|
|
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;
|
|
}
|
|
/// <summary>
|
|
/// Aggiorna un valore del dizionario in SOSTITUZIONE e lo restituisce
|
|
/// </summary>
|
|
/// <param name="i"></param>
|
|
/// <param name="newVal"></param>
|
|
/// <param name="searchString"></param>
|
|
/// <returns>Nuovo valore incrementato</returns>
|
|
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();
|
|
}
|
|
/// <summary>
|
|
/// Aggiorna un valore del dizionario in INCREMENTO e lo restituisce
|
|
/// </summary>
|
|
/// <param name="i"></param>
|
|
/// <param name="delta"></param>
|
|
/// <param name="searchString"></param>
|
|
/// <returns>Nuovo valore incrementato</returns>
|
|
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;
|
|
}
|
|
/// <summary>
|
|
/// Aggiorna un valore del dizionario in INCREMENTO e lo restituisce
|
|
/// </summary>
|
|
/// <param name="i"></param>
|
|
/// <param name="delta"></param>
|
|
/// <param name="searchString"></param>
|
|
/// <returns>Nuovo valore incrementato</returns>
|
|
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;
|
|
}
|
|
/// <summary>
|
|
/// Aggiorna un valore del dizionario in INCREMENTO e lo restituisce
|
|
/// </summary>
|
|
/// <param name="i"></param>
|
|
/// <param name="delta"></param>
|
|
/// <param name="searchString"></param>
|
|
/// <returns>Nuovo valore incrementato</returns>
|
|
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
|
|
|
|
#region area lettura configurazioni
|
|
|
|
/// <summary>
|
|
/// Legge il file di conf di una MAP di informazioni da gestire con lettura set memoria
|
|
/// </summary>
|
|
/// <param name="vettoreConf">nome vettore memoria</param>
|
|
/// <param name="nomeFile">file origine</param>
|
|
/// <param name="memSize">dimensione (in byte) della memoria</param>
|
|
/// <param name="numVett">dimensione (in byte) della memoria</param>
|
|
protected void loadConfFile(ref otherData[] vettoreConf, string nomeFile, int memSize, ref int numVett)
|
|
{
|
|
otherData lastData = new otherData();
|
|
int totRighe = 0;
|
|
string linea;
|
|
totRighe = File.ReadLines(nomeFile).Count();
|
|
// creo un vettore della dimensione corretta... conta anche commenti tanto poi riduco...
|
|
vettoreConf = new otherData[File.ReadLines(nomeFile).Count()];
|
|
// carica da file...
|
|
StreamReader file = new StreamReader(nomeFile);
|
|
// leggo 1 linea alla volta...
|
|
int numRiga = 0;
|
|
int bitNum = 0;
|
|
int byteNum = 0;
|
|
while ((linea = file.ReadLine()) != null)
|
|
{
|
|
// SE non è un commento...
|
|
if (linea.Substring(0, 1) != "#")
|
|
{
|
|
// se finisce per BIT allora processo bit-a-bit...
|
|
if (linea.EndsWith("BOOL"))
|
|
{
|
|
try
|
|
{
|
|
string[] memIdx = linea.Split(utils.CRC("testCharSep"))[0].Split('.');
|
|
// calcolo bit e byte number...
|
|
int.TryParse(memIdx[0], out byteNum);
|
|
if (memIdx.Length > 1)
|
|
{
|
|
int.TryParse(memIdx[1], out bitNum);
|
|
}
|
|
else
|
|
{
|
|
bitNum = 0;
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
byteNum = 0;
|
|
bitNum = 0;
|
|
}
|
|
lastData = decodeBitData(linea, utils.CRC("testCharSep"), byteNum, 1, bitNum);
|
|
vettoreConf[numRiga] = lastData;
|
|
}
|
|
else
|
|
{
|
|
lastData = decodeOtherData(linea, utils.CRC("testCharSep"), "", 1, memSize);
|
|
vettoreConf[numRiga] = lastData;
|
|
}
|
|
numRiga++;
|
|
}
|
|
}
|
|
// salvo lunghezza file...
|
|
try
|
|
{
|
|
numVett = Convert.ToInt32(lastData.memAddr) + 1;
|
|
}
|
|
catch
|
|
{
|
|
numVett = numRiga + 1;
|
|
}
|
|
// chiudo file
|
|
file.Close();
|
|
// ora trimmo vettore al solo numero VERO dei valori caricati...
|
|
Array.Resize<otherData>(ref vettoreConf, numRiga);
|
|
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lgInfo(string.Format("Fine caricamento vettore di {0} variabili per file {1}", numRiga, nomeFile));
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Decodifica file MAP generico
|
|
/// </summary>
|
|
/// <param name="linea"></param>
|
|
/// <param name="separator"></param>
|
|
/// <param name="memPre"></param>
|
|
/// <param name="baseAddr"></param>
|
|
/// <param name="memSize"></param>
|
|
/// <returns></returns>
|
|
protected otherData decodeOtherData(string linea, char separator, string memPre, int baseAddr, int memSize)
|
|
{
|
|
string[] valori = linea.Split(separator);
|
|
int shift = 0;
|
|
try
|
|
{
|
|
shift = Convert.ToInt32(valori[0]) - 1;
|
|
}
|
|
catch
|
|
{ }
|
|
string memAddr = string.Format("{0}{1}", memPre, baseAddr + shift * memSize);
|
|
return new otherData(valori[0], memAddr, valori[1].Trim(), valori[2].Trim());
|
|
}
|
|
/// <summary>
|
|
/// Decodifica file MAP (caso <paramref name="ByteNum"/>.bit)
|
|
/// </summary>
|
|
/// <param name="linea"></param>
|
|
/// <param name="separator"></param>
|
|
/// <param name="ByteNum">indirizzo Byte: indirizzo di partenza memoria</param>
|
|
/// <param name="memSize">dimensione singolo slot in byte</param>
|
|
/// <param name="BitNum">indirizzo bit: numero riga x calcolo indice bit</param>
|
|
/// <returns></returns>
|
|
protected otherData decodeBitData(string linea, char separator, int ByteNum, int memSize, int BitNum)
|
|
{
|
|
string[] valori = linea.Split(separator);
|
|
int shift = 0;
|
|
try
|
|
{
|
|
shift = Convert.ToInt32(valori[0]) - 1;
|
|
}
|
|
catch
|
|
{ }
|
|
int resto = 0;
|
|
Math.DivRem(BitNum, 8, out resto);
|
|
string memAddr = string.Format("{0}.{1}", ByteNum + shift * memSize, resto);
|
|
return new otherData(valori[0], memAddr, valori[1].Trim(), valori[2].Trim());
|
|
}
|
|
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// effettua ogni log period una rilettura di TUTTI gli allarmi...
|
|
/// </summary>
|
|
public virtual void forceAlarmCheck()
|
|
{
|
|
}
|
|
|
|
#region IOB METHODS
|
|
|
|
/// <summary>
|
|
/// Valore del num max invii consecutivi da coda...
|
|
/// </summary>
|
|
protected int nMaxSend
|
|
{
|
|
get
|
|
{
|
|
int answ = 5;
|
|
try
|
|
{
|
|
answ = utils.CRI("nMaxSend");
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// DateTime Ultimo valore simulazione generato
|
|
/// </summary>
|
|
public DateTime lastSim;
|
|
/// <summary>
|
|
/// contatore x simulazione valori input
|
|
/// </summary>
|
|
public int countSim = 0;
|
|
/// <summary>
|
|
/// URL per check alive...
|
|
/// </summary>
|
|
public string urlAlive
|
|
{
|
|
get
|
|
{
|
|
return string.Format(@"http://{0}{1}{2}", cIobConf.serverData.MPIP, cIobConf.serverData.MPURL, cIobConf.serverData.CMDALIVE);
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// URL per check alive...
|
|
/// </summary>
|
|
public string urlIobEnabled
|
|
{
|
|
get
|
|
{
|
|
return string.Format(@"http://{0}{1}{2}{3}", cIobConf.serverData.MPIP, cIobConf.serverData.MPURL, cIobConf.serverData.CMDENABLED, cIobConf.codIOB);
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// URL per segnalazione reboot...
|
|
/// </summary>
|
|
public string urlReboot
|
|
{
|
|
get
|
|
{
|
|
string answ = "";
|
|
try
|
|
{
|
|
answ = string.Format(@"http://{0}{1}{2}{3}&mac={4}", cIobConf.serverData.MPIP, cIobConf.serverData.MPURL, cIobConf.serverData.CMDREBO, cIobConf.codIOB, GetMACAddress());
|
|
}
|
|
catch
|
|
{
|
|
answ = string.Format(@"http://{0}{1}{2}{3}", cIobConf.serverData.MPIP, cIobConf.serverData.MPURL, cIobConf.serverData.CMDREBO, cIobConf.codIOB);
|
|
}
|
|
return answ;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// URL per salvataggio contapezzi...
|
|
/// </summary>
|
|
public string urlGetCurrODL
|
|
{
|
|
get
|
|
{
|
|
string answ = "";
|
|
try
|
|
{
|
|
answ = string.Format(@"http://{0}{1}{2}/getCurrODL/{3}", cIobConf.serverData.MPIP, cIobConf.serverData.MPURL, cIobConf.serverData.CMDALIVE, cIobConf.codIOB);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgError(exc, "Errore in composizione urlGetCurrODL");
|
|
}
|
|
return answ;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// URL per salvataggio contapezzi...
|
|
/// </summary>
|
|
public string urlSetPzCount
|
|
{
|
|
get
|
|
{
|
|
string answ = "";
|
|
try
|
|
{
|
|
answ = string.Format(@"http://{0}{1}{2}/setCounter/{3}?counter=", cIobConf.serverData.MPIP, cIobConf.serverData.MPURL, cIobConf.serverData.CMDALIVE, cIobConf.codIOB);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgError(exc, "Errore in composizione urlSetPzCount");
|
|
}
|
|
return answ;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// URL per recupero contapezzi...
|
|
/// </summary>
|
|
public string urlGetPzCount
|
|
{
|
|
get
|
|
{
|
|
string answ = "";
|
|
try
|
|
{
|
|
answ = string.Format(@"http://{0}{1}{2}/getCounter/{3}", cIobConf.serverData.MPIP, cIobConf.serverData.MPURL, cIobConf.serverData.CMDALIVE, cIobConf.codIOB);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgError(exc, "Errore in composizione urlGetPzCount");
|
|
}
|
|
return answ;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// URL per recupero contapezzi REGISTRATI da TC...
|
|
/// </summary>
|
|
public string urlGetPzCountRec
|
|
{
|
|
get
|
|
{
|
|
string answ = "";
|
|
try
|
|
{
|
|
answ = string.Format(@"http://{0}{1}{2}/getCounterTCRec/{3}", cIobConf.serverData.MPIP, cIobConf.serverData.MPURL, cIobConf.serverData.CMDALIVE, cIobConf.codIOB);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgError(exc, "Errore in composizione urlGetPzCountRec");
|
|
}
|
|
return answ;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// URL per salvataggio dati associazione Machine 2 IOB...
|
|
/// </summary>
|
|
public string urlSetM2IOB
|
|
{
|
|
get
|
|
{
|
|
string answ = "";
|
|
try
|
|
{
|
|
string machineName = Environment.MachineName;
|
|
answ = string.Format(@"http://{0}{1}{2}/setM2IOB/{3}?IOB_name={4}", cIobConf.serverData.MPIP, cIobConf.serverData.MPURL, cIobConf.serverData.CMDALIVE, cIobConf.codIOB, machineName);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgError(exc, "Errore in composizione urlSetM2IOB");
|
|
}
|
|
return answ;
|
|
}
|
|
}
|
|
public string GetMACAddress()
|
|
{
|
|
NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
|
|
String sMacAddress = string.Empty;
|
|
foreach (NetworkInterface adapter in nics)
|
|
{
|
|
if (sMacAddress == String.Empty)// only return MAC Address from first card
|
|
{
|
|
IPInterfaceProperties properties = adapter.GetIPProperties();
|
|
//sMacAddress = adapter.GetPhysicalAddress().ToString();
|
|
sMacAddress = string.Join(":", (from z in adapter.GetPhysicalAddress().GetAddressBytes() select z.ToString("X2")).ToArray());
|
|
}
|
|
}
|
|
return sMacAddress;
|
|
}
|
|
/// <summary>
|
|
/// Fornisce URL INPUT per i parametri richiesti
|
|
/// </summary>
|
|
/// <param name="queueVal">valore salvato in coda formato dtEve#valore#counter</param>
|
|
/// <returns></returns>
|
|
public string urlInput(string queueVal)
|
|
{
|
|
// URL base x input
|
|
string answ = string.Format(@"http://{0}{1}{2}", cIobConf.serverData.MPIP, cIobConf.serverData.MPURL, cIobConf.serverData.CMDBASE);
|
|
// decodifica valore!
|
|
string[] valori = qDecodeIN(queueVal);
|
|
// aggiungo macchina e valore...
|
|
answ += string.Format(@"{0}?valore={1}", cIobConf.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;
|
|
}
|
|
/// <summary>
|
|
/// Fornisce URL di tipo FluxLog
|
|
/// </summary>
|
|
/// <param name="queueVal">valore salvato in coda nel formato dtEve#flux#valore#counter</param>
|
|
/// <returns></returns>
|
|
public string urlFLog(string queueVal)
|
|
{
|
|
// URL base x input
|
|
string answ = string.Format(@"http://{0}{1}{2}", cIobConf.serverData.MPIP, cIobConf.serverData.MPURL, cIobConf.serverData.CMDFLOG);
|
|
// decodifica valore!
|
|
string[] valori = qDecodeIN(queueVal);
|
|
// aggiungo macchina e valore...
|
|
answ += string.Format(@"{0}?flux={1}&&valore={2}", cIobConf.codIOB, valori[1], valori[2]);
|
|
// aggiondo dataOra evento e corrente + contatore...
|
|
answ += string.Format(@"&&dtEve={0}&&dtCurr={1:yyyyMMddHHmmssfff}&&cnt={2}", valori[0], DateTime.Now, valori[3]);
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua chiamata URL e restituisce risultato
|
|
/// </summary>
|
|
/// <param name="URL"></param>
|
|
/// <returns></returns>
|
|
public string callUrl(string URL)
|
|
{
|
|
return utils.callUrl(URL);
|
|
}
|
|
/// <summary>
|
|
/// test ping all'indirizzo impostato nei parametri
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private IPStatus testPingServer()
|
|
{
|
|
IPStatus answ = IPStatus.Unknown; ;
|
|
IPAddress address;
|
|
PingReply reply;
|
|
Ping pingSender = new Ping();
|
|
address = IPAddress.Loopback;
|
|
string ipAdrr = cIobConf.serverData.MPIP.Replace("http://", "").Replace("https://", "");
|
|
IPAddress.TryParse(ipAdrr, out address);
|
|
int pingMsTimeout = utils.CRI("pingMsTimeout");
|
|
reply = pingSender.Send(address, pingMsTimeout);
|
|
answ = reply.Status;
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// Verifica se il server sia ALIVE (tramite PING)
|
|
/// </summary>
|
|
public bool checkServerAlive
|
|
{
|
|
get
|
|
{
|
|
bool answ = false;
|
|
// controllo se ho un VETO all'invio...
|
|
if (dtVetoPing < DateTime.Now)
|
|
{
|
|
if (DemoOut)
|
|
{
|
|
answ = false;
|
|
}
|
|
else
|
|
{
|
|
IPStatus pingStatus = testPingServer();
|
|
// se passa il ping faccio il resto...
|
|
if (pingStatus == IPStatus.Success)
|
|
{
|
|
try
|
|
{
|
|
// chiamo URL, se restituisce "OK" è alive!
|
|
answ = (callUrl(urlAlive) == "OK");
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgError("Errore in checkServerAlive:{0}{1}", Environment.NewLine, exc);
|
|
}
|
|
// verifico SE è variato stato online/offline...
|
|
if (MPOnline != answ)
|
|
{
|
|
// se ORA sono online riporto...
|
|
if (answ)
|
|
{
|
|
lgInfo("SERVER ONLINE");
|
|
parentForm.commSrvActive = 1;
|
|
dtVetoPing = DateTime.Now.AddMinutes(-5);
|
|
utils.dtVetoSend = DateTime.Now.AddMinutes(-5);
|
|
}
|
|
else
|
|
{
|
|
lgInfo("SERVER OFFLINE");
|
|
parentForm.commSrvActive = 0;
|
|
}
|
|
// salvo nuovo status...
|
|
MPOnline = answ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
lgInfo("SERVER NOT RESPONDING (PING)");
|
|
// imposto un veto per pauseSendMSec
|
|
int pauseSendMSec = utils.CRI("pauseSendMSec");
|
|
// aggiungo NOISE... +/- 33%
|
|
Random rnd = new Random();
|
|
int noise = rnd.Next(1, pauseSendMSec / 3);
|
|
pauseSendMSec += noise - (pauseSendMSec / 6);
|
|
// imposto veto
|
|
dtVetoPing = DateTime.Now.AddMilliseconds(pauseSendMSec);
|
|
}
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Verifica se la IOB sia ENABLED (da server o Demo)
|
|
/// </summary>
|
|
private bool checkIobEnabled
|
|
{
|
|
get
|
|
{
|
|
bool answ = false;
|
|
if (DemoOut)
|
|
{
|
|
answ = (QueueIN.Count + QueueFLog.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)
|
|
{
|
|
lgInfo("IOB ONLINE");
|
|
}
|
|
else
|
|
{
|
|
lgInfo("IOB OFFLINE");
|
|
}
|
|
// salvo nuovo status...
|
|
IobOnline = answ;
|
|
}
|
|
// fix colore
|
|
if (answ)
|
|
{
|
|
parentForm.commSrvActive = 2;
|
|
}
|
|
else
|
|
{
|
|
parentForm.commSrvActive = 1;
|
|
}
|
|
return answ;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Processo la coda SignalIN...
|
|
/// </summary>
|
|
public void svuotaCodaSignIN()
|
|
{
|
|
// 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++)
|
|
{
|
|
trySendQueuedVal();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// mostro VETO-SEND x invio... GIALLO
|
|
parentForm.sOUT = Semaforo.SG;
|
|
if (periodicLog)
|
|
{
|
|
lgInfo("IOB - VETO SEND");
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// mostro SERVER KO x invio... ROSSO
|
|
parentForm.sOUT = Semaforo.SR;
|
|
if (periodicLog)
|
|
{
|
|
lgInfo("IOB - SERVER NOT READY");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Invio del + vecchio valore in coda (se c'è)
|
|
/// </summary>
|
|
private void trySendQueuedVal()
|
|
{
|
|
// SE ho qualcosa in coda...
|
|
if (QueueIN.Count > 0)
|
|
{
|
|
// recupero ed aggiorno ULTIMO valore...
|
|
lastSignInVal = QueueIN.Dequeue();
|
|
// INVIO!!!
|
|
sendToMoonPro(urlType.SignIN, lastSignInVal);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processo la coda FLog...
|
|
/// </summary>
|
|
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)
|
|
{
|
|
// 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 (QueueFLog.Count > 0)
|
|
{
|
|
// INVIO!!!
|
|
sendToMoonPro(urlType.FLog, QueueFLog.Dequeue());
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// mostro VETO-SEND x invio... GIALLO
|
|
parentForm.sOUT = Semaforo.SG;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// mostro SERVER KO x invio... ROSSO
|
|
parentForm.sOUT = Semaforo.SR;
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Classe fittizia in caso di processing task in VHF
|
|
/// </summary>
|
|
public virtual void processVHF()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Classe fittizia in caso di processing GLOBALE di tutto in 1 solo colpo...
|
|
/// </summary>
|
|
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 OPPURE se è passato + di un timeout di controllo...
|
|
if (B_output != B_previous)
|
|
{
|
|
accodaSigIN();
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Processa gestione memoria x invio dati QUANDO IOB è disconnesso da CNC...
|
|
/// </summary>
|
|
public void processMemoryDiscon()
|
|
{
|
|
// controllo contatore invio "keepalive"... invio solo a scadenza
|
|
if (DateTime.Now.Subtract(lastDisconnCheck).TotalSeconds > utils.CRI("disconMaxSec"))
|
|
{
|
|
// resetto tutti i vlaori BYTE IN/PREV/OUT... così invio macchina spenta...
|
|
B_input = 0;
|
|
B_output = 0;
|
|
B_previous = 0;
|
|
accodaSigIN();
|
|
// update controllo
|
|
lastDisconnCheck = DateTime.Now;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Esegue filtraggio dati x bit blinking!!!
|
|
/// </summary>
|
|
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<bool>().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<bool>().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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua lettura dati
|
|
/// </summary>
|
|
public virtual void readAllData()
|
|
{
|
|
if (DemoIn)
|
|
{
|
|
// segnalo che sono in Demo
|
|
parentForm.sIN = Semaforo.SV;
|
|
}
|
|
if (connectionOk)
|
|
{
|
|
readSemafori();
|
|
}
|
|
else
|
|
{
|
|
lgError("Errore connessione mancante x readSemafori");
|
|
}
|
|
|
|
nReadIN++;
|
|
// aggiorno valore mostrato...
|
|
displayRawData();
|
|
}
|
|
/// <summary>
|
|
/// Effettua gestioen programma: legge e mostra su display...
|
|
/// </summary>
|
|
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));
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Processo lettura dati sysinfo
|
|
/// </summary>
|
|
private void processSysInfo()
|
|
{
|
|
if (utils.CRB("enableSysInfo"))
|
|
{
|
|
Dictionary<string, string> currSysInfo = new Dictionary<string, string>();
|
|
|
|
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));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Restituisce info sistema
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public virtual Dictionary<string, string> getSysInfo()
|
|
{
|
|
Dictionary<string, string> outVal = new Dictionary<string, string>();
|
|
return outVal;
|
|
}
|
|
/// <summary>
|
|
/// Restituisce info DINAMICHE
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public virtual Dictionary<string, string> getDynData()
|
|
{
|
|
Dictionary<string, string> outVal = new Dictionary<string, string>();
|
|
return outVal;
|
|
}
|
|
/// <summary>
|
|
/// Restituisce info OVERRIDES
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public virtual Dictionary<string, string> getOverrides()
|
|
{
|
|
Dictionary<string, string> outVal = new Dictionary<string, string>();
|
|
return outVal;
|
|
}
|
|
/// <summary>
|
|
/// Recupera eventuali allarmi CNC...
|
|
/// </summary>
|
|
public virtual Dictionary<string, string> getCncAlarms()
|
|
{
|
|
Dictionary<string, string> outVal = new Dictionary<string, string>();
|
|
return outVal;
|
|
}
|
|
/// <summary>
|
|
/// Restituisce programma in esecuzione
|
|
/// </summary>
|
|
public virtual string getPrgName()
|
|
{
|
|
return "";
|
|
}
|
|
/// <summary>
|
|
/// Effettua lettura semafori principale
|
|
/// </summary>
|
|
public virtual void readSemafori()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua processing contapezzi (ed eventualmente alza il bit di contapezzo...)
|
|
/// </summary>
|
|
public virtual void processContapezzi()
|
|
{ }
|
|
/// <summary>
|
|
/// Effettua processing mode/status (EDIT/MDI/...)
|
|
/// </summary>
|
|
public virtual void processMode()
|
|
{ }
|
|
/// <summary>
|
|
/// Effettua processing del recupero delle speed (RPM, feedrate) degli assi
|
|
/// </summary>
|
|
public void processDynData()
|
|
{
|
|
if (utils.CRB("enableDynData"))
|
|
{
|
|
Dictionary<string, string> currDynData = new Dictionary<string, string>();
|
|
|
|
if (connectionOk)
|
|
{
|
|
currDynData = getDynData();
|
|
}
|
|
else
|
|
{
|
|
lgError("Errore connessione mancante x getDynData");
|
|
}
|
|
// verifico SE sia cambiato il programma...
|
|
if (lastDynData != currDynData["DYNDATA"])
|
|
{
|
|
// salvo!
|
|
lastDynData = currDynData["DYNDATA"];
|
|
// per ogni valore del dizionario mostro ed accodo!
|
|
string sVal = "";
|
|
foreach (var item in currDynData)
|
|
{
|
|
sVal = string.Format("[DYNDATA]{0}|{1}", item.Key, item.Value);
|
|
// chiamo accodamento...
|
|
accodaFLog(sVal, qEncodeFLog(item.Key, item.Value));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Effettua processing del recupero delle speed (RPM, feedrate) degli assi
|
|
/// </summary>
|
|
public void processCncAlarms()
|
|
{
|
|
if (utils.CRB("enableAlarms"))
|
|
{
|
|
Dictionary<string, string> currAlarms = new Dictionary<string, string>();
|
|
if (connectionOk)
|
|
{
|
|
currAlarms = getCncAlarms();
|
|
}
|
|
else
|
|
{
|
|
lgError("Errore connessione mancante x getCncAlarms");
|
|
}
|
|
// verifico SE sia cambiato il programma...
|
|
if (currAlarms.Count > 0)
|
|
{
|
|
if (lastAlarm != currAlarms["CNC_ALARM"])
|
|
{
|
|
// salvo!
|
|
lastAlarm = currAlarms["CNC_ALARM"];
|
|
// per ogni valore del dizionario mostro ed accodo!
|
|
string sVal = "";
|
|
foreach (var item in currAlarms)
|
|
{
|
|
sVal = string.Format("[CNC_ALARM]{0}|{1}", item.Key, item.Value);
|
|
// chiamo accodamento...
|
|
accodaFLog(sVal, qEncodeFLog(item.Key, item.Value));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua processing del recupero delle OVERRIDE (spindle, feedrate, rapid)
|
|
/// </summary>
|
|
public virtual void processOverride()
|
|
{
|
|
if (utils.CRB("enableOverrides"))
|
|
{
|
|
Dictionary<string, string> currOverride = new Dictionary<string, string>();
|
|
if (connectionOk)
|
|
{
|
|
currOverride = getOverrides();
|
|
}
|
|
else
|
|
{
|
|
lgError("Errore connessione mancante x getOverrides");
|
|
}
|
|
|
|
// SE sono connesso...
|
|
if (connectionOk)
|
|
{
|
|
// se HO dei valori override...
|
|
if (currOverride.Count > 0)
|
|
{
|
|
// verifico SE sia cambiato il programma...
|
|
if (lastOverrideFS != currOverride["FEED_OVER"] || lastOverrideRapid != currOverride["RAPID_OVER"])
|
|
{
|
|
// salvo!
|
|
lastOverrideFS = currOverride["FEED_OVER"];
|
|
lastOverrideRapid = currOverride["RAPID_OVER"];
|
|
// per ogni valore del dizionario mostro ed accodo!
|
|
string sVal = "";
|
|
foreach (var item in currOverride)
|
|
{
|
|
sVal = string.Format("[OVERRIDES]{0}|{1}", item.Key, item.Value);
|
|
// chiamo accodamento...
|
|
accodaFLog(sVal, qEncodeFLog(item.Key, item.Value));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// metodo dummy x salvataggio aree memoria conf x CN
|
|
/// </summary>
|
|
/// <param name="tipo">tipo di DUMP</param>
|
|
public virtual void saveMemDump(dumpType tipo)
|
|
{
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region gestione code (accumulo, invio)
|
|
|
|
/// <summary>
|
|
/// Fornisce il valore letto da BITMAP in formato valido x messa in coda nel formato dtEve#value#cont
|
|
/// </summary>
|
|
protected string qEncodeIN
|
|
{
|
|
get
|
|
{
|
|
string answ = "";
|
|
try
|
|
{
|
|
answ = string.Format("{0:yyyyMMddHHmmssfff}#{1:X2}#{2}", DateTime.Now, B_output, counterSigIN);
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Fornisce il valore di flusso e valore in formato valido x messa in coda nel formato dtEve#flux#value#cont
|
|
/// </summary>
|
|
public string qEncodeFLog(string flusso, string valore)
|
|
{
|
|
string answ = "";
|
|
try
|
|
{
|
|
answ = string.Format("{0:yyyyMMddHHmmssfff}#{1}#{2}#{3}", DateTime.Now, flusso, valore, counterFLog);
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// Decodifica valore della coda IN nel formato
|
|
/// answ[0]=dtEve
|
|
/// answ[1]=valore
|
|
/// answ[2]=counter
|
|
/// </summary>
|
|
/// <param name="queueVal">dtEve + '#' + value + '#' + cont</param>
|
|
/// <returns></returns>
|
|
protected string[] qDecodeIN(string queueVal)
|
|
{
|
|
return queueVal.Split('#');
|
|
}
|
|
/// <summary>
|
|
/// Accumula in coda i valori Signal IN e logga...
|
|
/// </summary>
|
|
public void accodaSigIN()
|
|
{
|
|
// mostro dati variati letti...
|
|
displayInData();
|
|
// --> accodo (valore già formattato)!
|
|
QueueIN.Enqueue(qEncodeIN);
|
|
// loggo!
|
|
lgInfo(string.Format("[QUEUE-IN] {0}", qEncodeIN));
|
|
// aggiorno counters ed eventuale reset
|
|
nReadFilt++;
|
|
if (nReadFilt > int.MaxValue - 1)
|
|
{
|
|
nReadFilt = 0; // per evitare buffer overflow...
|
|
}
|
|
|
|
counterSigIN++;
|
|
if (counterSigIN > 9999)
|
|
{
|
|
counterSigIN = 0;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Accumula in coda i valori Signal IN e logga...
|
|
/// </summary>
|
|
/// <param name="val">VALORE RAW (x display)</param>
|
|
/// <param name="encodedVal">VALORE già processato con qEncodeFLog(...)</param>
|
|
public void accodaFLog(string val, string encodedVal)
|
|
{
|
|
// mostro dati variati letti...
|
|
displayOtherData(val);
|
|
// --> accodo (valore già formattato)!
|
|
QueueFLog.Enqueue(encodedVal);
|
|
// loggo!
|
|
lgInfo(string.Format("[QUEUE-FLOG] {0}", encodedVal));
|
|
counterFLog++;
|
|
if (counterFLog > 9999)
|
|
{
|
|
counterFLog = 0;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Effettua invio a MoonPro del valore richiesto
|
|
/// </summary>
|
|
/// <param name="tipoUrl"></param>
|
|
/// <param name="queueVal">Valore da trasmettere: es
|
|
/// INPUT: lo status rilevato in HEX
|
|
/// FLog: il valore da trasmettere per il flusso indicato</param>
|
|
public void sendToMoonPro(urlType tipoUrl, string queueVal)
|
|
{
|
|
// recupero e formatto URL dati da coda...
|
|
switch (tipoUrl)
|
|
{
|
|
case urlType.FLog:
|
|
lastUrl = urlFLog(queueVal);
|
|
break;
|
|
case urlType.SignIN:
|
|
lastUrl = urlInput(queueVal);
|
|
break;
|
|
default:
|
|
lastUrl = "";
|
|
break;
|
|
}
|
|
// se NON sono in demo effettuo invio!
|
|
if (!DemoOut)
|
|
{
|
|
// chiamo URL!
|
|
string answ = callUrl(lastUrl);
|
|
// loggo!
|
|
lgInfo(string.Format("[SEND] {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!
|
|
lgInfo(string.Format("{0} -> [SIM]", queueVal));
|
|
}
|
|
nSendOut++;
|
|
// riporto cosa inviato
|
|
displayOutData();
|
|
// aggiorno data ultimo watchdog...
|
|
lastWatchDog = DateTime.Now;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region gestione dataMonitor (update visualizzazione valori)
|
|
|
|
/// <summary>
|
|
/// Mostra i dati grezzi letti in esadecimale
|
|
/// </summary>
|
|
private void displayRawData()
|
|
{
|
|
// mostro update...
|
|
string newString = string.Format("{0:X}", B_input);
|
|
accodaRawData(newString);
|
|
// salvo coda debug...
|
|
QueueDebug.Enqueue(B_input);
|
|
}
|
|
/// <summary>
|
|
/// Update visualizzaizone BIT in ingresso
|
|
/// </summary>
|
|
public void displayInData()
|
|
{
|
|
// mostro update...
|
|
string newString = string.Format("{0:0000}|{1}", counterSigIN, utils.IntToBinStr(B_output, 8));
|
|
accodaSignaInlData(newString);
|
|
}
|
|
/// <summary>
|
|
/// Mostra cosa ha/avrebbe inviato
|
|
/// </summary>
|
|
public void displayOutData()
|
|
{
|
|
accodaUrlData(lastUrl);
|
|
}
|
|
/// <summary>
|
|
/// Mostra cosa ha/avrebbe inviato
|
|
/// </summary>
|
|
/// <param name="newData"></param>
|
|
public void displayOtherData(string newData)
|
|
{
|
|
// mostro update...
|
|
accodaOtherData(newData);
|
|
}
|
|
/// <summary>
|
|
/// Accoda (visualizzando in cima allo stack) la nuova stringa di output per area OTHER DATA
|
|
/// </summary>
|
|
/// <param name="newLine"></param>
|
|
public void accodaRawData(string newLine)
|
|
{
|
|
// inserisco in cima allo stack, trimmo e aggiorno display
|
|
parentForm.dataMonitor_0 = limitLine2show(string.Format("{0}{1}{2}", newLine, Environment.NewLine, parentForm.dataMonitor_0));
|
|
}
|
|
/// <summary>
|
|
/// Accoda (visualizzando in cima allo stack) la nuova stringa di output per area OTHER DATA
|
|
/// </summary>
|
|
/// <param name="newLine"></param>
|
|
public void accodaSignaInlData(string newLine)
|
|
{
|
|
// inserisco in cima allo stack, trimmo e aggiorno display
|
|
parentForm.dataMonitor_1 = limitLine2show(string.Format("{0}{1}{2}", newLine, Environment.NewLine, parentForm.dataMonitor_1));
|
|
}
|
|
/// <summary>
|
|
/// Accoda (visualizzando in cima allo stack) la nuova stringa di output per area OTHER DATA
|
|
/// </summary>
|
|
/// <param name="newLine"></param>
|
|
public void accodaUrlData(string newLine)
|
|
{
|
|
// inserisco in cima allo stack, trimmo e aggiorno display
|
|
parentForm.dataMonitor_2 = limitLine2show(string.Format("{0}{1}{2}", newLine, Environment.NewLine, parentForm.dataMonitor_2));
|
|
}
|
|
/// <summary>
|
|
/// Accoda (visualizzando in cima allo stack) la nuova stringa di output per area OTHER DATA
|
|
/// </summary>
|
|
/// <param name="newLine"></param>
|
|
public void accodaOtherData(string newLine)
|
|
{
|
|
// inserisco in cima allo stack, trimmo e aggiorno display
|
|
parentForm.dataMonitor_3 = limitLine2show(string.Format("{0}{1}{2}", newLine, Environment.NewLine, parentForm.dataMonitor_3));
|
|
}
|
|
/// <summary>
|
|
/// Effettua un trim della stringa al numero max di linee da mostrare a video
|
|
/// </summary>
|
|
/// <param name="newString"></param>
|
|
/// <returns></returns>
|
|
private string limitLine2show(string newString)
|
|
{
|
|
// se num righe superiore a limite trimmo...
|
|
if (newString.Split('\n').Length > parentForm.nLine2show)
|
|
{
|
|
//int idx = newString.LastIndexOf('\r');
|
|
int idx = newString.LastIndexOf(Environment.NewLine);
|
|
newString = newString.Substring(0, idx);
|
|
}
|
|
return newString;
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
|
}
|