using AutoUpdaterDotNET;
using IOB_UT;
using MapoSDK;
using Newtonsoft.Json;
using NLog;
using NLog.Config;
using NLog.Targets;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Threading;
using System.Windows.Forms;
namespace IOB_WIN
{
public partial class MainForm : Form
{
#region variabili globali, utils ed helpers
///
/// Oggetto connessioen REDIS
///
public RedisIobCache redisMan;
///
/// Parametri (opzionali) di avvio
///
protected string[] myArgs;
///
/// Dizionario dei parametri di avvio (da elenco args...)
///
protected Dictionary startParams = new Dictionary();
///
/// Modalità di avvio
///
protected StartMode ModoAvvio = StartMode.STD;
///
/// Ramo applicazione (x update)
///
protected string branchName = "master";
///
/// Indirizzo server
///
protected string MPIP = "";
///
/// URL base applicazione
///
protected string MPURL = "";
///
/// chiamata x check alive di base
///
protected string CMDALIVE = "";
///
/// chiamata x invio comunicazioen reboot dell'IOBMAN
///
protected string CMDREBO = "";
///
/// chiamata x ricevere un codice IOB da gestire/acquisire
///
protected string CMDIOB2CALL = "";
///
/// Num max di CNC da gestire
///
protected int MAXCNC = 1;
///
/// Lista delle IOB da avviare
///
protected List IOB2START;
///
/// oggetto logging
///
public static Logger lg;
///
/// Data Avvio form
///
protected DateTime formStartTime;
///
/// Data ultimo controllo comunicazione
///
public DateTime lastComCheck;
///
/// mostra un testo sulla status bar + LOG
///
///
public void displayTaskAndLog(string txt2show)
{
lblStatus.Text = txt2show;
lblStatus.Invalidate();
lgInfo(txt2show);
}
///
/// Mostra update delle statistiche di comunicazione (num plc connessi, indirizzo server) con colore ad indicare anomalie...
///
///
///
///
public void updateComStats(int numPLC, int numAttivi, bool serverOk)
{
// testo
lblComStats.Text = $"{numAttivi}/{numPLC} PLC --> {MPIP} (MP/IO)";
// colore secondo valori... server !="ND" è ok, PLC > 0 è OK
int score = 0;
if (serverOk)
{
score++;
}
if (numPLC > 0 && numAttivi == numPLC)
{
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;
}
}
///
/// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere...
///
///
protected void lgInfo(string txt2log)
{
lg.Factory.Configuration.Variables["codIOB"] = "MAIN";
lg.Info(txt2log);
}
///
/// Effettua logging ERROR corretto impostanto anche la variabile IOB prima di scrivere...
///
///
protected void lgError(string txt2log)
{
lg.Factory.Configuration.Variables["codIOB"] = "MAIN";
lg.Error(txt2log);
}
#endregion
#region gestione update
///
/// var x gestione reset progBar... arrivato a 3 faccio reset
///
protected int resetProgBar = 0;
///
/// URL stringa di UPDATE...
///
protected string updateUrl
{
get
{
return string.Format("http://seriate.steamware.net:8083/SWS/MAPO/IOB-WIN/{0}/manifest.xml", branchName);
}
}
///
/// IP del PC
///
protected string currIP
{
get
{
string answ = "127.0.0.1";
return answ;
}
}
///
/// URL per segnalazione reboot...
///
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;
}
}
///
/// URL per chiedere quale sia la IOB da acquisire/gestire (se c'è...)
///
protected string urlIob2call
{
get
{
string answ = "";
try
{
answ = string.Format(@"http://{0}{1}{2}{3}", MPIP, MPURL, CMDIOB2CALL, utils.GetIP());
}
catch
{ }
return answ;
}
}
///
/// URL per recuperare i file dell'IOB (SENZA IOB)
///
protected string urlDownloadFile
{
get
{
string answ = "";
try
{
answ = string.Format(@"http://{0}{1}/IOB/getFiles/", MPIP, MPURL);
}
catch
{ }
return answ;
}
}
///
/// URL per recuperare i file dell'IOB su CLOUD (SENZA IOB)
///
protected string urlDownloadFileCloud
{
get
{
return @"http://seriate.steamware.net:8083/MP/IO/IOB/getFiles/";
}
}
///
/// URL per salvare i file dell'IOB (SENZA IOB)
///
protected string urlUploadFile
{
get
{
string answ = "";
try
{
answ = string.Format(@"http://{0}{1}/IOB/uploadFile/", MPIP, MPURL);
}
catch
{ }
return answ;
}
}
///
/// URL per salvare i file dell'IOB su CLOUD (SENZA IOB)
///
protected string urlUploadFileCloud
{
get
{
return @"http://seriate.steamware.net:8083/MP/IO/IOB/uploadFile/";
}
}
///
/// Richeista verifica update
///
///
///
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.ReportErrors = false;
AutoUpdater.DownloadPath = @"C:\Steamware\src\";
AutoUpdater.ApplicationExitEvent += AutoUpdater_ApplicationExitEvent;
AutoUpdater.Start(updateUrl);
}
private void AutoUpdater_ApplicationExitEvent()
{
displayTaskAndLog("Chiusura Adapters");
Thread.Sleep(100);
// chiudo tutto
closeAllChild();
displayTaskAndLog("Chiusura Applicazione");
// attendo 1 sec...
Thread.Sleep(1000);
// ESCO!
Application.Exit();
}
#endregion
#region init form
///
/// Init Main Form
///
public MainForm(string[] args)
{
// salvo aprametri avvio...
saveArgs(args);
// continuo iNIT!!!
InitializeComponent();
myInit();
if (args != null)
{
if (args.Length > 0)
{
lgInfo("Argomenti di avvio:");
foreach (var item in myArgs)
{
lgInfo(item);
}
}
else
{
lgInfo("NESSUN Argomento di avvio trovato");
}
}
}
///
/// effettua salvataggio argomenti
///
///
protected void saveArgs(string[] args)
{
if (args != null)
{
// salvo args di avvio (sono parametri tipo param1=val1 param2=test1,test2,test3
myArgs = args;
if (myArgs.Length > 0)
{
// salvo dictionary!
foreach (var item in myArgs)
{
var kvp = item.Split('=');
startParams.Add(kvp[0], kvp[1]);
}
}
// verifico gli args...
if (startParams.ContainsKey("MODE"))
{
try
{
ModoAvvio = (StartMode)Enum.Parse(typeof(StartMode), startParams["MODE"]);
}
catch
{ }
}
}
}
protected void myInit()
{
DateTime adesso = DateTime.Now;
resetProgBar = 0;
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 = $"{ConfigurationManager.AppSettings.Get("appName")} ({ModoAvvio})";
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"))
{
try
{
loadIniFile(utils.mainConfFilePath);
lgInfo("INI LOADED");
// avvio child come richiesto!
startAdapters();
}
catch (Exception exc)
{
displayTaskAndLog(string.Format("Eccezione in myInit: {0}", exc));
}
}
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");
}
///
/// test ping all'indirizzo impostato nei parametri
///
///
private IPStatus testPingServer
{
get
{
IPStatus answ = IPStatus.Unknown;
IPAddress address;
PingReply reply;
Ping pingSender = new Ping();
address = IPAddress.Loopback;
string ipAdrr = MPIP;
IPAddress.TryParse(ipAdrr, out address);
try
{
reply = pingSender.Send(address, 500);
answ = reply.Status;
}
catch (Exception exc)
{
lgError($"testPingServer EXCEPTION in fase di ping{Environment.NewLine}{exc}");
}
return answ;
}
}
///
/// Avvio gli adapters richeisti
///
private void startAdapters()
{
// avvio child richiesti
foreach (var item in IOB2START)
{
openChild(item);
}
}
///
/// Carica file ini della configurazione richiesta
///
///
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", "");
// Gestione IOB da avviare
IOB2START = new List();
// SE se sono in modo UPD --> nessuno
if (ModoAvvio == StartMode.UPD)
{
IOB2START.Add("NONE");
}
else
{
string[] elenco = null;
// se modalità MAN CERCO se sostituire STARTLIST
if (ModoAvvio == StartMode.MAN)
{
if (!string.IsNullOrEmpty(startParams["IOB"]))
{
STARTLIST = startParams["IOB"];
}
}
// se ho qualcosa...
if (!string.IsNullOrEmpty(STARTLIST))
{
elenco = STARTLIST.Split(',');
// inserisco da elenco!
foreach (var item in elenco)
{
IOB2START.Add(item);
}
}
else
{
IOB2START.Add("NONE");
}
}
// init redis...
string firstIob = "00";
if (IOB2START.Count > 0)
{
firstIob = IOB2START[0];
}
redisMan = new RedisIobCache(MPIP, firstIob);
}
#endregion
#region check comunicazione
///
/// Visualizzazione stato di comunicazione attiva con PLC
///
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();
}
}
///
/// Effettua verifiche varie comunicazione verso PLC e verso server
///
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