Files
CMS-MTConn/MTC_Adapter/MTC-ADB/MainForm.cs
T

758 lines
24 KiB
C#

/*
* Copyright Copyright 2017, Steamware s.r.l. & CMS/SCM s.p.a.
*
* Based on data, code and example by MTC consortium & System Insights, Inc.
*
* */
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
using NLog;
using MTC;
using NLog.Config;
using NLog.Targets;
using System.Collections;
using System.Configuration;
using System.Diagnostics;
using System.IO;
namespace MTC_ADB
{
public partial class MainForm : Form
{
#region variabili ed oggetti globali
/// <summary>
/// timer base in avvio
/// </summary>
protected int startTimerMs = 250;
/// <summary>
/// contatore normale
/// </summary>
protected int normCount = 5000; // di norma 5 sec x refresh...
/// <summary>
/// ultimo tentativo riavvio...
/// </summary>
protected DateTime lastStartTry;
/// <summary>
/// oggetto logging
/// </summary>
public static Logger lg;
#endregion
public MainForm()
{
InitializeComponent();
myInit();
}
private void myInit()
{
lblStatus.Text = "Loading";
lastStartTry = DateTime.Now;
// fix icon!
Icon = Icon.ExtractAssociatedIcon(defIconFilePath);
notifyIcon1.Icon = Icon.ExtractAssociatedIcon(defIconFilePath);
// fix versione!
lblApp.Text = string.Format("{0}", ConfigurationManager.AppSettings.Get("appName"));
lblVers.Text = string.Format(" v.{0}", System.Reflection.Assembly.GetExecutingAssembly().GetName().Version);
startTimerMs = utils.CRI("startTimerMs");
#if DEBUG
// Setup the logging view for Sentinel - http://sentinel.codeplex.com
var sentinalTarget = new NLogViewerTarget()
{
Name = "sentinal",
Address = "udp://127.0.0.1:9999",
IncludeNLogData = false
};
var sentinalRule = new LoggingRule("*", LogLevel.Trace, sentinalTarget);
LogManager.Configuration.AddTarget("sentinal", sentinalTarget);
LogManager.Configuration.LoggingRules.Add(sentinalRule);
#endif
LogManager.ReconfigExistingLoggers();
lg = LogManager.GetCurrentClassLogger();
displayTaskAndWait("Starting MainForm");
// se abilitato autoload conf leggo file corretto...
if (utils.CRB("autoLoadConf"))
{
//loadXmlFile(defConfFilePath);
lg.Info("XML LOADED");
//loadPersistLayer(defPersLayerFile);
lg.Info("PersLayerFile READ");
//agObj.loadPersData();
lg.Info("PersLayerFile LOADED");
}
else
{
//// definisco e avvio tipo adapter generico
//tipoScelto = tipoAdapter.ND;
//adpConf = new AdapterConf();
//loadAdapterType();
displayTaskAndWait("Waiting for config file selection");
}
// Start timer periodico
gather.Interval = utils.CRI("timerIntMs");
gather.Enabled = true;
displayTaskAndWait("Running");
createTrayMenu();
displayTaskAndWait("Tray Menu OK");
// avvio minimizzato se richiesto
if (utils.CRB("startMinimized"))
{
// imposto minimized se necessario!
if (WindowState != FormWindowState.Minimized)
{
WindowState = FormWindowState.Minimized;
}
displayTaskAndWait("Minimized");
}
displayTaskAndWait("Main Form OK");
}
/// <summary>
/// Verifica finale a fine show...
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MainForm_Shown(object sender, EventArgs e)
{
// avvio minimizzato se richiesto
if (utils.CRB("startMinimized"))
{
// controllo e mando a tray...
sendToTray();
}
displayTaskAndWait("Main Form SHOWN");
}
/// <summary>
/// mostra un testo sulla status bar ed attende startTimerMs
/// </summary>
/// <param name="txt2show"></param>
public void displayTaskAndWait(string txt2show)
{
lblStatus.Text = txt2show;
lg.Info(txt2show);
Thread.Sleep(startTimerMs);
}
/// <summary>
/// crea menù tray x applicazione
/// </summary>
private void createTrayMenu()
{
// Fix testi menù tray...
trayMenu.Items.Clear();
// SE permessa massimizzazione...
if (utils.CRB("windowCanMax"))
{
trayMenu.Items.Add("Show MTC-ADB");
}
// se è permesso tray close...
if (utils.CRB("trayClose"))
{
trayMenu.Items.Add("Close MTC-ADB");
}
}
/// <summary>
/// doppio click su tray icon
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void notifyIcon1_DoubleClick(object sender, EventArgs e)
{
// SOLO SE PERMESSO mostrare full...
if (utils.CRB("windowCanMax"))
{
Show();
WindowState = FormWindowState.Normal;
}
}
/// <summary>
/// evento resize
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MainForm_Resize(object sender, EventArgs e)
{
checkFormVisibility();
}
/// <summary>
/// Verifica stato windows (minimized/normal) e visibilità con tray...
/// </summary>
private void checkFormVisibility()
{
// se non può massimizzare imposto COMUNQUE a minimized...
if (!utils.CRB("windowCanMax"))
{
WindowState = FormWindowState.Minimized;
}
// controllo cosa devo mostrare...
if (WindowState == FormWindowState.Minimized)
{
notifyIcon1.Visible = false;
sendToTray();
}
else
{
notifyIcon1.Visible = false;
}
}
/// <summary>
/// Gestisce "andata nel tray" della form
/// </summary>
private void sendToTray()
{
if (!notifyIcon1.Visible)
{
notifyIcon1.BalloonTipTitle = utils.CRS("appName");
notifyIcon1.BalloonTipText = string.Format("{0} running on tray", utils.CRS("appName"));
notifyIcon1.Visible = true;
notifyIcon1.ShowBalloonTip(100);
}
Hide();
}
/// <summary>
/// click su menù contestuale in tray
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void trayMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
if (e.ClickedItem.Text.StartsWith("Close"))
{
// stop adapter...
closeAdapter();
// chiudo!
Close();
}
else if (e.ClickedItem.Text.StartsWith("Show"))
{
if (utils.CRB("windowCanMax"))
{
Show();
WindowState = FormWindowState.Normal;
}
}
}
protected string defConfFilePath
{
get
{
return string.Format(@"{0}\{1}", utils.confDir, utils.CRS("defaultConfFile"));
}
}
/// <summary>
/// File persistenza generale
/// </summary>
protected string defPersLayerFile
{
get
{
return string.Format(@"{0}\{1}", utils.dataDatDir, utils.CRS("defaultPersLayerFile"));
}
}
protected string defIconFilePath
{
get
{
return string.Format(@"{0}\MTCA.ico", utils.resxDir);
}
}
/// <summary>
/// carica adapter richiesto
/// </summary>
private void loadAdapterType()
{
#if false
switch (tipoScelto)
{
case tipoAdapter.DEMO:
agObj = new AdapterDemo(this, adpConf);
EnableTab(tabCtrlMain.TabPages[1], true);
EnableTab(tabCtrlMain.TabPages[2], true);
start.Enabled = true;
break;
case tipoAdapter.ESAGV:
agObj = new AdapterESA(this, adpConf);
EnableTab(tabCtrlMain.TabPages[1], true);
EnableTab(tabCtrlMain.TabPages[2], false);
start.Enabled = true;
break;
case tipoAdapter.FANUC:
agObj = new AdapterFanuc(this, adpConf);
EnableTab(tabCtrlMain.TabPages[1], true);
EnableTab(tabCtrlMain.TabPages[2], false);
start.Enabled = true;
break;
case tipoAdapter.OSAI:
agObj = new AdapterOsai(this, adpConf);
EnableTab(tabCtrlMain.TabPages[1], true);
EnableTab(tabCtrlMain.TabPages[2], false);
start.Enabled = true;
break;
case tipoAdapter.SIEMENS:
agObj = new AdapterSiemens(this, adpConf);
EnableTab(tabCtrlMain.TabPages[1], true);
EnableTab(tabCtrlMain.TabPages[2], false);
start.Enabled = true;
break;
case tipoAdapter.ND:
default:
agObj = new AdapterDemo(this, adpConf);
EnableTab(tabCtrlMain.TabPages[1], false);
EnableTab(tabCtrlMain.TabPages[2], false);
start.Enabled = false;
break;
}
lblCurrAdapt.Text = string.Format("Adapter loaded: {0}", tipoScelto.ToString().ToUpper());
// carico i default values su interfaccia
setDefaults();
displayTaskAndWait(string.Format("Caricata conf per adapter {0}", tipoScelto));
#endif
}
/// <summary>
/// impostazione valori defaults
/// </summary>
private void setDefaults()
{
MainProgrBar.Minimum = 0;
MainProgrBar.Maximum = 1000;
MainProgrBar.Value = 0;
MainProgrBar.Step = 1;
}
/// <summary>
/// Avvio dell'adapter
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void start_Click(object sender, EventArgs e)
{
avviaAdapter();
#if false
agObj.loadPersData();
#endif
// salvo che ho avviato adapter
lg.Info("Completato LOAD Adapter");
}
public void avviaAdapter()
{
displayTaskAndWait("Adapter starting");
#if false
int porta = Convert.ToInt32(port.Text);
agObj.startAdapter(porta);
displayTaskAndWait("Adapter started!");
// fix buttons start/stop/dump
start.Enabled = false;
stop.Enabled = true;
dump.Enabled = true;
if (utils.CRB("openDumpOnStart"))
{
displayTaskAndWait("Dump Window starting");
apriDumpAgent();
displayTaskAndWait("Dump Windows OK");
}
displayTaskAndWait("Start Timers");
// inizializzo contatori fast/mid/slow
fastCount = utils.CRI("fastCount");
normCount = utils.CRI("normCount");
slowCount = utils.CRI("slowCount");
alarmSyncCount = utils.CRI("alarmSyncCount");
displayTaskAndWait("Adapter Running...");
// forzo check allarmi..
agObj.forceAlarmCheck();
#endif
}
/// <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
lg.Info("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);
}
private void gather_Tick(object sender, EventArgs e)
{
#if false
// eseguo cicli attivi SOLO se adapter è in EFFETTIVO running...
if (agObj.adpRunning)
{
// inizio a riportare che sto eseguendo..
advProgBar();
if (agObj.connectionOk)
{
// check esecuzione FastTask
checkFastTask();
// check esecuzione NormTask
checkNormTask();
// check esecuzione SlowTask
checkSlowTask();
// check esecuzione AlarmSync
checkAlarmSync();
}
else
{
double currWait = DateTime.Now.Subtract(lastStartTry).TotalMilliseconds;
if (agObj.adpTryRestart && currWait > utils.CRI("waitRecMSec"))
{
lastStartTry = DateTime.Now;
agObj.tryConnect();
agObj.loadPersData();
}
}
// se è arrivato a MAX resetto...
if (MainProgrBar.Value >= MainProgrBar.Maximum)
{
MainProgrBar.Value = 0;
}
}
else
{
// 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 (agObj.adpTryRestart && currWait > utils.CRI("waitRecMSec"))
{
lastStartTry = DateTime.Now;
avviaAdapter();
agObj.loadPersData();
}
}
#endif
}
public void resetProgBar()
{
MainProgrBar.Value = 0;
}
private void checkAlarmSync()
{
#if false
alarmSyncCount--;
if (alarmSyncCount <= 0)
{
alarmSyncCount = utils.CRI("alarmSyncCount");
// avvio fase raccolta dati e invio con adapter
agObj.gaterAndSend(gatherCycle.VLF);
}
#endif
}
private void checkSlowTask()
{
#if false
slowCount--;
if (slowCount <= 0)
{
slowCount = utils.CRI("slowCount");
// avvio fase raccolta dati e invio con adapter
agObj.gaterAndSend(gatherCycle.LF);
// refresh stringhe code M/S/T
refreshCodeMST();
// effettua salvataggio del file di conf con i valori ATTUALI dei parametri ove applicabile/aggiornati (es ore utilizzo, KM assi percorsi...) --> sia file corrente che file "history"
persistData();
}
#endif
}
/// <summary>
/// file persistenza generale
/// </summary>
public string histPersLayerFile
{
get
{
return string.Format(@"{0}\{1:yyyy}\{1:yyyy-MM-dd}.mtc", utils.dataDatDir, DateTime.Now);
}
}
/// <summary>
/// file persistenza generale data attuale ANTICIPATA di xx giorni
/// </summary>
/// <param name="numDD">num DD di anticipo</param>
/// <returns></returns>
public string prevPersLayerFile(int numDD)
{
return string.Format(@"{0}\{1:yyyy}\{1:yyyy-MM-dd}.mtc", utils.dataDatDir, DateTime.Now.AddDays(-numDD));
}
/// <summary>
/// salva i valori attuali del file di conf sia in file corrente che in cartella valori storici
/// </summary>
public void persistData()
{
// salvo ogni "autoSaveSec" secondi dall'ultimo salvataggio...
TimeSpan tempoMod = new TimeSpan(0);
if (File.Exists(defPersLayerFile))
{
DateTime adesso = DateTime.Now;
tempoMod = DateTime.Now.Subtract(File.GetLastWriteTime(defPersLayerFile));
}
if (tempoMod.TotalSeconds > utils.CRI("autoSaveSec"))
{
savePersistLayer(defPersLayerFile);
savePersistLayer(histPersLayerFile);
}
}
private void checkNormTask()
{
// decremento...
normCount--;
// se il counter è a zero eseguo...
if (normCount <= 0)
{
normCount = utils.CRI("normCount");
#if false
// avvio fase raccolta dati e invio con adapter
agObj.gaterAndSend(gatherCycle.MF);
#endif
}
}
/// <summary>
/// Avanza la barra di stato...
/// </summary>
public void advProgBar()
{
try
{
MainProgrBar.PerformStep();
}
catch
{ }
}
private void checkFastTask()
{
#if false
// decremento...
fastCount--;
// se il counter è a zero eseguo...
if (fastCount <= 0)
{
fastCount = utils.CRI("fastCount");
// avvio fase raccolta dati e invio con adapter
agObj.gaterAndSend(gatherCycle.HF);
refreshVisualStrobes();
}
#endif
}
private void message_Leave(object sender, EventArgs e)
{
}
// apro eseguibile dump
private void dump_Click(object sender, EventArgs e)
{
apriDumpAgent();
}
/// <summary>
/// apre agent di dump in CMD
/// </summary>
private static void apriDumpAgent()
{
string path = Application.StartupPath;
try
{
Process.Start(string.Format(@"{0}\..\..\dump\dump.exe", path));
}
catch
{
Process.Start(string.Format(@"{0}\dump\dump.exe", path));
}
}
/// <summary>
/// Carica file XML della configurazione richiesta
/// </summary>
/// <param name="XmlConfFile"></param>
private void loadXmlFile(string XmlConfFile)
{
#if false
displayTaskAndWait(string.Format("Loading XML: {0}", XmlConfFile));
// Read the configuration object from a file
adpConf = AdapterConf.Deserialize(XmlConfFile);
// indico quale sia il tipo di adapter
tipoScelto = adpConf.TipoAdapt;
loadAdapterType();
// carico file XML in web browser...
wbXmlConf.DocumentText = AdapterConf.rawXml(XmlConfFile);
displayTaskAndWait("XML loaded");
// avvio macchina con adapter specificato...
if (utils.CRB("autoStartOnLoad"))
{
displayTaskAndWait("Auto Starting...");
// avvio!
avviaAdapter();
displayTaskAndWait("Auto Started!");
}
#endif
}
/// <summary>
/// salva su file l'oggetto AdapterConf
/// </summary>
/// <param name="XmlConfFile"></param>
public void saveXmlFile(string XmlConfFile)
{
#if false
AdapterConf.Serialize(XmlConfFile, agObj.currAdpConf);
#endif
}
/// <summary>
/// Salva su file l'oggetto di persistenza dati
/// </summary>
/// <param name="filePath"></param>
public void savePersistLayer(string filePath)
{
#if false
// in primis check semaforo salvataggio...
if (!agObj.adpSaving)
{
// alzo semaforo salvataggio
agObj.adpSaving = true;
// se HO dei dati...
if (agObj.persistenceLayer != null)
{
try
{
utils.WritePlain(agObj.persistenceLayer, filePath);
}
catch (Exception exc)
{
lg.Error(string.Format("Errore salvataggio file{0}{1}", Environment.NewLine, exc));
}
}
else
{
lg.Info("persistenceLayer null, non salvato...");
}
// abbasso semaforo salvataggio
agObj.adpSaving = false;
}
#endif
}
/// <summary>
/// Carica da file l'oggetto di persistenza dati
/// </summary>
/// <param name="filePath"></param>
public void loadPersistLayer(string filePath)
{
#if false
// inizializzo prima di leggere...
agObj.persistenceLayer = new Dictionary<string, string>();
agObj.persistenceLayer = utils.ReadPlain(filePath);
// 2017.03.23 check problema files corrotti...
if (agObj.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(prevPersLayerFile(numDD));
}
catch
{ }
numDD++;
}
// se sono uscito PROVO a passare il file storico letto buono (oppure vuoto...)
agObj.persistenceLayer = lastRead;
}
#endif
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
closeAdapter();
}
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)
{
#if false
agObj.stopAdapter(tryRestart);
// salvo!
savePersistLayer(defPersLayerFile);
savePersistLayer(histPersLayerFile);
stop.Enabled = false;
dump.Enabled = false;
start.Enabled = true;
if (stopTimer)
{
gather.Enabled = false;
agObj.tryDisconnect();
}
#endif
}
}
}