Files
Mapo-IOB-WIN/IOB-WIN/AdapterForm.cs
T
2018-11-28 17:08:26 +01:00

948 lines
26 KiB
C#

using IOB_UT;
using NLog;
using NLog.Config;
using NLog.Targets;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
namespace IOB_WIN
{
public partial class AdapterForm : Form
{
#region inizializzazione contatori
/// <summary>
/// contatore veloce
/// </summary>
protected int fastCount;
/// <summary>
/// contatore normale
/// </summary>
protected int normCount;
/// <summary>
/// contatore lento
/// </summary>
protected int slowCount;
/// <summary>
/// contatore sync allarmi
/// </summary>
protected int verySlowCount;
/// <summary>
/// Contatore campionamento memoria
/// </summary>
protected int sampleMemCount;
/// <summary>
/// timer base in avvio
/// </summary>
protected int startTimerMs = 250;
/// <summary>
/// ultimo tentativo riavvio...
/// </summary>
protected DateTime lastStartTry;
/// <summary>
/// Data-Ora prima apertura FORM...
/// </summary>
protected DateTime firstStart;
#endregion
#region inizializzazione oggetti base
/// <summary>
/// oggetto logging
/// </summary>
public static Logger lg;
/// <summary>
/// Oggetto x gestione dell'adapter GENERICO (x poter usare metodi di ognuno...)
/// </summary>
IobGeneric iobObj;
/// <summary>
/// configurazione caricata
/// </summary>
IobConfiguration IOBConf;
/// <summary>
/// tipo di adapter prescelto...
/// </summary>
public tipoAdapter tipoScelto = tipoAdapter.DEMO;
/// <summary>
/// Vendor macchina
/// </summary>
public string curVendor = "";
/// <summary>
/// Modello macchina
/// </summary>
public string curModel = "";
/// <summary>
/// Codice IOB della macchina cui connettersi (x scegliere corretto file di conf...)
/// </summary>
protected string CurrIOB { get; set; }
#endregion
#region utils ed helpers
/// <summary>
/// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere...
/// </summary>
/// <param name="txt2log"></param>
protected void lgInfo(string txt2log)
{
lg.Factory.Configuration.Variables["codIOB"] = this.CurrIOB;
lg.Info(txt2log);
}
/// <summary>
/// Effettua logging ERROR corretto impostanto anche la variabile IOB prima di scrivere...
/// </summary>
/// <param name="txt2log"></param>
protected void lgError(string txt2log)
{
lg.Factory.Configuration.Variables["codIOB"] = this.CurrIOB;
lg.Error(txt2log);
}
private class Item
{
public string Name;
public int Value;
public Item(string name, int value)
{
Name = name; Value = value;
}
}
/// <summary>
/// mostra un testo sulla status bar + LOG
/// </summary>
/// <param name="txt2show"></param>
public void displayTaskAndLog(string txt2show)
{
lblStatus.Text = txt2show;
lblStatus.Invalidate();
lgInfo(txt2show);
}
/// <summary>
/// Mostra update delle statistiche di comunicazione (numero chiamate, tempo medio...)
/// </summary>
/// <param name="txt2show"></param>
public void updateComStats(string txt2show)
{
lblComStats.Text = string.Format("{0} | ", txt2show);
}
#endregion
#region gestione form e visibilità
/// <summary>
/// File configurazione default
/// </summary>
public string defConfFilePath
{
get
{
return string.Format(@"{0}\{1}.ini", utils.confDir, CurrIOB);
}
}
/// <summary>
/// Avvio MainForm
/// </summary>
/// <param name="codIOB"></param>
public AdapterForm(string codIOB)
{
CurrIOB = codIOB;
// continuo avvio...
InitializeComponent();
lblStatus.Text = "Loading";
// inizializzo orologi
firstStart = DateTime.Now;
lastStartTry = DateTime.Now;
startTimerMs = utils.CRI("startTimerMs");
#if DEBUG
// Setup the logging view for Sentinel - http://sentinel.codeplex.com
var sentinelTarget = new NLogViewerTarget()
{
Name = "sentinel",
Address = "udp://127.0.0.1:9999",
IncludeNLogData = false
};
var sentinelRule = new LoggingRule("*", LogLevel.Trace, sentinelTarget);
LogManager.Configuration.AddTarget("sentinel", sentinelTarget);
LogManager.Configuration.LoggingRules.Add(sentinelRule);
#endif
LogManager.ReconfigExistingLoggers();
lg = LogManager.GetCurrentClassLogger();
displayTaskAndLog("MainForm Starting");
// se abilitato autoload conf leggo file corretto...
if (utils.CRB("autoLoadConf"))
{
try
{
loadIniFile(defConfFilePath);
lgInfo("INI LOADED");
loadPersistLayer(utils.defPersLayerFile);
lgInfo("PersLayerFile READ");
iobObj.loadPersData();
lgInfo("PersLayerFile LOADED");
}
catch (Exception exc)
{
displayTaskAndLog(string.Format("Eccezione in autoLoadConf: {0}", exc));
}
}
else
{
// definisco e avvio tipo adapter generico
tipoScelto = tipoAdapter.ND;
curVendor = "ACME";
curModel = "NONE";
IOBConf = new IobConfiguration();
loadIobType();
displayTaskAndLog("Waiting for config file selection");
}
// Start timer periodico comunicazione
gather.Interval = utils.CRI("timerIntMs");
gather.Enabled = true;
displayTaskAndLog(string.Format("Main timer set: {0}ms", gather.Interval));
// Start timer periodico interfaccia
displTimer.Interval = utils.CRI("timerIntMs");
displTimer.Enabled = true;
displayTaskAndLog("Program Running");
try
{
// verifico server online...
if (iobObj.checkServerAlive)
{
// segnalo reboot (programma)...
iobObj.callUrl(iobObj.urlReboot);
}
else
{
displayTaskAndLog("Server OFFLINE");
}
}
catch (Exception exc)
{
lgError(string.Format("AdapterForm: EXCEPTION in fase di chiamata URL di reboot:{0}{1}{2}", iobObj.urlReboot, Environment.NewLine, exc));
}
displayTaskAndLog("Main Form OK");
}
/// <summary>
/// Fase chiusura Form
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
closeAdapter();
}
/// <summary>
/// Mostrata form
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MainForm_Shown(object sender, EventArgs e)
{
displayTaskAndLog("Main Form SHOWN");
}
/// <summary>
/// Completato resize form
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MainForm_Resize(object sender, EventArgs e)
{
}
#endregion
#region gestione metodi specifici FORM
private void checkSendTask()
{
// avvio fase invio con adapter (code MST)
iobObj.getAndSend(gatherCycle.VHF);
}
private void checkFastTask()
{
// decremento...
fastCount--;
// se il counter è a zero eseguo...
if (fastCount <= 0)
{
fastCount = utils.CRI("fastCount");
// avvio fase raccolta dati e invio con adapter
iobObj.getAndSend(gatherCycle.HF);
}
}
private void checkNormTask()
{
// decremento...
normCount--;
// se il counter è a zero eseguo...
if (normCount <= 0)
{
normCount = utils.CRI("normCount");
// avvio fase raccolta dati e invio con adapter
iobObj.getAndSend(gatherCycle.MF);
}
}
private void checkSlowTask()
{
slowCount--;
if (slowCount <= 0)
{
slowCount = utils.CRI("slowCount");
// avvio fase raccolta dati e invio con adapter
iobObj.getAndSend(gatherCycle.LF);
}
}
private void checkVerySlowData()
{
verySlowCount--;
if (verySlowCount <= 0)
{
verySlowCount = utils.CRI("verySlowCount");
// avvio fase raccolta dati e invio con adapter
iobObj.getAndSend(gatherCycle.VLF);
}
}
private void checkSampleMem()
{
// decremento contatore...
sampleMemCount--;
if (sampleMemCount <= 0)
{
sampleMemCount = utils.CRI("sampleMemCount");
// avvio fase raccolta dati e invio con adapter
iobObj.saveMemDump(dumpType.SAMPLE);
}
}
private void refreshFormData()
{
// aggiorno visualizzazioni varie in form...
lQueueLen.Text = iobObj.QueueIN.Count.ToString();
}
private void gather_Tick(object sender, EventArgs e)
{
try
{
// check esecuzione SendTask (VHF) COMUNQUE...
checkSendTask();
// eseguo cicli attivi SOLO se adapter è in EFFETTIVO running...
if (iobObj.adpRunning)
{
if (iobObj.connectionOk)
{
// se richiesto faccio memory DUMP INIZIALE!
if (iobObj.doStartMemDump)
{
lgInfo("Inizio dump memoria");
iobObj.saveMemDump(dumpType.STARTUP);
// fatto! non ripeto...
iobObj.doStartMemDump = false;
lgInfo("Finito dump memoria");
}
// controllo se sia abilitato sampleDump della meoria (periodico)
if (iobObj.doSampleMemory)
{
checkSampleMem();
}
// check esecuzione FastTask
checkFastTask();
// check esecuzione NormTask
checkNormTask();
// check esecuzione SlowTask
checkSlowTask();
// check esecuzione AlarmSync
checkVerySlowData();
if (utils.CRI("waitEndCycle") > 0)
{
Thread.Sleep(utils.CRI("waitEndCycle"));
}
}
else
{
double currWait = DateTime.Now.Subtract(lastStartTry).TotalMilliseconds;
if (iobObj.adpTryRestart && currWait > utils.CRI("waitRecMSec"))
{
lastStartTry = DateTime.Now;
iobObj.tryConnect();
iobObj.loadPersData();
}
}
}
else
{
if (iobObj.verboseLog)
{
lgInfo("PLC <--> IOB Not connected");
}
// verifico SE debba tentare il riavvio, ovvero NON running ma tryReconn e non ho riprovato x oltre waitRecMSec
double currWait = DateTime.Now.Subtract(lastStartTry).TotalMilliseconds;
if (iobObj.adpTryRestart && currWait > utils.CRI("waitRecMSec"))
{
lastStartTry = DateTime.Now;
avviaAdapter();
iobObj.loadPersData();
}
}
}
catch (Exception exc)
{
lgError(string.Format("Eccezione in fase di gatherTick: {0}{1}", Environment.NewLine, exc));
}
}
/// <summary>
/// Chiusura adapter
/// </summary>
private void closeAdapter()
{
fermaTutto(true, false);
}
/// <summary>
/// Ferma tutti i componenti adapter + update buttons
/// </summary>
/// <param name="stopTimer">determina se fermare il timer (gather) principale (solo se non si chiude)</param>
/// <param name="tryRestart">determina se tentare di riconnettersi</param>
private void fermaTutto(bool stopTimer, bool tryRestart)
{
iobObj.stopAdapter(tryRestart);
// salvo!
savePersistLayer(utils.defPersLayerFile);
savePersistLayer(utils.histPersLayerFile);
stop.Enabled = false;
start.Enabled = true;
restart.Enabled = false;
if (stopTimer)
{
gather.Enabled = false;
iobObj.tryDisconnect();
}
sIN = Semaforo.SS;
sOUT = Semaforo.SS;
}
/// <summary>
/// Carica file ini della configurazione richiesta
/// </summary>
/// <param name="iniConfFile"></param>
private void loadIniFile(string iniConfFile)
{
// out di cosa faccio...
displayTaskAndLog(string.Format("Loading iniConfFile: {0}", iniConfFile));
// leggo file
IniFile fIni = new IniFile(iniConfFile);
// leggo vendor e modello...
curVendor = fIni.ReadString("MACHINE", "VENDOR", "ACME");
curModel = fIni.ReadString("MACHINE", "MODEL", "NONE");
// verifico tipo adapter
tipoScelto = (tipoAdapter)Enum.Parse(typeof(tipoAdapter), fIni.ReadString("IOB", "CNCTYPE", "DEMO"));
// carivo vettore parametri opzionai
Dictionary<string, string> optParRead = new Dictionary<string, string>();
string[] optParRows = fIni.ReadSection("OPTPAR");
if (optParRows.Length > 0)
{
try
{
string[] kvp;
foreach (var item in optParRows)
{
kvp = item.Split('=');
optParRead.Add(kvp[0], kvp[1]);
}
}
catch (Exception exc)
{
lgError(string.Format("EXCEPTION in fase di lettura OPTPAR: {0}{1}", Environment.NewLine, exc));
}
}
// inizializzio conf IOB
IOBConf = new IobConfiguration
{
pingMsTimeout = fIni.ReadInteger("IOB", "PING_MS_TIMEOUT", 250),
vendor = curVendor,
model = curModel,
tipoIob = tipoScelto,
optPar = optParRead,
versIOB = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString(),
codIOB = CurrIOB, // fIni.ReadString("IOB", "IDXMACC", "0"),
cncIpAddr = fIni.ReadString("CNC", "IP", "::1"),
cncPort = fIni.ReadString("CNC", "PORT", "0"),
iniFileName = iniConfFile,
cpuType = fIni.ReadString("CNC", "CPUTYPE", ""),
rack = (short)fIni.ReadInteger("CNC", "RACK", 0),
slot = (short)fIni.ReadInteger("CNC", "SLOT", 0),
serverData = new serverMapo(fIni.ReadString("SERVER", "MPIP", "::1"), fIni.ReadString("SERVER", "MPURL", "/"), fIni.ReadString("SERVER", "CMDBASE", "/"), fIni.ReadString("SERVER", "CMDFLOG", "/"), fIni.ReadString("SERVER", "CMDALIVE", "/"), fIni.ReadString("SERVER", "CMDENABLED", "/"), fIni.ReadString("SERVER", "CMDREBO", "/")),
MAX_COUNTER_BLINK = Convert.ToInt32(fIni.ReadString("BLINK", "MAX_COUNTER_BLINK", "1")),
BLINK_FILT = Convert.ToInt32(fIni.ReadString("BLINK", "BLINK_FILT", "0"))
};
loadIobType();
// avvio macchina con adapter specificato...
if (utils.CRB("autoStartOnLoad"))
{
displayTaskAndLog("Auto Starting...");
// avvio!
avviaAdapter();
displayTaskAndLog("Auto Started!");
}
try
{
// segnalo reboot (programma)... metto in coda invio...
//iobObj.sendToMoonPro(urlType.FLog, "IOB INI Loaded");
//iobObj.QueueFLog.Enqueue(iobObj.qEncodeFLog("IOB-STATUS", "IOB INI Loaded"));
}
catch (Exception exc)
{
lgError(string.Format("EXCEPTION in fase di chiamata URL di segnalazione caricamento INI file:{0}{1}", Environment.NewLine, exc));
}
}
/// <summary>
/// Salva su file l'oggetto di persistenza dati
/// </summary>
/// <param name="filePath"></param>
public void savePersistLayer(string filePath)
{
// in primis check semaforo salvataggio...
if (!iobObj.adpSaving)
{
// alzo semaforo salvataggio
iobObj.adpSaving = true;
// se HO dei dati...
if (iobObj.persistenceLayer != null)
{
try
{
utils.WritePlain(iobObj.persistenceLayer, filePath);
}
catch (Exception exc)
{
lgError(string.Format("Errore salvataggio file{0}{1}", Environment.NewLine, exc));
}
}
else
{
lgInfo("persistenceLayer null, non salvato...");
}
// abbasso semaforo salvataggio
iobObj.adpSaving = false;
}
}
/// <summary>
/// Carica da file l'oggetto di persistenza dati
/// </summary>
/// <param name="filePath"></param>
public void loadPersistLayer(string filePath)
{
// inizializzo prima di leggere...
iobObj.persistenceLayer = new Dictionary<string, string>();
iobObj.persistenceLayer = utils.ReadPlain(filePath);
// 2017.03.23 check problema files corrotti...
if (iobObj.persistenceLayer.Count == 0)
{
// se avesse letto un valore NON coerente (senza righe) PROVA a leggere a ritroso vecchi files... da histPersLayerFile e precedenti...
int numDD = 0;
int maxNumDD = utils.CRI("maxNumDD");
Dictionary<string, string> lastRead = new Dictionary<string, string>();
// continuo fino a che non leggo almeno 1 riga valida e non ho raggiunto maxDD
while (numDD < maxNumDD && lastRead.Count == 0)
{
// leggo il file storico alla data anticipata... (ci provo...)
try
{
lastRead = utils.ReadPlain(utils.prevPersLayerFile(numDD));
}
catch
{ }
numDD++;
}
// se sono uscito PROVO a passare il file storico letto buono (oppure vuoto...)
iobObj.persistenceLayer = lastRead;
}
}
#endregion
private void mLoadConf_Click(object sender, EventArgs e)
{
// mostro selettore file x leggere adapter..
OpenFileDialog openFileDial = new OpenFileDialog();
// directory iniziale
openFileDial.InitialDirectory = utils.confDir; // string.Format(@"{0}\{1}", Application.StartupPath, utils.CRS("dataConfPath"));
// Set filter options and filter index.
openFileDial.Filter = "INI Files (.ini)|*.ini|All Files (*.*)|*.*";
openFileDial.FilterIndex = 1;
// altre opzioni
openFileDial.Multiselect = false;
// Call the ShowDialog method to show the dialog box.
DialogResult userClickedOK = openFileDial.ShowDialog();
// Process input if the user clicked OK.
if (userClickedOK == DialogResult.OK)
{
string iniConfFile = openFileDial.FileName;
loadIniFile(iniConfFile);
lgInfo("INI LOADED");
loadPersistLayer(utils.defPersLayerFile);
lgInfo("PersLayerFile READ");
iobObj.loadPersData();
lgInfo("PersLayerFile LOADED");
}
}
/// <summary>
/// carica IOB richiesto
/// </summary>
private void loadIobType()
{
switch (tipoScelto)
{
case tipoAdapter.DEMO:
iobObj = new IobDemo(this, IOBConf);
start.Enabled = true;
break;
case tipoAdapter.FANUC:
iobObj = new IobFanuc(this, IOBConf);
start.Enabled = true;
break;
case tipoAdapter.KAWASAKI:
iobObj = new IobKawasaki(this, IOBConf);
start.Enabled = true;
break;
case tipoAdapter.OSAI_OPEN:
case tipoAdapter.OSAI_CNDEX:
case tipoAdapter.OSAI_VB6:
// versione CVCncLib
iobObj = new IobOSAI(this, IOBConf);
start.Enabled = true;
break;
case tipoAdapter.SIEMENS:
iobObj = new IobSiemens(this, IOBConf);
start.Enabled = true;
break;
case tipoAdapter.SIEMENS_FAPE:
iobObj = new IobSiemensFape(this, IOBConf);
start.Enabled = true;
break;
case tipoAdapter.SIEMENS_TORRI:
iobObj = new IobSiemensTorri(this, IOBConf);
start.Enabled = true;
break;
case tipoAdapter.ND:
default:
iobObj = new IobDemo(this, IOBConf);
start.Enabled = false;
break;
}
lblCNC.Text = string.Format("CNC: {0} [{1}:{2}]", IOBConf.tipoIob, IOBConf.cncIpAddr, IOBConf.cncPort);
lblSrvUrl.Text = string.Format("SRV: {0} | URL: {1}{2}", IOBConf.serverData.MPIP, IOBConf.serverData.MPURL, IOBConf.serverData.CMDBASE);
lblTopCent.Text = string.Format("IOB {0}", IOBConf.codIOB);
// carico i default values su interfaccia
setDefaults();
displayTaskAndLog(string.Format("Caricata conf per adapter {0}", tipoScelto));
}
/// <summary>
/// impostazione valori defaults
/// </summary>
private void setDefaults()
{
stop.Enabled = false;
lQueueLen.Text = "ND";
nLine2show = utils.CRI("numRowConsole");
}
/// <summary>
/// Visualizzazione stato di comunicazione attiva con PLC
/// </summary>
public bool commPlcActive
{
set
{
// se true --> comunica/verde, altrimenti grigio
lblCNC.ForeColor = value ? Color.SeaGreen : Color.Black;
lblSrvUrl.ForeColor = value ? Color.SeaGreen : Color.DarkSlateGray;
statusStrip1.Refresh();
}
}
/// <summary>
/// Avvio dell'adapter
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void start_Click(object sender, EventArgs e)
{
avviaAdapter();
iobObj.loadPersData();
// salvo che ho avviato adapter
lgInfo("Completato LOAD Adapter");
}
/// <summary>
/// Avvio l'adapter
/// </summary>
public void avviaAdapter()
{
displayTaskAndLog("Adapter starting");
// se NON sta girando...
if (!iobObj.adpRunning)
{
int porta = Convert.ToInt32(port.Text);
iobObj.startAdapter(porta);
displayTaskAndLog("Adapter started!");
// fix buttons start/stop/dump
start.Enabled = false;
stop.Enabled = true;
restart.Enabled = true;
displayTaskAndLog("Start Timers");
// inizializzo contatori fast/mid/slow
fastCount = utils.CRI("fastCount");
normCount = utils.CRI("normCount");
slowCount = utils.CRI("slowCount");
verySlowCount = utils.CRI("verySlowCount");
displayTaskAndLog("Adapter Running...");
// forzo check allarmi..
iobObj.forceAlarmCheck();
try
{
// segnalo reboot (programma)...
//iobObj.sendToMoonPro(urlType.FLog, "IOB Started");
//iobObj.QueueFLog.Enqueue(iobObj.qEncodeFLog("IOB-STATUS", "IOB Started"));
}
catch (Exception exc)
{
lgError(string.Format("EXCEPTION in fase di chiamata URL di segnalazione AVVIO IOB:{0}{1}", Environment.NewLine, exc));
}
}
else
{
displayTaskAndLog("Adapter STILL Running...");
}
}
/// <summary>
/// Button restart
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void restart_Click(object sender, EventArgs e)
{
// faccio stop...
fermaAdapter(false);
displayTaskAndLog("RESTARTING: Adapter Stopped");
// rileggo INI
loadIniFile(defConfFilePath);
displayTaskAndLog("RESTARTING: Ini File Reloaded");
// faccio start...
avviaAdapter();
iobObj.loadPersData();
displayTaskAndLog("RESTARTING: Adapter Started");
}
/// <summary>
/// fermata dell'adapter
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void stop_Click(object sender, EventArgs e)
{
fermaAdapter(false);
// salvo che ho fermato adapter
lgInfo("UNLOAD Adapter");
}
/// <summary>
/// Ferma l'adapter
/// </summary>
/// <param name="tryRestart">determina se si debba tentare riavvio automatico (per caduta connessione)</param>
public void fermaAdapter(bool tryRestart)
{
fermaTutto(false, tryRestart);
}
/// <summary>
/// Stringa dati monitoraggio mostrata (1 SX)...
/// </summary>
public string dataMonitor_0
{
get
{
return lblRawData.Text;
}
set
{
lblRawData.Text = value;
}
}
/// <summary>
/// Stringa dati monitoraggio mostrata (1 SX)...
/// </summary>
public string dataMonitor_1
{
get
{
return lblOutMessage.Text;
}
set
{
lblOutMessage.Text = value;
}
}
/// <summary>
/// Stringa dati monitoraggio mostrata (2 centro)...
/// </summary>
public string dataMonitor_2
{
get
{
return lblOutMessage2.Text;
}
set
{
lblOutMessage2.Text = value;
}
}
/// <summary>
/// Stringa dati monitoraggio mostrata (3 dx)...
/// </summary>
public string dataMonitor_3
{
get
{
return lblOutMessage3.Text;
}
set
{
lblOutMessage3.Text = value;
}
}
/// <summary>
/// label del numero di record processati (libera)
/// </summary>
public string dataProcLabel
{
get
{
return tslDataProc.Text;
}
set
{
tslDataProc.Text = value;
}
}
/// <summary>
/// Numero max linee da mostrare (da controllo)...
/// </summary>
public int nLine2show
{
get
{
int answ = 5;
try
{
Int32.TryParse(nLines.Text, out answ);
}
catch
{ }
return answ;
}
set
{
nLines.Text = value.ToString();
}
}
/// <summary>
/// Imposta COLORE SFONDO x Semaforo IN
/// </summary>
public Semaforo sIN
{
set
{
bIN.BackColor = decSemaforo(value);
bIN.Refresh();
}
}
/// <summary>
/// Imposta COLORE SFONDO x Semaforo OUT
/// </summary>
public Semaforo sOUT
{
set
{
bOUT.BackColor = decSemaforo(value);
bOUT.Refresh();
}
}
/// <summary>
/// Decodifica colore da valore semaforico
/// </summary>
/// <param name="valore"></param>
/// <returns></returns>
public Color decSemaforo(Semaforo valore)
{
Color colore = Color.LightGray;
switch (valore)
{
case Semaforo.SV:
colore = Color.LightGreen;
break;
case Semaforo.SG:
colore = Color.LightGoldenrodYellow;
break;
case Semaforo.SR:
colore = Color.Red;
break;
case Semaforo.SS:
colore = Color.DarkGray;
break;
default:
colore = Color.LightGray;
break;
}
return colore;
}
private void displTimer_Tick(object sender, EventArgs e)
{
// aggiorno solo componenti visuali...
// aggiorno uptime...
TimeSpan uptime = DateTime.Now.Subtract(firstStart);
tslUptime.Text = string.Format("Runtime: {0}gg {1:00}:{2:00}:{3:00}", uptime.Days, uptime.Hours, uptime.Minutes, uptime.Seconds);
}
}
}