Files
Mapo-IOB-WIN/IOB-WIN/MainForm.cs
T
2018-11-18 16:45:52 +01:00

724 lines
19 KiB
C#

using AutoUpdaterDotNET;
using IOB_UT;
using NLog;
using NLog.Config;
using NLog.Targets;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Windows.Forms;
namespace IOB_WIN
{
public partial class MainForm : Form
{
#region variabili globali, utils ed helpers
/// <summary>
/// Ramo applicazione (x update)
/// </summary>
protected string branchName = "master";
/// <summary>
/// Indirizzo server
/// </summary>
protected string MPIP = "";
/// <summary>
/// URL base applicazione
/// </summary>
protected string MPURL = "";
/// <summary>
/// chiamata x check alive di base
/// </summary>
protected string CMDALIVE = "";
/// <summary>
/// chiamata x invio comunicazioen reboot dell'IOBMAN
/// </summary>
protected string CMDREBO = "";
/// <summary>
/// chiamata x ricevere un codice IOB da gestire/acquisire
/// </summary>
protected string CMDIOB2CALL = "";
/// <summary>
/// Num max di CNC da gestire
/// </summary>
protected int MAXCNC = 1;
/// <summary>
/// Lista delle IOB da avviare
/// </summary>
protected List<string> IOB2START;
/// <summary>
/// oggetto logging
/// </summary>
public static Logger lg;
/// <summary>
/// Data Avvio form
/// </summary>
protected DateTime formStartTime;
/// <summary>
/// Data ultimo controllo comunicazione
/// </summary>
public DateTime lastComCheck;
/// <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 (num plc connessi, indirizzo server) con colore ad indicare anomalie...
/// </summary>
/// <param name="numPLC"></param>
/// <param name="serverOk"></param>
public void updateComStats(int numPLC, bool serverOk)
{
// testo
lblComStats.Text = string.Format("{0} PLC --> {1} (MP/IO)", numPLC, MPIP);
// colore secondo valori... server !="ND" è ok, PLC > 0 è OK
int score = 0;
if (serverOk)
{
score++;
}
if (numPLC > 0)
{
score++;
}
switch (score)
{
case 0:
lblComStats.ForeColor = Color.Red;
break;
case 1:
lblComStats.ForeColor = Color.Orange;
break;
case 2:
lblComStats.ForeColor = Color.Green;
break;
default:
lblComStats.ForeColor = Color.Gray;
break;
}
}
/// <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"] = "MAIN";
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"] = "MAIN";
lg.Error(txt2log);
}
#endregion
#region gestione update
/// <summary>
/// URL stringa di UPDATE...
/// </summary>
protected string updateUrl
{
get
{
return string.Format("http://seriate.steamware.net:8083/SWS/MAPO/IOB-WIN/{0}/manifest.xml", branchName);
}
}
/// <summary>
/// IP del PC
/// </summary>
protected string currIP
{
get
{
string answ = "127.0.0.1";
return answ;
}
}
/// <summary>
/// URL per segnalazione reboot...
/// </summary>
protected string urlReboot
{
get
{
string answ = "";
try
{
answ = string.Format(@"http://{0}{1}{2}{3}&mac={4}", MPIP, MPURL, CMDREBO, utils.GetIP(), utils.GetMACAddress());
}
catch
{
answ = string.Format(@"http://{0}{1}{2}{3}", MPIP, MPURL, CMDREBO, utils.GetIP());
}
return answ;
}
}
/// <summary>
/// URL per chiedere quale sia la IOB da acquisire/gestire (se c'è...)
/// </summary>
protected string urlIob2call
{
get
{
string answ = "";
try
{
answ = string.Format(@"http://{0}{1}{2}{3}", MPIP, MPURL, CMDIOB2CALL, utils.GetIP());
}
catch
{ }
return answ;
}
}
/// <summary>
/// Richeista verifica update
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void mCheckUpdates_Click(object sender, EventArgs e)
{
lg.Info(string.Format("Avvio procedura controllo update:{0}branch: {1} | url: {2}", Environment.NewLine, branchName, updateUrl));
// avvio controllo
AutoUpdater.ShowSkipButton = false;
AutoUpdater.ShowRemindLaterButton = false;
AutoUpdater.RunUpdateAsAdmin = utils.CRB("AUpdAsAdm");
AutoUpdater.Start(updateUrl);
}
#endregion
#region init form
public MainForm()
{
InitializeComponent();
myInit();
}
protected void myInit()
{
DateTime adesso = DateTime.Now;
formStartTime = adesso;
lastComCheck = adesso.AddHours(-1);
lblStatus.Text = "Loading";
// fix icon!
notifyIcon1.Text = string.Format("IOB-WIN | {0}", System.Reflection.Assembly.GetExecutingAssembly().GetName().Version);
Icon = Icon.ExtractAssociatedIcon(utils.defIconFilePath);
notifyIcon1.Icon = Icon.ExtractAssociatedIcon(utils.defIconFilePath);
// fix versione!
lblApp.Text = string.Format("{0}", ConfigurationManager.AppSettings.Get("appName"));
lblVers.Text = string.Format(" v.{0}", System.Reflection.Assembly.GetExecutingAssembly().GetName().Version);
#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"))
{
loadIniFile(utils.mainConfFilePath);
lgInfo("INI LOADED");
// avvio child come richiesto!
startAdapters();
}
else
{
displayTaskAndLog("Waiting for config file selection");
}
displayTaskAndLog("Program Running");
createTrayMenu();
displayTaskAndLog("Tray Menu OK");
// avvio minimizzato se richiesto
if (utils.CRB("startMinimized"))
{
// imposto minimized se necessario!
if (WindowState != FormWindowState.Minimized)
{
WindowState = FormWindowState.Minimized;
}
displayTaskAndLog("Minimized");
}
try
{
IPStatus pingStatus = testPingServer();
// se passa il ping faccio il resto...
if (pingStatus == IPStatus.Success)
{
// segnalo reboot (programma)...
utils.callUrl(urlReboot);
}
else
{
displayTaskAndLog("Server unreachable, cannot send urlReboot for MAIN FORM");
}
}
catch (Exception exc)
{
lgError(string.Format("MainForm myInit EXCEPTION in fase di chiamata URL di reboot:{0}{1}{2}", urlReboot, Environment.NewLine, exc));
}
displayTaskAndLog("Main Form OK");
}
/// <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 = MPIP;
IPAddress.TryParse(ipAdrr, out address);
reply = pingSender.Send(address, 100);
answ = reply.Status;
return answ;
}
/// <summary>
/// Avvio gli adapters richeisti
/// </summary>
private void startAdapters()
{
// avvio child richiesti
foreach (var item in IOB2START)
{
openChild(item);
}
}
/// <summary>
/// Carica file ini della configurazione richiesta
/// </summary>
/// <param name="iniConfFile"></param>
private void loadIniFile(string iniConfFile)
{
displayTaskAndLog(string.Format("Loading iniConfFile: {0}", iniConfFile));
IniFile fIni = new IniFile(iniConfFile);
// salvo valori letti da INI file...
branchName = fIni.ReadString("BRANCH", "NAME", "master");
MPIP = fIni.ReadString("SERVER", "MPIP", "ND");
MPURL = fIni.ReadString("SERVER", "MPURL", "/MP/IO");
CMDALIVE = fIni.ReadString("SERVER", "CMDALIVE", "/IOB");
CMDREBO = fIni.ReadString("SERVER", "CMDREBO", "/IOB/sendRebootGateway?GWIP=");
CMDIOB2CALL = fIni.ReadString("SERVER", "CMDIOB2CALL", "/IOB/getIob2call?GWIP=");
MAXCNC = fIni.ReadInteger("IOB", "MAXCNC", 1);
string STARTLIST = fIni.ReadString("IOB", "STARTLIST", "");
if (STARTLIST != "")
{
IOB2START = new List<string>();
string[] elenco = STARTLIST.Split(',');
foreach (var item in elenco)
{
IOB2START.Add(item);
}
}
// se NON sono in DEBUG faccio check update...
#if !(DEBUG)
// avvio autoupdater...
AutoUpdater.RunUpdateAsAdmin = utils.CRB("AUpdAsAdm");
AutoUpdater.Start(updateUrl);
#endif
}
#endregion
#region check comunicazione
/// <summary>
/// Visualizzazione stato di comunicazione attiva con PLC
/// </summary>
public bool commPlcActive
{
set
{
// se true --> comunica/verde, altrimenti grigio
lblApp.ForeColor = value ? Color.SeaGreen : Color.Black;
lblVers.ForeColor = value ? Color.SeaGreen : Color.DarkSlateGray;
statusStrip1.Refresh();
}
}
/// <summary>
/// Effettua verifiche varie comunicazione verso PLC e verso server
/// </summary>
private void checkCom()
{
// eseguo update se è passato almeno comCheckTOut secondi da ultimo check...
if (DateTime.Now.Subtract(lastComCheck).TotalSeconds > utils.CRI("comCheckTOut"))
{
lastComCheck = DateTime.Now;
// conta quanti child form di adapter verso PLC siano aperti !!!FARE!!! chiedere con un metodo che siano ATTIVI e contare quello...
int numPLC = this.MdiChildren.Count<Form>();
// update stato!
updateComStats(numPLC, testServer);
}
}
/// <summary>
/// Verifica il server: esiste IP, risponde a ping, risponde a pagina ALIVE
/// </summary>
protected bool testServer
{
get
{
bool answ = false;
// check server: indirizzo esiste
if (MPIP != "")
{
IPAddress address = IPAddress.Loopback;
// check stato server (SOLO PING!)
IPAddress.TryParse(MPIP, out address);
if (address != IPAddress.Loopback)
{
answ = utils.pingAddress(address);
}
}
return answ;
}
}
#endregion
#region gestione child form
/// <summary>
/// CHiude le finestre child attive
/// </summary>
protected void closeActiveChild()
{
if (this.HasChildren)
{
try
{
this.ActiveMdiChild.Close();
this.LayoutMdi(MdiLayout.TileHorizontal);
}
catch
{ }
}
}
/// <summary>
/// Apre la finestra child con conf
/// </summary>
protected void openChild(string IOB)
{
if (IOB == null)
{
throw new ArgumentNullException(nameof(IOB));
}
AdapterForm child = new AdapterForm(IOB);
child.MdiParent = this;
child.Text = IOB;
child.Show();
child.Shown += Child_Shown;
child.FormClosed += Child_FormClosed;
}
/// <summary>
/// FIx finestre restanti post chiusura di una finestra...
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Child_FormClosed(object sender, FormClosedEventArgs e)
{
this.LayoutMdi(MdiLayout.TileHorizontal);
}
/// <summary>
/// Sistemazione finestre POST visualizzazione...
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Child_Shown(object sender, EventArgs e)
{
this.LayoutMdi(MdiLayout.TileHorizontal);
}
//private void closeChildToolStripMenuItem_Click(object sender, EventArgs e)
//{
// closeActiveChild();
//}
//private void openChildToolStripMenuItem_Click(object sender, EventArgs e)
//{
// openNewChild();
//}
/// <summary>
/// Effettua apertura di una nuova finestra CHILD
/// </summary>
private void openNewChild()
{
// IOB di default...
string reqIOB = "";
// richiede al server COSA aprire
try
{
reqIOB = utils.callUrl(urlIob2call);
}
catch (Exception exc)
{
reqIOB = utils.CRS("defIOB");
displayTaskAndLog(string.Format("Apertura IOB di default da CRS (fallita chiamata a server):{0}{1}", Environment.NewLine, exc));
}
if (reqIOB == "")
{
reqIOB = utils.CRS("defIOB");
}
// se non ottiene risposta apre la demo...
openChild(reqIOB);
}
/// <summary>
/// Chiusura applicazione
/// </summary>
private void closeAllChild()
{
// ferma tutti i child form...
foreach (var ChildForm in this.MdiChildren)
{
try
{
ChildForm.Close();
}
catch
{ }
}
}
private void uploadIOBConfToolStripMenuItem_Click(object sender, EventArgs e)
{
// !!!FARE!!!
// upload su server i file CONF delle IOB attive
}
private void downloadIOBConfToolStripMenuItem_Click(object sender, EventArgs e)
{
// !!!FARE!!!
// download da su server di TUTTI i file CONF delle IOB
}
private void sendIOBAssignmentsToolStripMenuItem_Click(object sender, EventArgs e)
{
// !!!FARE!!!
// salva su server quali IOB siano gestite dal PC (da conf su MAIN...)
}
private void getIOBAssignmentsToolStripMenuItem_Click(object sender, EventArgs e)
{
// !!!FARE!!!
// fa un check su server di quali IOB siano assegnate al PC (e modifica il file MAIN di avvio ripartendo...)
}
#endregion
#region gestione tray
/// <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 IOB-WIN");
}
// se è permesso tray close...
if (utils.CRB("trayClose"))
{
trayMenu.Items.Add("Close IOB-WIN");
}
}
/// <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>
/// 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;
}
// fix child!
this.LayoutMdi(MdiLayout.TileHorizontal);
}
/// <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 child adapters...
closeAllChild();
// chiudo!
Close();
}
else if (e.ClickedItem.Text.StartsWith("Show"))
{
if (utils.CRB("windowCanMax"))
{
Show();
WindowState = FormWindowState.Normal;
}
}
}
#endregion
#region gestione FORM principale
/// <summary>
/// timer principale
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MainTimer_Tick(object sender, EventArgs e)
{
// inizio a riportare che sto funzionando..
advProgBar();
checkCom();
}
/// <summary>
/// Avanza la barra di stato...
/// </summary>
public void advProgBar()
{
try
{
// aggiorno runtime...
TimeSpan uptime = DateTime.Now.Subtract(formStartTime);
tslRunTime.Text = string.Format("Running: {0}gg {1:00}:{2:00}:{3:00}", uptime.Days, uptime.Hours, uptime.Minutes, uptime.Seconds);
// se è arrivato a MAX resetto...
MainProgrBar.PerformStep();
if (MainProgrBar.Value >= MainProgrBar.Maximum)
{
MainProgrBar.Value = 0;
}
MainProgrBar.Invalidate();
}
catch
{ }
}
/// <summary>
/// evento chiusura
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
closeAllChild();
}
/// <summary>
/// evento visualizzazione
/// </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();
}
displayTaskAndLog("Main Form SHOWN");
}
/// <summary>
/// evento resize
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MainForm_Resize(object sender, EventArgs e)
{
checkFormVisibility();
}
#endregion
}
}