Files
2021-07-23 12:22:43 +02:00

2326 lines
84 KiB
C#

/*
* Copyright Copyright 2016+, Steamware s.r.l. & CMS/SCM s.p.a.
*
* Based on data, code and example by MTC consortium & System Insights, Inc.
*
* */
using MTC;
using NLog;
using NLog.Config;
using NLog.Targets;
using SCMA.AdapterCom;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
namespace SCMA
{
public partial class MainForm : 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 alarmSyncCount;
/// <summary>
/// timer base in avvio
/// </summary>
protected int startTimerMs = 250;
/// <summary>
/// ultimo tentativo riavvio...
/// </summary>
protected DateTime lastStartTry;
#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>
AdapterPLC.Generic agObj;
/// <summary>
/// configurazione caricata
/// </summary>
AdapterConf adpConf;
/// <summary>
/// DataModel caricato
/// </summary>
DataModel currDataModel;
/// <summary>
/// tipo di adapter prescelto...
/// </summary>
public tipoAdapter tipoScelto = tipoAdapter.DEMO;
//public Gateway protocollo
#endregion
#region utils ed helpers
public static void EnableTab(TabPage page, bool enable)
{
EnableControls(page.Controls, enable);
}
private static void EnableControls(Control.ControlCollection ctls, bool enable)
{
foreach (Control ctl in ctls)
{
ctl.Enabled = enable;
EnableControls(ctl.Controls, enable);
}
}
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 ed attende startTimerMs
/// </summary>
/// <param name="txt2show"></param>
public void displayTaskAndWait(string txt2show)
{
lblStatus.Text = txt2show;
lg.Info(txt2show);
Thread.Sleep(startTimerMs);
}
/// <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>
/// Gestione form principale
/// </summary>
public MainForm()
{
InitializeComponent();
lblStatus.Text = "Loading";
lastStartTry = DateTime.Now;
// fix icon!
notifyIcon1.Text = string.Format("SCMA | {0}", System.Reflection.Assembly.GetExecutingAssembly().GetName().Version);
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");
// inizio con tab control disabilitati
EnableTab(tabCtrlMain.TabPages[1], false);
EnableTab(tabCtrlMain.TabPages[2], false);
// 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("Program 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>
/// 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 SCMA");
}
// se è permesso tray close...
if (utils.CRB("trayClose"))
{
trayMenu.Items.Add("Close SCMA");
}
}
/// <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;
}
}
}
#endregion
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}\Scma.ico", utils.resxDir);
}
}
/// <summary>
/// carica adapter richiesto
/// </summary>
private void loadAdapterType()
{
Gateway currGateway;
switch (utils.CRS("adpProto"))
{
case "MTC":
currGateway = new GatewayMTC();
break;
case "SOURS":
currGateway = new GatewaySOURS();
break;
case "":
default:
currGateway = new Gateway();
break;
}
// ira inizializzo VERO adapter x tipo controllo e protocollo...
switch (tipoScelto)
{
case tipoAdapter.DEMO:
agObj = new AdapterPLC.Demo(this, adpConf, currGateway);
EnableTab(tabCtrlMain.TabPages[1], true);
EnableTab(tabCtrlMain.TabPages[2], true);
start.Enabled = true;
break;
case tipoAdapter.ESAGVCMS:
agObj = new AdapterPLC.CMS.EsaKosmos(this, adpConf, currGateway);
EnableTab(tabCtrlMain.TabPages[1], true);
EnableTab(tabCtrlMain.TabPages[2], false);
start.Enabled = true;
break;
case tipoAdapter.ESAGVSCM:
agObj = new AdapterPLC.SCM.EsaKvara(this, adpConf, currGateway);
EnableTab(tabCtrlMain.TabPages[1], true);
EnableTab(tabCtrlMain.TabPages[2], false);
start.Enabled = true;
break;
case tipoAdapter.FANUC:
agObj = new AdapterPLC.CMS.Fanuc(this, adpConf, currGateway);
EnableTab(tabCtrlMain.TabPages[1], true);
EnableTab(tabCtrlMain.TabPages[2], false);
start.Enabled = true;
break;
case tipoAdapter.OSAI:
agObj = new AdapterPLC.CMS.Osai(this, adpConf, currGateway);
EnableTab(tabCtrlMain.TabPages[1], true);
EnableTab(tabCtrlMain.TabPages[2], false);
start.Enabled = true;
break;
case tipoAdapter.SIEMENS:
agObj = new AdapterPLC.CMS.Siemens(this, adpConf, currGateway);
EnableTab(tabCtrlMain.TabPages[1], true);
EnableTab(tabCtrlMain.TabPages[2], false);
start.Enabled = true;
break;
case tipoAdapter.ND:
default:
agObj = new AdapterPLC.Demo(this, adpConf, currGateway);
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));
}
/// <summary>
/// impostazione valori defaults
/// </summary>
private void setDefaults()
{
stop.Enabled = false;
dump.Enabled = false;
D1_NAME.Text = "DEMO MACHINE"; // utils.CRS("D1_NAME");
D1_ID.Text = "DEMO ID"; //utils.CRS("D1_ID");
D1_UUID.Text = "DEMO UUID"; // utils.CRS("D1_UUID");
program.Text = "DEMO PRG"; // utils.CRS("D1_PROGRAM");
PROG_ROW_NUM.Text = "0";
partID.Text = "DEMO PART-ID"; // utils.CRS("PartID");
pzOk = 0;
pzKo = 0;
Power = 1000;
AccTime = 1440 * 365;
OPERATOR_ID.Text = "OPxxxx";
STATUS_STRB_DW0.Text = utils.binaryForm(0);
STATUS_STRB_DW1.Text = utils.binaryForm(0);
STATUS_STRB_DW2.Text = utils.binaryForm(0);
STATUS_STRB_DW3.Text = utils.binaryForm(0);
STATUS_ACK_DW0.Text = utils.binaryForm(0);
STATUS_ACK_DW1.Text = utils.binaryForm(0);
STATUS_ACK_DW2.Text = utils.binaryForm(0);
STATUS_ACK_DW3.Text = utils.binaryForm(0);
MainProgrBar.Minimum = 0;
MainProgrBar.Maximum = 1000;
MainProgrBar.Value = 0;
MainProgrBar.Step = 1;
// compilo combobox causali fermo...
string[] contenuto = File.ReadAllLines(utils.confDir + "\\HaltTypeList.map");
System.Collections.Generic.Dictionary<string, string> comboSource = new Dictionary<string, string>();
foreach (var line in contenuto)
{
// se la linea non è commento e non è vuota...
if (line.Length > 0 && line[0] != '#')
{
string[] tokens = line.Split(':');
comboSource.Add(tokens[0], tokens[1]);
}
}
functionalMode.DataSource = new BindingSource(comboSource, null);
functionalMode.DisplayMember = "Value";
functionalMode.ValueMember = "Key";
string[] row = { "0", "0", "0", "0", "0", "0" };
PosAct.Rows.Add(row);
// fix componenti vettoriali PATH, UNOP, ASSI...
for (int i = 0; i < adpConf.nPath; i++)
{
cbPathSel.Items.Insert(i, adpConf.Path[i].ident);
}
if (adpConf.nPath > 0)
{
cbPathSel.SelectedIndex = 0;
}
for (int i = 0; i < adpConf.nUnOp; i++)
{
cbUnOpSel.Items.Insert(i, adpConf.UnOp[i].ident);
}
if (adpConf.nUnOp > 0)
{
cbUnOpSel.SelectedIndex = 0;
}
for (int i = 0; i < adpConf.nAxis; i++)
{
cbAxNum.Items.Insert(i, adpConf.Axis[i].ident);
}
if (adpConf.nAxis > 0)
{
cbAxNum.SelectedIndex = 0;
}
}
/// <summary>
/// Avvio dell'adapter
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void start_Click(object sender, EventArgs e)
{
avviaAdapter();
agObj.loadPersData();
// salvo che ho avviato adapter
lg.Info("Completato LOAD Adapter");
}
public void avviaAdapter()
{
displayTaskAndWait("Adapter starting");
// se NON sta girando...
if (!agObj.adpRunning)
{
agObj.startAdapter();
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();
}
else
{
displayTaskAndWait("Adapter STILL Running...");
}
}
/// <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)
{
// 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();
// check esecuzione SendTask (VHF)
checkSendTask();
if (utils.CRI("waitEndCycle") > 0)
{
Thread.Sleep(utils.CRI("waitEndCycle"));
}
}
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();
}
}
}
public void resetProgBar()
{
MainProgrBar.Value = 0;
}
/// <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();
}
}
private void checkAlarmSync()
{
alarmSyncCount--;
if (alarmSyncCount <= 0)
{
alarmSyncCount = utils.CRI("alarmSyncCount");
// avvio fase raccolta dati e invio con adapter
agObj.gaterAndSend(gatherCycle.VLF);
}
}
private void checkSlowTask()
{
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();
}
}
/// <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");
// avvio fase raccolta dati e invio con adapter
agObj.gaterAndSend(gatherCycle.MF);
}
}
/// <summary>
/// Avanza la barra di stato...
/// </summary>
public void advProgBar()
{
try
{
MainProgrBar.PerformStep();
MainProgrBar.Invalidate();
}
catch
{ }
}
private void checkSendTask()
{
// avvio fase invio con adapter (code MST)
agObj.gaterAndSend(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
agObj.gaterAndSend(gatherCycle.HF);
refreshVisualStrobes();
}
}
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()
{
// solo se sono in modalità MTC...
if (utils.CRS("adpProto") == "MTC")
{
string path = Application.StartupPath;
try
{
Process.Start(string.Format(@"{0}\..\..\dump\dump.exe", path));
}
catch
{
Process.Start(string.Format(@"{0}\dump\dump.exe", path));
}
}
}
#region classi x simulazione valori vari
/// <summary>
/// simula alcuni dati generando ad esempio numeri casuali... SE abilitato e SE adapter è DEMO
/// </summary>
private void simulateData()
{
if (enableDataSim.Checked && tipoScelto == tipoAdapter.DEMO)
{
DateTime adesso = DateTime.Now;
Random rnd = new Random();
// 10% casi cambia riga
if (rnd.Next(0, 100) > 90)
{
PROG_ROW_NUM.Text = rnd.Next(1, 10000).ToString();
}
// cambio posizioni 6% casi: aggiungo codici M
if (rnd.Next(0, 100) > 95)
{
agObj.appendCodeMST("M", rnd.Next(1, 30).ToString(), 0);
}
// cambio posizioni 3% casi: aggiungo codici S
if (rnd.Next(0, 100) > 97)
{
agObj.appendCodeMST("S", rnd.Next(100, 10000).ToString(), 0);
}
// cambio posizioni 3% casi: aggiungo codici T
if (rnd.Next(0, 100) > 97)
{
agObj.appendCodeMST("T", rnd.Next(1, 100).ToString(), 0);
}
// aggiungo 1 pz al totale nel 0.3% dei casi (-->TC circa 333 x tick)...
if (rnd.Next(0, 1000) > 997)
{
pzOk++;
agObj.STROBE_PLC = agObj.STROBE_PLC | Strobe.PZ_OK;
}
// cambio posizioni XYZ/ijk nel 20% dei casi x ogni terna...
if (rnd.Next(0, 100) > 80)
{
PosAct.Rows[0].Cells[0].Value = rnd.Next(0, 100);
PosAct.Rows[0].Cells[1].Value = rnd.Next(0, 100);
PosAct.Rows[0].Cells[2].Value = rnd.Next(0, 100);
agObj.STROBE_PLC = agObj.STROBE_PLC | Strobe.POS_ACT;
}
if (rnd.Next(0, 100) > 80)
{
PosAct.Rows[0].Cells[3].Value = rnd.Next(0, 100);
PosAct.Rows[0].Cells[4].Value = rnd.Next(0, 100);
PosAct.Rows[0].Cells[5].Value = rnd.Next(0, 100);
agObj.STROBE_PLC = agObj.STROBE_PLC | Strobe.POS_ACT;
}
// cambio power nel 15% dei casi...
if (rnd.Next(0, 100) > 85)
{
Power += rnd.Next(-10, 10);
}
// aggiungo 1 min AccTime nel 0.1% dei casi
if (rnd.Next(0, 1000) > 999)
{
AccTime++;
}
// toggle 1 allarme sys nello 0.5% dei casi
if (rnd.Next(0, 1000) > 995)
{
int codAlarm = rnd.Next(1, 3);
switch (codAlarm)
{
case 1:
SysErr_01.Checked = !SysErr_01.Checked;
break;
case 2:
SysErr_02.Checked = !SysErr_02.Checked;
break;
default:
SysErr_03.Checked = !SysErr_03.Checked;
break;
}
agObj.STATUS_FLAG = agObj.STATUS_FLAG | StatusBitMap.AL01;
}
// toggle 1 allarme PLC nello 0.4% dei casi
if (rnd.Next(0, 1000) > 996)
{
int codAlarm = rnd.Next(1, 3);
switch (codAlarm)
{
case 1:
PlcErr_01.Checked = !PlcErr_01.Checked;
break;
case 2:
PlcErr_02.Checked = !PlcErr_02.Checked;
break;
default:
PlcErr_03.Checked = !PlcErr_03.Checked;
break;
}
agObj.STATUS_FLAG = agObj.STATUS_FLAG | StatusBitMap.AL02;
}
// toggle 1 allarme CNC nello 0.3% dei casi
if (rnd.Next(0, 1000) > 997)
{
int codAlarm = rnd.Next(1, 3);
switch (codAlarm)
{
case 1:
CncErr_01.Checked = !CncErr_01.Checked;
break;
case 2:
CncErr_02.Checked = !CncErr_02.Checked;
break;
default:
CncErr_03.Checked = !CncErr_03.Checked;
break;
}
agObj.STATUS_FLAG = agObj.STATUS_FLAG | StatusBitMap.AL03;
}
// nel 2% dei casi imposto un RUN MODE diverso da RUN
if (rnd.Next(0, 100) > 98)
{
int codSel = rnd.Next(1, 3);
switch (codSel)
{
case 1:
manual.Checked = true;
break;
case 2:
mdi.Checked = true;
break;
default:
edit.Checked = true;
break;
}
}
// nel 3% degli altri casi riporto RUN MODE a RUN
else
{
if (rnd.Next(0, 100) > 97)
{
automatic.Checked = true;
}
}
// nel 2% dei casi imposto un EXE MODE diverso da AUTO
if (rnd.Next(0, 100) > 98)
{
int codSel = rnd.Next(1, 3);
switch (codSel)
{
case 1:
ready.Checked = true;
break;
case 2:
stopped.Checked = true;
break;
default:
feedhold.Checked = true;
break;
}
}
// nel 3% degli altri casi riporto EXE MODE a AUTO
else
{
if (rnd.Next(0, 100) > 97)
{
running.Checked = true;
}
}
// controllo se ci sia il flag di lettura di un evento M/S/T nel qual caso lo abbasso...
if (utils.IsSetAll(agObj.STROBE_ADP, Strobe.M_CODE))
{
if (utils.IsSetAll(agObj.STROBE_PLC, Strobe.M_CODE))
{
agObj.STROBE_PLC -= Strobe.M_CODE;
}
}
if (utils.IsSetAll(agObj.STROBE_ADP, Strobe.S_CODE))
{
if (utils.IsSetAll(agObj.STROBE_PLC, Strobe.S_CODE))
{
agObj.STROBE_PLC -= Strobe.S_CODE;
}
}
if (utils.IsSetAll(agObj.STROBE_ADP, Strobe.T_CODE))
{
if (utils.IsSetAll(agObj.STROBE_PLC, Strobe.T_CODE))
{
agObj.STROBE_PLC -= Strobe.T_CODE;
}
}
// controllo se ci sia il flag di lettura di un evento pz ok/ko nel qual caso lo abbasso...
if (utils.IsSetAll(agObj.STROBE_ADP, Strobe.PZ_OK))
{
if (utils.IsSetAll(agObj.STROBE_PLC, Strobe.PZ_OK))
{
agObj.STROBE_PLC -= Strobe.PZ_OK;
}
}
if (utils.IsSetAll(agObj.STROBE_ADP, Strobe.PZ_KO))
{
if (utils.IsSetAll(agObj.STROBE_PLC, Strobe.PZ_KO))
{
agObj.STROBE_PLC -= Strobe.PZ_KO;
}
}
// controllo se ci sia il flag di lettura di un evento FEED_SPEED nel qual caso lo abbasso...
if (utils.IsSetAll(agObj.STROBE_ADP, Strobe.FEED_SPEED))
{
if (utils.IsSetAll(agObj.STROBE_PLC, Strobe.FEED_SPEED))
{
agObj.STROBE_PLC -= Strobe.FEED_SPEED;
}
}
// controllo se ci sia il flag di lettura di un evento POS_ACT nel qual caso lo abbasso...
if (utils.IsSetAll(agObj.STROBE_ADP, Strobe.POS_ACT))
{
if (utils.IsSetAll(agObj.STROBE_PLC, Strobe.POS_ACT))
{
agObj.STROBE_PLC -= Strobe.POS_ACT;
}
}
refreshVisualStrobes();
refreshCodeMST();
}
}
private void refreshVisualStrobes()
{
// aggiorno visualizzazione strobe!
STATUS_STRB_DW0.Text = utils.binaryForm((int)agObj.STRB_DW0);
STATUS_STRB_DW1.Text = utils.binaryForm((int)agObj.STRB_DW1);
STATUS_STRB_DW2.Text = utils.binaryForm((int)agObj.STRB_DW2);
STATUS_STRB_DW3.Text = utils.binaryForm((int)agObj.STRB_DW3);
STATUS_ACK_DW0.Text = utils.binaryForm((int)agObj.ACK_DW0);
STATUS_ACK_DW1.Text = utils.binaryForm((int)agObj.ACK_DW1);
STATUS_ACK_DW2.Text = utils.binaryForm((int)agObj.ACK_DW2);
STATUS_ACK_DW3.Text = utils.binaryForm((int)agObj.ACK_DW3);
}
/// <summary>
/// aggiorna visualizzazione code...
/// </summary>
private void refreshCodeMST()
{
lblCodaM.Text = string.Join(",", agObj.codaM[0].ToArray());
lblCodaT.Text = string.Join(",", agObj.codaT[0].ToArray());
lblCodaS.Text = string.Join(",", agObj.codaS[0].ToArray());
}
private void accodaCodM()
{
if (addCodM.Text.Trim() != "")
{
agObj.appendCodeMST("M", addCodM.Text.Trim(), 0);
addCodM.Text = "";
}
refreshCodeMST();
}
private void accodaCodS()
{
if (addCodS.Text.Trim() != "")
{
agObj.appendCodeMST("S", addCodS.Text.Trim(), 0);
addCodS.Text = "";
}
refreshCodeMST();
}
private void accodaCodT()
{
if (addCodT.Text.Trim() != "")
{
agObj.appendCodeMST("T", addCodT.Text.Trim(), 0);
addCodT.Text = "";
}
refreshCodeMST();
}
private void addCodM_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
// accodo testo
accodaCodM();
}
else if (e.KeyCode == Keys.Escape)
{
// svuoto!
addCodM.Text = "";
}
}
private void addCodM_Leave(object sender, EventArgs e)
{
accodaCodM();
}
private void addCodS_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
// accodo testo
accodaCodS();
}
else if (e.KeyCode == Keys.Escape)
{
// svuoto!
addCodS.Text = "";
}
}
private void addCodS_Leave(object sender, EventArgs e)
{
accodaCodS();
}
private void addCodT_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
// accodo testo
accodaCodT();
}
else if (e.KeyCode == Keys.Escape)
{
// svuoto!
addCodT.Text = "";
}
}
private void addCodT_Leave(object sender, EventArgs e)
{
accodaCodT();
}
#endregion
private void txtPathFeed_TextChanged(object sender, EventArgs e)
{
hsPathFeed.Value = Convert.ToInt32(txtPathFeed.Text);
}
private void txtPathFeedOver_TextChanged(object sender, EventArgs e)
{
hsPathFeedOver.Value = Convert.ToInt32(txtPathFeedOver.Text);
}
private void txtPathSpeedOver_TextChanged(object sender, EventArgs e)
{
hsPathSpeedOver.Value = Convert.ToInt32(txtPathSpeedOver.Text);
}
private void raiseFlag_FEED_SPEED()
{
// se non c'è flag lo alzo...
if (!utils.IsSetAll(agObj.STROBE_PLC, Strobe.FEED_SPEED))
{
agObj.STROBE_PLC = agObj.STROBE_PLC | Strobe.FEED_SPEED;
}
}
private void hsPathFeed_ValueChanged(object sender, EventArgs e)
{
txtPathFeed.Text = hsPathFeed.Value.ToString();
raiseFlag_FEED_SPEED();
}
private void hsPathFeedOver_ValueChanged(object sender, EventArgs e)
{
txtPathFeedOver.Text = hsPathFeedOver.Value.ToString();
raiseFlag_FEED_SPEED();
}
private void hsPathSpeedOver_ValueChanged(object sender, EventArgs e)
{
txtPathSpeedOver.Text = hsPathSpeedOver.Value.ToString();
raiseFlag_FEED_SPEED();
}
#region gestione load conf
private void mConfGen_Click(object sender, EventArgs e)
{
SetupAdapter setupWIndow = new SetupAdapter();
setupWIndow.Show(this);
}
private void mLoadAdaptConf_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 = "XML Files (.xml)|*.xml|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 XmlConfFile = openFileDial.FileName;
loadXmlFile(XmlConfFile);
lg.Info("XML LOADED");
loadPersistLayer(defPersLayerFile);
lg.Info("PersLayerFile READ");
agObj.loadPersData();
lg.Info("PersLayerFile LOADED");
}
}
/// <summary>
/// Carica file XML della configurazione richiesta
/// </summary>
/// <param name="XmlConfFile"></param>
private void loadXmlFile(string XmlConfFile)
{
displayTaskAndWait(string.Format("Loading XML: {0}", XmlConfFile));
// 2019.07.13: cambiata procedura SE ci trociamo nel caso OPC-UA / SOUR che parte da DataModel.xml...
if (utils.CRS("adpProto") == "SOURS" && XmlConfFile.EndsWith("DataModel.xml"))
{
if (utils.CRB("verbose"))
{
lg.Info("Inizio caricamento DataModel per OPC-UA REDIS server");
}
StreamReader file;
// carica da file...
file = new StreamReader(XmlConfFile);
// leggo file...
string rawDataModel = file.ReadToEnd();
// faccio un primo passaggio di pulizia commenti...
string sanitizedXml = utils.xmlSanitize(rawDataModel);
// chiudo file
file.Close();
// effettuo deserializzazione...
DataModel dm = new DataModel();
currDataModel = dm.Deserialize(sanitizedXml);
// avvio oggetto conf
tipoScelto = tipoAdapter.ND;
adpConf = new AdapterConf();
// salvo i dati "specifici" in base a quanto recuperato da DataModel...
// cerco da plc/Name il tipo di PLC...
string plcName = "";
var trovatoCnc = currDataModel.Properties.Find(x => x.BrowseName.Contains("Machine:Cnc:Name"));
var trovatoPlc = currDataModel.Properties.Find(x => x.BrowseName.Contains("Machine:Plc:Name"));
if (trovatoCnc != null)
{
plcName = trovatoCnc.Value;
}
else if (trovatoPlc != null)
{
plcName = trovatoPlc.Value;
}
Enum.TryParse<tipoAdapter>(plcName, true, out tipoScelto);
adpConf.NomeAdapt = plcName;
adpConf.TipoAdapt = tipoScelto;
adpConf.Version = 2;
// preparo file temp x generazione regole
StreamWriter fileOut;
// apro in scrittura il file x mettere le regole...
fileOut = new StreamWriter(utils.nameRepRoleFileSOUR);
fileOut.WriteLine("#------------------------------------------------------------");
fileOut.WriteLine("# AUTO GENERATED Replacement Conf File");
fileOut.WriteLine("#------------------------------------------------------------");
fileOut.WriteLine("");
// altre variabili
element newElement;
int numRules = 0;
string replString = "";
// cerco ASSI come componenti...
List<DataRefItem<string, string>> dataRefList;
int numAx = 0;
List<element> listaAx = new List<element>();
List<DataModel.Component> selAxes = currDataModel.Components.FindAll(x => x.BrowseName.Contains("Machine:Axes:"));
string axBaseName = "";
string axType = "LINEAR";
foreach (var item in selAxes)
{
numAx++;
axBaseName = $"Axis_{numAx.ToString("00")}";
// preparo la datarefList x TIPO assi e gruppo...
dataRefList = new List<DataRefItem<string, string>>();
// calcolo TIPO DI ASSE
DataModel.Property tipoAsse = currDataModel.Properties.Find(x => x.BrowseName.Contains($"{item.BrowseName}:Type"));
if (tipoAsse != null)
{
axType = tipoAsse.Value;
}
else
{
axType = "LINEAR";
}
// aggiungo conf specifiche...
dataRefList.Add(new DataRefItem<string, string>($"Axis_{ numAx.ToString("00") }_Grp", "00"));
dataRefList.Add(new DataRefItem<string, string>($"Axis_{ numAx.ToString("00") }_Type", axType));
newElement = new element()
{
ident = axBaseName,
dataRefList = dataRefList
};
listaAx.Add(newElement);
// aggiungo su file...
replString = item.BrowseName.Replace("Machine:", "");
fileOut.WriteLine($"A|I|{newElement.ident}_PosAct|{replString}:CurrentPos");
fileOut.WriteLine($"A|I|{newElement.ident}_PosTgt|{replString}:TargetPos");
fileOut.WriteLine($"A|I|{newElement.ident}_InvDDone|{replString}:Inversions");
fileOut.WriteLine($"A|I|{newElement.ident}_DistDone|{replString}:Distance");
fileOut.WriteLine($"A|I|{newElement.ident}_FeedAct|{replString}:FeedRate");
fileOut.WriteLine($"A|I|{newElement.ident}_FeedOver|{replString}:FeedOverride");
fileOut.WriteLine($"A|I|{newElement.ident}_MainProc|{replString}:ParentProc");
fileOut.WriteLine($"A|I|{newElement.ident}_Descr|{replString}:Name");
fileOut.WriteLine($"A|I|AV_{newElement.ident}_Load|{replString}:Load");
fileOut.WriteLine($"A|I|{newElement.ident}_AccTime|{replString}:ActiveTime");
fileOut.WriteLine($"A|I|{newElement.ident}_Dir|{replString}:Direction");
fileOut.WriteLine($"A|I|{newElement.ident}_MastId|{replString}:MasterId");
fileOut.WriteLine($"A|I|{newElement.ident}_Type|{replString}:Type");
numRules += 13;
}
fileOut.WriteLine("");
// cerco PATH/Processi come componenti...
int numProc = 0;
List<element> listaProc = new List<element>();
List<DataModel.Component> selProc = currDataModel.Components.FindAll(x => x.BrowseName.Contains("Machine:Cnc:CncProcesses:"));
string procBaseName = "";
foreach (var item in selProc)
{
numProc++;
procBaseName = $"Path_{numProc.ToString("00")}";
newElement = new element()
{
ident = procBaseName
};
listaProc.Add(newElement);
// aggiungo su file...
replString = item.BrowseName.Replace("Machine:", "");
fileOut.WriteLine($"A|I|{newElement.ident}_CodG_Act|{replString}:CodG");
fileOut.WriteLine($"A|I|{newElement.ident}_Cod_M|{replString}:CodM");
fileOut.WriteLine($"A|I|{newElement.ident}_Cod_S|{replString}:CodS");
fileOut.WriteLine($"A|I|{newElement.ident}_Cod_T|{replString}:CodT");
fileOut.WriteLine($"A|I|{newElement.ident}_EXE_MODE|{replString}:Status");
fileOut.WriteLine($"A|I|{newElement.ident}_RUN_MODE|{replString}:Mode");
fileOut.WriteLine($"A|I|{newElement.ident}_RapidOverr|{replString}:RapidOverride");
fileOut.WriteLine($"A|I|{newElement.ident}_FeedOverr|{replString}:FeedOverride");
numRules += 8;
}
fileOut.WriteLine("");
// cerco UnOp / Gruppi operatori come componenti...
int numUnOp = 0;
List<element> listaUnOp = new List<element>();
List<DataModel.Component> selUnOp = currDataModel.Components.FindAll(x => x.BrowseName.Contains("Machine:OperatingGroups:"));
string procUnOp = "";
foreach (var item in selUnOp)
{
numUnOp++;
procUnOp = $"UnOp_{numUnOp.ToString("00")}";
newElement = new element()
{
ident = procUnOp
};
listaUnOp.Add(newElement);
// aggiungo su file...
replString = item.BrowseName.Replace("Machine:", "");
fileOut.WriteLine($"A|I|{newElement.ident}_Speed|{replString}:SpeedRate");
fileOut.WriteLine($"A|I|{newElement.ident}_KRev|{replString}:Distance");
fileOut.WriteLine($"A|I|{newElement.ident}_AccTime|{replString}:ActiveTime");
fileOut.WriteLine($"A|I|{newElement.ident}_ToolId|{replString}:ToolId");
fileOut.WriteLine($"A|I|{newElement.ident}_NumCU|{replString}:ToolChanges");
fileOut.WriteLine($"A|I|{newElement.ident}_Load|{replString}:Load");
fileOut.WriteLine($"A|I|{newElement.ident}_SpeedOverr|{replString}:SpeedOverride");
fileOut.WriteLine($"A|I|{newElement.ident}_Status|{replString}:Status");
fileOut.WriteLine($"A|I|{newElement.ident}_Count|{replString}:Repetitions");
numRules += 9;
}
fileOut.WriteLine("");
// cerco nei gruppi ausiliari...
// VacuumPump...
int numVP = 0;
List<element> listaVP = new List<element>();
// VacuumAct
int numVA = 0;
List<element> listaVA = new List<element>();
// SlittaMag
int numSlMag = 0;
List<element> listaSlMag = new List<element>();
// ProtMag
int numProtMag = 0;
List<element> listaProtMag = new List<element>();
// SlittaTast
int numSlTas = 0;
List<element> listaSlTas = new List<element>();
// Cooler...
int numCool = 0;
List<element> listaCool = new List<element>();
// Lubro...
int numLub = 0;
List<element> listaLub = new List<element>();
// Press...
int numPres = 0;
List<element> listaPress = new List<element>();
// Temperature...
int numTemp = 0;
List<element> listaTemp = new List<element>();
// ricerca gruppi AUX
List<DataModel.Property> selAux = currDataModel.Properties.FindAll(x => x.BrowseName.Contains("Machine:AuxiliaryGroups"));
foreach (var item in selAux)
{
if (item.Value == "COOLER")
{
numCool++;
newElement = new element()
{
ident = $"Cooler_{numCool.ToString("00")}"
};
listaCool.Add(newElement);
// aggiungo su file...
replString = item.BrowseName.Replace("Machine:", "").Replace(":Type", "");
fileOut.WriteLine($"A|I|{newElement.ident}_Status|{replString}:Status");
numRules++;
}
if (item.Value == "LUBRO")
{
numLub++;
newElement = new element()
{
ident = $"Lubro_{numLub.ToString("00")}"
};
listaLub.Add(newElement);
// aggiungo su file...
replString = item.BrowseName.Replace("Machine:", "").Replace(":Type", "");
fileOut.WriteLine($"A|I|{newElement.ident}_Count|{replString}:Repetitions");
numRules++;
}
if (item.Value == "VACUUM_PUMP")
{
numVP++;
newElement = new element()
{
ident = $"VacPump_{numVP.ToString("00")}"
};
listaVP.Add(newElement);
// aggiungo su file...
replString = item.BrowseName.Replace("Machine:", "").Replace(":Type", "");
fileOut.WriteLine($"A|I|{newElement.ident}_Status|{replString}:Status");
fileOut.WriteLine($"A|I|{newElement.ident}_WrkTime|{replString}:ActiveTime");
numRules += 2;
}
if (item.Value == "VACUUM_ACT")
{
numVA++;
newElement = new element()
{
ident = $"VacAct_{numVA.ToString("00")}"
};
listaVA.Add(newElement);
// aggiungo su file...
replString = item.BrowseName.Replace("Machine:", "").Replace(":Type", "");
fileOut.WriteLine($"A|I|{newElement.ident}_Count|{replString}:Repetitions");
fileOut.WriteLine($"A|I|{newElement.ident}_Value|{replString}:Value");
numRules++;
}
if (item.Value == "SLITTA_MAG")
{
numSlMag++;
newElement = new element()
{
ident = $"SlittaMagazzino_{numSlMag.ToString("00")}"
};
listaSlMag.Add(newElement);
// aggiungo su file...
replString = item.BrowseName.Replace("Machine:", "").Replace(":Type", "");
fileOut.WriteLine($"A|I|{newElement.ident}_Count|{replString}:Repetitions");
numRules++;
}
if (item.Value == "PROT_MAG")
{
numProtMag++;
newElement = new element()
{
ident = $"ProtezioneMagazzino_{numProtMag.ToString("00")}"
};
listaProtMag.Add(newElement);
// aggiungo su file...
replString = item.BrowseName.Replace("Machine:", "").Replace(":Type", "");
fileOut.WriteLine($"A|I|{newElement.ident}_Count|{replString}:Repetitions");
numRules++;
}
if (item.Value == "SLITTA_TAST")
{
numSlTas++;
newElement = new element()
{
ident = $"SlittaTastatore_{numPres.ToString("00")}"
};
listaSlTas.Add(newElement);
// aggiungo su file...
replString = item.BrowseName.Replace("Machine:", "").Replace(":Type", "");
fileOut.WriteLine($"A|I|{newElement.ident}_Count|{replString}:Repetitions");
numRules++;
}
if (item.Value == "PRESSURE")
{
numPres++;
newElement = new element()
{
ident = $"Press_{numPres.ToString("00")}"
};
listaPress.Add(newElement);
// aggiungo su file...
replString = item.BrowseName.Replace("Machine:", "").Replace(":Type", "");
fileOut.WriteLine($"A|I|{newElement.ident}_Value|{replString}:Value");
fileOut.WriteLine($"A|I|{newElement.ident}_Status|{replString}:Status");
fileOut.WriteLine($"A|I|{newElement.ident}_Count|{replString}:Repetitions");
numRules += 1;
}
if (item.Value == "TEMPERATURE")
{
numTemp++;
newElement = new element()
{
ident = $"Temp_{numTemp.ToString("00")}"
};
listaTemp.Add(newElement);
// aggiungo su file...
replString = item.BrowseName.Replace("Machine:", "").Replace(":Type", "");
fileOut.WriteLine($"A|I|{newElement.ident}_Value|{replString}:Value");
numRules += 1;
}
}
// aggiungo elementi trovati...
if (numAx > 0)
{
element[] elencoAx = listaAx.ToArray();
adpConf.Axis = elencoAx;
}
if (numProc > 0)
{
element[] elencoProc = listaProc.ToArray();
adpConf.Path = elencoProc;
}
if (numUnOp > 0)
{
element[] elencoUnOp = listaUnOp.ToArray();
adpConf.UnOp = elencoUnOp;
}
if (numCool > 0)
{
element[] elencoCool = listaCool.ToArray();
adpConf.Cooler = elencoCool;
}
if (numLub > 0)
{
element[] elencoLub = listaLub.ToArray();
adpConf.Lubro = elencoLub;
}
if (numVP > 0)
{
element[] elencoVP = listaVP.ToArray();
adpConf.VacuumPump = elencoVP;
}
if (numVA > 0)
{
element[] elencoVA = listaVA.ToArray();
adpConf.VacuumAct = elencoVA;
}
if (numSlMag > 0)
{
element[] elencoSlMag = listaSlMag.ToArray();
adpConf.SlittaMag = elencoSlMag;
}
if (numSlTas > 0)
{
element[] elencoSlTas = listaSlTas.ToArray();
adpConf.SlittaTas = elencoSlTas;
}
if (numPres > 0)
{
element[] elencoPress = listaPress.ToArray();
adpConf.Press = elencoPress;
}
if (numTemp > 0)
{
element[] elencoTemp = listaTemp.ToArray();
adpConf.Temp = elencoTemp;
}
fileOut.WriteLine("");
fileOut.WriteLine("#------------------------------------------------------------");
fileOut.WriteLine($"# EOF: {numRules} rules added");
fileOut.WriteLine("#------------------------------------------------------------");
// chiudo file regole!
fileOut.Close();
// compilo il file StatusList.SOUR.map
fileOut = new StreamWriter(utils.StatusListFileSOUR);
int numStatus = 0;
fileOut.WriteLine("#------------------------------------------------------------");
fileOut.WriteLine("# AUTO GENERATED StatusList File");
fileOut.WriteLine("#------------------------------------------------------------");
fileOut.WriteLine("");
// ricerca in variabili
List<DataModel.Variable> selStatus = currDataModel.Variables.FindAll(x => x.CmsDataType.Equals("StatusList")).OrderBy(x=> x.CmsDataIndex).ToList();
foreach (var item in selStatus)
{
// compilo il file di conf...
fileOut.WriteLine($"{item.CmsDataIndex}|{item.BrowseName.Replace("Machine:", "")}|{item.CmsDataOpt}");
numStatus++;
}
fileOut.WriteLine("");
fileOut.WriteLine("#------------------------------------------------------------");
fileOut.WriteLine($"# EOF: {numStatus} status added");
fileOut.WriteLine("#------------------------------------------------------------");
// chiudo file regole!
fileOut.Close();
// compilo il file CounterList.SOUR.map
fileOut = new StreamWriter(utils.CounterListFileSOUR);
int numCounter = 0;
fileOut.WriteLine("#------------------------------------------------------------");
fileOut.WriteLine("# AUTO GENERATED CounterList File");
fileOut.WriteLine("#------------------------------------------------------------");
fileOut.WriteLine("");
// ricerca in variabili
List<DataModel.Variable> selCounter = currDataModel.Variables.FindAll(x => x.CmsDataType.Equals("CounterList")).OrderBy(x => x.CmsDataIndex).ToList();
foreach (var item in selCounter)
{
// compilo il file di conf... se è RTV aggiungo la parte RTV..
fileOut.WriteLine($"{item.CmsDataIndex}|{item.BrowseName.Replace("Machine:", "")}|{item.CmsDataOpt}|{item.CmsDataScale}");
numCounter++;
}
fileOut.WriteLine("");
fileOut.WriteLine("#------------------------------------------------------------");
fileOut.WriteLine($"# EOF: {numCounter} counters added");
fileOut.WriteLine("#------------------------------------------------------------");
// chiudo file regole!
fileOut.Close();
// compilo il file AnalogList.SOUR.map
fileOut = new StreamWriter(utils.AnalogListFileSOUR);
int numAnalog = 0;
fileOut.WriteLine("#------------------------------------------------------------");
fileOut.WriteLine("# AUTO GENERATED AnalogList File");
fileOut.WriteLine("#------------------------------------------------------------");
fileOut.WriteLine("");
// ricerca in variabili
List<DataModel.Variable> selAnalog = currDataModel.Variables.FindAll(x => x.CmsDataType.Equals("AnalogData")).OrderBy(x => x.CmsDataIndex).ToList();
foreach (var item in selAnalog)
{
// compilo il file di conf...
fileOut.WriteLine($"{item.CmsDataIndex}|{item.BrowseName.Replace("Machine:", "")}|{item.CmsDataOpt}");
numAnalog++;
}
fileOut.WriteLine("");
fileOut.WriteLine("#------------------------------------------------------------");
fileOut.WriteLine($"# EOF: {numAnalog} analog added");
fileOut.WriteLine("#------------------------------------------------------------");
// chiudo file regole!
fileOut.Close();
// compilo il file StringList.SOUR.map
fileOut = new StreamWriter(utils.StringListFileSOUR);
int numString = 0;
fileOut.WriteLine("#------------------------------------------------------------");
fileOut.WriteLine("# AUTO GENERATED StringList File");
fileOut.WriteLine("#------------------------------------------------------------");
fileOut.WriteLine("");
// ricerca in variabili
List<DataModel.Variable> selString = currDataModel.Variables.FindAll(x => x.CmsDataType.Equals("StringData")).OrderBy(x => x.CmsDataIndex).ToList();
foreach (var item in selString)
{
// compilo il file di conf...
fileOut.WriteLine($"{item.CmsDataIndex}|{item.BrowseName.Replace("Machine:", "")}|{item.CmsDataOpt}");
numString++;
}
fileOut.WriteLine("");
fileOut.WriteLine("#------------------------------------------------------------");
fileOut.WriteLine($"# EOF: {numString} string added");
fileOut.WriteLine("#------------------------------------------------------------");
// chiudo file regole!
fileOut.Close();
}
else
{
// legge obj configurazione "legacy"
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!");
}
}
/// <summary>
/// salva su file l'oggetto AdapterConf
/// </summary>
/// <param name="XmlConfFile"></param>
public void saveXmlFile(string XmlConfFile)
{
AdapterConf.Serialize(XmlConfFile, agObj.currAdpConf);
}
/// <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 (!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;
}
}
/// <summary>
/// Carica da file l'oggetto di persistenza dati
/// </summary>
/// <param name="filePath"></param>
public void loadPersistLayer(string filePath)
{
// 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;
}
}
#endregion
#region accesso dati produzione
/// <summary>
/// Dati di produzione (su form)
/// </summary>
public prodData datiProd
{
get
{
prodData answ = new prodData();
// carico da form
answ.Operator = OPERATOR_ID.Text;
// variabili lette da + controlli
answ.Status = stop.Enabled;
answ.Power = Power;
answ.AccTime = AccTime;
answ.EmrStop = estop.Checked;
answ.FuncMode = ((KeyValuePair<string, string>)functionalMode.SelectedItem).Key;
answ.MessageCode = messageCode.Text;
answ.MessageText = messageText.Text;
// parto vuoto con StatusBitMap...
agObj.STATUS_FLAG = 0;
// aggiorno status flag in base a valori...
if (answ.EmrStop)
{
agObj.STATUS_FLAG = agObj.STATUS_FLAG | StatusBitMap.ESTOP;
}
if (automatic.Checked)
{
agObj.STATUS_FLAG = agObj.STATUS_FLAG | StatusBitMap.RM_AUTO;
}
else if (mdi.Checked)
{
agObj.STATUS_FLAG = agObj.STATUS_FLAG | StatusBitMap.RM_MDI;
}
else if (edit.Checked)
{
agObj.STATUS_FLAG = agObj.STATUS_FLAG | StatusBitMap.RM_EDIT;
}
else
{
agObj.STATUS_FLAG = agObj.STATUS_FLAG | StatusBitMap.RM_MANUAL;
}
if (running.Checked)
{
agObj.STATUS_FLAG = agObj.STATUS_FLAG | StatusBitMap.EM_RUN;
}
else if (feedhold.Checked)
{
agObj.STATUS_FLAG = agObj.STATUS_FLAG | StatusBitMap.EM_FEEDHOLD;
}
else if (stopped.Checked)
{
agObj.STATUS_FLAG = agObj.STATUS_FLAG | StatusBitMap.EM_STOP;
}
else if (ready.Checked)
{
agObj.STATUS_FLAG = agObj.STATUS_FLAG | StatusBitMap.EM_READY;
}
if (answ.FuncMode != "1")
{
agObj.STATUS_FLAG = agObj.STATUS_FLAG | StatusBitMap.HM;
}
// ritorno oggetto!
return answ;
}
}
private void pzKo_TextChanged(object sender, EventArgs e)
{
agObj.STROBE_PLC = agObj.STROBE_PLC | Strobe.PZ_KO;
txtPzTot.Text = pzTot.ToString();
}
protected int Power
{
get
{
int answ = 0;
try
{
answ = Convert.ToInt32(txtPower.Text.Trim());
}
catch
{ }
return answ;
}
set
{
txtPower.Text = value.ToString();
}
}
protected int AccTime
{
get
{
int answ = 0;
try
{
answ = Convert.ToInt32(txtAccTime.Text.Trim());
}
catch
{ }
return answ;
}
set
{
txtAccTime.Text = value.ToString();
}
}
protected int pzOk
{
get
{
int answ = 0;
try
{
answ = Convert.ToInt32(txtPzOk.Text.Trim());
}
catch
{ }
return answ;
}
set
{
txtPzOk.Text = value.ToString();
txtPzTot.Text = pzTot.ToString();
}
}
protected int pzKo
{
get
{
int answ = 0;
try
{
answ = Convert.ToInt32(txtPzKo.Text.Trim());
}
catch
{ }
return answ;
}
set
{
txtPzKo.Text = value.ToString();
txtPzTot.Text = pzTot.ToString();
}
}
protected int pzTot
{
get
{
return pzOk + pzKo;
}
}
#endregion
#region gestione Path
private void cbPathSel_SelectedIndexChanged(object sender, EventArgs e)
{
hsPathFeed.Value = 50;
hsPathFeedOver.Value = 50;
hsPathSpeedOver.Value = 50;
Random rnd = new Random();
PosAct.Rows[0].Cells[0].Value = rnd.Next(0, 1000);
PosAct.Rows[0].Cells[1].Value = rnd.Next(0, 1000);
PosAct.Rows[0].Cells[2].Value = rnd.Next(0, 1000);
PosAct.Rows[0].Cells[3].Value = rnd.Next(0, 360);
PosAct.Rows[0].Cells[4].Value = rnd.Next(0, 360);
PosAct.Rows[0].Cells[5].Value = rnd.Next(0, 360);
}
/// <summary>
/// Dati PATH
/// </summary>
public PathData CurrPath
{
get
{
PathData answ = new PathData();
// modifiche dati portati da macchina a path...
answ.ProgramName = program.Text;
answ.ProgrRow = PROG_ROW_NUM.Text;
answ.PartId = partID.Text;
answ.PathType = "LAVORO";
// pezzi
answ.pzTot = pzOk + pzKo;
if (automatic.Checked)
{
answ.RunMode = "AUTOMATIC";
}
else if (mdi.Checked)
{
answ.RunMode = "MANUAL_DATA_INPUT";
}
else if (edit.Checked)
{
answ.RunMode = "EDIT";
}
else
{
answ.RunMode = "MANUAL";
}
if (running.Checked)
{
answ.ExeMode = "ACTIVE";
}
else if (feedhold.Checked)
{
answ.ExeMode = "FEED_HOLD";
}
else if (stopped.Checked)
{
answ.ExeMode = "STOPPED";
}
else if (ready.Checked)
{
answ.ExeMode = "READY";
}
answ.ActiveAxes = "1 2 3 4 5 6"; // lascio sempre tutti attivi...
answ.PathSel = cbPathSel.SelectedIndex;
// FEED/SPEED
answ.PathFeedrate = hsPathFeed.Value;
answ.PathFeedrateOver = hsPathFeedOver.Value;
answ.PathRapidOver = hsPathSpeedOver.Value;
// posizione attuale
position posAct = new position();
DataGridViewCellCollection cells = PosAct.Rows[0].Cells;
float.TryParse(cells[0].Value.ToString(), out posAct.x);
float.TryParse(cells[1].Value.ToString(), out posAct.y);
float.TryParse(cells[2].Value.ToString(), out posAct.z);
float.TryParse(cells[3].Value.ToString(), out posAct.i);
float.TryParse(cells[4].Value.ToString(), out posAct.j);
float.TryParse(cells[5].Value.ToString(), out posAct.k);
answ.PathPosAct = posAct;
// aggiungo altri oggetti...
answ.CodG_Act = "G01 G10 G34 G60";
answ.SubMode = string.Format("# Asse selezionato {0} #", cbAxNum.SelectedIndex);
// ritorno oggetto!
return answ;
}
}
#endregion
#region gestione UnOp
private void cbUnOpSel_SelectedIndexChanged(object sender, EventArgs e)
{
uoToolId.Text = "1";
uoNumCU.Text = "2";
uoStatus.Text = "RUN";
uoVitaRes.Text = "100";
uoSpeed.Text = "80";
uoLoad.Text = "80";
uoAccTime.Text = "0";
}
/// <summary>
/// Dati UnOp
/// </summary>
public UnOpData CurrUnOp
{
get
{
UnOpData answ = new UnOpData();
answ.UnOpSel = cbUnOpSel.SelectedIndex;
int.TryParse(uoToolId.Text, out answ.UnOpToolId);
int.TryParse(uoNumCU.Text, out answ.UnOpNumCU);
answ.UnOpStatus = uoStatus.Text;
int.TryParse(uoVitaRes.Text, out answ.UnOpVitaRes);
answ.UnOpSpeed = uoSpeed.Value;
answ.UnOpLoad = uoLoad.Value;
int.TryParse(uoAccTime.Text, out answ.UnOpAccTime);
// ritorno oggetto!
return answ;
}
}
private void uoLoad_Scroll(object sender, ScrollEventArgs e)
{
uoLoadVal.Text = uoLoad.Value.ToString();
}
private void uoSpeed_Scroll(object sender, ScrollEventArgs e)
{
uoSpeedVal.Text = uoSpeed.Value.ToString();
}
#endregion
#region gestione assi
private void cbAxNum_SelectedIndexChanged(object sender, EventArgs e)
{
// aggiorna visualizzazione asse... imposto valori standard x controlli
AxMainProc.Text = "1";
AxIsMaster.Checked = false;
AxMastId.Text = "0";
cbAxType.SelectedIndex = 0;
AxDir.Text = "1";
AxLoad.Value = 50;
AxPosition.Value = 50;
AxFeedAct.Value = 50;
AxFeedOver.Value = 100;
AxAccelAct.Text = "0";
AxAccTime.Text = "0";
AxBatt.Text = "100";
}
/// <summary>
/// Dati di produzione (su form)
/// </summary>
public AxisData CurrAxis
{
get
{
Random rnd = new Random();
AxisData answ = new AxisData();
answ.AxisSel = cbAxNum.SelectedIndex;
answ.AxisMainProc = AxMainProc.Text;
answ.AxisIsMaster = AxIsMaster.Checked;
answ.AxisMastId = AxMastId.Text;
answ.AxisType = AxisType;
answ.AxisDir = AxDir.Text;
answ.AxisLoad = AxLoad.Value;
answ.AxisPosAct = AxPosition.Value;// + rnd.Next(-2, 2);
answ.AxisPosTgt = AxPosition.Value;
answ.AxisFeedAct = AxFeedAct.Value;
answ.AxisFeedOver = AxFeedOver.Value;
answ.AxisAccel = AxAccelAct.Text;
answ.AxisAccTime = AxAccTime.Text;
answ.AxisBattery = AxBatt.Text;
// restituisco oggetto
return answ;
}
}
protected string AxisType
{
get
{
string answ = "";
try
{
answ = cbAxType.SelectedItem.ToString(); ;
}
catch
{ }
return answ;
}
}
private void xLoad_Scroll(object sender, ScrollEventArgs e)
{
AxLoadValue.Text = AxLoad.Value.ToString();
}
private void xPosition_Scroll(object sender, ScrollEventArgs e)
{
AxPositionValue.Text = AxPosition.Value.ToString();
}
private void cLoad_Scroll(object sender, ScrollEventArgs e)
{
AxFeedActValue.Text = AxFeedAct.Value.ToString();
}
private void cSpeed_Scroll(object sender, ScrollEventArgs e)
{
AxFeedOverValue.Text = AxFeedOver.Value.ToString();
}
#endregion
/// <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;
}
}
private void SysErr_01_CheckedChanged(object sender, EventArgs e)
{
// aggiorno il vettore allarmi (da 128 byte) sulla base della selezione dei checkbox (per i primi 9...) - ultimi 3 selezionano 8 allarmi ciascuno...
BitArray bitArray = new BitArray(1024);
bitArray[7] = SysErr_01.Checked;
bitArray[6] = SysErr_02.Checked;
bitArray[5] = SysErr_03.Checked;
bitArray[4] = PlcErr_01.Checked;
bitArray[3] = PlcErr_02.Checked;
bitArray[2] = PlcErr_03.Checked;
bitArray[1] = CncErr_01.Checked;
bitArray[0] = CncErr_02.Checked;
bitArray[15] = CncErr_03.Checked;
// ne assegno 8 alla volta...
for (int i = 0; i < 8; i++)
{
bitArray[16 + i] = ErrRT_01.Checked;
bitArray[24 + i] = ErrRT_02.Checked;
bitArray[32 + i] = ErrRT_03.Checked;
}
byte[] newAlarm = utils.ToByteArray(bitArray);
Buffer.BlockCopy(newAlarm, 0, agObj.currGateway.AlarmFlags, 0, 32);
}
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)
{
agObj.stopAdapter(tryRestart);
// salvo!
savePersistLayer(defPersLayerFile);
savePersistLayer(histPersLayerFile);
stop.Enabled = false;
dump.Enabled = false;
start.Enabled = true;
if (stopTimer)
{
gather.Enabled = false;
agObj.tryDisconnect();
}
}
}
}