6503 lines
258 KiB
C#
6503 lines
258 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using NLog;
|
|
|
|
namespace SCMA.AdapterPLC
|
|
{
|
|
using AdapterCom;
|
|
using MTC;
|
|
using OPC_UA_REDIS;
|
|
|
|
#region macro oggetti da istanziare a blocchi da configurazione XML
|
|
|
|
/// <summary>
|
|
/// Singola pompa da vuoto, 0..n
|
|
/// </summary>
|
|
public class VacuumPump : element
|
|
{
|
|
/// <summary>
|
|
/// Stato: ACTIVE/INACTIVE
|
|
/// </summary>
|
|
public string statusKey { get { return string.Format("{0}_Status", ident); } }
|
|
|
|
/// <summary>
|
|
/// Valore work time della pompa vuoto
|
|
/// </summary>
|
|
public string workTimeKey { get { return string.Format("{0}_WrkTime", ident); } }
|
|
|
|
/// <summary>
|
|
/// Classe Vacuum Pump (pompa)
|
|
/// </summary>
|
|
/// <param name="baseElem">element base contenente parametri (da XML)</param>
|
|
public VacuumPump(element baseElem)
|
|
{
|
|
ident = baseElem.ident;
|
|
dataRefList = baseElem.dataRefList;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Singolo attuatore vuoto, 0..n
|
|
/// </summary>
|
|
public class VacuumAct : element
|
|
{
|
|
/// <summary>
|
|
/// valore contatore azioni
|
|
/// </summary>
|
|
public string countKey { get { return string.Format("{0}_Count", ident); } }
|
|
|
|
/// <summary>
|
|
/// Classe Vacuum Actuator (valvola)
|
|
/// </summary>
|
|
/// <param name="baseElem">element base contenente parametri (da XML)</param>
|
|
public VacuumAct(element baseElem)
|
|
{
|
|
ident = baseElem.ident;
|
|
dataRefList = baseElem.dataRefList;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Singolo attuatore per lubrificazione, 0..n
|
|
/// </summary>
|
|
public class Lubro : element
|
|
{
|
|
/// <summary>
|
|
/// Stato: ACTIVE/INACTIVE
|
|
/// </summary>
|
|
public string statusKey { get { return string.Format("{0}_Status", ident); } }
|
|
|
|
/// <summary>
|
|
/// valore contatore (numero pompate necessarie per far scattare sensore)
|
|
/// </summary>
|
|
public string countKey { get { return string.Format("{0}_Count", ident); } }
|
|
|
|
/// <summary>
|
|
/// Classe Lubrorefrigerante
|
|
/// </summary>
|
|
/// <param name="baseElem">element base contenente parametri (da XML)</param>
|
|
public Lubro(element baseElem)
|
|
{
|
|
ident = baseElem.ident;
|
|
dataRefList = baseElem.dataRefList;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Singola Slitta Mag, 0..n
|
|
/// </summary>
|
|
public class SlittaMag : element
|
|
{
|
|
/// <summary>
|
|
/// valore contatore (numero attivazioni/disattivazioni slitta magazzino)
|
|
/// </summary>
|
|
public string countKey { get { return string.Format("{0}_Count", ident); } }
|
|
|
|
/// <summary>
|
|
/// Classe Slitta Magazzino
|
|
/// </summary>
|
|
/// <param name="baseElem">element base contenente parametri (da XML)</param>
|
|
public SlittaMag(element baseElem)
|
|
{
|
|
ident = baseElem.ident;
|
|
dataRefList = baseElem.dataRefList;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Singolo attuatore Protezione Magazzino, 0..n
|
|
/// </summary>
|
|
public class ProtMag : element
|
|
{
|
|
/// <summary>
|
|
/// valore contatore (numero attivazioni/disattivazioni valvola)
|
|
/// </summary>
|
|
public string countKey { get { return string.Format("{0}_Count", ident); } }
|
|
|
|
/// <summary>
|
|
/// Classe Protezione Magazzino
|
|
/// </summary>
|
|
/// <param name="baseElem">element base contenente parametri (da XML)</param>
|
|
public ProtMag(element baseElem)
|
|
{
|
|
ident = baseElem.ident;
|
|
dataRefList = baseElem.dataRefList;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Singolo refrigeratore, 0..n
|
|
/// </summary>
|
|
public class Cooler : element
|
|
{
|
|
/// <summary>
|
|
/// Stato: ACTIVE/INACTIVE
|
|
/// </summary>
|
|
public string statusKey { get { return string.Format("{0}_Status", ident); } }
|
|
|
|
/// <summary>
|
|
/// Classe refrigeratore
|
|
/// </summary>
|
|
/// <param name="baseElem">element base contenente parametri (da XML)</param>
|
|
public Cooler(element baseElem)
|
|
{
|
|
ident = baseElem.ident;
|
|
dataRefList = baseElem.dataRefList;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Singola Pressione rilevata, 0..n
|
|
/// </summary>
|
|
public class Press : element
|
|
{
|
|
/// <summary>
|
|
/// valore variabile (valore pressione istantaneo)
|
|
/// </summary>
|
|
public string valueKey { get { return string.Format("{0}_Value", ident); } }
|
|
|
|
/// <summary>
|
|
/// Classe pressione con Idx e descrizione
|
|
/// </summary>
|
|
/// <param name="baseElem">element base contenente parametri (da XML)</param>
|
|
public Press(element baseElem)
|
|
{
|
|
ident = baseElem.ident;
|
|
dataRefList = baseElem.dataRefList;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Singola temperatura rilevata, 0..n
|
|
/// </summary>
|
|
public class Tempe : element
|
|
{
|
|
/// <summary>
|
|
/// valore variabile (valore temperatura istantaneo)
|
|
/// </summary>
|
|
public string valueKey { get { return string.Format("{0}_Value", ident); } }
|
|
|
|
/// <summary>
|
|
/// Classe temperatura con Idx e descrizione
|
|
/// </summary>
|
|
/// <param name="baseElem">element base contenente parametri (da XML)</param>
|
|
public Tempe(element baseElem)
|
|
{
|
|
ident = baseElem.ident;
|
|
dataRefList = baseElem.dataRefList;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Singola Area Memoria (Kvara 1..4)
|
|
/// </summary>
|
|
public class MemArea : element
|
|
{
|
|
/// <summary>
|
|
/// Programma caricato
|
|
/// </summary>
|
|
public string prgNameKey { get { return string.Format("{0}_PROG_NAME", ident); } }
|
|
|
|
/// <summary>
|
|
/// Programma caricato
|
|
/// </summary>
|
|
public string prgRunningKey { get { return string.Format("{0}_RUNNING", ident); } }
|
|
|
|
/// <summary>
|
|
/// Programma caricato
|
|
/// </summary>
|
|
public string numExeKey { get { return string.Format("{0}_NUM_EXE", ident); } }
|
|
|
|
/// <summary>
|
|
/// Programma caricato
|
|
/// </summary>
|
|
public string numRepKey { get { return string.Format("{0}_NUM_REP", ident); } }
|
|
|
|
/// <summary>
|
|
/// INIT Classe Memory Area
|
|
/// </summary>
|
|
/// <param name="baseElem">element base contenente parametri (da XML)</param>
|
|
public MemArea(element baseElem)
|
|
{
|
|
ident = baseElem.ident;
|
|
dataRefList = baseElem.dataRefList;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Singolo path, da 1..20
|
|
/// </summary>
|
|
public class Path : element
|
|
{
|
|
/// <summary>
|
|
/// Tipo Path (LAVOR/ASSERV)
|
|
/// </summary>
|
|
public string pathTypeKey { get { return string.Format("{0}_Type", ident); } }
|
|
/// <summary>
|
|
/// Cod Particolare su Path
|
|
/// </summary>
|
|
public string partIdKey { get { return string.Format("{0}_PartId", ident); } }
|
|
/// <summary>
|
|
/// Contapezzi x PATH
|
|
/// </summary>
|
|
public string partCountKey { get { return string.Format("{0}_PZ_TOT", ident); } }
|
|
/// <summary>
|
|
/// Codici M sul PATH
|
|
/// </summary>
|
|
public string pathCodMKey { get { return string.Format("{0}_Cod_M", ident); } }
|
|
/// <summary>
|
|
/// Codici S sul PATH
|
|
/// </summary>
|
|
public string pathCodSKey { get { return string.Format("{0}_Cod_S", ident); } }
|
|
/// <summary>
|
|
/// Codici T sul PATH
|
|
/// </summary>
|
|
public string pathCodTKey { get { return string.Format("{0}_Cod_T", ident); } }
|
|
/// <summary>
|
|
/// Modalità RUN del PATH: AUTO/EDIT/MDI/JOG/JOGINC/REF/HANDLE
|
|
/// </summary>
|
|
public string runModeKey { get { return string.Format("{0}_RUN_MODE", ident); } }
|
|
/// <summary>
|
|
/// Modalità execution del path: RUN/HOLD/FEED_HOLD/...
|
|
/// </summary>
|
|
public string exeModeKey { get { return string.Format("{0}_EXE_MODE", ident); } }
|
|
/// <summary>
|
|
/// Programma corrente
|
|
/// </summary>
|
|
public string currProgKey { get { return string.Format("{0}_CurrProg", ident); } }
|
|
/// <summary>
|
|
/// Area Programma corrente/selezionata
|
|
/// </summary>
|
|
public string currAreaKey { get { return string.Format("{0}_CurrArea", ident); } }
|
|
/// <summary>
|
|
/// num riga corrente
|
|
/// </summary>
|
|
public string currProgRowNumKey { get { return string.Format("{0}_CurrProg_RowNum", ident); } }
|
|
/// <summary>
|
|
/// Assi attivi per path
|
|
/// </summary>
|
|
public string activeAxesKey { get { return string.Format("{0}_ActiveAxes", ident); } }
|
|
/// <summary>
|
|
/// Feedrate
|
|
/// </summary>
|
|
public string feedKey { get { return string.Format("{0}_FeedRate", ident); } }
|
|
/// <summary>
|
|
/// Override feed
|
|
/// </summary>
|
|
public string feedOverKey { get { return string.Format("{0}_FeedOverr", ident); } }
|
|
/// <summary>
|
|
/// Override speed
|
|
/// </summary>
|
|
public string rapidOverKey { get { return string.Format("{0}_RapidOverr", ident); } }
|
|
/// <summary>
|
|
/// Override Jog
|
|
/// </summary>
|
|
public string jogOverKey { get { return string.Format("{0}_JogOverr", ident); } }
|
|
/// <summary>
|
|
/// Override Spindle_01
|
|
/// </summary>
|
|
public string spindleOver_01_Key { get { return string.Format("{0}_SpindleOver_01", ident); } }
|
|
/// <summary>
|
|
/// Override Spindle_02
|
|
/// </summary>
|
|
public string spindleOver_02_Key { get { return string.Format("{0}_SpindleOver_02", ident); } }
|
|
/// <summary>
|
|
/// Override Spindle_03
|
|
/// </summary>
|
|
public string spindleOver_03_Key { get { return string.Format("{0}_SpindleOver_03", ident); } }
|
|
/// <summary>
|
|
/// Override Spindle_04
|
|
/// </summary>
|
|
public string spindleOver_04_Key { get { return string.Format("{0}_SpindleOver_04", ident); } }
|
|
/// <summary>
|
|
/// Posizione X
|
|
/// </summary>
|
|
public string posAct_X_Key { get { return string.Format("{0}_PosActX", ident); } }
|
|
/// <summary>
|
|
/// Posizione Y
|
|
/// </summary>
|
|
public string posAct_Y_Key { get { return string.Format("{0}_PosActY", ident); } }
|
|
/// <summary>
|
|
/// Posizione Z
|
|
/// </summary>
|
|
public string posAct_Z_Key { get { return string.Format("{0}_PosActZ", ident); } }
|
|
/// <summary>
|
|
/// Angolo I
|
|
/// </summary>
|
|
public string posAct_I_Key { get { return string.Format("{0}_PosActI", ident); } }
|
|
/// <summary>
|
|
/// Angolo J
|
|
/// </summary>
|
|
public string posAct_J_Key { get { return string.Format("{0}_PosActJ", ident); } }
|
|
/// <summary>
|
|
/// Angolo K
|
|
/// </summary>
|
|
public string posAct_K_Key { get { return string.Format("{0}_PosActK", ident); } }
|
|
/// <summary>
|
|
/// Stato dei codici G attivi
|
|
/// </summary>
|
|
public string gCodeAct_Key { get { return string.Format("{0}_CodG_Act", ident); } }
|
|
/// <summary>
|
|
/// Stato dei SubMode attivi
|
|
/// </summary>
|
|
public string subModeKey { get { return string.Format("{0}_SubMode", ident); } }
|
|
/// <summary>
|
|
/// Allarmi CNC del PATH
|
|
/// </summary>
|
|
public string alarmCncKey { get { return string.Format("{0}_AlarmCNC", ident); } }
|
|
/// <summary>
|
|
/// Allarmi PCL del PATH
|
|
/// </summary>
|
|
public string alarmPlcKey { get { return string.Format("{0}_AlarmPLC", ident); } }
|
|
/// <summary>
|
|
/// Classe Path con Idx e descrizione
|
|
/// </summary>
|
|
/// <param name="baseElem">element base contenente parametri (da XML)</param>
|
|
public Path(element baseElem)
|
|
{
|
|
ident = baseElem.ident;
|
|
dataRefList = baseElem.dataRefList;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Singolo mandrino, 1..n
|
|
/// </summary>
|
|
public class UnOp : element
|
|
{
|
|
/// <summary>
|
|
/// ToolID
|
|
/// </summary>
|
|
public string toolIdKey { get { return string.Format("{0}_ToolId", ident); } }
|
|
/// <summary>
|
|
/// valore numero Cambi Utensili effettuato
|
|
/// </summary>
|
|
public string numCUKey { get { return string.Format("{0}_NumCU", ident); } }
|
|
/// <summary>
|
|
/// status utensili
|
|
/// </summary>
|
|
public string statusKey { get { return string.Format("{0}_Status", ident); } }
|
|
/// <summary>
|
|
/// valore vita residua utensile
|
|
/// </summary>
|
|
public string vitaResKey { get { return string.Format("{0}_VitaRes", ident); } }
|
|
/// <summary>
|
|
/// tipologia di vita residua utensile:
|
|
/// 0 : "ND" (famiglia senza gestione vitautensili)
|
|
/// 1 : "Time [s]"
|
|
/// 2 : "Stroke [n]"
|
|
/// 3 : "Distance [m]" ([ft] se la macchina è impostata in pollici)
|
|
/// </summary>
|
|
public string vitaResTypeKey { get { return string.Format("{0}_VitaResType", ident); } }
|
|
/// <summary>
|
|
/// valore speed
|
|
/// </summary>
|
|
public string speedKey { get { return string.Format("{0}_Speed", ident); } }
|
|
/// <summary>
|
|
/// valore speed override
|
|
/// </summary>
|
|
public string speedOverKey { get { return string.Format("{0}_SpeedOverr", ident); } }
|
|
/// <summary>
|
|
/// valore load
|
|
/// </summary>
|
|
public string loadKey { get { return string.Format("{0}_Load", ident); } }
|
|
/// <summary>
|
|
/// valore tempo cumulato di impiego
|
|
/// </summary>
|
|
public string accTimeKey { get { return string.Format("{0}_AccTime", ident); } }
|
|
/// <summary>
|
|
/// contatore cumulato di giri mandrino (migliaia)
|
|
/// </summary>
|
|
public string kRevKey { get { return string.Format("{0}_KRev", ident); } }
|
|
/// <summary>
|
|
/// contatore cumulato di apertura testa
|
|
/// </summary>
|
|
public string countKey { get { return string.Format("{0}_Count", ident); } }
|
|
/// <summary>
|
|
/// Classe Unita Operatrice (Mandrino) con Idx e descrizione
|
|
/// </summary>
|
|
/// <param name="baseElem">element base contenente parametri (da XML)</param>
|
|
public UnOp(element baseElem)
|
|
{
|
|
ident = baseElem.ident;
|
|
dataRefList = baseElem.dataRefList;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Asse singolo, 1..n
|
|
/// </summary>
|
|
public class Axis : element
|
|
{
|
|
/// <summary>
|
|
/// Descrizione asse (nome assegnato)
|
|
/// </summary>
|
|
public string descriptionKey { get { return string.Format("{0}_Descr", ident); } }
|
|
/// <summary>
|
|
/// Processo di appartenenza
|
|
/// </summary>
|
|
public string mainProcKey { get { return string.Format("{0}_MainProc", ident); } }
|
|
/// <summary>
|
|
/// Bit se sia master (=1) o slave (=0)
|
|
/// </summary>
|
|
public string isMastKey { get { return string.Format("{0}_IsMast", ident); } }
|
|
/// <summary>
|
|
/// ID del master
|
|
/// </summary>
|
|
public string mastIdKey { get { return string.Format("{0}_MastId", ident); } }
|
|
/// <summary>
|
|
/// Gruppo di appartenenza dell'asse
|
|
/// </summary>
|
|
public string groupKey { get { return string.Format("{0}_Grp", ident); } }
|
|
/// <summary>
|
|
/// Tipo asse: lineare, rotazionale...
|
|
/// </summary>
|
|
public string typeKey { get { return string.Format("{0}_Type", ident); } }
|
|
/// <summary>
|
|
/// Bit direzione: 1 = avanti/clockwise, 0 indietro/counterclockwise
|
|
/// </summary>
|
|
public string directionKey { get { return string.Format("{0}_Dir", ident); } }
|
|
/// <summary>
|
|
/// load
|
|
/// </summary>
|
|
public string loadKey { get { return string.Format("{0}_Load", ident); } }
|
|
/// <summary>
|
|
/// posizione attuale
|
|
/// </summary>
|
|
public string posActKey { get { return string.Format("{0}_PosAct", ident); } }
|
|
/// <summary>
|
|
/// posizione target
|
|
/// </summary>
|
|
public string posTgtKey { get { return string.Format("{0}_PosTgt", ident); } }
|
|
/// <summary>
|
|
/// feed attuale
|
|
/// </summary>
|
|
public string feedrateKey { get { return string.Format("{0}_FeedAct", ident); } }
|
|
/// <summary>
|
|
/// Feed Override
|
|
/// </summary>
|
|
public string feedOverKey { get { return string.Format("{0}_FeedOver", ident); } }
|
|
/// <summary>
|
|
/// Accelerazione Attuale
|
|
/// </summary>
|
|
public string accelActKey { get { return string.Format("{0}_AccelAct", ident); } }
|
|
/// <summary>
|
|
/// Tempo Lavoro cumulato
|
|
/// </summary>
|
|
public string accTimeKey { get { return string.Format("{0}_AccTime", ident); } }
|
|
/// <summary>
|
|
/// Carica batteria
|
|
/// </summary>
|
|
public string batteryKey { get { return string.Format("{0}_Battery", ident); } }
|
|
/// <summary>
|
|
/// Distanza compiuta nell'intervallo di tempo
|
|
/// </summary>
|
|
public string distDoneKey { get { return string.Format("{0}_DistDone", ident); } }
|
|
/// <summary>
|
|
/// numero di inversioni di direzione fatte nell'intervallo di tempo
|
|
/// </summary>
|
|
public string invDDoneKey { get { return string.Format("{0}_InvDDone", ident); } }
|
|
/// <summary>
|
|
/// Allarmi CNC del PATH
|
|
/// </summary>
|
|
public string alarmCncKey { get { return string.Format("{0}_AlarmCNC", ident); } }
|
|
/// <summary>
|
|
/// Allarmi PCL del PATH
|
|
/// </summary>
|
|
public string alarmPlcKey { get { return string.Format("{0}_AlarmPLC", ident); } }
|
|
|
|
/// <summary>
|
|
/// Classe Asse con relativo ID UNIVOCO
|
|
/// </summary>
|
|
/// <param name="baseElem">element base contenente parametri (da XML)</param>
|
|
public Axis(element baseElem)
|
|
{
|
|
ident = baseElem.ident;
|
|
// valori da conf esplicita
|
|
dataRefList = baseElem.dataRefList;
|
|
}
|
|
}
|
|
|
|
#endregion macro oggetti da istanziare a blocchi da configurazione XML
|
|
|
|
public class Generic
|
|
{
|
|
/// <summary>
|
|
/// inizializzo l'oggetto sulla form SULLA BASE DEL FILE DI CONFIGURAZIONE letto
|
|
/// </summary>
|
|
/// <param name="caller">FORM chaimante</param>
|
|
/// <param name="adpConf">CONFIGURAZIONE adapter</param>
|
|
/// <param name="gatewayObj">OGGETTO gestione comunicazione OUT (tipologia e metodi)</param>
|
|
public Generic(MainForm caller, AdapterConf adpConf, Gateway gatewayObj)
|
|
{
|
|
lg = LogManager.GetCurrentClassLogger();
|
|
lg.Info("Avvio preliminare AdapterGeneric");
|
|
|
|
currGateway = gatewayObj;
|
|
lg.Info(string.Format("Impostato protocollo di comunicazione {0}", currGateway.protocollo));
|
|
|
|
procIotMem = utils.CRB("procIotMem");
|
|
|
|
currAdpConf = adpConf;
|
|
|
|
// inizializzo vettore gruppi assi, MAX 20!!!
|
|
FeedRateGrp = new int[20];
|
|
|
|
// inizializzo FeedRatePath...
|
|
FeedRatePath = new int[adpConf.nPath];
|
|
// init override path...
|
|
FeedRateOverPath = new int[adpConf.nPath];
|
|
RapidOverPath = new int[adpConf.nPath];
|
|
SpeedRateOverPath = new int[adpConf.nPath];
|
|
|
|
// salvo il form chiamante
|
|
parentForm = caller;
|
|
addItemsToGateway(adpConf);
|
|
|
|
// inizializzo vettori code MST x num path...
|
|
codaM = new List<string>[adpConf.nPath];
|
|
codaS = new List<string>[adpConf.nPath];
|
|
codaT = new List<string>[adpConf.nPath];
|
|
for (int i = 0; i < adpConf.nPath; i++)
|
|
{
|
|
codaM[i] = new List<string>();
|
|
codaS[i] = new List<string>();
|
|
codaT[i] = new List<string>();
|
|
}
|
|
|
|
// concluso!
|
|
lg.Info("Istanziata classe preliminare AdapterGeneric");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua aggiunta items a Gateway...
|
|
/// </summary>
|
|
/// <param name="adpConf"></param>
|
|
private void addItemsToGateway(AdapterConf adpConf)
|
|
{
|
|
|
|
// solo se sono in modalità SOUR aggiungo item cablati...
|
|
if (currGateway.protocollo == gwProtocol.SOURS)
|
|
{
|
|
currGateway.addItemNodeAndSet("Alarm", itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet("Emergency", itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
}
|
|
// solo se sono in modalità MTC aggiungo item cablati...
|
|
else
|
|
{
|
|
// item disponibilità
|
|
currGateway.addItemNodeAndSet("AVAIL", itemType.Event, availStatus.AVAILABLE.ToString());
|
|
currGateway.addItemNodeAndSet("MESSAGE", itemType.Message, "");
|
|
// assets
|
|
currGateway.addItemNodeAndSet("MTC_asset_chg", itemType.Event, "");
|
|
currGateway.addItemNodeAndSet("MTC_asset_rem", itemType.Event, "");
|
|
// modalità esecutiva e funzionale
|
|
currGateway.addItemNodeAndSet("FUNCT_MODE", itemType.Message, "");
|
|
// dati utente
|
|
currGateway.addItemNodeAndSet("OperatorId", itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet("CLOCK", itemType.Sample, DateTime.Now.Date.ToFileTimeUtc());
|
|
currGateway.addItemNodeAndSet("SlittaTastatore_Count", itemType.Sample, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
}
|
|
// status, clock, emergency stop
|
|
currGateway.addItemNodeAndSet("E_STOP", itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet("STATUS", itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
|
|
// tempi, potenza, processo, counters vari ACC_TIME_WORK
|
|
currGateway.addItemNodeAndSet("ACC_TIME", itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet("ACC_TIME_WORK", itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
|
|
currGateway.addItemNodeAndSet("POWER", itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
|
|
// testing e autodiagnostica
|
|
currGateway.addItemNodeAndSet("TESTING_DATA", itemType.Message, "");
|
|
|
|
// strobe/status non riconosciuti
|
|
currGateway.addItemNodeAndSet("UNK_STATUS", itemType.Message, "");
|
|
currGateway.addItemNodeAndSet("UNK_STROBE", itemType.Message, "");
|
|
|
|
// Aree memoria
|
|
vettMemArea = new MemArea[adpConf.nMemArea];
|
|
for (int i = 0; i < adpConf.nMemArea; i++)
|
|
{
|
|
vettMemArea[i] = new MemArea(adpConf.MemArea[i]);
|
|
currGateway.addItemNodeAndSet(vettMemArea[i].prgNameKey, itemType.Message, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettMemArea[i].prgRunningKey, itemType.Message, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettMemArea[i].numExeKey, itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettMemArea[i].numRepKey, itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
}
|
|
// Pompe vuoto
|
|
vettVacPump = new VacuumPump[adpConf.nVacuumPump];
|
|
for (int i = 0; i < adpConf.nVacuumPump; i++)
|
|
{
|
|
vettVacPump[i] = new VacuumPump(adpConf.VacuumPump[i]);
|
|
currGateway.addItemNodeAndSet(vettVacPump[i].statusKey, itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettVacPump[i].workTimeKey, itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
}
|
|
|
|
// Attuatori vuoto
|
|
vettVacAct = new VacuumAct[adpConf.nVacuumAct];
|
|
for (int i = 0; i < adpConf.nVacuumAct; i++)
|
|
{
|
|
vettVacAct[i] = new VacuumAct(adpConf.VacuumAct[i]);
|
|
currGateway.addItemNodeAndSet(vettVacAct[i].countKey, itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
}
|
|
// Lubrorefrigeranti
|
|
vettLubro = new Lubro[adpConf.nLubro];
|
|
for (int i = 0; i < adpConf.nLubro; i++)
|
|
{
|
|
vettLubro[i] = new Lubro(adpConf.Lubro[i]);
|
|
currGateway.addItemNodeAndSet(vettLubro[i].countKey, itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
if (currGateway.protocollo != gwProtocol.SOURS)
|
|
{
|
|
currGateway.addItemNodeAndSet(vettLubro[i].statusKey, itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
}
|
|
}
|
|
// Slitta Mag
|
|
vettSlittaMag = new SlittaMag[adpConf.nSlittaMag];
|
|
for (int i = 0; i < adpConf.nSlittaMag; i++)
|
|
{
|
|
vettSlittaMag[i] = new SlittaMag(adpConf.SlittaMag[i]);
|
|
currGateway.addItemNodeAndSet(vettSlittaMag[i].countKey, itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
}
|
|
// Protezione Mag
|
|
vettProtMag = new ProtMag[adpConf.nProtMag];
|
|
for (int i = 0; i < adpConf.nProtMag; i++)
|
|
{
|
|
vettProtMag[i] = new ProtMag(adpConf.ProtMag[i]);
|
|
currGateway.addItemNodeAndSet(vettProtMag[i].countKey, itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
}
|
|
// Cooler
|
|
vettCooler = new Cooler[adpConf.nCooler];
|
|
for (int i = 0; i < adpConf.nCooler; i++)
|
|
{
|
|
vettCooler[i] = new Cooler(adpConf.Cooler[i]);
|
|
currGateway.addItemNodeAndSet(vettCooler[i].statusKey, itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
}
|
|
// Press
|
|
vettPress = new Press[adpConf.nPress];
|
|
for (int i = 0; i < adpConf.nPress; i++)
|
|
{
|
|
vettPress[i] = new Press(adpConf.Press[i]);
|
|
currGateway.addItemNodeAndSet(vettPress[i].valueKey, itemType.Sample, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
}
|
|
// Temp
|
|
vettTempe = new Tempe[adpConf.nTemp];
|
|
for (int i = 0; i < adpConf.nTemp; i++)
|
|
{
|
|
vettTempe[i] = new Tempe(adpConf.Temp[i]);
|
|
currGateway.addItemNodeAndSet(vettTempe[i].valueKey, itemType.Sample, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
}
|
|
// 2019.08.28 RIMETTO GESTIONE PROCESSO SEL!
|
|
//// lo riporto SOLO SE HO almeno 2 processi AND protocollo NON OPC-UA
|
|
//if (currGateway.protocollo != gwProtocol.SOURS && currAdpConf.nPath > 1)
|
|
//{
|
|
currGateway.addItemNodeAndSet("PROC_SEL", itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
//}
|
|
vettPath = new Path[adpConf.nPath];
|
|
for (int i = 0; i < adpConf.nPath; i++)
|
|
{
|
|
vettPath[i] = new Path(adpConf.Path[i]);
|
|
//samples
|
|
currGateway.addItemNodeAndSet(vettPath[i].feedKey, itemType.Sample, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettPath[i].feedOverKey, itemType.Sample, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettPath[i].rapidOverKey, itemType.Sample, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
// SOLO SE NON sono SOUR...
|
|
if (currGateway.protocollo != gwProtocol.SOURS)
|
|
{
|
|
currGateway.addItemNodeAndSet(vettPath[i].spindleOver_01_Key, itemType.Sample, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettPath[i].spindleOver_02_Key, itemType.Sample, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettPath[i].spindleOver_03_Key, itemType.Sample, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettPath[i].spindleOver_04_Key, itemType.Sample, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettPath[i].jogOverKey, itemType.Sample, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettPath[i].posAct_X_Key, itemType.Sample, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettPath[i].posAct_Y_Key, itemType.Sample, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettPath[i].posAct_Z_Key, itemType.Sample, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettPath[i].posAct_I_Key, itemType.Sample, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettPath[i].posAct_J_Key, itemType.Sample, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettPath[i].posAct_K_Key, itemType.Sample, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettPath[i].partIdKey, itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettPath[i].partCountKey, itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettPath[i].currProgKey, itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettPath[i].currProgRowNumKey, itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettPath[i].currAreaKey, itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
// conditions...
|
|
currGateway.addItemNodeAndSet(vettPath[i].alarmCncKey, itemType.Condition, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettPath[i].alarmPlcKey, itemType.Condition, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettPath[i].activeAxesKey, itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
}
|
|
// messages & events
|
|
currGateway.addItemNodeAndSet(vettPath[i].pathTypeKey, itemType.Message, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettPath[i].pathCodMKey, itemType.Message, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettPath[i].pathCodSKey, itemType.Message, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettPath[i].pathCodTKey, itemType.Message, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettPath[i].runModeKey, itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettPath[i].exeModeKey, itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettPath[i].gCodeAct_Key, itemType.Message, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettPath[i].subModeKey, itemType.Message, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
}
|
|
// UnOp
|
|
vettUnOp = new UnOp[adpConf.nUnOp];
|
|
for (int i = 0; i < adpConf.nUnOp; i++)
|
|
{
|
|
vettUnOp[i] = new UnOp(adpConf.UnOp[i]);
|
|
currGateway.addItemNodeAndSet(vettUnOp[i].toolIdKey, itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettUnOp[i].numCUKey, itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettUnOp[i].statusKey, itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettUnOp[i].vitaResKey, itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettUnOp[i].vitaResTypeKey, itemType.Message, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettUnOp[i].speedKey, itemType.Sample, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettUnOp[i].speedOverKey, itemType.Sample, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettUnOp[i].loadKey, itemType.Sample, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettUnOp[i].accTimeKey, itemType.Sample, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettUnOp[i].countKey, itemType.Sample, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
|
|
// SOLO SE NON sono SOUR...
|
|
if (currGateway.protocollo != gwProtocol.SOURS)
|
|
{
|
|
currGateway.addItemNodeAndSet(vettUnOp[i].kRevKey, itemType.Sample, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
}
|
|
}
|
|
// Assi
|
|
vettAxis = new Axis[adpConf.nAxis];
|
|
for (int i = 0; i < adpConf.nAxis; i++)
|
|
{
|
|
vettAxis[i] = new Axis(adpConf.Axis[i]);
|
|
// SOLO SE NON sono SOUR...
|
|
if (currGateway.protocollo != gwProtocol.SOURS)
|
|
{
|
|
currGateway.addItemNodeAndSet(vettAxis[i].batteryKey, itemType.Sample, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettAxis[i].groupKey, itemType.Message, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettAxis[i].accelActKey, itemType.Sample, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettAxis[i].isMastKey, itemType.Message, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
// conditions...
|
|
currGateway.addItemNodeAndSet(vettAxis[i].alarmCncKey, itemType.Condition, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettAxis[i].alarmPlcKey, itemType.Condition, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettAxis[i].mastIdKey, itemType.Message, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
}
|
|
currGateway.addItemNodeAndSet(vettAxis[i].descriptionKey, itemType.Message, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettAxis[i].mainProcKey, itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettAxis[i].directionKey, itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettAxis[i].loadKey, itemType.Sample, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettAxis[i].posActKey, itemType.Sample, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettAxis[i].posTgtKey, itemType.Sample, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettAxis[i].feedrateKey, itemType.Sample, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettAxis[i].feedOverKey, itemType.Sample, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettAxis[i].accTimeKey, itemType.Sample, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettAxis[i].distDoneKey, itemType.Sample, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
currGateway.addItemNodeAndSet(vettAxis[i].invDDoneKey, itemType.Event, availStatus.UNAVAILABLE.ToString().ToLower());
|
|
}
|
|
|
|
// allarmi "base"
|
|
currGateway.addAlarmNodes();
|
|
|
|
// 2019.07.22 NON RIPORTO USER_ACTION x SOUR
|
|
if (currGateway.protocollo != gwProtocol.SOURS)
|
|
{
|
|
// azioni utente
|
|
currGateway.addItemNodeAndSet("USER_ACTION", itemType.Message, "");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// alias booleano false = R
|
|
/// </summary>
|
|
public bool R = false;
|
|
|
|
/// <summary>
|
|
/// alias booleano true = W
|
|
/// </summary>
|
|
public bool W = true;
|
|
|
|
/// <summary>
|
|
/// wrapper di log
|
|
/// </summary>
|
|
public static Logger lg;
|
|
|
|
/// <summary>
|
|
/// valore booleano di check se sia in fase di COMUNICAZIONE ATTIVA con il PLC/NC
|
|
/// </summary>
|
|
protected bool adpCommAct;
|
|
|
|
/// <summary>
|
|
/// valore booleano di check se sia stato AVVIATO l'adapter (Running)
|
|
/// </summary>
|
|
public bool adpRunning = false;
|
|
|
|
/// <summary>
|
|
/// valore booleano di check se l'adapter STIA SALVANDO
|
|
/// </summary>
|
|
public bool adpSaving = false;
|
|
|
|
/// <summary>
|
|
/// valore booleano (richiesta di riavvio automatico)
|
|
/// </summary>
|
|
public bool adpTryRestart;
|
|
|
|
/// <summary>
|
|
/// Ultimo valore watchdog rilevato
|
|
/// </summary>
|
|
public bool lastWatchDog = false;
|
|
|
|
/// <summary>
|
|
/// Determina se utilizzare blocchi di memoria IOT contigui (e quindi processing "monoblocco" semplificato"=
|
|
/// </summary>
|
|
public bool procIotMem = false;
|
|
|
|
/// <summary>
|
|
/// porta x adapter (x restart)
|
|
/// </summary>
|
|
protected int adpPortNum;
|
|
|
|
/// <summary>
|
|
/// DataOra ultimo avvio adapter x watchdog
|
|
/// </summary>
|
|
protected DateTime adpStartRun;
|
|
|
|
/// <summary>
|
|
/// Data/ora ultimo avvio adapter
|
|
/// </summary>
|
|
public DateTime dtAvvioAdp = DateTime.Now;
|
|
|
|
/// <summary>
|
|
/// Data/ora ultimo spegnimento adapter
|
|
/// </summary>
|
|
public DateTime dtStopAdp = DateTime.Now;
|
|
|
|
/// <summary>
|
|
/// vettore gestione cronometraggi
|
|
/// </summary>
|
|
public DateTime inizio;
|
|
|
|
/// <summary>
|
|
/// Conteggio ATTUALE ore macchina ON
|
|
/// </summary>
|
|
public double contOreMaccOn;
|
|
|
|
/// <summary>
|
|
/// Conteggio ATTUALE ore macchina IN LAVORO
|
|
/// </summary>
|
|
public double contOreMaccLav;
|
|
|
|
/// <summary>
|
|
/// Conteggio ATTUALE numero movimenti Slitta Tastatore
|
|
/// </summary>
|
|
public double contSlittaTast;
|
|
|
|
/// <summary>
|
|
/// Vettore ATTUALE dei contatori giri cumulati elettromandrino (migliaia)
|
|
/// </summary>
|
|
public uint[] contGiriElettrom;
|
|
/// <summary>
|
|
/// Vettore ATTUALE dei contatori ore lavorate elettromandrino
|
|
/// </summary>
|
|
public uint[] contOreElettrom;
|
|
|
|
/// <summary>
|
|
/// Vettore ATTUALE dei contatori del movimento degli assi
|
|
/// </summary>
|
|
public double[] contDistMovAssi;
|
|
|
|
/// <summary>
|
|
/// Vettore ATTUALE dei contatori del tempo cumulato degli assi
|
|
/// </summary>
|
|
public double[] contAccTimeAssi;
|
|
|
|
/// <summary>
|
|
/// Vettore ATTUALE dei contatori del num inv degli assi
|
|
/// </summary>
|
|
public uint[] contNumInvAssi;
|
|
|
|
/// <summary>
|
|
/// vettore dei ProgramName dei path ATTIVI
|
|
/// </summary>
|
|
public string[] currPathProgrName;
|
|
|
|
/// <summary>
|
|
/// vettore dei PartId dei path ATTIVI
|
|
/// </summary>
|
|
public string[] currPathPartId;
|
|
|
|
/// <summary>
|
|
/// Vettore ATTUALE dei contatori del num pezzi fatti x PartId
|
|
/// </summary>
|
|
public uint[] currPathPartCount;
|
|
|
|
/// <summary>
|
|
/// Vettore ATTUALE dei contatori del work time x VacPump
|
|
/// </summary>
|
|
public uint[] currVacPumpWrkTime;
|
|
|
|
/// <summary>
|
|
/// Vettore ATTUALE dei contatori del numero impieghi VacAct
|
|
/// </summary>
|
|
public uint[] currVacActCount;
|
|
|
|
/// <summary>
|
|
/// Vettore ATTUALE dei contatori del Lubro
|
|
/// </summary>
|
|
public uint[] currLubroCount;
|
|
|
|
/// <summary>
|
|
/// Vettore ATTUALE dei contatori del numero cambi utensili x UnOp
|
|
/// </summary>
|
|
public uint[] currNumCambiUt;
|
|
/// <summary>
|
|
/// Vettore ATTUALE dei contatori del numero cambi utensili x UnOp
|
|
/// </summary>
|
|
public uint[] currRepetitionUnOp;
|
|
|
|
/// <summary>
|
|
/// Vettore ATTUALE dei contatori GENERICI MONOTONI CRESCENTI
|
|
/// </summary>
|
|
public uint[] currCounters;
|
|
/// <summary>
|
|
/// Vettore ATTUALE dei contatori GENERICI LIBERI
|
|
/// </summary>
|
|
public uint[] currRTCounters;
|
|
/// <summary>
|
|
/// Vettore ATTUALE dei contatori x VALORI GENERICI
|
|
/// </summary>
|
|
public int[] currRTVCount;
|
|
|
|
/// <summary>
|
|
/// Vettore ATTUALE dei contatori del numero movimenti Slitta Magazzino
|
|
/// </summary>
|
|
public uint[] currSlittaMag;
|
|
|
|
/// <summary>
|
|
/// Vettore ATTUALE dei contatori del numero movimenti Protezione Magazzino
|
|
/// </summary>
|
|
public uint[] currProtMag;
|
|
|
|
/// <summary>
|
|
/// Conteggio ISTANTANEO ore macchina ON
|
|
/// </summary>
|
|
public sampleVect istOreMaccOn;
|
|
|
|
/// <summary>
|
|
/// isteggio ISTANTANEO ore macchina IN LAVORO
|
|
/// </summary>
|
|
public sampleVect istOreMaccLav;
|
|
|
|
/// <summary>
|
|
/// Conteggio ISTANTANEO contatore del numero movimenti Slitta Tastatore
|
|
/// </summary>
|
|
public sampleVect istSlittaTast;
|
|
|
|
/// <summary>
|
|
/// Vettore ISTANTANEO dei contatori giri cumulati elettromandrino (migliaia)
|
|
/// </summary>
|
|
public sampleVect[] istGiriElettrom;
|
|
/// <summary>
|
|
/// Vettore ISTANTANEO dei contatori Apertura teste
|
|
/// </summary>
|
|
public sampleVect[] istRepetitionUnOp;
|
|
/// <summary>
|
|
/// Vettore ISTANTANEO dei contatori ORE LAVORATE elettromandrino
|
|
/// </summary>
|
|
public sampleVect[] istOreElettrom;
|
|
/// <summary>
|
|
/// Vettore ISTANTANEO dei contatori del movimento degli assi
|
|
/// </summary>
|
|
public sampleVect[] istDistMovAssi;
|
|
|
|
/// <summary>
|
|
/// Vettore ISTANTANEO dei contatori del LOAD degli assi
|
|
/// </summary>
|
|
public sampleVect[] istLoadAssi;
|
|
|
|
/// <summary>
|
|
/// Vettore ISTANTANEO dei contatori del tempo cumulato degli assi
|
|
/// </summary>
|
|
public sampleVect[] istAccTimeAssi;
|
|
|
|
/// <summary>
|
|
/// Vettore ISTANTANEO dei contatori del num inv degli assi
|
|
/// </summary>
|
|
public sampleVect[] istNumInvAssi;
|
|
|
|
/// <summary>
|
|
/// vettore dei Program Name dei path ISTANTANEI (nuovi/letti)
|
|
/// </summary>
|
|
public string[] istPathProgrName;
|
|
|
|
/// <summary>
|
|
/// vettore dei PartId dei path ISTANTANEI (nuovi/letti)
|
|
/// </summary>
|
|
public string[] istPathPartId;
|
|
|
|
/// <summary>
|
|
/// Vettore ISTANTANEO dei contatori del num pezzi fatti x PartId
|
|
/// </summary>
|
|
public sampleVect[] istPathPartCount;
|
|
|
|
/// <summary>
|
|
/// Vettore ISTANTANEO dei contatori del work time x VacPump
|
|
/// </summary>
|
|
public sampleVect[] istVacPumpWrkTime;
|
|
|
|
/// <summary>
|
|
/// Vettore ISTANTANEO dei contatori del numero impieghi VacAct
|
|
/// </summary>
|
|
public sampleVect[] istVacActCount;
|
|
|
|
/// <summary>
|
|
/// Vettore ISTANTANEO dei contatori del Lubro
|
|
/// </summary>
|
|
public sampleVect[] istLubroCount;
|
|
|
|
/// <summary>
|
|
/// Vettore ISTANTANEO dei contatori del numero cambi utensili x UnOp
|
|
/// </summary>
|
|
public sampleVect[] istNumCambiUt;
|
|
|
|
/// <summary>
|
|
/// Vettore ISTANTANEO dei contatori generici MONOTONI CRESCENTI
|
|
/// </summary>
|
|
public sampleVect[] istCounters;
|
|
/// <summary>
|
|
/// Vettore ISTANTANEO dei contatori generici LIBERI
|
|
/// </summary>
|
|
public sampleVect[] istRTCounters;
|
|
/// <summary>
|
|
/// Vettore ISTANTANEO dei contatori generici LIBERI x VALORI
|
|
/// </summary>
|
|
public sampleVect[] istRTVCount;
|
|
|
|
/// <summary>
|
|
/// Vettore ISTANTANEO dei contatori del numero movimenti Slitta Magazzino
|
|
/// </summary>
|
|
public sampleVect[] istSlittaMag;
|
|
|
|
/// <summary>
|
|
/// Vettore ISTANTANEO dei contatori del numero movimenti Protezione Magazzino
|
|
/// </summary>
|
|
public sampleVect[] istProtMag;
|
|
|
|
/// <summary>
|
|
/// vettore valori in file interscambio
|
|
/// </summary>
|
|
public Dictionary<string, string> generalStatus;
|
|
|
|
/// <summary>
|
|
/// Contenuto valori contatori manutenzione da PLC
|
|
/// </summary>
|
|
public otherData[] maintData;
|
|
|
|
/// <summary>
|
|
/// Contenuto valori variabili analogiche da PLC
|
|
/// </summary>
|
|
public otherData[] analogData;
|
|
|
|
/// <summary>
|
|
/// Contenuto valori variabili stringa da PLC
|
|
/// </summary>
|
|
public otherData[] stringData;
|
|
|
|
/// <summary>
|
|
/// Contenuto valori status data da PLC
|
|
/// </summary>
|
|
public otherData[] statusData;
|
|
|
|
/// <summary>
|
|
/// data-ora ultimo controllo movimento assi
|
|
/// </summary>
|
|
public DateTime lastChekAccumTimeAxis;
|
|
|
|
/// <summary>
|
|
/// posizione precedente assi per calcolo distanze...
|
|
/// </summary>
|
|
public double[] prevPosAxis;
|
|
|
|
/// <summary>
|
|
/// direzione precedente assi per calcolo inversioni...
|
|
/// </summary>
|
|
public int[] prevDirAxis;
|
|
|
|
/// <summary>
|
|
/// blocco memoria BYTE x lettura TUTTI i dati di buffer M/S/T
|
|
/// </summary>
|
|
public byte[] MemBlock_MST;
|
|
|
|
/// <summary>
|
|
/// Indica se sia necessario il salto x array codici MST (OSAI = 1, FANUC/SIEMENS=0)
|
|
/// </summary>
|
|
public int saltoMST = 0;
|
|
|
|
/// <summary>
|
|
/// Determina se sia encessario convertire valori little/big endian (SIEMENS=true, OSAI=FALSE)
|
|
/// </summary>
|
|
public bool hasBigEndian = false;
|
|
|
|
/// <summary>
|
|
/// Verifica se siano stati già mostrati gli allarmi x debug...
|
|
/// </summary>
|
|
public bool alarmMsgDispl = true;
|
|
|
|
/// <summary>
|
|
/// dimensione massima vettore memorie UT
|
|
/// </summary>
|
|
public short numMemUt = 200;
|
|
/// <summary>
|
|
/// Processo selezionato
|
|
/// </summary>
|
|
public string procSel = "";
|
|
/// <summary>
|
|
/// Modo del processo selezionato
|
|
/// </summary>
|
|
public int procMode = 0;
|
|
|
|
/// <summary>
|
|
/// Form chiamante
|
|
/// </summary>
|
|
protected MainForm parentForm;
|
|
|
|
/// <summary>
|
|
/// Conf adapter corrente
|
|
/// </summary>
|
|
public AdapterConf currAdpConf;
|
|
|
|
/// <summary>
|
|
/// Obj gestione la comunicazione a valle (secondo standard LOGFILE / MTC / SOURS)
|
|
/// </summary>
|
|
public Gateway currGateway;
|
|
|
|
#region altri oggetti
|
|
|
|
/// <summary>
|
|
/// 16 byte di strobe (4 word da 32 bit di flags...)
|
|
/// </summary>
|
|
public byte[] Strobes = new byte[16];
|
|
/// <summary>
|
|
/// 16 byte di strobe in risposta (4 word da 32 bit di flags...)
|
|
/// </summary>
|
|
public byte[] Acknowl = new byte[16];
|
|
|
|
public Dictionary<string, string> elencoSubMode;
|
|
|
|
/// <summary>
|
|
/// Prima word di strobe da array flag completo
|
|
/// </summary>
|
|
public StFlag32 STRB_DW0
|
|
{
|
|
get
|
|
{
|
|
return (StFlag32)BitConverter.ToUInt32(Strobes, 0);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Seconda word di strobe da array flag completo
|
|
/// </summary>
|
|
public StFlag32 STRB_DW1
|
|
{
|
|
get
|
|
{
|
|
return (StFlag32)BitConverter.ToUInt32(Strobes, 4);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Terza word di strobe da array flag completo
|
|
/// </summary>
|
|
public StFlag32 STRB_DW2
|
|
{
|
|
get
|
|
{
|
|
return (StFlag32)BitConverter.ToUInt32(Strobes, 8);
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Valore statud x standard OPC-UA (da valorizzare in adapter specifico)
|
|
/// valore default a -1 --> SE NON VALORIZZATO NON LO USA:..
|
|
/// </summary>
|
|
public int ouStatus = -1;
|
|
|
|
/// <summary>
|
|
/// Quarta word di strobe da array flag completo
|
|
/// </summary>
|
|
public StFlag32 STRB_DW3
|
|
{
|
|
get
|
|
{
|
|
return (StFlag32)BitConverter.ToUInt32(Strobes, 12);
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// PRIMO BYTE della Quarta word di strobe
|
|
/// </summary>
|
|
public byte ACK_DW3_B0
|
|
{
|
|
get
|
|
{
|
|
return Acknowl[12];
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Quarta word di strobe da array flag completo
|
|
/// </summary>
|
|
public StFlag32 STRB_DW4
|
|
{
|
|
get
|
|
{
|
|
return (StFlag32)BitConverter.ToUInt32(Strobes, 16);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Prima word di ACKnowledgment da array flag completo
|
|
/// </summary>
|
|
public StFlag32 ACK_DW0
|
|
{
|
|
get
|
|
{
|
|
return (StFlag32)BitConverter.ToUInt32(Acknowl, 0);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Seconda word di ACKnowledgment da array flag completo
|
|
/// </summary>
|
|
public StFlag32 ACK_DW1
|
|
{
|
|
get
|
|
{
|
|
return (StFlag32)BitConverter.ToUInt32(Acknowl, 4);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Terza word di ACKnowledgment da array flag completo
|
|
/// </summary>
|
|
public StFlag32 ACK_DW2
|
|
{
|
|
get
|
|
{
|
|
return (StFlag32)BitConverter.ToUInt32(Acknowl, 8);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Quarta word di ACKnowledgment da array flag completo
|
|
/// </summary>
|
|
public StFlag32 ACK_DW3
|
|
{
|
|
get
|
|
{
|
|
return (StFlag32)BitConverter.ToUInt32(Acknowl, 12);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Strobe mask PLC
|
|
/// </summary>
|
|
public Strobe STROBE_PLC = 0;
|
|
|
|
/// <summary>
|
|
/// Strobe mask adapter
|
|
/// </summary>
|
|
public Strobe STROBE_ADP = 0;
|
|
|
|
/// <summary>
|
|
/// Status flag
|
|
/// </summary>
|
|
public StatusBitMap STATUS_FLAG = 0;
|
|
|
|
/// <summary>
|
|
/// Variabili stato macchina principali
|
|
/// </summary>
|
|
public StFlag8 ST_MACCH = 0;
|
|
|
|
public List<string>[] codaM;
|
|
public List<string>[] codaS;
|
|
public List<string>[] codaT;
|
|
|
|
/// <summary>
|
|
/// Verifica se los tatus sia recuperabile dal PLC ( oppure da calcolare)
|
|
/// </summary>
|
|
public bool ouStatusByPlc
|
|
{
|
|
get
|
|
{
|
|
return utils.CRB("ouStatusByPlc");
|
|
}
|
|
}
|
|
|
|
#endregion altri oggetti
|
|
|
|
#region Gestione contatori & obj specifici (Events & Samples)
|
|
|
|
/// <summary>
|
|
/// Vettore conters monotoni crescenti - EVENT
|
|
/// </summary>
|
|
public List<string> elCounter;
|
|
|
|
/// <summary>
|
|
/// Vettore conters realtime (liberi) - EVENT
|
|
/// </summary>
|
|
public List<string> elRTCounter;
|
|
/// <summary>
|
|
/// Vettore conters realtime value GENERICI comprensivo di indice - EVENT
|
|
/// </summary>
|
|
public Dictionary<string, int> elRTVCount;
|
|
|
|
/// <summary>
|
|
/// Vettore status (EVENT)
|
|
/// </summary>
|
|
public List<string> elStatus;
|
|
|
|
/// <summary>
|
|
/// Vettore analog data (SAMPLE)
|
|
/// </summary>
|
|
public List<string> elAnalogData;
|
|
|
|
/// <summary>
|
|
/// Vettore string data (SAMPLE)
|
|
/// </summary>
|
|
public List<string> elStringData;
|
|
|
|
#endregion Gestione contatori & obj specifici (Events & Samples)
|
|
|
|
#region oggetti complessi/completi
|
|
|
|
public VacuumPump[] vettVacPump;
|
|
public VacuumAct[] vettVacAct;
|
|
public Lubro[] vettLubro;
|
|
public SlittaMag[] vettSlittaMag;
|
|
public ProtMag[] vettProtMag;
|
|
public Cooler[] vettCooler;
|
|
public Press[] vettPress;
|
|
public Tempe[] vettTempe;
|
|
public Path[] vettPath;
|
|
public UnOp[] vettUnOp;
|
|
public Axis[] vettAxis;
|
|
public MemArea[] vettMemArea;
|
|
public Dictionary<string, string> DirectMem = new Dictionary<string, string>();
|
|
|
|
#endregion oggetti complessi/completi
|
|
|
|
public event EventHandler eh_refreshed;
|
|
|
|
/// <summary>
|
|
/// caricamento allarmi da file
|
|
/// </summary>
|
|
protected void loadAllarmi()
|
|
{
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lg.Info("Inizio caricamento vettore allarmi");
|
|
}
|
|
|
|
int totRighe = 0;
|
|
string fileName = string.Format(@"{0}\{1}", utils.confDir, utils.CRS("AlarmList"));
|
|
string linea;
|
|
totRighe = File.ReadLines(fileName).Count();
|
|
// creo un vettore della dimensione corretta... conta anche commenti tanto poi riduco...
|
|
currGateway.elencoAllarmi = new allarme[File.ReadLines(fileName).Count()];
|
|
// carica da file...
|
|
StreamReader file = new StreamReader(fileName);
|
|
// leggo 1 linea alla volta...
|
|
int numRiga = 0;
|
|
while ((linea = file.ReadLine()) != null)
|
|
{
|
|
// SE non è un commento...
|
|
if (linea.Substring(0, 1) != "#")
|
|
{
|
|
//elencoAllarmi[rumRiga] = decodeAlarmLine(linea, ':');
|
|
currGateway.elencoAllarmi[numRiga] = decodeAlarmLine(linea, utils.CRC("testCharSep"));
|
|
numRiga++;
|
|
}
|
|
}
|
|
// chiudo file
|
|
file.Close();
|
|
// ora trimmo vettore al solo numero VERO degli allarmi caricati...
|
|
Array.Resize<allarme>(ref currGateway.elencoAllarmi, numRiga);
|
|
|
|
// inizializzo a zero il vettore allarmi...
|
|
int numByte = (int)Math.Ceiling(Convert.ToDecimal(numRiga) / 8);
|
|
// 2016.07.20: dimensione AlarmFlags è la MAX tra quella del numero allarmi ed il numero allarmi standard dalla memoria...
|
|
if (numByte < 32)
|
|
{
|
|
numByte = 32;
|
|
}
|
|
|
|
currGateway.AlarmFlags = new byte[numByte];
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lg.Info(string.Format("Fine caricamento vettore allarmi: {0} allarmi caricati!", numRiga));
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Caricamento file rimappatura naming (per evitare uso improprio di "_" che porta a "split")
|
|
/// impiega il file delle sostituzioni "inizio/fine/contenuto/tutto" (NameRepRolesList)
|
|
/// </summary>
|
|
protected void loadNameRepRoles()
|
|
{
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lg.Info("Inizio caricamento dizionario remapping nomi variabili");
|
|
}
|
|
try
|
|
{
|
|
// PRIMA leggo il file GENERATO di replacement... NON dando per scontato ci sia...
|
|
if (File.Exists(utils.nameRepRoleFileSOUR))
|
|
{
|
|
importFile(utils.nameRepRoleFileSOUR);
|
|
}
|
|
|
|
// processo file pre REPLACE parziale (con like) - file DI BASE ESPLICITO
|
|
importFile(utils.nameRepRoleFile);
|
|
}
|
|
|
|
catch
|
|
{ }
|
|
}
|
|
|
|
private void importFile(string fileName)
|
|
{
|
|
// init variabili
|
|
string linea;
|
|
int rumRiga = 0;
|
|
string valSost = "";
|
|
string valTrad;
|
|
string sMode = "";
|
|
string sSearch = "";
|
|
string[] dictSubst;
|
|
subsMode modoSearch;
|
|
substSearch tipoCerca;
|
|
StreamReader file;
|
|
replDict replacement;
|
|
// carica da file...
|
|
file = new StreamReader(fileName);
|
|
// leggo 1 linea alla volta
|
|
while ((linea = file.ReadLine()) != null)
|
|
{
|
|
linea = linea.Trim();
|
|
// se HA CONTENUTO
|
|
if (linea != "")
|
|
{
|
|
// SE non è un commento...
|
|
if (linea.Substring(0, 1) != "#")
|
|
{
|
|
dictSubst = linea.Split(utils.CRC("testCharSep"));
|
|
// recupero valori inseriti
|
|
sMode = dictSubst[0].Trim();
|
|
sSearch = dictSubst[1].Trim();
|
|
valSost = dictSubst[2].Trim();
|
|
valTrad = dictSubst[3].Trim();
|
|
switch (sMode)
|
|
{
|
|
case "X":
|
|
modoSearch = subsMode.X;
|
|
break;
|
|
default:
|
|
case "A":
|
|
modoSearch = subsMode.A;
|
|
break;
|
|
}
|
|
switch (sSearch)
|
|
{
|
|
case "B":
|
|
tipoCerca = substSearch.B;
|
|
break;
|
|
case "C":
|
|
tipoCerca = substSearch.C;
|
|
break;
|
|
case "E":
|
|
tipoCerca = substSearch.E;
|
|
break;
|
|
default:
|
|
case "I":
|
|
tipoCerca = substSearch.I;
|
|
break;
|
|
}
|
|
replacement = new replDict { modo = modoSearch, search = tipoCerca, tradz = valTrad };
|
|
// 3 oggetti: tipo ricerca | valOriginale | valTradotto
|
|
if (currGateway.nameRepRoles != null && currGateway.nameRepRoles.ContainsKey(valSost))
|
|
{
|
|
currGateway.nameRepRoles.Remove(valSost);
|
|
}
|
|
currGateway.nameRepRoles.Add(valSost, replacement);
|
|
rumRiga++;
|
|
}
|
|
}
|
|
}
|
|
// chiudo file
|
|
file.Close();
|
|
|
|
// registro chiusura
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lg.Info(string.Format("Fine caricamento file {0} con dizionario traduzioni nomi: {1} regole caricate", fileName, rumRiga));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Caricamento file rimappatura naming (per evitare uso improprio di "_" che porta a "split")
|
|
/// impiega il file delle sostituzioni "inizio/fine/contenuto/tutto" (NameRepRolesList)
|
|
/// </summary>
|
|
protected void loadMemCopyList()
|
|
{
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lg.Info("Inizio caricamento dizionario copia variabili REDIS");
|
|
}
|
|
string linea;
|
|
string fileName = "";
|
|
int rumRiga = 0;
|
|
string valSost = "";
|
|
string valTrad;
|
|
string[] dictSubst;
|
|
StreamReader file;
|
|
try
|
|
{
|
|
// processo file pre REPLACE parziale (con like)
|
|
fileName = string.Format(@"{0}\{1}", utils.confDir, utils.CRS("MemCopyList"));
|
|
// carica da file...
|
|
file = new StreamReader(fileName);
|
|
// leggo 1 linea alla volta...
|
|
while ((linea = file.ReadLine()) != null)
|
|
{
|
|
linea = linea.Trim();
|
|
// se HA CONTENUTO
|
|
if (linea != "")
|
|
{
|
|
// SE non è un commento...
|
|
if (linea.Substring(0, 1) != "#")
|
|
{
|
|
dictSubst = linea.Split(utils.CRC("testCharSep"));
|
|
// recupero valori inseriti
|
|
valSost = dictSubst[0].Trim();
|
|
valTrad = dictSubst[1].Trim();
|
|
|
|
// 3 oggetti: tipo ricerca | valOriginale | valTradotto
|
|
if (currGateway.memCopyList != null && currGateway.memCopyList.ContainsKey(valSost))
|
|
{
|
|
currGateway.nameRepRoles.Remove(valSost);
|
|
}
|
|
currGateway.memCopyList.Add(valSost, valTrad);
|
|
rumRiga++;
|
|
}
|
|
}
|
|
}
|
|
// chiudo file
|
|
file.Close();
|
|
|
|
// registro chiusura
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lg.Info(string.Format("Fine caricamento dizionario copia variabili MemCopy: {0} righe caricate", rumRiga));
|
|
}
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
/// <summary>
|
|
/// Caricamento altri file necessari epr adapter all'avvio
|
|
/// </summary>
|
|
protected virtual void loadOtherFile()
|
|
{
|
|
// se è SOURS --> leggo datamodel...
|
|
if (currGateway.protocollo == gwProtocol.SOURS)
|
|
{
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lg.Info("Inizio caricamento DataModel per OPC-UA REDIS server");
|
|
}
|
|
string fileName = "";
|
|
int rumRiga = 0;
|
|
StreamReader file;
|
|
// processo file pre REPLACE parziale (con like)
|
|
fileName = string.Format(@"{0}\{1}", utils.confDir, utils.CRS("DataModel"));
|
|
// carica da file...
|
|
file = new StreamReader(fileName);
|
|
// leggo file...
|
|
string rawDataModel = file.ReadToEnd();
|
|
|
|
// pre-processo datamodel...
|
|
currGateway.DataModel = utils.xmlSanitize(rawDataModel);
|
|
// chiudo file
|
|
file.Close();
|
|
|
|
|
|
// secondo metodo x deserializzare...
|
|
DataModel dm = new DataModel();
|
|
var currMachine2 = dm.Deserialize(currGateway.DataModel);
|
|
|
|
// registro chiusura
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lg.Info(string.Format("Fine caricamento DataModel XML: {0} righe caricate", rumRiga));
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Lettura file gestione dati manutenzione da PLC
|
|
/// </summary>
|
|
/// <param name="memPre"></param>
|
|
/// <param name="baseAddr"></param>
|
|
/// <param name="memSize"></param>
|
|
public void loadMaintData(string memPre, int baseAddr, int memSize)
|
|
{
|
|
// carico dati x Maintenance
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lg.Info("Inizio caricamento vettore variabili manutenzione gestite");
|
|
}
|
|
|
|
int totRighe = 0;
|
|
int numCounters = 0;
|
|
int numRTCounters = 0;
|
|
int numRTVCount = 0;
|
|
string fileName = utils.CounterListFile;
|
|
if (currGateway.protocollo == gwProtocol.SOURS)
|
|
{
|
|
fileName = utils.CounterListFileSOUR;
|
|
}
|
|
string linea;
|
|
totRighe = File.ReadLines(fileName).Count();
|
|
// creo un vettore della dimensione corretta... conta anche commenti tanto poi riduco...
|
|
maintData = new otherData[File.ReadLines(fileName).Count()];
|
|
// carica da file...
|
|
StreamReader file = new StreamReader(fileName);
|
|
// leggo 1 linea alla volta...
|
|
int numRiga = 0;
|
|
while ((linea = file.ReadLine()) != null)
|
|
{
|
|
// se NON VUOTA...
|
|
if (linea != "")
|
|
{
|
|
// SE non è un commento...
|
|
if (linea.Substring(0, 1) != "#")
|
|
{
|
|
maintData[numRiga] = decodeOtherData(linea, utils.CRC("testCharSep"), memPre, baseAddr, memSize);
|
|
// se è un counter lo processo come tale..
|
|
if (maintData[numRiga].varName.StartsWith("Counter_"))
|
|
{
|
|
numCounters++;
|
|
}
|
|
else if (maintData[numRiga].varName.StartsWith("RTCounter_"))
|
|
{
|
|
numRTCounters++;
|
|
}
|
|
else if (maintData[numRiga].dataType == "RTV")
|
|
{
|
|
numRTVCount++;
|
|
}
|
|
numRiga++;
|
|
}
|
|
}
|
|
}
|
|
// chiudo file
|
|
file.Close();
|
|
// ora trimmo vettore al solo numero VERO dei valori caricati...
|
|
Array.Resize<otherData>(ref maintData, numRiga);
|
|
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lg.Info(string.Format("Fine caricamento vettore di {0} variabili manutenzione gestite", numRiga));
|
|
}
|
|
// se log verboso 10+ --> scrivo tutti!
|
|
if (utils.CRI("loglevel") > 9)
|
|
{
|
|
foreach (var item in maintData)
|
|
{
|
|
lg.Info($"VarName: {item.varName} | dataType: {item.dataType} | codNum: {item.codNum} | memAddr: {item.memAddr}");
|
|
}
|
|
}
|
|
|
|
elCounter = new List<string>();
|
|
elRTCounter = new List<string>();
|
|
elRTVCount = new Dictionary<string, int>();
|
|
currCounters = new uint[numCounters];
|
|
currRTCounters = new uint[numRTCounters];
|
|
currRTVCount = new int[numRTVCount];
|
|
istCounters = new sampleVect[numCounters];
|
|
istRTCounters = new sampleVect[numRTCounters];
|
|
istRTVCount = new sampleVect[numRTVCount];
|
|
int idx = 0;
|
|
int idxRT = 0;
|
|
int idxRTV = 0;
|
|
foreach (otherData item in maintData)
|
|
{
|
|
if (item.varName.StartsWith("Counter_"))
|
|
{
|
|
elCounter.Add(item.varName);
|
|
currGateway.addItemNodeByType(item.varName, itemType.Event);
|
|
istCounters[idx] = new sampleVect();
|
|
idx++;
|
|
}
|
|
else if (item.varName.StartsWith("RTCounter_"))
|
|
{
|
|
elRTCounter.Add(item.varName);
|
|
currGateway.addItemNodeByType(item.varName, itemType.Event);
|
|
istRTCounters[idxRT] = new sampleVect();
|
|
idxRT++;
|
|
}
|
|
else if (item.dataType == "RTV")
|
|
{
|
|
elRTVCount.Add(item.varName, idxRTV);
|
|
currGateway.addItemNodeByType(item.varName, itemType.Event);
|
|
istRTVCount[idxRTV] = new sampleVect();
|
|
idxRTV++;
|
|
}
|
|
else
|
|
{
|
|
currGateway.addItemNodeByType(item.varName, itemType.Event);
|
|
}
|
|
}
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lg.Info(string.Format("inizializzato vettore di {0} MTC.EVENTS delle variabili CONTATORI generiche", numRiga));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Lettura file gestione dati analogici da PLC
|
|
/// </summary>
|
|
/// <param name="memPre"></param>
|
|
/// <param name="baseAddr"></param>
|
|
/// <param name="memSize"></param>
|
|
public void loadAnalogData(string memPre, int baseAddr, int memSize)
|
|
{
|
|
// carico dati x Maintenance
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lg.Info("Inizio caricamento vettore variabili analogiche gestite");
|
|
}
|
|
|
|
int totRighe = 0;
|
|
string fileName = utils.AnalogListFile;
|
|
if (currGateway.protocollo == gwProtocol.SOURS)
|
|
{
|
|
fileName = utils.AnalogListFileSOUR;
|
|
}
|
|
string linea;
|
|
totRighe = File.ReadLines(fileName).Count();
|
|
// creo un vettore della dimensione corretta... conta anche commenti tanto poi riduco...
|
|
analogData = new otherData[File.ReadLines(fileName).Count()];
|
|
// carica da file...
|
|
StreamReader file = new StreamReader(fileName);
|
|
// leggo 1 linea alla volta...
|
|
int numRiga = 0;
|
|
while ((linea = file.ReadLine()) != null)
|
|
{
|
|
// se NON VUOTA...
|
|
if (linea != "")
|
|
{
|
|
// SE non è un commento...
|
|
if (linea.Substring(0, 1) != "#")
|
|
{
|
|
analogData[numRiga] = decodeOtherData(linea, utils.CRC("testCharSep"), memPre, baseAddr, memSize);
|
|
numRiga++;
|
|
}
|
|
}
|
|
}
|
|
// chiudo file
|
|
file.Close();
|
|
// ora trimmo vettore al solo numero VERO dei valori caricati...
|
|
Array.Resize<otherData>(ref analogData, numRiga);
|
|
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lg.Info(string.Format("Fine caricamento vettore di {0} variabili analogiche gestite", numRiga));
|
|
}
|
|
|
|
// ora inizializzo l'insieme dei Samples delle var analogiche
|
|
elAnalogData = new List<string>();
|
|
string varName = "";
|
|
for (int i = 0; i < numRiga; i++)
|
|
{
|
|
varName = analogData[i].varName;
|
|
if (currGateway.protocollo != gwProtocol.SOURS)
|
|
{
|
|
varName = string.Format("AV_" + analogData[i].varName);
|
|
}
|
|
elAnalogData.Add(varName);
|
|
currGateway.addItemNodeByType(varName, itemType.Sample);
|
|
}
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lg.Info(string.Format("inizializzato vettore di {0} MTC.SAMPLES delle variabili analogiche", numRiga));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Lettura file gestione dati status da PLC
|
|
/// </summary>
|
|
/// <param name="memPre"></param>
|
|
/// <param name="baseAddr"></param>
|
|
/// <param name="memSize"></param>
|
|
public void loadStatusData(string memPre, int baseAddr, int memSize)
|
|
{
|
|
// carico dati x Maintenance
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lg.Info("Inizio caricamento vettore variabili status gestite");
|
|
}
|
|
|
|
int totRighe = 0;
|
|
// secondo protocollo scelgo quale file...
|
|
string fileName = utils.StatusListFile;
|
|
if (currGateway.protocollo == gwProtocol.SOURS)
|
|
{
|
|
fileName = utils.StatusListFileSOUR;
|
|
}
|
|
string linea;
|
|
totRighe = File.ReadLines(fileName).Count();
|
|
// creo un vettore della dimensione corretta... conta anche commenti tanto poi riduco...
|
|
statusData = new otherData[File.ReadLines(fileName).Count()];
|
|
// carica da file...
|
|
StreamReader file = new StreamReader(fileName);
|
|
// leggo 1 linea alla volta...
|
|
int numRiga = 0;
|
|
while ((linea = file.ReadLine()) != null)
|
|
{
|
|
// se NON VUOTA...
|
|
if (linea != "")
|
|
{
|
|
// SE non è un commento...
|
|
if (linea.Substring(0, 1) != "#")
|
|
{
|
|
statusData[numRiga] = decodeBitData(linea, utils.CRC("testCharSep"), memPre, baseAddr, memSize);
|
|
numRiga++;
|
|
}
|
|
}
|
|
}
|
|
// chiudo file
|
|
file.Close();
|
|
// ora trimmo vettore al solo numero VERO dei valori caricati...
|
|
Array.Resize<otherData>(ref statusData, numRiga);
|
|
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lg.Info(string.Format("Fine caricamento vettore di {0} variabili status gestite", numRiga));
|
|
}
|
|
|
|
// ora inizializzo l'insieme degli Eventi di status
|
|
elStatus = new List<string>();
|
|
string varName = "";
|
|
for (int i = 0; i < numRiga; i++)
|
|
{
|
|
varName = statusData[i].varName;
|
|
if (currGateway.protocollo != gwProtocol.SOURS)
|
|
{
|
|
varName = string.Format("ST_" + statusData[i].varName);
|
|
}
|
|
elStatus.Add(varName);
|
|
currGateway.addItemNodeByType(varName, itemType.Event);
|
|
}
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lg.Info(string.Format("inizializzato vettore di {0} MTC.EVENTS di status", numRiga));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Lettura file gestione dati stringa da PLC
|
|
/// </summary>
|
|
/// <param name="memPre"></param>
|
|
/// <param name="baseAddr"></param>
|
|
/// <param name="memSize"></param>
|
|
public void loadStringData(string memPre, int baseAddr, int memSize)
|
|
{
|
|
// carico dati x Maintenance
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lg.Info("Inizio caricamento vettore variabili stringa gestite");
|
|
}
|
|
|
|
int totRighe = 0;
|
|
string fileName = utils.StringListFile;
|
|
if (currGateway.protocollo == gwProtocol.SOURS)
|
|
{
|
|
fileName = utils.StringListFileSOUR;
|
|
}
|
|
string linea;
|
|
totRighe = File.ReadLines(fileName).Count();
|
|
// creo un vettore della dimensione corretta... conta anche commenti tanto poi riduco...
|
|
stringData = new otherData[File.ReadLines(fileName).Count()];
|
|
// carica da file...
|
|
StreamReader file = new StreamReader(fileName);
|
|
// leggo 1 linea alla volta...
|
|
int numRiga = 0;
|
|
while ((linea = file.ReadLine()) != null)
|
|
{
|
|
// se NON VUOTA...
|
|
if (linea != "")
|
|
{
|
|
// SE non è un commento...
|
|
if (linea.Substring(0, 1) != "#")
|
|
{
|
|
stringData[numRiga] = decodeOtherData(linea, utils.CRC("testCharSep"), memPre, baseAddr, memSize);
|
|
numRiga++;
|
|
}
|
|
}
|
|
}
|
|
// chiudo file
|
|
file.Close();
|
|
// ora trimmo vettore al solo numero VERO dei valori caricati...
|
|
Array.Resize<otherData>(ref stringData, numRiga);
|
|
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lg.Info(string.Format("Fine caricamento vettore di {0} variabili stringa gestite", numRiga));
|
|
}
|
|
|
|
// ora inizializzo l'insieme dei Samples delle var analogiche
|
|
elStringData = new List<string>();
|
|
string varName = "";
|
|
for (int i = 0; i < numRiga; i++)
|
|
{
|
|
varName = stringData[i].varName;
|
|
if (currGateway.protocollo != gwProtocol.SOURS)
|
|
{
|
|
varName = string.Format("STR_" + stringData[i].varName);
|
|
}
|
|
elStringData.Add(varName);
|
|
currGateway.addItemNodeByType(varName, itemType.Sample);
|
|
}
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lg.Info(string.Format("inizializzato vettore di {0} MTC.SAMPLES delle variabili string", numRiga));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// caricamento allarmi da file
|
|
/// </summary>
|
|
protected void loadSubMode()
|
|
{
|
|
try
|
|
{
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lg.Info("Inizio caricamento vettore SubMode");
|
|
}
|
|
|
|
int totRighe = 0;
|
|
string fileName = string.Format(@"{0}\{1}", utils.confDir, utils.CRS("SubModeListFilePath"));
|
|
string linea;
|
|
totRighe = File.ReadLines(fileName).Count();
|
|
// inizializzo
|
|
elencoSubMode = new Dictionary<string, string>();
|
|
// carica da file...
|
|
StreamReader file = new StreamReader(fileName);
|
|
// leggo 1 linea alla volta...
|
|
string[] valori;
|
|
while ((linea = file.ReadLine()) != null)
|
|
{
|
|
// SE non è un commento...
|
|
if (linea.Substring(0, 1) != "#")
|
|
{
|
|
valori = linea.Split(':');
|
|
elencoSubMode.Add(valori[0], valori[1]);
|
|
}
|
|
}
|
|
// chiudo file
|
|
file.Close();
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lg.Info("Fine caricamento vettore SubMode");
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error(exc, "Eccezione in caricamento SubMode");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Decodifica file allarme, con linee allarme composte come di seguito
|
|
/// LEGACY: CodAllarme | Gruppo | Livello | Descrizione (verrà poi replicata in IT e EN)
|
|
/// v1811: CodAllarme | Gruppo | Livello | Descrizione (lingua corrente) | Descrizione IT (italiano) | Descrizione EN (inglese)
|
|
/// </summary>
|
|
/// <param name="linea">Allarme in formato tutto su 1 linea</param>
|
|
/// <param name="separator">Tipicamente |</param>
|
|
/// <returns></returns>
|
|
protected allarme decodeAlarmLine(string linea, char separator)
|
|
{
|
|
string[] valori = linea.Split(separator);
|
|
allarme answ = new allarme();
|
|
// in base a quanti oggetti ho uso tutti i valori indicati singolarmente
|
|
if (valori.Length == 6)
|
|
{
|
|
answ = new allarme(valori[0], valori[1], valori[2], valori[3], valori[4], valori[5]);
|
|
}
|
|
else // oppure decido di replicare lingua corrente --> IT / EN
|
|
{
|
|
answ = new allarme(valori[0], valori[1], valori[2], valori[3]);
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recupera il numero (iniziale) da una stringa prendendo la aprte sino al separatore...
|
|
/// </summary>
|
|
/// <param name="linea"></param>
|
|
/// <param name="separator"></param>
|
|
/// <returns></returns>
|
|
protected int startNumb(string linea, char separator)
|
|
{
|
|
int answ = 0;
|
|
try
|
|
{
|
|
answ = Convert.ToInt32(linea.Substring(0, linea.IndexOf(separator)));
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Decodifica file datiProdSCM
|
|
/// </summary>
|
|
/// <param name="linea"></param>
|
|
/// <param name="separator"></param>
|
|
/// <returns></returns>
|
|
protected datiProdSCM decodeScmProdLine(string linea, char separator)
|
|
{
|
|
string[] valori = linea.Split(separator);
|
|
datiProdSCM answ = null;
|
|
if (valori.Length == 23)
|
|
{
|
|
answ = new datiProdSCM(valori);
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Decodifica file allarme
|
|
/// </summary>
|
|
/// <param name="linea"></param>
|
|
/// <param name="separator"></param>
|
|
/// <param name="memPre">tipo memoria (R/D/...)</param>
|
|
/// <param name="baseAddr">indirizzo di partenza memoria</param>
|
|
/// <param name="memSize">dimensione singolo slot in byte</param>
|
|
/// <returns></returns>
|
|
protected otherData decodeOtherData(string linea, char separator, string memPre, int baseAddr, int memSize)
|
|
{
|
|
string[] valori = linea.Split(separator);
|
|
int shift = 0;
|
|
try
|
|
{
|
|
shift = Convert.ToInt32(valori[0]) - 1;
|
|
}
|
|
catch
|
|
{ }
|
|
string memAddr = string.Format("{0}{1}", memPre, baseAddr + shift * memSize);
|
|
int scale = 1;
|
|
if (valori.Length > 3)
|
|
{
|
|
int.TryParse(valori[3].Trim(), out scale);
|
|
}
|
|
return new otherData(valori[0], memAddr, valori[1].Trim(), valori[2].Trim(), scale);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Decodifica file MAP (caso ESA/IOT)
|
|
/// </summary>
|
|
/// <param name="linea"></param>
|
|
/// <param name="separator"></param>
|
|
/// <param name="ByteNum">indirizzo Byte: indirizzo di partenza memoria</param>
|
|
/// <param name="memSize">dimensione singolo slot in byte</param>
|
|
/// <param name="BitNum">indirizzo bit: numero riga x calcolo indice bit</param>
|
|
/// <returns></returns>
|
|
protected otherData decodeBitData(string linea, char separator, int ByteNum, int memSize, int BitNum)
|
|
{
|
|
string[] valori = linea.Split(separator);
|
|
int shift = 0;
|
|
try
|
|
{
|
|
shift = Convert.ToInt32(valori[0]) - 1;
|
|
}
|
|
catch
|
|
{ }
|
|
int resto = 0;
|
|
Math.DivRem(BitNum, 8, out resto);
|
|
string memAddr = string.Format("{0}.{1}", ByteNum + shift * memSize, resto);
|
|
return new otherData(valori[0], memAddr, valori[1].Trim(), valori[2].Trim());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Decodifica file MAP (caso FANUC/OSAI/...)
|
|
/// </summary>
|
|
/// <param name="linea"></param>
|
|
/// <param name="separator"></param>
|
|
/// <param name="memPre">tipo memoria (R/D/...)</param>
|
|
/// <param name="baseAddr">indirizzo Byte: indirizzo di partenza memoria</param>
|
|
/// <param name="memSize">dimensione singolo slot in byte</param>
|
|
/// <returns></returns>
|
|
protected otherData decodeBitData(string linea, char separator, string memPre, int baseAddr, int memSize)
|
|
{
|
|
string[] valori = linea.Split(separator);
|
|
int shift = 0;
|
|
//indirizzo bit: numero riga x calcolo indice bit (base 0!!!)
|
|
int numRiga = 0;
|
|
int.TryParse(valori[0], out numRiga);
|
|
numRiga--;
|
|
try
|
|
{
|
|
shift = (numRiga) / (8 * memSize);
|
|
}
|
|
catch
|
|
{ }
|
|
int resto = 0;
|
|
Math.DivRem(numRiga, 8 * memSize, out resto);
|
|
string memAddr = string.Format("{0}{1}.{2}", memPre, baseAddr + shift, resto);
|
|
return new otherData(valori[0], memAddr, valori[1].Trim(), valori[2].Trim());
|
|
}
|
|
|
|
#region metodi adapter
|
|
|
|
/// <summary>
|
|
/// lettura file di persistenza
|
|
/// </summary>
|
|
public void loadPersData()
|
|
{
|
|
try
|
|
{
|
|
// nuova lettura valori da file persistenza...
|
|
contOreMaccOn = getStoredValDouble("ACC_TIME");
|
|
contOreMaccLav = getStoredValDouble("ACC_TIME_WORK");
|
|
contSlittaTast = getStoredValDouble("SlittaTastatore_Count");
|
|
|
|
for (int i = 0; i < currAdpConf.nUnOp; i++)
|
|
{
|
|
contGiriElettrom[i] = getStoredValUInt(string.Format("UnOp_{0:00}_AccTime", i + 1));
|
|
contOreElettrom[i] = getStoredValUInt(string.Format("UnOp_{0:00}_KRev", i + 1));
|
|
currNumCambiUt[i] = getStoredValUInt(string.Format("UnOp_{0:00}_NumCU", i + 1));
|
|
currRepetitionUnOp[i] = getStoredValUInt(string.Format("UnOp_{0:00}_Count", i + 1));
|
|
}
|
|
|
|
for (int i = 0; i < currAdpConf.nAxis; i++)
|
|
{
|
|
contDistMovAssi[i] = getStoredValUInt(string.Format("Axis_{0:00}_DistDone", i + 1));
|
|
contNumInvAssi[i] = getStoredValUInt(string.Format("Axis_{0:00}_InvDDone", i + 1));
|
|
contAccTimeAssi[i] = getStoredValDouble(string.Format("Axis_{0:00}_AccTime", i + 1));
|
|
}
|
|
|
|
for (int i = 0; i < currAdpConf.nVacuumPump; i++)
|
|
{
|
|
currVacPumpWrkTime[i] = getStoredValUInt(string.Format("VacPump_{0:00}_WrkTime", i + 1));
|
|
}
|
|
|
|
for (int i = 0; i < currAdpConf.nVacuumAct; i++)
|
|
{
|
|
currVacActCount[i] = getStoredValUInt(string.Format("VacAct_{0:00}_Count", i + 1));
|
|
}
|
|
|
|
for (int i = 0; i < currAdpConf.nLubro; i++)
|
|
{
|
|
currLubroCount[i] = getStoredValUInt(string.Format("Lubro_{0:00}_Count", i + 1));
|
|
}
|
|
|
|
for (int i = 0; i < currAdpConf.nSlittaMag; i++)
|
|
{
|
|
currSlittaMag[i] = getStoredValUInt(string.Format("SlittaMagazzino_{0:00}_Count", i + 1));
|
|
}
|
|
|
|
if (elCounter != null)
|
|
{
|
|
for (int i = 0; i < elCounter.Count; i++)
|
|
{
|
|
currCounters[i] = getStoredValUInt(string.Format("Counter_{0:000}", i + 1));
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < currAdpConf.nProtMag; i++)
|
|
{
|
|
currProtMag[i] = getStoredValUInt(string.Format("ProtMagazzino_{0:00}_Count", i + 1));
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error(string.Format("Eccezione in decodifica valori PersLayer: {0}{1}", Environment.NewLine, exc));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Avvia l'adapter secondo parametri app.config
|
|
/// </summary>
|
|
public virtual void startAdapter()
|
|
{
|
|
lg.Info("Starting adapter...");
|
|
// leggo parametri da app.config
|
|
int port = 0;
|
|
if (currGateway.protocollo == gwProtocol.MTC)
|
|
{
|
|
port = utils.CRI("MTC_port");
|
|
}
|
|
else if (currGateway.protocollo == gwProtocol.SOURS)
|
|
{
|
|
port = utils.CRI("SOURS_port");
|
|
}
|
|
// continuo
|
|
parentForm.commPlcActive = false;
|
|
adpRunning = true;
|
|
|
|
dtAvvioAdp = DateTime.Now;
|
|
TimingData.resetData();
|
|
// inizializzo vettori di utility..
|
|
loadAllarmi();
|
|
loadNameRepRoles();
|
|
loadSubMode();
|
|
loadOtherFile();
|
|
|
|
// salvo porta!
|
|
adpPortNum = port;
|
|
currGateway.port = port;
|
|
// avvio
|
|
currGateway.start();
|
|
|
|
// setto status a ACTIV, SOLO SE è MTC
|
|
if (currGateway.protocollo == gwProtocol.MTC)
|
|
{
|
|
currGateway.updateItemNodeValue("STATUS", actStatus.ACTIVE.ToString());
|
|
}
|
|
|
|
// resetto running flag...
|
|
adpCommAct = false;
|
|
|
|
// avvio i Sample vectors...
|
|
istOreMaccOn = new sampleVect();
|
|
istOreMaccLav = new sampleVect();
|
|
istSlittaTast = new sampleVect();
|
|
|
|
// carico valori da adapter x i conteggi
|
|
contOreMaccOn = currAdpConf.ContOreMaccOn;
|
|
contOreMaccLav = currAdpConf.ContOreMaccLav;
|
|
contSlittaTast = currAdpConf.ContSlittaTast;
|
|
|
|
// UnOp
|
|
contGiriElettrom = new uint[currAdpConf.nUnOp];
|
|
contOreElettrom = new uint[currAdpConf.nUnOp];
|
|
istGiriElettrom = new sampleVect[currAdpConf.nUnOp];
|
|
istRepetitionUnOp = new sampleVect[currAdpConf.nUnOp];
|
|
istOreElettrom = new sampleVect[currAdpConf.nUnOp];
|
|
currNumCambiUt = new uint[currAdpConf.nUnOp];
|
|
currRepetitionUnOp = new uint[currAdpConf.nUnOp];
|
|
|
|
istNumCambiUt = new sampleVect[currAdpConf.nUnOp];
|
|
for (int i = 0; i < currAdpConf.nUnOp; i++)
|
|
{
|
|
// leggo tutti i dati...
|
|
List<DataRefItem<string, string>> listaDR = currAdpConf.UnOp[i].dataRefList;
|
|
// punto all'item
|
|
DataRefItem<string, string> riContKRev = listaDR.Find(x => x.Key == string.Format("UnOp_{0:00}_KRev", i + 1));
|
|
DataRefItem<string, string> riContOre = listaDR.Find(x => x.Key == string.Format("UnOp_{0:00}_AccTime", i + 1));
|
|
DataRefItem<string, string> riContNumCU = listaDR.Find(x => x.Key == string.Format("UnOp_{0:00}_NumCU", i + 1));
|
|
DataRefItem<string, string> riRepUO = listaDR.Find(x => x.Key == string.Format("UnOp_{0:00}_Count", i + 1));
|
|
// recupero valore giri...
|
|
UInt32 contTotGiri = Convert.ToUInt32(riContKRev.Value);
|
|
// recupero valore ore...
|
|
UInt32 contTotOre = Convert.ToUInt32(riContOre.Value);
|
|
// recupero valore num cambi ut...
|
|
UInt32 contNumCU = Convert.ToUInt32(riContNumCU.Value);
|
|
UInt32 contRepUO = Convert.ToUInt32(riRepUO.Value);
|
|
// salvo valore letto
|
|
contGiriElettrom[i] = contTotGiri;
|
|
contOreElettrom[i] = contTotOre;
|
|
currNumCambiUt[i] = contNumCU;
|
|
currRepetitionUnOp[i] = contRepUO;
|
|
istGiriElettrom[i] = new sampleVect();
|
|
istRepetitionUnOp[i] = new sampleVect();
|
|
istOreElettrom[i] = new sampleVect();
|
|
istNumCambiUt[i] = new sampleVect();
|
|
}
|
|
// imposto num assi e leggo valori salvati...
|
|
contDistMovAssi = new double[currAdpConf.nAxis];
|
|
istDistMovAssi = new sampleVect[currAdpConf.nAxis];
|
|
istLoadAssi = new sampleVect[currAdpConf.nAxis];
|
|
contNumInvAssi = new uint[currAdpConf.nAxis];
|
|
istAccTimeAssi = new sampleVect[currAdpConf.nAxis];
|
|
contAccTimeAssi = new double[currAdpConf.nAxis];
|
|
istNumInvAssi = new sampleVect[currAdpConf.nAxis];
|
|
lastChekAccumTimeAxis = DateTime.Now;
|
|
for (int i = 0; i < currAdpConf.nAxis; i++)
|
|
{
|
|
// leggo tutti i dati...
|
|
List<DataRefItem<string, string>> listaDR = currAdpConf.Axis[i].dataRefList;
|
|
// punto all'item
|
|
DataRefItem<string, string> riContDist = listaDR.Find(x => x.Key == string.Format("Axis_{0:00}_DistDone", i + 1));
|
|
DataRefItem<string, string> riNumInv = listaDR.Find(x => x.Key == string.Format("Axis_{0:00}_Invers", i + 1));
|
|
DataRefItem<string, string> riAccTime = listaDR.Find(x => x.Key == string.Format("Axis_{0:00}_AccTime", i + 1));
|
|
// recupero valori...
|
|
contDistMovAssi[i] = Convert.ToUInt32(riContDist.Value);
|
|
contNumInvAssi[i] = Convert.ToUInt32(riNumInv.Value);
|
|
contAccTimeAssi[i] = Convert.ToDouble(riAccTime.Value);
|
|
|
|
// nons erve init generale allarmi finale
|
|
istDistMovAssi[i] = new sampleVect();
|
|
istLoadAssi[i] = new sampleVect();
|
|
istAccTimeAssi[i] = new sampleVect();
|
|
istNumInvAssi[i] = new sampleVect();
|
|
}
|
|
currPathPartId = new string[currAdpConf.nPath];
|
|
istPathPartId = new string[currAdpConf.nPath];
|
|
currPathProgrName = new string[currAdpConf.nPath];
|
|
istPathProgrName = new string[currAdpConf.nPath];
|
|
currPathPartCount = new uint[currAdpConf.nPath];
|
|
istPathPartCount = new sampleVect[currAdpConf.nPath];
|
|
for (int i = 0; i < currAdpConf.nPath; i++)
|
|
{
|
|
// leggo tutti i dati...
|
|
List<DataRefItem<string, string>> listaDR = currAdpConf.Path[i].dataRefList;
|
|
// punto all'item
|
|
DataRefItem<string, string> riPathProgr = listaDR.Find(x => x.Key == string.Format("Path_{0:00}_PartId", i + 1));
|
|
DataRefItem<string, string> riPathPzTot = listaDR.Find(x => x.Key == string.Format("Path_{0:00}_PZ_TOT", i + 1));
|
|
// recupero valori...
|
|
currPathPartId[i] = riPathProgr.Value;
|
|
currPathPartCount[i] = Convert.ToUInt32(riPathPzTot.Value);
|
|
currPathProgrName[i] = "";
|
|
if (currGateway.protocollo != gwProtocol.SOURS)
|
|
{
|
|
currGateway.initAlarm(currGateway.conditionNodes[vettPath[i].alarmCncKey]);
|
|
currGateway.initAlarm(currGateway.conditionNodes[vettPath[i].alarmPlcKey]);
|
|
}
|
|
istPathPartCount[i] = new sampleVect();
|
|
}
|
|
currVacPumpWrkTime = new uint[currAdpConf.nVacuumPump];
|
|
istVacPumpWrkTime = new sampleVect[currAdpConf.nVacuumPump];
|
|
for (int i = 0; i < currAdpConf.nVacuumPump; i++)
|
|
{
|
|
// leggo tutti i dati...
|
|
List<DataRefItem<string, string>> listaDR = currAdpConf.VacuumPump[i].dataRefList;
|
|
// punto all'item
|
|
DataRefItem<string, string> riVacPumpWrk = listaDR.Find(x => x.Key == string.Format("VacPump_{0:00}_WrkTime", i + 1));
|
|
// recupero valori...
|
|
currVacPumpWrkTime[i] = Convert.ToUInt32(riVacPumpWrk.Value);
|
|
istVacPumpWrkTime[i] = new sampleVect();
|
|
}
|
|
currVacActCount = new uint[currAdpConf.nVacuumAct];
|
|
istVacActCount = new sampleVect[currAdpConf.nVacuumAct];
|
|
for (int i = 0; i < currAdpConf.nVacuumAct; i++)
|
|
{
|
|
// leggo tutti i dati...
|
|
List<DataRefItem<string, string>> listaDR = currAdpConf.VacuumAct[i].dataRefList;
|
|
// punto all'item
|
|
DataRefItem<string, string> riVacActCount = listaDR.Find(x => x.Key == string.Format("VacAct_{0:00}_Count", i + 1));
|
|
// recupero valori...
|
|
currVacActCount[i] = Convert.ToUInt32(riVacActCount.Value);
|
|
istVacActCount[i] = new sampleVect();
|
|
}
|
|
currLubroCount = new uint[currAdpConf.nLubro];
|
|
istLubroCount = new sampleVect[currAdpConf.nLubro];
|
|
for (int i = 0; i < currAdpConf.nLubro; i++)
|
|
{
|
|
// leggo tutti i dati...
|
|
List<DataRefItem<string, string>> listaDR = currAdpConf.Lubro[i].dataRefList;
|
|
// punto all'item
|
|
DataRefItem<string, string> riLubro = listaDR.Find(x => x.Key == string.Format("Lubro_{0:00}_Count", i + 1));
|
|
// recupero valori...
|
|
currLubroCount[i] = Convert.ToUInt32(riLubro.Value);
|
|
istLubroCount[i] = new sampleVect();
|
|
}
|
|
currSlittaMag = new uint[currAdpConf.nSlittaMag];
|
|
istSlittaMag = new sampleVect[currAdpConf.nSlittaMag];
|
|
for (int i = 0; i < currAdpConf.nSlittaMag; i++)
|
|
{
|
|
// leggo tutti i dati...
|
|
List<DataRefItem<string, string>> listaDR = currAdpConf.SlittaMag[i].dataRefList;
|
|
// punto all'item
|
|
DataRefItem<string, string> riSlittaMag = listaDR.Find(x => x.Key == string.Format("SlittaMagazzino_{0:00}_Count", i + 1));
|
|
// recupero valori...
|
|
currSlittaMag[i] = Convert.ToUInt32(riSlittaMag.Value);
|
|
istSlittaMag[i] = new sampleVect();
|
|
}
|
|
currProtMag = new uint[currAdpConf.nProtMag];
|
|
istProtMag = new sampleVect[currAdpConf.nProtMag];
|
|
for (int i = 0; i < currAdpConf.nProtMag; i++)
|
|
{
|
|
// leggo tutti i dati...
|
|
List<DataRefItem<string, string>> listaDR = currAdpConf.ProtMag[i].dataRefList;
|
|
// punto all'item
|
|
DataRefItem<string, string> riProtMag = listaDR.Find(x => x.Key == string.Format("ProtMagazzino_{0:00}_Count", i + 1));
|
|
// recupero valori...
|
|
currProtMag[i] = Convert.ToUInt32(riProtMag.Value);
|
|
istProtMag[i] = new sampleVect();
|
|
}
|
|
// inizializzo TUTTI gli alarms
|
|
currGateway.initAlarms();
|
|
|
|
adpTryRestart = true;
|
|
parentForm.displayTaskAndWait("Adapter Started!");
|
|
}
|
|
|
|
/// <summary>
|
|
/// ferma l'adapter...
|
|
/// </summary>
|
|
/// <param name="tryRestart">indica se si debba tentare di riavviare l'adapter (con caduta connessione viene fermato in automatico)</param>
|
|
public void stopAdapter(bool tryRestart)
|
|
{
|
|
parentForm.displayTaskAndWait("Stopping adapter...");
|
|
adpTryRestart = false;
|
|
|
|
if (currGateway.protocollo == gwProtocol.MTC)
|
|
{
|
|
currGateway.updateItemNodeValue("STATUS", actStatus.INACTIVE.ToString());
|
|
}
|
|
// faccio una chiamata extra ad ogni metodo di check...
|
|
gaterAndSend(gatherCycle.HF);
|
|
gaterAndSend(gatherCycle.MF);
|
|
gaterAndSend(gatherCycle.LF);
|
|
gaterAndSend(gatherCycle.VLF);
|
|
parentForm.displayTaskAndWait("Stopping adapter - last periodic data read...");
|
|
|
|
// chiudo la connessione all'adapter...
|
|
tryDisconnect();
|
|
// Stop everything...
|
|
try
|
|
{
|
|
currGateway.stop();
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error(exc, "Eccezione in chiusura Adapter:{0}{1}", Environment.NewLine, exc);
|
|
}
|
|
dtStopAdp = DateTime.Now;
|
|
adpPortNum = currGateway.port;
|
|
adpTryRestart = tryRestart;
|
|
adpRunning = false;
|
|
|
|
// chiudo!
|
|
parentForm.resetProgBar();
|
|
parentForm.dataMonitor_1 = "... not connected, waiting for data ...";
|
|
parentForm.dataMonitor_2 = "";
|
|
parentForm.dataMonitor_3 = "";
|
|
parentForm.displayTaskAndWait("Adapter Stopped.");
|
|
parentForm.commPlcActive = false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// effettua recupero dati ed invio valori modificati...
|
|
/// </summary>
|
|
/// <param name="ciclo"></param>
|
|
public void gaterAndSend(gatherCycle ciclo)
|
|
{
|
|
// controllo connessione/connettività
|
|
if (connectionOk)
|
|
{
|
|
// controllo non sia già in esecuzione...
|
|
if (!adpCommAct)
|
|
{
|
|
// provo ad avviare
|
|
try
|
|
{
|
|
// avvio fase raccolta dati
|
|
currGateway.beginDataCollect();
|
|
|
|
// imposto flag adapter running..
|
|
adpCommAct = true;
|
|
adpStartRun = DateTime.Now;
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
parentForm.displayTaskAndWait(string.Format("Adapter NOT STARTED!!!{0}{1}", Environment.NewLine, exc));
|
|
adpCommAct = false;
|
|
adpStartRun = DateTime.Now;
|
|
}
|
|
if (adpCommAct)
|
|
{
|
|
// try / catch generale altrimenti segno che è disconnesso...
|
|
try
|
|
{
|
|
// processing degli strobes di allarme (da ULTIMA rappresentazione vettore dell'ADP)
|
|
processAlarm();
|
|
// se sono in debug testo invio vario dati che ho generalizzato da MTC...
|
|
#if DEBUG
|
|
testData();
|
|
#endif
|
|
bool showDebugData = false;
|
|
|
|
// verifico se processare tutto "in un colpo solo"
|
|
if (procIotMem)
|
|
{
|
|
processAllMemory();
|
|
// ciclo lento x log...
|
|
if (ciclo == gatherCycle.LF)
|
|
{
|
|
// Eventuale log!
|
|
if (utils.CRB("recTime"))
|
|
{
|
|
logTimeResults();
|
|
}
|
|
}
|
|
}
|
|
// oppure in "modalità classica" con multistep...
|
|
else
|
|
{
|
|
// ciclo VHF x invii...
|
|
if (ciclo == gatherCycle.VHF)
|
|
{
|
|
// processo e svuoto Eventuali code di invio per Codici M/S/T
|
|
trySendCodMST();
|
|
}
|
|
// POI CONTROLLO cicli + lenti di lettura...
|
|
// ciclo HF: recupero update status & strobes vari
|
|
if (ciclo == gatherCycle.HF)
|
|
{
|
|
// parte che eseguo SEMPRE: RECUPERO stato di tutti gli strobe/status e degli ack attualmente noti
|
|
getStrobeAndAckStatus();
|
|
|
|
// faccio refresh degli allarmi segnalati (da strobe su vettore locale)
|
|
refreshAlarmState(STRB_DW0, true);
|
|
// acquisizione degli status
|
|
processStatus();
|
|
// processing degli strobes
|
|
processStrobe();
|
|
}
|
|
else if (ciclo == gatherCycle.MF)
|
|
{
|
|
resetDebugConsole();
|
|
// leggo parametri a media freq (dati globali, path, assi, Unità Operatrice)
|
|
getGlobalData();
|
|
getUnOp();
|
|
getPath();
|
|
getAxis();
|
|
|
|
// se NON in modalità PROD eseguo chiamate "extra" x allarmi
|
|
if (utils.CRS("mode") == "debug")
|
|
{
|
|
// SOLO in modalità testing forzo il controllo continuo allarmi...
|
|
forceAlarmCheck();
|
|
}
|
|
// salva richiesta update x dati debug
|
|
showDebugData = true;
|
|
}
|
|
// ciclo lento
|
|
else if (ciclo == gatherCycle.LF)
|
|
{
|
|
// leggo EVENTUALI parametri da config file
|
|
getConfigParam();
|
|
///acquisisco dati su programma in esecuzione e dati generali (stato, orologio, power...)
|
|
getSlowChangingData();
|
|
|
|
// Eventuale log!
|
|
if (utils.CRB("recTime"))
|
|
{
|
|
logTimeResults();
|
|
}
|
|
}
|
|
// ciclo lentissimo
|
|
else if (ciclo == gatherCycle.VLF)
|
|
{
|
|
lg.Info("Richiesta lettura completa allarmi attivi");
|
|
// faccio comunque rilettura completa allarmi...
|
|
forceAlarmCheck();
|
|
}
|
|
}
|
|
if (showDebugData)
|
|
{
|
|
// verifica se debba salvare e mostrare dati
|
|
checkSavePersDataLayer();
|
|
}
|
|
|
|
// INVIO dati variati!
|
|
currGateway.sendChanged();
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
// segnalo eccezione e indico disconnesso...
|
|
lg.Error(exc, string.Format("Errore in gestione ciclo principale ADP, fermo adapter{0}{1}", Environment.NewLine, exc));
|
|
parentForm.fermaAdapter(true);
|
|
}
|
|
// tolgo flag running
|
|
adpCommAct = false;
|
|
}
|
|
else
|
|
{
|
|
lg.Info("ADP not running...");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// log ADP running
|
|
lg.Error("Non eseguo chiamata: ADP ancora in running");
|
|
// se è bloccato da oltre maxSec lo sblocco...
|
|
if (DateTime.Now.Subtract(adpStartRun).TotalSeconds > utils.CRI("maxAdapterLockSec"))
|
|
{
|
|
// tolgo flag running
|
|
adpCommAct = false;
|
|
adpStartRun = DateTime.Now;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// log connessione KO
|
|
lg.Error("CicloMF - Connessione non disponibile, provo a riconnettere");
|
|
// provo a riconnettere SE abilitato tryRestart...
|
|
if (adpTryRestart && !connectionOk)
|
|
{
|
|
lg.Info("ConnKO - tryConnect");
|
|
tryConnect();
|
|
}
|
|
}
|
|
if (eh_refreshed != null)
|
|
{
|
|
eh_refreshed(this, new EventArgs());
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Effettua verifica direzione asse
|
|
/// </summary>
|
|
/// <param name="newDir"></param>
|
|
/// <param name="i"></param>
|
|
protected string calculateDirection(int newDir, int i)
|
|
{
|
|
string tipoAsse = "";
|
|
string direzione = "";
|
|
try
|
|
{
|
|
tipoAsse = currGateway.getItemNode(vettAxis[i].typeKey).ToString();
|
|
if (tipoAsse.EndsWith("UNAVAILABLE"))
|
|
{
|
|
tipoAsse = "LINEAR";
|
|
}
|
|
}
|
|
catch
|
|
{ }
|
|
if (tipoAsse == "" || tipoAsse == "OPC_UA_REDIS.DataItemRed")
|
|
{
|
|
// recupero info TIPO ASSE
|
|
List<DataRefItem<string, string>> drl = vettAxis[i].dataRefList;
|
|
foreach (var item in drl)
|
|
{
|
|
if (item.Key == vettAxis[i].typeKey)
|
|
{
|
|
tipoAsse = item.Value;
|
|
}
|
|
}
|
|
}
|
|
// verifico tipo direzione da tipo asse...
|
|
if (tipoAsse == "LINEAR")
|
|
{
|
|
if (currGateway.protocollo == gwProtocol.SOURS)
|
|
{
|
|
direzione = (newDir > 0) ? "POS" : "NEG";
|
|
}
|
|
else
|
|
{
|
|
// ?: conditional operator.
|
|
direzione = (newDir > 0) ? "POSITIVE" : "NEGATIVE";
|
|
}
|
|
}
|
|
else if (tipoAsse == "ROTATIONAL")
|
|
{
|
|
if (currGateway.protocollo == gwProtocol.SOURS)
|
|
{
|
|
direzione = (newDir > 0) ? "CW" : "CCW";
|
|
}
|
|
else
|
|
{
|
|
direzione = (newDir > 0) ? "CLOCKWISE" : "COUNTER_CLOCKWISE";
|
|
}
|
|
}
|
|
return direzione;
|
|
}
|
|
/// <summary>
|
|
/// Area per effettuazione test (tipicamente variabili scambiate da MTC --> generali...
|
|
/// </summary>
|
|
private void testData()
|
|
{
|
|
// imposto continuamente valore assetChange/removal x TESGING !!!FARE!!! togliere
|
|
int sCount = DateTime.Now.Second;
|
|
}
|
|
|
|
public void resetDebugConsole()
|
|
{
|
|
// resetto console debug...
|
|
parentForm.dataMonitor_1 = "";
|
|
parentForm.dataMonitor_2 = "";
|
|
parentForm.dataMonitor_3 = "";
|
|
// indico msg allarme NON inviati
|
|
alarmMsgDispl = false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// recupero dati globali (e comuni)
|
|
/// </summary>
|
|
public virtual void getGlobalData()
|
|
{
|
|
// accodo dati path in DataMonitor......
|
|
StringBuilder sb1 = new StringBuilder();
|
|
StringBuilder sb2 = new StringBuilder();
|
|
|
|
// dati base...
|
|
string currProc = "";
|
|
// 2019.08.28 RIMETTO GESTIONE PROCESSO SEL!
|
|
//if (currGateway.protocollo != gwProtocol.SOURS || currAdpConf.nPath > 1)
|
|
//{
|
|
try
|
|
{
|
|
currProc = currGateway.getItemNode("PROC_SEL").ToString();
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error($"Eccezione in recupero PROC_SEL:{Environment.NewLine}{exc}");
|
|
}
|
|
//}
|
|
sb1.AppendLine(string.Format("POWER {0}: | EmStop:{1} | ProcSel: {2}", currGateway.getItemNode("POWER"), currGateway.getItemNode("E_STOP"), currProc));
|
|
|
|
try
|
|
{
|
|
// leggo dati globali...
|
|
readGlobalData();
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error($"Eccezione in readGlobalData:{Environment.NewLine}{exc}");
|
|
}
|
|
|
|
// legge overrides...
|
|
try
|
|
{
|
|
readOverrides(ref sb1);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error($"Eccezione in readOverrides:{Environment.NewLine}{exc}");
|
|
}
|
|
// processo allarmi CNC
|
|
try
|
|
{
|
|
procCncAlarm();
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error($"Eccezione in procCncAlarm:{Environment.NewLine}{exc}");
|
|
}
|
|
// accodo dati base!
|
|
try
|
|
{
|
|
parentForm.dataMonitor_1 += sb1.ToString();
|
|
// accodo dati UT...
|
|
for (int i = 0; i < currAdpConf.nUnOp; i++)
|
|
{
|
|
sb2.AppendLine(string.Format("UT: ToolId {0} | VitaRes {1} | TipoVita {2} ", currGateway.getItemNode(vettUnOp[i].toolIdKey), currGateway.getItemNode(vettUnOp[i].vitaResKey), currGateway.getItemNode(vettUnOp[i].vitaResTypeKey)));
|
|
}
|
|
parentForm.dataMonitor_2 = sb2.ToString();
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error($"Eccezione in accodamento a parentForm:{Environment.NewLine}{exc}");
|
|
}
|
|
// gestisco lettura dati manutenzione da PLC...
|
|
try
|
|
{
|
|
getMtzDataFromPlc();
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error($"Eccezione in getMtzDataFromPlc:{Environment.NewLine}{exc}");
|
|
}
|
|
// gestisco lettura dati status da PLC...
|
|
try
|
|
{
|
|
getStatusDataFromPlc();
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error($"Eccezione in getStatusDataFromPlc:{Environment.NewLine}{exc}");
|
|
}
|
|
// gestisco lettura dati analogici da PLC...
|
|
try
|
|
{
|
|
getAnalogDataFromPlc();
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error($"Eccezione in getAnalogDataFromPlc:{Environment.NewLine}{exc}");
|
|
}
|
|
// gestisco lettura dati stringa da PLC...
|
|
try
|
|
{
|
|
getStringDataFromPlc();
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error($"Eccezione in getStringDataFromPlc:{Environment.NewLine}{exc}");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Legge dati globali...
|
|
/// </summary>
|
|
public virtual void readGlobalData()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// legge dati override...
|
|
/// </summary>
|
|
/// <param name="sb1"></param>
|
|
/// <returns></returns>
|
|
public virtual bool readOverrides(ref StringBuilder sb1)
|
|
{
|
|
bool fatto = false;
|
|
return fatto;
|
|
}
|
|
|
|
/// <summary>
|
|
/// processa allarmi CNC...
|
|
/// </summary>
|
|
public virtual bool procCncAlarm()
|
|
{
|
|
bool fatto = false;
|
|
return fatto;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gestione lettura dati manutenzione
|
|
/// </summary>
|
|
public virtual bool getMtzDataFromPlc()
|
|
{
|
|
bool fatto = false;
|
|
return fatto;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gestione lettura dati analogici
|
|
/// </summary>
|
|
public virtual bool getAnalogDataFromPlc()
|
|
{
|
|
bool fatto = false;
|
|
return fatto;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gestione lettura dati stringa
|
|
/// </summary>
|
|
public virtual bool getStringDataFromPlc()
|
|
{
|
|
bool fatto = false;
|
|
return fatto;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gestione lettura dati status da PLC
|
|
/// </summary>
|
|
public virtual bool getStatusDataFromPlc()
|
|
{
|
|
bool fatto = false;
|
|
return fatto;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processa i dati di override di un path
|
|
/// </summary>
|
|
/// <param name="currIdx">idx path (zero based)</param>
|
|
/// <param name="dataVector">vettore 7 valori dei dati (valori int16 jog/feed/rapid/spindle[1..4])</param>
|
|
/// <param name="sb">StringBuilder da aggiornare</param>
|
|
public bool procPathOverride(int currIdx, ushort[] dataVector, ref StringBuilder sb)
|
|
{
|
|
bool fatto = false;
|
|
// 2019.09.20: provo a salvare i 3 override...
|
|
try
|
|
{
|
|
FeedRateOverPath[currIdx] = dataVector[1];
|
|
RapidOverPath[currIdx] = dataVector[2];
|
|
SpeedRateOverPath[currIdx] = dataVector[3];
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error(exc, $"Errore in processing override per path {currIdx}");
|
|
}
|
|
// altro processing
|
|
try
|
|
{
|
|
// SOLO SE NON sono SOUR...
|
|
if (currGateway.protocollo != gwProtocol.SOURS)
|
|
{
|
|
currGateway.updateItemNodeValue(vettPath[currIdx].jogOverKey, dataVector[0] / 100);
|
|
}
|
|
|
|
// se ho + di 1 path prendo la sua...
|
|
if (FeedRatePath.Length > 1)
|
|
{
|
|
currGateway.updateItemNodeValue(vettPath[currIdx].feedKey, FeedRatePath[currIdx]);
|
|
}
|
|
else
|
|
{
|
|
// prendo quella GLOBALE...
|
|
currGateway.updateItemNodeValue(vettPath[currIdx].feedKey, FeedRate);
|
|
}
|
|
|
|
// leggo da vettore... CABLATO DIVISO PER 100!!!
|
|
currGateway.updateItemNodeValue(vettPath[currIdx].feedOverKey, dataVector[1] / 100);
|
|
currGateway.updateItemNodeValue(vettPath[currIdx].rapidOverKey, dataVector[2] / 100);
|
|
if (currGateway.protocollo != gwProtocol.SOURS)
|
|
{
|
|
currGateway.updateItemNodeValue(vettPath[currIdx].spindleOver_01_Key, dataVector[3] / 100);
|
|
currGateway.updateItemNodeValue(vettPath[currIdx].spindleOver_02_Key, dataVector[4] / 100);
|
|
currGateway.updateItemNodeValue(vettPath[currIdx].spindleOver_03_Key, dataVector[5] / 100);
|
|
currGateway.updateItemNodeValue(vettPath[currIdx].spindleOver_04_Key, dataVector[6] / 100);
|
|
}
|
|
|
|
// SE il processo è quello corrente...
|
|
string processo = string.Format("P{0}", currIdx + 1);
|
|
bool doProc = false;
|
|
if (currGateway.protocollo != gwProtocol.SOURS)
|
|
{
|
|
doProc = currGateway.getItemNode("PROC_SEL").ToString() == processo;
|
|
}
|
|
else
|
|
{
|
|
doProc = (((DataItemRed)currGateway.getItemNode("PROC_SEL")).Value.ToString() == processo);
|
|
}
|
|
if (doProc)
|
|
{
|
|
// se da conf richeisto salvo override globale come max tra i 4 letti...
|
|
if (utils.CRB("getMaxSpOver"))
|
|
{
|
|
int maxSpeedOver = 0;
|
|
maxSpeedOver = ((dataVector[3] / 100) > maxSpeedOver) ? dataVector[3] / 100 : maxSpeedOver;
|
|
maxSpeedOver = ((dataVector[4] / 100) > maxSpeedOver) ? dataVector[4] / 100 : maxSpeedOver;
|
|
maxSpeedOver = ((dataVector[5] / 100) > maxSpeedOver) ? dataVector[5] / 100 : maxSpeedOver;
|
|
maxSpeedOver = ((dataVector[6] / 100) > maxSpeedOver) ? dataVector[6] / 100 : maxSpeedOver;
|
|
|
|
// includo lettura override spindle... è la massima tra quelle che ho letto (dai path)
|
|
SpeedRateOver = maxSpeedOver;
|
|
}
|
|
}
|
|
|
|
// salvo stringa!
|
|
sb.AppendLine(string.Format("P{0} - Override % Jog | Feed | Rapid: {1} | {2} | {3}", currIdx + 1, dataVector[0] / 100, dataVector[1] / 100, dataVector[2] / 100));
|
|
sb.AppendLine(string.Format("P{0} - Override % Spindle 1 | 2 | 3 | 4: {1} | {2} | {3} | {4}", currIdx + 1, dataVector[3] / 100, dataVector[4] / 100, dataVector[5] / 100, dataVector[6] / 100));
|
|
fatto = true;
|
|
}
|
|
catch
|
|
{ }
|
|
return fatto;
|
|
}
|
|
|
|
/// <summary>
|
|
/// riporta il log di tutti i dati di results temporali registrati
|
|
/// </summary>
|
|
public void logTimeResults()
|
|
{
|
|
if (TimingData.results.Count > 0)
|
|
{
|
|
lg.Info("{0}--------------- START TIMING DATA ---------------", Environment.NewLine);
|
|
int globNumCall = 0;
|
|
TimeSpan globAvgMsec = new TimeSpan(0);
|
|
foreach (TimeRec item in TimingData.results)
|
|
{
|
|
lg.Info("Chiamate {0}: effettuate {1}, tempo medio {2:N2} msec | impegno canale {3:P3}", item.codCall, item.numCall, item.avgMsec, item.totMsec.TotalSeconds / DateTime.Now.Subtract(dtAvvioAdp).TotalSeconds);
|
|
globNumCall += item.numCall;
|
|
globAvgMsec += item.totMsec;
|
|
}
|
|
// riporto conteggio medio al secondo...
|
|
lg.Info("Chiamate GLOBALI: {0}, periodo: {1:N2} minuti.cent, tempo medio {2:N2} msec | impegno canale {3:P3}", globNumCall, DateTime.Now.Subtract(dtAvvioAdp).TotalMinutes, globAvgMsec.TotalMilliseconds / globNumCall, globAvgMsec.TotalSeconds / DateTime.Now.Subtract(dtAvvioAdp).TotalSeconds);
|
|
lg.Info("{0}--------------- STOP TIMING DATA ---------------{0}", Environment.NewLine);
|
|
// mostro in form statistiche globali!
|
|
parentForm.updateComStats(string.Format("Periodo: {0:N2}min | {1} x {2:N2}ms | canale {3:P3}", DateTime.Now.Subtract(dtAvvioAdp).TotalMinutes, globNumCall, globAvgMsec.TotalMilliseconds / globNumCall, globAvgMsec.TotalSeconds / DateTime.Now.Subtract(dtAvvioAdp).TotalSeconds));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// verifico se ho dati M/S/T e li invio nel caso
|
|
/// </summary>
|
|
public virtual void trySendCodMST()
|
|
{
|
|
// ciclo su + path
|
|
for (int i = 0; i < currAdpConf.nPath; i++)
|
|
{
|
|
// verifico SE ho codici M/S/T da inviare...
|
|
string codiceM = getNextMCode(i);
|
|
string codiceS = getNextSCode(i);
|
|
string codiceT = getNextTCode(i);
|
|
if (codiceM != "")
|
|
{
|
|
currGateway.updateItemNodeValue(vettPath[i].pathCodMKey, string.Format("[M{0}]", codiceM));
|
|
}
|
|
if (codiceS != "")
|
|
{
|
|
currGateway.updateItemNodeValue(vettPath[i].pathCodSKey, string.Format("[S{0}]", codiceS));
|
|
}
|
|
if (codiceT != "")
|
|
{
|
|
currGateway.updateItemNodeValue(vettPath[i].pathCodTKey, string.Format("[T{0}]", codiceT));
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Metodo base connessione...
|
|
/// </summary>
|
|
public virtual void tryConnect()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Metodo base disconnessione...
|
|
/// </summary>
|
|
public virtual void tryDisconnect()
|
|
{
|
|
}
|
|
|
|
protected bool _connOk = false;
|
|
|
|
/// <summary>
|
|
/// Salva verifica stato connessione OK
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public virtual bool connectionOk
|
|
{
|
|
get
|
|
{
|
|
return _connOk;
|
|
}
|
|
set
|
|
{
|
|
_connOk = value;
|
|
}
|
|
}
|
|
|
|
#region gestione allarmi
|
|
|
|
/// <summary>
|
|
/// effettua ogni log period una rilettura di TUTTI gli allarmi...
|
|
/// </summary>
|
|
public virtual void forceAlarmCheck()
|
|
{
|
|
// carico status allarmi (completo)
|
|
StFlag32 forceAlarm = (StFlag32)unchecked((int)UInt32.MaxValue);
|
|
try
|
|
{
|
|
refreshAlarmState(forceAlarm, false);
|
|
}
|
|
catch
|
|
{
|
|
lg.Error("Errore in fase di esecuzione di forceAlarmCheck");
|
|
}
|
|
if (utils.CRB("recTime"))
|
|
{
|
|
logTimeResults();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua refresh del vettore privato degli allarmi attivi
|
|
/// </summary>
|
|
/// <param name="Alarm2Refresh">flag mask degli allarmi da aggiornare</param>
|
|
/// <param name="giveAck">boolean: se si debba tornare ACK</param>
|
|
public virtual void refreshAlarmState(StFlag32 Alarm2Refresh, bool giveAck)
|
|
{
|
|
// log bitmap se verboso attivo + ho allarmi da refreshare
|
|
if ((Alarm2Refresh != StFlag32.NONE) && utils.CRB("verbose"))
|
|
{
|
|
lg.Info("AG-RAS | Richiesto refresh allarmi x bitmask: {0}", utils.binaryForm((int)Alarm2Refresh));
|
|
}
|
|
|
|
bool ackReturned = false;
|
|
// byte di acknowledge...
|
|
byte[] retACK_DW0 = new byte[4];
|
|
// inizio impostando una bitmap x ACK che abbia i bit abbassati se lo strobe è disattivo: AND logico tra STR e ACK
|
|
retACK_DW0 = BitConverter.GetBytes(Convert.ToUInt32(STRB_DW0 & ACK_DW0));
|
|
|
|
inizio = DateTime.Now;
|
|
uint[] MemBlock;
|
|
// controllo, SE devo leggere tutto uso un unico accesso ai 128byte, altrimenti leggo a blocchi di 32bit...
|
|
if (Alarm2Refresh == (StFlag32)unchecked((int)UInt32.MaxValue))
|
|
{
|
|
// blocco memoria x lettura dati COMPLETO (4Byte*32 = 128Byte)
|
|
MemBlock = new uint[32];
|
|
// recupero tutti i 32 bit del blocco
|
|
inizio = DateTime.Now;
|
|
readAllAlarms(ref MemBlock);
|
|
if (utils.CRB("recTime"))
|
|
{
|
|
TimingData.addResult(string.Format("R{0}-STRB_DW0", MemBlock.Length * 4), DateTime.Now.Subtract(inizio).Ticks);
|
|
}
|
|
|
|
if (currGateway.AlarmFlags != null)
|
|
{
|
|
try
|
|
{
|
|
// aggiorno vettore allarmi x intero! size del vettore di destinazione (in byte!!!!)
|
|
Buffer.BlockCopy(MemBlock, 0, currGateway.AlarmFlags, 0, currGateway.AlarmFlags.Length);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error(string.Format("Errore in BLOCKCOPY{0}{1}", Environment.NewLine, exc));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (Alarm2Refresh != StFlag32.NONE)
|
|
{
|
|
// blocco memoria x lettura dati
|
|
MemBlock = new uint[1];
|
|
// verifico gli allarmi di tutti i bit alzati...
|
|
for (int i = 0; i < 32; i++)
|
|
{
|
|
if (Alarm2Refresh.HasFlag((StFlag32)Math.Pow(2, i)))
|
|
{
|
|
// recupero tutti i 32 bit del blocco
|
|
inizio = DateTime.Now;
|
|
readAlarmBlock(ref MemBlock, i);
|
|
if (utils.CRB("recTime"))
|
|
{
|
|
TimingData.addResult(string.Format("R{0}-STRB_DW0", MemBlock.Length * 4), DateTime.Now.Subtract(inizio).Ticks);
|
|
}
|
|
|
|
try
|
|
{
|
|
// aggiorno vettore allarmi x intero!
|
|
Buffer.BlockCopy(MemBlock, 0, currGateway.AlarmFlags, i * 4, 4);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error(string.Format("Errore in BLOCKCOPY per indice i = {2},{0}{1}", Environment.NewLine, exc, i));
|
|
}
|
|
if (utils.CRI("loglevel") > 5)
|
|
{
|
|
lg.Info("Bit {0}, MemBlock: {1}", i, MemBlock[0]);
|
|
}
|
|
// segnalo allarme letto! memorizzo allarme nel vettore ack....
|
|
retACK_DW0 = utils.setBitOnStFlag(retACK_DW0, true, i);
|
|
}
|
|
}
|
|
// scrivo ack se richiesto!!!
|
|
if (giveAck)
|
|
{
|
|
// scrivo update ad ack!!!
|
|
inizio = DateTime.Now;
|
|
writeAlarmAck(ref retACK_DW0);
|
|
if (utils.CRB("recTime"))
|
|
{
|
|
TimingData.addResult(string.Format("W{0}-ACK_DW0", retACK_DW0.Length), DateTime.Now.Subtract(inizio).Ticks);
|
|
}
|
|
|
|
ackReturned = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// SE non ho già tornato un ACK...
|
|
if (!ackReturned)
|
|
{
|
|
// se è diverso il vettori degli ACK in memoria da quello PLC...
|
|
if (ACK_DW0 != (StFlag32)BitConverter.ToUInt32(retACK_DW0, 0))
|
|
{
|
|
// invio INTERO set ACK_DW0 con bit abbassati...
|
|
retACK_DW0 = BitConverter.GetBytes(Convert.ToUInt32(STRB_DW0 & ACK_DW0));
|
|
inizio = DateTime.Now;
|
|
writeAlarmAck(ref retACK_DW0);
|
|
if (utils.CRB("recTime"))
|
|
{
|
|
TimingData.addResult(string.Format("W{0}-ACK_DW0", retACK_DW0.Length), DateTime.Now.Subtract(inizio).Ticks);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Scrive vettore ACK degli allarmi
|
|
/// </summary>
|
|
/// <param name="retACK_DW0"></param>
|
|
/// <returns></returns>
|
|
public virtual bool writeAlarmAck(ref byte[] retACK_DW0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Legge vettore di TUTTE memorie tipo DWord dato vettore memorie (completo)
|
|
/// </summary>
|
|
/// <param name="MemBlock"></param>
|
|
/// <returns></returns>
|
|
public virtual bool readAllAlarms(ref uint[] MemBlock)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Legge vettore di TUTTE memorie tipo DWord dato indice di partenza e vettore memorie
|
|
/// </summary>
|
|
/// <param name="MemBlock"></param>
|
|
/// <param name="blockIndex"></param>
|
|
/// <returns></returns>
|
|
public virtual bool readAlarmBlock(ref uint[] MemBlock, int blockIndex)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
#endregion gestione allarmi
|
|
|
|
#region gestione altri strobe/ack
|
|
|
|
/// <summary>
|
|
/// Invia (se necessario) il watchdog di stato in vita... blink 0/1 ogni secondo
|
|
/// </summary>
|
|
public void sendWatchDog()
|
|
{
|
|
bool setFlag = false;
|
|
// 2017.07.24 gestisco 32 bit perché c'è la parte finale del doppio watchdog incrociato...
|
|
byte[] retACK_DW = new byte[4];
|
|
// gestione su ultimi 2 bit della DW2 STR/ACK: il PRIMO bit è gestito in master da ADAPTER, il secondo da PLC; in primis io COPIO il valore del bit finale (di cui è slave...)
|
|
retACK_DW = utils.setBitOnStFlag(retACK_DW, STRB_DW2.HasFlag(StFlag32.B31), 31);
|
|
// ...poi gestisco il penultimo bit di cui è master... ogni 2 secondi...
|
|
|
|
int restoB30 = 0;
|
|
Math.DivRem(DateTime.Now.Second, 2, out restoB30);
|
|
// i secondi dispari controllo...
|
|
if (restoB30 > 0)
|
|
{
|
|
if (STRB_DW2.HasFlag(StFlag32.B30) == ACK_DW2.HasFlag(StFlag32.B30))
|
|
{
|
|
// ... SE in ingresso ho strobe uguale lo cambio!!!
|
|
retACK_DW = utils.setBitOnStFlag(retACK_DW, !ACK_DW2.HasFlag(StFlag32.B30), 30);
|
|
}
|
|
else
|
|
{
|
|
retACK_DW = utils.setBitOnStFlag(retACK_DW, ACK_DW2.HasFlag(StFlag32.B30), 30);
|
|
}
|
|
}
|
|
|
|
// 2018.10.01 gestione bit status dei check ULTERIORI... SE abilitato
|
|
if (utils.CRB("stChkEnabled"))
|
|
{
|
|
if (currGateway.protocollo == gwProtocol.SOURS)
|
|
{
|
|
bool rOK = false;
|
|
// imposto bit controllo servizio REDIS attivo
|
|
rOK = currGateway.checkStatus(1);
|
|
retACK_DW = utils.setBitOnStFlag(retACK_DW, rOK, 16);
|
|
|
|
|
|
// controllo catena REDIS | OPC-UA | Gateway | Internet
|
|
// !!!FARE!!!
|
|
// verifico se ci siano messaggi da recapitare (MConnect --> GateWay --> macchina)
|
|
// !!!FARE!!!
|
|
}
|
|
else if (currGateway.protocollo == gwProtocol.MTC)
|
|
{
|
|
bool agentOk = false;
|
|
// imposto bit controllo AGENT attivo
|
|
agentOk = currGateway.checkStatus(1);
|
|
retACK_DW = utils.setBitOnStFlag(retACK_DW, agentOk, 24);
|
|
// imposto bit controllo AGENT valido
|
|
agentOk = currGateway.checkStatus(2);
|
|
retACK_DW = utils.setBitOnStFlag(retACK_DW, agentOk, 25);
|
|
// imposto bit controllo CURRENT valido
|
|
agentOk = currGateway.checkStatus(3);
|
|
retACK_DW = utils.setBitOnStFlag(retACK_DW, agentOk, 26);
|
|
}
|
|
}
|
|
|
|
// 2016.10.18 aggiungo scrittura del bit di "watchdog" al primo bit della DW2... come resto tra secondi / 2
|
|
if (utils.CRB("sendWatchDog"))
|
|
{
|
|
int resto = 0;
|
|
Math.DivRem(DateTime.Now.Second / utils.CRI("cycleWatchDog"), 2, out resto);
|
|
setFlag = resto != 0;
|
|
// se watchdog è cambiato lo invio, altrimenti lascio come è...
|
|
if (setFlag != lastWatchDog)
|
|
{
|
|
lastWatchDog = setFlag;
|
|
}
|
|
retACK_DW = utils.setBitOnStFlag(retACK_DW, setFlag, 0); // imposto primo bit!!!
|
|
// scrivo su area PLC SE variato
|
|
if (ACK_DW2 != (StFlag32)BitConverter.ToUInt32(retACK_DW, 0))
|
|
{
|
|
inizio = DateTime.Now;
|
|
writeWatchDog(ref retACK_DW);
|
|
if (utils.CRB("recTime"))
|
|
{
|
|
TimingData.addResult(string.Format("W{0}-WatchDog", retACK_DW.Length), DateTime.Now.Subtract(inizio).Ticks);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Scrive watchdog
|
|
/// </summary>
|
|
/// <param name="retACK_DW"></param>
|
|
/// <returns></returns>
|
|
public virtual bool writeWatchDog(ref byte[] retACK_DW)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
#endregion gestione altri strobe/ack
|
|
|
|
/// <summary>
|
|
/// recupero dati PATH
|
|
/// </summary>
|
|
public virtual void getPath()
|
|
{
|
|
// SE presente recupero dati path
|
|
checkPath();
|
|
|
|
// dati BASE, ciclando su path
|
|
for (int i = 0; i < currAdpConf.nPath; i++)
|
|
{
|
|
// se ho + di 1 path prendo la sua...
|
|
if (FeedRatePath.Length > 1)
|
|
{
|
|
currGateway.updateItemNodeValue(vettPath[i].feedKey, FeedRatePath[i]);
|
|
}
|
|
else
|
|
{
|
|
currGateway.updateItemNodeValue(vettPath[i].feedKey, FeedRate);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recupero dati Unità Operatrici / Mandrini
|
|
/// </summary>
|
|
public virtual void getUnOp()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processing dati UnOp
|
|
/// </summary>
|
|
/// <param name="unOpSpeedMem"></param>
|
|
public void procUnOp(byte[] unOpSpeedMem)
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
int numUnOp = currAdpConf.nUnOp;
|
|
int locSpeedRate = 0;
|
|
// cicl su path x leggere le velocità dell'UnOp
|
|
for (int i = 0; i < numUnOp; i++)
|
|
{
|
|
// leggo valore Codice
|
|
locSpeedRate = BitConverter.ToUInt16(unOpSpeedMem, 2 * i);
|
|
// leggo 41° byte = indice 40 + 2*i x le var del carico UnOp
|
|
UnOpLoad = unOpSpeedMem[40 + i];
|
|
|
|
// Eventuale fix bigEndian...
|
|
if (hasBigEndian)
|
|
{
|
|
locSpeedRate = Endian.SwapUInt16((ushort)locSpeedRate);
|
|
}
|
|
currGateway.updateItemNodeValue(vettUnOp[i].speedKey, locSpeedRate);
|
|
currGateway.updateItemNodeValue(vettUnOp[i].loadKey, UnOpLoad);
|
|
currGateway.updateItemNodeValue(vettUnOp[i].speedOverKey, SpeedRateOver);
|
|
|
|
sb.AppendLine(string.Format("UnOp_{0}: SpeedRate {1} rpm | Load {2} | SpOv: {3}", i + 1, locSpeedRate, UnOpLoad, SpeedRateOver));
|
|
}
|
|
|
|
parentForm.dataMonitor_2 += sb.ToString();
|
|
}
|
|
|
|
/// <summary>
|
|
/// recupero dati ASSI
|
|
/// </summary>
|
|
public virtual void getAxis()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gestione STROBE --> ACK per codici M/S/T
|
|
/// </summary>
|
|
/// <param name="currStrobe">byte di strobe corrente</param>
|
|
/// <param name="bitNum">0/1/2</param>
|
|
/// <param name="retACK_DW1">vettore da restituire di ACK</param>
|
|
/// <param name="memShift">shift memoria x buffer dati da leggere</param>
|
|
/// <param name="MemBlock">Vettore completo dei valori + buffer code M/S/T</param>
|
|
/// <param name="Coda">Quale coda: M/S/T</param>
|
|
/// <param name="idxPath">Path (0,1,...)</param>
|
|
public void gestStrobeCodMST(StFlag8 currStrobe, int bitNum, ref byte[] retACK_DW1, int memShift, byte[] MemBlock, string Coda, int idxPath)
|
|
{
|
|
UInt16 numEv = 0;
|
|
UInt16 codEv = 0;
|
|
if (currStrobe.HasFlag((StFlag8)Math.Pow(2, bitNum)))
|
|
{
|
|
try
|
|
{
|
|
// verifico sia > 0 il numero di valori da leggere - indice 0 sull'area...
|
|
numEv = BitConverter.ToUInt16(MemBlock, 2 * memShift);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error(exc, "Errore in gestStrobeCodMST --> BitConverter 01");
|
|
}
|
|
// se è bigEndian devo swappare!
|
|
if (hasBigEndian)
|
|
{
|
|
numEv = Endian.SwapUInt16(numEv);
|
|
}
|
|
|
|
if (numEv > 0)
|
|
{
|
|
// il num ev rappresenta quanti slot 16bit (da 2 byte) sono stati valorizzati, VA FATTO CICLO E LETTI TUTTI
|
|
for (int i = 0; i < numEv; i++)
|
|
{
|
|
try
|
|
{
|
|
// leggo valore Codice
|
|
codEv = BitConverter.ToUInt16(MemBlock, 2 * (1 + saltoMST + i + memShift));
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error(exc, "Errore in gestStrobeCodMST --> BitConverter 02");
|
|
}
|
|
if (hasBigEndian)
|
|
{
|
|
codEv = Endian.SwapUInt16(codEv);
|
|
}
|
|
// accodo Evento Codice
|
|
appendCodeMST(Coda, codEv.ToString(), idxPath);
|
|
}
|
|
}
|
|
// memorizzo allarme nel vettore ack....
|
|
retACK_DW1 = utils.setBitOnStFlag(retACK_DW1, true, bitNum);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gestione strobe UserAction: salva dati e gestione ACK
|
|
/// </summary>
|
|
/// <param name="idxPath"></param>
|
|
/// <param name="bitNum"></param>
|
|
/// <param name="retACK_DW1"></param>
|
|
/// <param name="UserAction"></param>
|
|
/// <param name="azione"></param>
|
|
public void gestStrobeUserAction(int idxPath, int bitNum, ref byte[] retACK_DW1, ref string UserAction, string azione)
|
|
{
|
|
if (STRB_DW1.HasFlag((StFlag32)Math.Pow(2, bitNum + 16 * idxPath)))
|
|
{
|
|
// salvo Evento UserAction in variabile...
|
|
UserAction += azione;
|
|
// memorizzo allarme nel vettore ack....
|
|
retACK_DW1 = utils.setBitOnStFlag(retACK_DW1, true, bitNum);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ricarica dati da file di scambio con CMSConnect
|
|
/// </summary>
|
|
public void reloadDataFromFile()
|
|
{
|
|
if (currGateway.protocollo == gwProtocol.MTC)
|
|
{
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lg.Info("Inizio lettura dati da file");
|
|
}
|
|
|
|
int totRighe = 0;
|
|
// da rivedere: se sono N+1 file (N=path + generale) deve essere ad esempio nomeComune_*.mtc --> ciclo per leggerne N
|
|
string fileName = string.Format(@"{0}\{1}", utils.dataDir, utils.CRS("GeneralStatusFilePath"));
|
|
string linea;
|
|
// creo un vettore della dimensione corretta... conta anche commenti tanto poi riduco...
|
|
generalStatus = new Dictionary<string, string>();
|
|
try
|
|
{
|
|
totRighe = File.ReadLines(fileName).Count();
|
|
// carica da file...
|
|
System.IO.StreamReader file = new System.IO.StreamReader(fileName);
|
|
if (file != null)
|
|
{
|
|
// leggo 1 linea alla volta...
|
|
string[] valori;
|
|
while ((linea = file.ReadLine()) != null)
|
|
{
|
|
// SE non è un commento...
|
|
if (linea.Substring(0, 1) != "#")
|
|
{
|
|
valori = linea.Split(utils.CRC("testCharSep"));
|
|
generalStatus.Add(valori[0], valori[1]);
|
|
}
|
|
}
|
|
// chiudo file
|
|
file.Close();
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lg.Info("Fine lettura dati da file scambio CMS");
|
|
}
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error(exc, "Errore in lettura dati da file scambio CMS");
|
|
}
|
|
|
|
// ora salvo valori letti...
|
|
foreach (KeyValuePair<string, string> item in generalStatus)
|
|
{
|
|
// verifico la chiave e nel caso aggiorno...
|
|
switch (item.Key)
|
|
{
|
|
case "OperatorId":
|
|
currGateway.updateItemNodeValue("OperatorId", item.Value);
|
|
break;
|
|
|
|
case "Path_01_CurrProg":
|
|
istPathProgrName[0] = item.Value;
|
|
break;
|
|
|
|
case "Path_02_CurrProg":
|
|
istPathProgrName[1] = item.Value;
|
|
break;
|
|
|
|
case "Path_03_CurrProg":
|
|
istPathProgrName[2] = item.Value;
|
|
break;
|
|
|
|
case "Path_04_CurrProg":
|
|
istPathProgrName[3] = item.Value;
|
|
break;
|
|
|
|
case "Path_05_CurrProg":
|
|
istPathProgrName[4] = item.Value;
|
|
break;
|
|
|
|
case "Path_06_CurrProg":
|
|
istPathProgrName[5] = item.Value;
|
|
break;
|
|
|
|
case "Path_01_PartId":
|
|
istPathPartId[0] = item.Value;
|
|
break;
|
|
|
|
case "Path_02_PartId":
|
|
istPathPartId[1] = item.Value;
|
|
break;
|
|
|
|
case "Path_03_PartId":
|
|
istPathPartId[2] = item.Value;
|
|
break;
|
|
|
|
case "Path_04_PartId":
|
|
istPathPartId[3] = item.Value;
|
|
break;
|
|
|
|
case "Path_05_PartId":
|
|
istPathPartId[4] = item.Value;
|
|
break;
|
|
|
|
case "Path_06_PartId":
|
|
istPathPartId[5] = item.Value;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// verifica gli status attivi
|
|
/// </summary>
|
|
public virtual void processStatus()
|
|
{
|
|
// status macchina (SOUR)
|
|
string sourStatus = "UNDEFINED";
|
|
if (currGateway.protocollo == gwProtocol.SOURS)
|
|
{
|
|
// recupero byte dello status!
|
|
ouStatus = ACK_DW3_B0;
|
|
|
|
// recupero valore PUNTUALE status da apposita area memoria... se ha valore >=0...
|
|
if (ouStatusByPlc && ouStatus >= 0)
|
|
{
|
|
sourStatus = ((macState)ouStatus).ToString();
|
|
}
|
|
// calcolo status da ALTRE info (vs leggo variabile...)
|
|
else
|
|
{
|
|
// calcolo lo status...
|
|
if (!STRB_DW2.HasFlag(StFlag32.B01))
|
|
{
|
|
sourStatus = macState.POWER_OFF.ToString();
|
|
}
|
|
else if (STRB_DW2.HasFlag(StFlag32.B11))
|
|
{
|
|
sourStatus = macState.FAIL.ToString();
|
|
}
|
|
else if (STRB_DW2.HasFlag(StFlag32.B04) && STRB_DW2.HasFlag(StFlag32.B09))
|
|
{
|
|
sourStatus = macState.EXE.ToString();
|
|
}
|
|
else
|
|
{
|
|
sourStatus = macState.READY.ToString();
|
|
}
|
|
}
|
|
|
|
currGateway.updateItemNodeValue("STATUS", sourStatus);
|
|
}
|
|
|
|
|
|
// update status da DW2/ DW3
|
|
|
|
// EMstop: verifico BIT e di conseguenza imposto
|
|
if (STRB_DW2.HasFlag(StFlag32.B00))
|
|
{
|
|
if (currGateway.protocollo == gwProtocol.SOURS)
|
|
{
|
|
currGateway.updateItemNodeValue("E_STOP", true);
|
|
}
|
|
else
|
|
{
|
|
currGateway.updateItemNodeValue("E_STOP", emStatus.TRIGGERED.ToString());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (currGateway.protocollo == gwProtocol.SOURS)
|
|
{
|
|
currGateway.updateItemNodeValue("E_STOP", false);
|
|
}
|
|
else
|
|
{
|
|
currGateway.updateItemNodeValue("E_STOP", emStatus.ARMED.ToString());
|
|
}
|
|
}
|
|
|
|
// verifico POWER ON...
|
|
if (STRB_DW2.HasFlag(StFlag32.B01))
|
|
{
|
|
if (currGateway.protocollo == gwProtocol.SOURS)
|
|
{
|
|
currGateway.updateItemNodeValue("POWER", true);
|
|
}
|
|
else
|
|
{
|
|
currGateway.updateItemNodeValue("POWER", onOffStatus.ON.ToString());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (currGateway.protocollo == gwProtocol.SOURS)
|
|
{
|
|
currGateway.updateItemNodeValue("POWER", false);
|
|
}
|
|
else
|
|
{
|
|
currGateway.updateItemNodeValue("POWER", onOffStatus.OFF.ToString());
|
|
}
|
|
}
|
|
|
|
// Processo selezionato 0=P1, 1=P2
|
|
|
|
if (STRB_DW2.HasFlag(StFlag32.B02))
|
|
{
|
|
procSel = "P2";
|
|
}
|
|
else
|
|
{
|
|
procSel = "P1";
|
|
}
|
|
|
|
// 2019.08.28 RIMETTO GESTIONE PROCESSO SEL!
|
|
//// lo riporto SOLO SE HO almeno 2 processi oppure protocollo NON OPC-UA
|
|
//if (currGateway.protocollo != gwProtocol.SOURS || currAdpConf.nPath > 1)
|
|
//{
|
|
if (currGateway.getItemNode("PROC_SEL").ToString() != procSel)
|
|
{
|
|
currGateway.updateItemNodeValue("PROC_SEL", procSel);
|
|
}
|
|
//}
|
|
|
|
// processo ora i dai dei path... di sicuro il primo
|
|
procPath01_Status();
|
|
//...e se c'è pure il secondo...
|
|
if (currAdpConf.nPath > 1)
|
|
{
|
|
// anche il secondo!
|
|
procPath02_Status();
|
|
}
|
|
|
|
// cerco status allarmi presenti
|
|
if (STRB_DW2.HasFlag(StFlag32.B29))
|
|
{
|
|
currGateway.alarmPresent = true;
|
|
}
|
|
else
|
|
{
|
|
currGateway.alarmPresent = false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processa status del path 01...
|
|
/// </summary>
|
|
public void procPath01_Status()
|
|
{
|
|
// HARD CODE: forzo path 1 (indice 0...) x iniziare...
|
|
int idxPath = 0;
|
|
string pathType = "";
|
|
// verifico tipo processo path...
|
|
if (STRB_DW2.HasFlag(StFlag32.B03))
|
|
{
|
|
if (currGateway.protocollo == gwProtocol.SOURS)
|
|
{
|
|
pathType = "LAV";
|
|
}
|
|
else
|
|
{
|
|
pathType = "LAVORO";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (currGateway.protocollo == gwProtocol.SOURS)
|
|
{
|
|
pathType = "ASS";
|
|
}
|
|
else
|
|
{
|
|
pathType = "ASSERV";
|
|
}
|
|
}
|
|
|
|
// switch su RUN mode...
|
|
string runMode = "";
|
|
int currRunMode = 0;
|
|
if (STRB_DW2.HasFlag(StFlag32.B04))
|
|
{
|
|
currRunMode = (int)MtcRunMode.AUTOMATIC;
|
|
}
|
|
else if (STRB_DW2.HasFlag(StFlag32.B05))
|
|
{
|
|
currRunMode = (int)MtcRunMode.EDIT;
|
|
}
|
|
else if (STRB_DW2.HasFlag(StFlag32.B06))
|
|
{
|
|
currRunMode = (int)MtcRunMode.MANUAL_DATA_INPUT;
|
|
}
|
|
else if (STRB_DW2.HasFlag(StFlag32.B07))
|
|
{
|
|
currRunMode = (int)MtcRunMode.MANUAL;
|
|
}
|
|
else if (STRB_DW2.HasFlag(StFlag32.B08))
|
|
{
|
|
currRunMode = (int)MtcRunMode.SEMI_AUTO;
|
|
}
|
|
// traduco...
|
|
if (currGateway.protocollo == gwProtocol.SOURS)
|
|
{
|
|
runMode = ((OpcUaPathMode)currRunMode).ToString();
|
|
}
|
|
else
|
|
{
|
|
runMode = ((MtcRunMode)currRunMode).ToString();
|
|
}
|
|
// se proc corrente --> salvo
|
|
if (procSel == "P1")
|
|
{
|
|
procMode = currRunMode;
|
|
}
|
|
|
|
// switch su EXE mode...
|
|
string exeMode = "";
|
|
int currExeMode = 0;
|
|
if (STRB_DW2.HasFlag(StFlag32.B09))
|
|
{
|
|
currExeMode = (int)MtcExeMode.ACTIVE;
|
|
}
|
|
else if (STRB_DW2.HasFlag(StFlag32.B10))
|
|
{
|
|
currExeMode = (int)MtcExeMode.READY;
|
|
}
|
|
else if (STRB_DW2.HasFlag(StFlag32.B11))
|
|
{
|
|
currExeMode = (int)MtcExeMode.STOPPED;
|
|
}
|
|
else if (STRB_DW2.HasFlag(StFlag32.B12))
|
|
{
|
|
currExeMode = (int)MtcExeMode.FEED_HOLD;
|
|
}
|
|
else if (STRB_DW2.HasFlag(StFlag32.B13))
|
|
{
|
|
currExeMode = (int)MtcExeMode.OPTIONAL_STOP;
|
|
}
|
|
else if (STRB_DW2.HasFlag(StFlag32.B14))
|
|
{
|
|
currExeMode = (int)MtcExeMode.PROGRAM_STOPPED;
|
|
}
|
|
else if (STRB_DW2.HasFlag(StFlag32.B15))
|
|
{
|
|
currExeMode = (int)MtcExeMode.PROGRAM_COMPLETED;
|
|
}
|
|
// traduco...
|
|
if (currGateway.protocollo == gwProtocol.SOURS)
|
|
{
|
|
exeMode = ((OpcUaPathStatus)currExeMode).ToString();
|
|
}
|
|
else
|
|
{
|
|
exeMode = ((MtcExeMode)currExeMode).ToString();
|
|
}
|
|
|
|
// inizializzo SEMPRE a vuoto...
|
|
string SubMode = "";
|
|
// verifico sulla STRB_DW3 i submode che POTREBBERO tutti sovrapposti...
|
|
if (STRB_DW3 != StFlag32.NONE)
|
|
{
|
|
// cerco i bit alzati --> aggiungo relativo submode!
|
|
for (int i = 0; i < 32; i++)
|
|
{
|
|
// converto! e aggiungo allarmi sollevati al corretto controller allarmi...
|
|
if (STRB_DW3.HasFlag((StFlag32)Math.Pow(2, i)))
|
|
{
|
|
SubMode += string.Format(" [P{0:00}_{1}]", idxPath + 1, elencoSubMode[i.ToString()]);
|
|
}
|
|
}
|
|
}
|
|
|
|
// salvo in blocco le info ricostruite x path!
|
|
savePathData(idxPath, pathType, runMode, exeMode, SubMode.Trim());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processa status del path 02...
|
|
/// </summary>
|
|
public void procPath02_Status()
|
|
{
|
|
// HARD CODE: forzo path 2 (indice 1)...
|
|
int idxPath = 1;
|
|
string pathType = "";
|
|
// verifico tipo processo path...
|
|
if (STRB_DW1.HasFlag(StFlag32.B16))
|
|
{
|
|
if (currGateway.protocollo == gwProtocol.SOURS)
|
|
{
|
|
pathType = "LAV";
|
|
}
|
|
else
|
|
{
|
|
pathType = "LAVORO";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (currGateway.protocollo == gwProtocol.SOURS)
|
|
{
|
|
pathType = "ASS";
|
|
}
|
|
else
|
|
{
|
|
pathType = "ASSERV";
|
|
}
|
|
}
|
|
|
|
// switch su RUN mode...
|
|
string runMode = "";
|
|
int currRunMode = 0;
|
|
if (STRB_DW2.HasFlag(StFlag32.B17))
|
|
{
|
|
currRunMode = (int)MtcRunMode.AUTOMATIC;
|
|
}
|
|
else if (STRB_DW2.HasFlag(StFlag32.B18))
|
|
{
|
|
currRunMode = (int)MtcRunMode.EDIT;
|
|
}
|
|
else if (STRB_DW2.HasFlag(StFlag32.B19))
|
|
{
|
|
currRunMode = (int)MtcRunMode.MANUAL_DATA_INPUT;
|
|
}
|
|
else if (STRB_DW2.HasFlag(StFlag32.B20))
|
|
{
|
|
currRunMode = (int)MtcRunMode.MANUAL;
|
|
}
|
|
else if (STRB_DW2.HasFlag(StFlag32.B21))
|
|
{
|
|
currRunMode = (int)MtcRunMode.SEMI_AUTO;
|
|
}
|
|
// traduco...
|
|
if (currGateway.protocollo == gwProtocol.SOURS)
|
|
{
|
|
runMode = ((OpcUaPathMode)currRunMode).ToString();
|
|
}
|
|
else
|
|
{
|
|
runMode = ((MtcRunMode)currRunMode).ToString();
|
|
}
|
|
// se proc corrente --> salvo
|
|
if (procSel == "P2")
|
|
{
|
|
procMode = currRunMode;
|
|
}
|
|
|
|
// switch su EXE mode...
|
|
string exeMode = "";
|
|
int currExeMode = 0;
|
|
if (STRB_DW2.HasFlag(StFlag32.B22))
|
|
{
|
|
currExeMode = (int)MtcExeMode.ACTIVE;
|
|
}
|
|
else if (STRB_DW2.HasFlag(StFlag32.B23))
|
|
{
|
|
currExeMode = (int)MtcExeMode.READY;
|
|
}
|
|
else if (STRB_DW2.HasFlag(StFlag32.B24))
|
|
{
|
|
currExeMode = (int)MtcExeMode.STOPPED;
|
|
}
|
|
else if (STRB_DW2.HasFlag(StFlag32.B25))
|
|
{
|
|
currExeMode = (int)MtcExeMode.FEED_HOLD;
|
|
}
|
|
else if (STRB_DW2.HasFlag(StFlag32.B26))
|
|
{
|
|
currExeMode = (int)MtcExeMode.OPTIONAL_STOP;
|
|
}
|
|
else if (STRB_DW2.HasFlag(StFlag32.B27))
|
|
{
|
|
currExeMode = (int)MtcExeMode.PROGRAM_STOPPED;
|
|
}
|
|
else if (STRB_DW2.HasFlag(StFlag32.B28))
|
|
{
|
|
currExeMode = (int)MtcExeMode.PROGRAM_COMPLETED;
|
|
}
|
|
// traduco...
|
|
if (currGateway.protocollo == gwProtocol.SOURS)
|
|
{
|
|
exeMode = ((OpcUaPathStatus)currExeMode).ToString();
|
|
}
|
|
else
|
|
{
|
|
exeMode = ((MtcExeMode)currExeMode).ToString();
|
|
}
|
|
|
|
// inizializzo SEMPRE a vuoto...
|
|
string SubMode = "";
|
|
// verifico sulla STRB_DW3 i submode che POTREBBERO tutti sovrapposti...
|
|
if (STRB_DW4 != StFlag32.NONE)
|
|
{
|
|
// cerco i bit alzati --> aggiungo relativo submode!
|
|
for (int i = 0; i < 32; i++)
|
|
{
|
|
// converto! e aggiungo allarmi sollevati al corretto controller allarmi...
|
|
if (STRB_DW4.HasFlag((StFlag32)Math.Pow(2, i)))
|
|
{
|
|
SubMode += string.Format(" [P{0:00}_{1}]", idxPath + 1, elencoSubMode[i.ToString()]);
|
|
}
|
|
}
|
|
}
|
|
|
|
// salvo in blocco le info ricostruite x path!
|
|
savePathData(idxPath, pathType, runMode, exeMode, SubMode.Trim());
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salva i valori per il path indicato SE variati...
|
|
/// </summary>
|
|
/// <param name="idxPath"></param>
|
|
/// <param name="pathType"></param>
|
|
/// <param name="pathRunMode"></param>
|
|
/// <param name="pathExeMode"></param>
|
|
/// <param name="pathSubMode"></param>
|
|
public void savePathData(int idxPath, string pathType, string pathRunMode, string pathExeMode, string pathSubMode)
|
|
{
|
|
// salvo type
|
|
if (currGateway.getItemNode(vettPath[idxPath].pathTypeKey).ToString() != pathType)
|
|
{
|
|
currGateway.updateItemNodeValue(vettPath[idxPath].pathTypeKey, pathType);
|
|
}
|
|
// salvo RUN mode
|
|
if (currGateway.getItemNode(vettPath[idxPath].runModeKey).ToString() != pathRunMode)
|
|
{
|
|
currGateway.updateItemNodeValue(vettPath[idxPath].runModeKey, pathRunMode);
|
|
}
|
|
// salvo EXE mode
|
|
if (currGateway.getItemNode(vettPath[idxPath].exeModeKey).ToString() != pathExeMode)
|
|
{
|
|
currGateway.updateItemNodeValue(vettPath[idxPath].exeModeKey, pathExeMode);
|
|
}
|
|
// salvo i submode..
|
|
if (currGateway.getItemNode(vettPath[idxPath].subModeKey).ToString() != pathSubMode)
|
|
{
|
|
currGateway.updateItemNodeValue(vettPath[idxPath].subModeKey, pathSubMode);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// processo tutti gli strobe attivi
|
|
/// </summary>
|
|
public virtual void processStrobe()
|
|
{
|
|
// ...da gestire su ogni adapter...
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processa strobe x un dato path
|
|
/// </summary>
|
|
/// <param name="idxPath">path corrente</param>
|
|
/// <param name="currStrobe">Byte di strobe del path corrente</param>
|
|
/// <param name="currAck">Byte di strobe del path corrente</param>
|
|
/// <param name="memIndexMST">indice x lettura memoria MST del path</param>
|
|
/// <param name="memIndexAck">indice x scrittura ACK x path</param>
|
|
/// <param name="UserAction">stringa COMPLESSIVA azioni utente</param>
|
|
public void procPathStrobes(int idxPath, StFlag8 currStrobe, StFlag8 currAck, int memIndexMST, int memIndexAck, ref string UserAction)
|
|
{
|
|
// byte di strobe e di acknowledge... inizializzo!!!
|
|
byte[] currACK_DW = new byte[1];
|
|
// altre variabili
|
|
int bitNum = 0;
|
|
inizio = DateTime.Now;
|
|
// incomincio vera e propria gestione...
|
|
try
|
|
{
|
|
// controllo TUTTI i flag: se ce ne sono di alzati DEVO processare...
|
|
if (currStrobe != StFlag8.NONE)
|
|
{
|
|
// se ho un M/S/T leggo area...
|
|
if (currStrobe.HasFlag(StFlag8.B0) || currStrobe.HasFlag(StFlag8.B1) || currStrobe.HasFlag(StFlag8.B2))
|
|
{
|
|
// leggo memoria (direttamente a Byte...)!
|
|
readMST_data(idxPath, memIndexMST, ref MemBlock_MST);
|
|
|
|
// check COD_M
|
|
bitNum = 0;
|
|
gestStrobeCodMST(currStrobe, bitNum, ref currACK_DW, 0, MemBlock_MST, "M", idxPath);
|
|
|
|
// check COD_S
|
|
bitNum = 1;
|
|
gestStrobeCodMST(currStrobe, bitNum, ref currACK_DW, 11 + saltoMST, MemBlock_MST, "S", idxPath);
|
|
|
|
// check COD_T
|
|
bitNum = 2;
|
|
gestStrobeCodMST(currStrobe, bitNum, ref currACK_DW, 17 + 2 * saltoMST, MemBlock_MST, "T", idxPath);
|
|
}
|
|
|
|
// check FILE DATI MODIFICATO: ricaricare...
|
|
bitNum = 3;
|
|
if (STRB_DW1.HasFlag((StFlag32)Math.Pow(2, bitNum)))
|
|
{
|
|
lg.Info("Notifica file modificato");
|
|
try
|
|
{
|
|
// reload dati da file...
|
|
reloadDataFromFile();
|
|
|
|
// memorizzo allarme nel vettore ack....
|
|
currACK_DW = utils.setBitOnStFlag(currACK_DW, true, bitNum);
|
|
}
|
|
catch
|
|
{
|
|
lg.Info("Errore lettura dati da file");
|
|
}
|
|
}
|
|
|
|
// AREA strobe USER ACTION
|
|
// chiamato Start...
|
|
bitNum = 4;
|
|
gestStrobeUserAction(idxPath, bitNum, ref currACK_DW, ref UserAction, string.Format(" (P{0:00} START) ", idxPath + 1));
|
|
// chiamato Stop...
|
|
bitNum = 5;
|
|
gestStrobeUserAction(idxPath, bitNum, ref currACK_DW, ref UserAction, string.Format(" (P{0:00} STOP) ", idxPath + 1));
|
|
// chiamato Reset...
|
|
bitNum = 6;
|
|
gestStrobeUserAction(idxPath, bitNum, ref currACK_DW, ref UserAction, string.Format(" (P{0:00} RESET) ", idxPath + 1));
|
|
}
|
|
else
|
|
{
|
|
// inizializzo 4 byte a zero!!!
|
|
currACK_DW = new byte[1];
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error(string.Format("Errore in strobe:{0}{1}", Environment.NewLine, exc));
|
|
}
|
|
|
|
// scrivo update ad ack SE VARIATO!!!
|
|
if (currAck != (StFlag8)currACK_DW[0])
|
|
{
|
|
writeMST_ACK(memIndexAck, ref currACK_DW);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verifica strobe autotest
|
|
/// </summary>
|
|
/// <param name="currStrobe"></param>
|
|
/// <param name="currAck"></param>
|
|
/// <param name="memIndexAck"></param>
|
|
/// <param name="memOrderStart"></param>
|
|
public void processTestStrobe(StFlag8 currStrobe, StFlag8 currAck, int memIndexAck, int memOrderStart)
|
|
{
|
|
// byte di strobe e di acknowledge... inizializzo!!!
|
|
byte[] currACK_DW = new byte[1];
|
|
string TestingData = "";
|
|
// INIZIO TEST...
|
|
int bitNum = 6;
|
|
if (currStrobe.HasFlag((StFlag8)Math.Pow(2, bitNum)))
|
|
{
|
|
// formatto stringa risultato
|
|
TestingData = string.Format("START TEST{0}", getTestData(utils.CRS("testCharSep")));
|
|
|
|
// memorizzo allarme nel vettore ack....
|
|
currACK_DW = utils.setBitOnStFlag(currACK_DW, true, bitNum);
|
|
}
|
|
// FINE TEST...
|
|
bitNum = 7;
|
|
if (currStrobe.HasFlag((StFlag8)Math.Pow(2, bitNum)))
|
|
{
|
|
// formatto stringa risultato
|
|
TestingData = string.Format("STOP TEST{0}", getTestData(utils.CRS("testCharSep")));
|
|
|
|
// memorizzo allarme nel vettore ack....
|
|
currACK_DW = utils.setBitOnStFlag(currACK_DW, true, bitNum);
|
|
}
|
|
|
|
// INVIO stato test...
|
|
if (currGateway.getItemNode("TESTING_DATA").ToString() != TestingData.Trim())
|
|
{
|
|
currGateway.updateItemNodeValue("TESTING_DATA", TestingData.Trim());
|
|
}
|
|
|
|
// scrivo update ad ack SE VARIATO!!!
|
|
if (currAck != (StFlag8)currACK_DW[0])
|
|
{
|
|
writeMST_ACK(memIndexAck, ref currACK_DW);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recupero info su test: numero + elenco parametri IN/OUT
|
|
/// </summary>
|
|
/// <param name="charSep"></param>
|
|
/// <returns></returns>
|
|
public string getTestData(string charSep)
|
|
{
|
|
string answ = "";
|
|
// Area di memoria x test... (64 DWord) (la prima va splittata)
|
|
UInt32[] MemBlockTestData = new UInt32[64];
|
|
// variabili numero test e num parametri impiegati
|
|
int testNum = 0;
|
|
int numPar = 0;
|
|
// variabile dove parcheggiare conversione codici dei parametri del test (IN o OUT)
|
|
UInt32 testParam = 0;
|
|
readTestData(ref MemBlockTestData);
|
|
|
|
// recupero cod univoco test e numero parametri impiegati
|
|
testNum = BitConverter.ToUInt16(BitConverter.GetBytes(MemBlockTestData[0]), 0);
|
|
numPar = BitConverter.ToUInt16(BitConverter.GetBytes(MemBlockTestData[0]), 2);
|
|
|
|
// riporto separatore + numero test + num parametri
|
|
answ = string.Format("{0}TN:{1}{0}NP:{2}", charSep, testNum, numPar);
|
|
// se ci sono parametri da accodare li recupero!
|
|
if (numPar > 0)
|
|
{
|
|
for (int i = 0; i < numPar; i++)
|
|
{
|
|
testParam = MemBlockTestData[1 + i];
|
|
answ += string.Format("{0}{1}", charSep, testParam);
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua lettura dati TESTING
|
|
/// </summary>
|
|
/// <param name="MemBlockTestData"></param>
|
|
/// <returns></returns>
|
|
public virtual bool readTestData(ref uint[] MemBlockTestData)
|
|
{
|
|
bool fatto = false;
|
|
return fatto;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Legge area memoria dati MST
|
|
/// </summary>
|
|
/// <param name="idxPath"></param>
|
|
/// <param name="memIndexMST"></param>
|
|
/// <param name="MemBlock_MST"></param>
|
|
/// <returns></returns>
|
|
public virtual bool readMST_data(int idxPath, int memIndexMST, ref byte[] MemBlock_MST)
|
|
{
|
|
bool fatto = false;
|
|
return fatto;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Scrive ACK x dati MST
|
|
/// </summary>
|
|
/// <param name="idxPath"></param>
|
|
/// <param name="memIndexMST"></param>
|
|
/// <param name="MemBlock_W"></param>
|
|
/// <returns></returns>
|
|
public virtual bool writeMST_ACK(int memIndexAck, ref byte[] currACK_DW)
|
|
{
|
|
bool fatto = false;
|
|
return fatto;
|
|
}
|
|
|
|
/// <summary>
|
|
/// processo il vettore LOCALE degli allarmi
|
|
/// </summary>
|
|
public virtual void processAlarm()
|
|
{
|
|
currGateway.processAlarm();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Classe fittizia in caso di processing GLOBALE di tutto in 1 solo colpo...
|
|
/// </summary>
|
|
public virtual void processAllMemory()
|
|
{ }
|
|
|
|
/// <summary>
|
|
/// metodo di recupero dei dati di identificativo macchina - DA CONF!!!
|
|
/// </summary>
|
|
public virtual void getConfigParam()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// dati "lenti" relativi al device
|
|
/// </summary>
|
|
public virtual void getSlowChangingData()
|
|
{
|
|
if (currGateway.protocollo == gwProtocol.MTC)
|
|
{
|
|
// dati da PC
|
|
currGateway.updateItemNodeValue("CLOCK", DateTime.Now);
|
|
|
|
// reload dati da file...
|
|
reloadDataFromFile();
|
|
}
|
|
|
|
// area gestione dati utensili... in base al num max di UnOp recupero i dati utensile... PROCEDURA AD HOC!!!
|
|
getDatiUt(currAdpConf.nUnOp);
|
|
}
|
|
|
|
/// <summary>
|
|
/// recupero di TUTTI gli strobes/status attivi
|
|
/// </summary>
|
|
public virtual void getStrobeAndAckStatus()
|
|
{
|
|
// da gestire su ogni adapter... legge tutto array STROBE!!!
|
|
}
|
|
/// <summary>
|
|
/// Effettua decodifica a ritroso della key SOUR
|
|
/// </summary>
|
|
/// <param name="varName"></param>
|
|
/// <param name="tgtName"></param>
|
|
/// <returns></returns>
|
|
protected string getOrigName(string varName)
|
|
{
|
|
string answ = varName;
|
|
// se il gateway è sour DEVO FARE CONTROLLO con fix...
|
|
if (utils.CRS("adpProto") == "SOURS")
|
|
{
|
|
GatewaySOURS gSour = (GatewaySOURS)currGateway;
|
|
answ = gSour.mAdapter.getOrigKey(varName);
|
|
}
|
|
// return!
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// Numero massimo (indice) valori maintData (privato)
|
|
/// </summary>
|
|
protected int _maintDataMaxNum = 0;
|
|
/// <summary>
|
|
/// Numero massimo (indice) valori maintData (calcolato)
|
|
/// </summary>
|
|
public int maintDataMaxNum
|
|
{
|
|
get
|
|
{
|
|
if (_maintDataMaxNum == 0)
|
|
{
|
|
if (maintData != null)
|
|
{
|
|
// prima stima
|
|
int idx = maintData.Length;
|
|
// ora ciclo...
|
|
foreach (var item in maintData)
|
|
{
|
|
int.TryParse(item.codNum, out idx);
|
|
_maintDataMaxNum = idx > _maintDataMaxNum ? idx : _maintDataMaxNum;
|
|
}
|
|
}
|
|
}
|
|
return _maintDataMaxNum;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processa la tabella di memoria dei dati di manutenzione
|
|
/// </summary>
|
|
/// <param name="tabDatiMtz"></param>
|
|
/// <param name="maintData"></param>
|
|
public void processMaintData(uint[] tabDatiMtz, otherData[] maintData)
|
|
{
|
|
// uno ad uno vado a inserirli nella mappa dei dati dell'adapter...
|
|
int numero = 0;
|
|
int idxTab = 0;
|
|
int valRead = 0;
|
|
string origName = "";
|
|
for (int i = 0; i < maintData.Length; i++)
|
|
{
|
|
numero = 0;
|
|
valRead = 0;
|
|
// calcolo idx a indice 0...
|
|
int.TryParse(maintData[i].codNum, out idxTab);
|
|
idxTab--;
|
|
origName = getOrigName(maintData[i].varName);
|
|
|
|
// 2020.04.30: inizio TENTANDO di calcolare valRead con suo fattore di scala
|
|
try
|
|
{
|
|
valRead = (int) (tabDatiMtz[idxTab]);
|
|
// se c'è fatt scala --> divido
|
|
if (maintData[i].scale != 0 && maintData[i].scale != 1)
|
|
{
|
|
// scalo!
|
|
valRead = valRead / maintData[i].scale;
|
|
}
|
|
}
|
|
catch
|
|
{ }
|
|
// decodifico...
|
|
if (origName == "ACC_TIME")
|
|
{
|
|
istOreMaccOn.addValue(DateTime.Now, (int)valRead);
|
|
//istOreMaccOn.addValue(DateTime.Now, Convert.ToInt32(tabDatiMtz[idxTab]));
|
|
}
|
|
else if (origName == "ACC_TIME_WORK")
|
|
{
|
|
istOreMaccLav.addValue(DateTime.Now, (int)valRead);
|
|
}
|
|
else if (origName == "SlittaTastatore_Count")
|
|
{
|
|
istSlittaTast.addValue(DateTime.Now, (int)valRead);
|
|
}
|
|
// DA RIVEDERE x check traduzione...
|
|
else if (origName.StartsWith("Counter_"))
|
|
{
|
|
try
|
|
{
|
|
numero = Convert.ToInt32(origName.Replace("Counter_", ""));
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
if (numero > 0 && istCounters.Length >= numero)
|
|
{
|
|
istCounters[numero - 1].addValue(DateTime.Now, (int)valRead);
|
|
}
|
|
}
|
|
else if (origName.StartsWith("RTCounter_"))
|
|
{
|
|
try
|
|
{
|
|
numero = Convert.ToInt32(origName.Replace("RTCounter_", ""));
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
if (numero > 0 && istRTCounters.Length >= numero)
|
|
{
|
|
istRTCounters[numero - 1].addValue(DateTime.Now, (int)valRead);
|
|
}
|
|
}
|
|
else if (elRTVCount.ContainsKey(origName))
|
|
{
|
|
// recupero da dictionary!
|
|
try
|
|
{
|
|
// numero base 0 --> +1!!!
|
|
numero = elRTVCount[origName] + 1;
|
|
}
|
|
catch
|
|
{
|
|
numero = 0;
|
|
}
|
|
if (numero > 0 && istRTVCount.Length >= numero)
|
|
{
|
|
istRTVCount[numero - 1].addValue(DateTime.Now, (int)valRead);
|
|
}
|
|
}
|
|
else if (origName.StartsWith("Path_"))
|
|
{
|
|
if (origName.EndsWith("_PZ_TOT"))
|
|
{
|
|
try
|
|
{
|
|
numero = Convert.ToInt32(origName.Replace("Path_", "").Replace("_PZ_TOT", ""));
|
|
}
|
|
catch
|
|
{ }
|
|
if (numero > 0 && vettPath.Length >= numero)
|
|
{
|
|
// SE NON E' SOUR...
|
|
if (currGateway.protocollo != gwProtocol.SOURS)
|
|
{
|
|
currGateway.updateItemNodeValue(vettPath[numero - 1].partCountKey, valRead);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (origName.StartsWith("Axis_"))
|
|
{
|
|
if (origName.EndsWith("_DistDone"))
|
|
{
|
|
try
|
|
{
|
|
numero = Convert.ToInt32(origName.Replace("Axis_", "").Replace("_DistDone", ""));
|
|
}
|
|
catch
|
|
{ }
|
|
if (numero > 0 && istDistMovAssi.Length >= numero)
|
|
{
|
|
istDistMovAssi[numero - 1].addValue(DateTime.Now, (int)valRead);
|
|
}
|
|
}
|
|
else if (origName.EndsWith("_InvDDone") || origName.EndsWith("_Invers"))
|
|
{
|
|
try
|
|
{
|
|
numero = Convert.ToInt32(origName.Replace("Axis_", "").Replace("_InvDDone", "").Replace("_Invers", ""));
|
|
}
|
|
catch
|
|
{ }
|
|
if (numero > 0 && istNumInvAssi.Length >= numero)
|
|
{
|
|
// 2016.07.06 debug di valori che potrebbero essere nulli...
|
|
try
|
|
{
|
|
valRead = (int) tabDatiMtz[idxTab];
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
valRead = 0;
|
|
lg.Error(string.Format("Errore in recupero num inversioni:{0}parametro: {1}{0}i: {2}{0}Exc: {3}", Environment.NewLine, maintData[i].varName, i, exc));
|
|
}
|
|
istNumInvAssi[numero - 1].addValue(DateTime.Now, Convert.ToInt32(valRead));
|
|
}
|
|
}
|
|
else if (origName.EndsWith("_AccTime"))
|
|
{
|
|
try
|
|
{
|
|
numero = Convert.ToInt32(origName.Replace("Axis_", "").Replace("_AccTime", ""));
|
|
}
|
|
catch
|
|
{ }
|
|
if (numero > 0 && istAccTimeAssi.Length >= numero)
|
|
{
|
|
// 2016.07.06 debug di valori che potrebbero essere nulli...
|
|
try
|
|
{
|
|
valRead = (int) tabDatiMtz[idxTab];
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
valRead = 0;
|
|
lg.Error(string.Format("Errore in recupero num AccTime:{0}parametro: {1}{0}i: {2}{0}Exc: {3}", Environment.NewLine, maintData[i].varName, i, exc));
|
|
}
|
|
istAccTimeAssi[numero - 1].addValue(DateTime.Now, Convert.ToInt32(valRead));
|
|
}
|
|
}
|
|
}
|
|
else if (origName.StartsWith("UnOp_") || origName.StartsWith("OperatingGroups:"))
|
|
{
|
|
if (origName.EndsWith("_AccTime") || origName.EndsWith("ActiveTime"))
|
|
{
|
|
try
|
|
{
|
|
numero = Convert.ToInt32(origName.Replace("UnOp_", "").Replace("_AccTime", ""));
|
|
}
|
|
catch
|
|
{ }
|
|
if (numero > 0 && istOreElettrom.Length >= numero)
|
|
{
|
|
istOreElettrom[numero - 1].addValue(DateTime.Now, (int)valRead);
|
|
}
|
|
}
|
|
else if (origName.EndsWith("_KRev") || origName.EndsWith("Distance"))
|
|
{
|
|
try
|
|
{
|
|
numero = Convert.ToInt32(origName.Replace("UnOp_", "").Replace("_KRev", ""));
|
|
}
|
|
catch
|
|
{ }
|
|
if (numero > 0 && istGiriElettrom.Length >= numero)
|
|
{
|
|
istGiriElettrom[numero - 1].addValue(DateTime.Now, (int)valRead);
|
|
}
|
|
}
|
|
else if (origName.EndsWith("_NumCambiUT"))
|
|
{
|
|
try
|
|
{
|
|
numero = Convert.ToInt32(origName.Replace("UnOp_", "").Replace("_NumCambiUT", ""));
|
|
}
|
|
catch
|
|
{ }
|
|
if (numero > 0 && istNumCambiUt.Length >= numero)
|
|
{
|
|
istNumCambiUt[numero - 1].addValue(DateTime.Now, (int)valRead);
|
|
}
|
|
}
|
|
else if (origName.EndsWith("_NumCU"))
|
|
{
|
|
try
|
|
{
|
|
numero = Convert.ToInt32(origName.Replace("UnOp_", "").Replace("_NumCU", ""));
|
|
}
|
|
catch
|
|
{ }
|
|
if (numero > 0 && istNumCambiUt.Length >= numero)
|
|
{
|
|
istNumCambiUt[numero - 1].addValue(DateTime.Now, (int)valRead);
|
|
}
|
|
}
|
|
else if (origName.EndsWith("_Count"))
|
|
{
|
|
try
|
|
{
|
|
numero = Convert.ToInt32(origName.Replace("UnOp_", "").Replace("_Count", ""));
|
|
}
|
|
catch
|
|
{ }
|
|
if (numero > 0 && istRepetitionUnOp.Length >= numero)
|
|
{
|
|
istRepetitionUnOp[numero - 1].addValue(DateTime.Now, (int)valRead);
|
|
}
|
|
}
|
|
}
|
|
else if (origName.StartsWith("VacPump_"))
|
|
{
|
|
if (origName.EndsWith("_WrkTime"))
|
|
{
|
|
try
|
|
{
|
|
numero = Convert.ToInt32(origName.Replace("VacPump_", "").Replace("_WrkTime", ""));
|
|
}
|
|
catch
|
|
{ }
|
|
if (numero > 0 && istVacPumpWrkTime.Length >= numero)
|
|
{
|
|
istVacPumpWrkTime[numero - 1].addValue(DateTime.Now, (int)valRead);
|
|
}
|
|
}
|
|
}
|
|
else if (origName.StartsWith("VacAct_"))
|
|
{
|
|
if (origName.EndsWith("_Count"))
|
|
{
|
|
try
|
|
{
|
|
numero = Convert.ToInt32(origName.Replace("VacAct_", "").Replace("_Count", ""));
|
|
}
|
|
catch
|
|
{ }
|
|
if (numero > 0 && istVacActCount.Length >= numero)
|
|
{
|
|
istVacActCount[numero - 1].addValue(DateTime.Now, (int)valRead);
|
|
}
|
|
}
|
|
}
|
|
else if (origName.StartsWith("Lubro_"))
|
|
{
|
|
if (origName.EndsWith("_Num") || origName.EndsWith("_Count"))
|
|
{
|
|
try
|
|
{
|
|
numero = Convert.ToInt32(origName.Replace("Lubro_", "").Replace("_Num", "").Replace("_Count", ""));
|
|
}
|
|
catch
|
|
{ }
|
|
if (numero > 0 && istLubroCount.Length >= numero)
|
|
{
|
|
istLubroCount[numero - 1].addValue(DateTime.Now, (int)valRead);
|
|
}
|
|
}
|
|
}
|
|
else if (origName.StartsWith("SlittaMagazzino_"))
|
|
{
|
|
if (origName.EndsWith("_Count"))
|
|
{
|
|
try
|
|
{
|
|
numero = Convert.ToInt32(origName.Replace("SlittaMagazzino_", "").Replace("_Count", ""));
|
|
}
|
|
catch
|
|
{ }
|
|
if (numero > 0 && istSlittaMag.Length >= numero)
|
|
{
|
|
istSlittaMag[numero - 1].addValue(DateTime.Now, (int)valRead);
|
|
}
|
|
}
|
|
}
|
|
else if (origName.StartsWith("ProtMagazzino_"))
|
|
{
|
|
if (origName.EndsWith("_Count"))
|
|
{
|
|
try
|
|
{
|
|
numero = Convert.ToInt32(origName.Replace("ProtMagazzino_", "").Replace("_Count", ""));
|
|
}
|
|
catch
|
|
{ }
|
|
if (numero > 0 && istProtMag.Length >= numero)
|
|
{
|
|
istProtMag[numero - 1].addValue(DateTime.Now, (int)valRead);
|
|
}
|
|
}
|
|
}
|
|
else if (origName.StartsWith("AuxiliaryGroups"))
|
|
{
|
|
try
|
|
{
|
|
currGateway.updateItemNodeValue(origName, valRead);
|
|
}
|
|
catch (Exception exc)
|
|
{ }
|
|
}
|
|
else //if (origName.StartsWith("ProtMagazzino_"))
|
|
{
|
|
try
|
|
{
|
|
currGateway.updateItemNodeValue(origName, valRead);
|
|
}
|
|
catch (Exception exc)
|
|
{ }
|
|
}
|
|
// !!!FIXME!!! verificare SE si vuole reinserire gestione contapezzi e/o variabili "freepass" qui...
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Numero massimo (indice) valori analogData (privato)
|
|
/// </summary>
|
|
protected int _analogDataMaxNum = 0;
|
|
/// <summary>
|
|
/// Numero massimo (indice) valori analogData (calcolato)
|
|
/// </summary>
|
|
public int analogDataMaxNum
|
|
{
|
|
get
|
|
{
|
|
if (_analogDataMaxNum == 0)
|
|
{
|
|
if (analogData != null)
|
|
{
|
|
// prima stima
|
|
int idx = analogData.Length;
|
|
// ora ciclo...
|
|
foreach (var item in analogData)
|
|
{
|
|
int.TryParse(item.codNum, out idx);
|
|
_analogDataMaxNum = idx > _analogDataMaxNum ? idx : _analogDataMaxNum;
|
|
}
|
|
}
|
|
}
|
|
return _analogDataMaxNum;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Numero massimo (indice) valori string (privato)
|
|
/// </summary>
|
|
protected int _stringDataMaxNum = 0;
|
|
/// <summary>
|
|
/// Numero massimo (indice) valori string (calcolato)
|
|
/// </summary>
|
|
public int stringDataMaxNum
|
|
{
|
|
get
|
|
{
|
|
if (_stringDataMaxNum == 0)
|
|
{
|
|
if (stringData != null)
|
|
{
|
|
// prima stima
|
|
int idx = stringData.Length;
|
|
// ora ciclo...
|
|
foreach (var item in stringData)
|
|
{
|
|
int.TryParse(item.codNum, out idx);
|
|
_stringDataMaxNum = idx > _stringDataMaxNum ? idx : _stringDataMaxNum;
|
|
}
|
|
}
|
|
}
|
|
return _stringDataMaxNum;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processa la tabella di memoria dei dati analogici
|
|
/// </summary>
|
|
/// <param name="tabDatiAnag"></param>
|
|
/// <param name="analogData"></param>
|
|
public void processAnalogData(int[] tabDatiAnag, otherData[] analogData)
|
|
{
|
|
// uno ad uno vado a inserirli nella mappa dei dati dell'adapter...
|
|
StringBuilder sb = new StringBuilder();
|
|
double analogVal = 0;
|
|
int idxTab = 0;
|
|
string origName = "";
|
|
for (int i = 0; i < analogData.Length; i++)
|
|
{
|
|
// calcolo idx a indice 0...
|
|
int.TryParse(analogData[i].codNum, out idxTab);
|
|
idxTab--;
|
|
origName = getOrigName(analogData[i].varName);
|
|
// gestisco in modalità "lazy" qualsiasi variabile (dividendo x opportuno fattore conversione...)
|
|
try
|
|
{
|
|
analogVal = (double)tabDatiAnag[idxTab] / (double)utils.CRI("fattDecVA");
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
analogVal = 0;
|
|
lg.Error(string.Format("Errore in recupero valore analogico:{0}parametro: {1}{0}i: {2}{0}Exc: {3}", Environment.NewLine, analogData[i].varName, i, exc));
|
|
}
|
|
// salvo vettore Eventi...
|
|
currGateway.updateItemNodeValue(elAnalogData[i], analogVal);
|
|
//currGateway.updateItemNodeValue(elAnalogData[idxTab], analogVal);
|
|
// accodo ultimi codici in visualizzazione...
|
|
sb.AppendLine(currGateway.getItemNode(elAnalogData[i]).ToString().Replace("|", " | "));
|
|
}
|
|
// aggiungo i vari analogici rilevati
|
|
parentForm.dataMonitor_3 += sb.ToString();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processa la tabella di memoria dei dati analogici
|
|
/// </summary>
|
|
/// <param name="tabDatiAnag"></param>
|
|
/// <param name="analogData"></param>
|
|
public void processAnalogData(uint[] tabDatiAnag, otherData[] analogData)
|
|
{
|
|
// uno ad uno vado a inserirli nella mappa dei dati dell'adapter...
|
|
StringBuilder sb = new StringBuilder();
|
|
double analogVal = 0;
|
|
int idxTab = 0;
|
|
string origName = "";
|
|
for (int i = 0; i < analogData.Length; i++)
|
|
{
|
|
// calcolo idx a indice 0...
|
|
int.TryParse(analogData[i].codNum, out idxTab);
|
|
idxTab--;
|
|
origName = getOrigName(analogData[i].varName);
|
|
// gestisco in modalità "lazy" qualsiasi variabile (dividendo x opportuno fattore conversione...)
|
|
try
|
|
{
|
|
analogVal = (double)tabDatiAnag[idxTab] / (double)utils.CRI("fattDecVA");
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
analogVal = 0;
|
|
lg.Error(string.Format("Errore in recupero valore analogico:{0}parametro: {1}{0}i: {2}{0}Exc: {3}", Environment.NewLine, analogData[i].varName, i, exc));
|
|
}
|
|
// salvo vettore Eventi...
|
|
currGateway.updateItemNodeValue(elAnalogData[idxTab], analogVal);
|
|
// accodo ultimi codici in visualizzazione...
|
|
sb.AppendLine(currGateway.getItemNode(elAnalogData[idxTab]).ToString().Replace("|", " | "));
|
|
}
|
|
// aggiungo i vari analogici rilevati
|
|
parentForm.dataMonitor_3 += sb.ToString();
|
|
}
|
|
/// <summary>
|
|
/// Processa la tabella di memoria dei dati stringa
|
|
/// </summary>
|
|
/// <param name="tabDatiString"></param>
|
|
/// <param name="stringData"></param>
|
|
public void processStringData(string[] tabDatiString, otherData[] stringData)
|
|
{
|
|
// uno ad uno vado a inserirli nella mappa dei dati dell'adapter...
|
|
StringBuilder sb = new StringBuilder();
|
|
int idxTab = 0;
|
|
string origName = "";
|
|
for (int i = 0; i < stringData.Length; i++)
|
|
{
|
|
// calcolo idx a indice 0...
|
|
int.TryParse(stringData[i].codNum, out idxTab);
|
|
idxTab--;
|
|
origName = getOrigName(stringData[i].varName);
|
|
|
|
// salvo vettore...
|
|
currGateway.updateItemNodeValue(elStringData[idxTab], tabDatiString[idxTab]);
|
|
// accodo ultimi codici in visualizzazione...
|
|
sb.AppendLine(currGateway.getItemNode(elStringData[idxTab]).ToString().Replace("|", " | "));
|
|
}
|
|
// aggiungo i vari analogici rilevati
|
|
parentForm.dataMonitor_3 += sb.ToString();
|
|
}
|
|
|
|
/// <summary>
|
|
/// processa dataLayer e se necessario salva/mostra
|
|
/// </summary>
|
|
public void checkSavePersDataLayer()
|
|
{
|
|
// aggiungo dettaglio valori ultimi codici MST
|
|
StringBuilder sb = new StringBuilder();
|
|
string codM = "";
|
|
string codS = "";
|
|
string codT = "";
|
|
for (int i = 0; i < currAdpConf.nPath; i++)
|
|
{
|
|
codM = currGateway.getItemNode(vettPath[i].pathCodMKey).ToString().Replace("NULL", "n.d.").Replace("UNAVAILABLE", "n.d.");
|
|
codS = currGateway.getItemNode(vettPath[i].pathCodSKey).ToString().Replace("NULL", "n.d.").Replace("UNAVAILABLE", "n.d.");
|
|
codT = currGateway.getItemNode(vettPath[i].pathCodTKey).ToString().Replace("NULL", "n.d.").Replace("UNAVAILABLE", "n.d.");
|
|
// accodo ultimi codici in visualizzazione...
|
|
sb.AppendLine(string.Format("P{0} last MST: {1} | {2} | {3}", i + 1, codM, codS, codT));
|
|
}
|
|
parentForm.dataMonitor_1 += sb.ToString();
|
|
|
|
if (persistenceLayer != null)
|
|
{
|
|
bool needSave = false;
|
|
// verifica se si debba aggiornare XML (e salva in adapter dati vari)
|
|
needSave = procOreMaccOn(needSave);
|
|
needSave = procOreMaccLav(needSave);
|
|
needSave = procProgrName(needSave);
|
|
needSave = procPartId(needSave);
|
|
needSave = procPzProd(needSave);
|
|
needSave = procGiriTotUnOp(needSave);
|
|
needSave = procNumCU(needSave);
|
|
needSave = procRepetitions(needSave);
|
|
needSave = procCounters(needSave);
|
|
needSave = procMovTotAssi(needSave);
|
|
needSave = procAccTimeAssi(needSave);
|
|
needSave = procNumInvAssi(needSave);
|
|
needSave = procVacPump(needSave);
|
|
needSave = procVacAct(needSave);
|
|
needSave = procLubro(needSave);
|
|
needSave = procSlittaMag(needSave);
|
|
needSave = procProtMag(needSave);
|
|
|
|
// salvo se necessario!
|
|
if (needSave)
|
|
{
|
|
parentForm.persistData();
|
|
}
|
|
// -------------------------------------------
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Numero massimo (indice) valori analogData (privato)
|
|
/// </summary>
|
|
protected int _statusDataMaxNum = 0;
|
|
/// <summary>
|
|
/// Numero massimo (indice) valori analogData (calcolato)
|
|
/// </summary>
|
|
public int statusDataMaxNum
|
|
{
|
|
get
|
|
{
|
|
if (_statusDataMaxNum == 0)
|
|
{
|
|
if (statusData != null)
|
|
{
|
|
// prima stima
|
|
int idx = statusData.Length;
|
|
// ora ciclo...
|
|
foreach (var item in statusData)
|
|
{
|
|
int.TryParse(item.codNum, out idx);
|
|
_statusDataMaxNum = idx > _statusDataMaxNum ? idx : _statusDataMaxNum;
|
|
}
|
|
}
|
|
}
|
|
return _statusDataMaxNum;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Processa la tabella di memoria degli status di manutenzione
|
|
/// </summary>
|
|
/// <param name="tabDatiStatus"></param>
|
|
/// <param name="statusData"></param>
|
|
public void processStatusData(byte[] tabDatiStatus, otherData[] statusData)
|
|
{
|
|
int bitNum = 0;
|
|
int byteNum = 0;
|
|
byte byteVal;
|
|
StringBuilder sb = new StringBuilder();
|
|
// uno ad uno vado a inserirli nella mappa dei dati dell'adapter...
|
|
int numero = 0;
|
|
string status = "";
|
|
int idxTab = 0;
|
|
string origName = "";
|
|
for (int i = 0; i < statusData.Length; i++)
|
|
{
|
|
numero = 0;
|
|
status = "";
|
|
// calcolo idx a indice 0...
|
|
int.TryParse(statusData[i].codNum, out idxTab);
|
|
idxTab--;
|
|
|
|
origName = getOrigName(statusData[i].varName);
|
|
// calcolo quale byte e quale bit devo leggere..
|
|
byteNum = idxTab / 8;
|
|
// indice zero dei bit nel byte ( da cui -1 )
|
|
bitNum = idxTab - (8 * byteNum);
|
|
// faccio vera lettura
|
|
byteVal = tabDatiStatus[byteNum];
|
|
// leggo bit come ACTIVE/INACTIVE
|
|
if (((StFlag8)byteVal).HasFlag((StFlag8)Math.Pow(2, bitNum)))
|
|
{
|
|
if (currGateway.protocollo == gwProtocol.SOURS)
|
|
{
|
|
status = "EXE";
|
|
}
|
|
else
|
|
{
|
|
status = "ACTIVE";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (currGateway.protocollo == gwProtocol.SOURS)
|
|
{
|
|
status = "READY";
|
|
}
|
|
else
|
|
{
|
|
status = "INACTIVE";
|
|
}
|
|
}
|
|
|
|
// gestione AGGIUNTIVA vettori memorie "vecchie" per retrocompatibilità...
|
|
if (origName.StartsWith("VacPump_"))
|
|
{
|
|
if (origName.EndsWith("_Status"))
|
|
{
|
|
try
|
|
{
|
|
numero = Convert.ToInt32(origName.Replace("VacPump_", "").Replace("_Status", ""));
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
if (numero > 0)
|
|
{
|
|
currGateway.updateItemNodeValue(vettVacPump[numero - 1].statusKey, status);
|
|
}
|
|
}
|
|
}
|
|
else if (origName.StartsWith("Cooler_"))
|
|
{
|
|
if (origName.EndsWith("_Status"))
|
|
{
|
|
try
|
|
{
|
|
numero = Convert.ToInt32(origName.Replace("Cooler_", "").Replace("_Status", ""));
|
|
}
|
|
catch
|
|
{ }
|
|
if (numero > 0)
|
|
{
|
|
currGateway.updateItemNodeValue(vettCooler[numero - 1].statusKey, status);
|
|
}
|
|
}
|
|
}
|
|
else if (origName.StartsWith("UnOp_"))
|
|
{
|
|
if (origName.EndsWith("_Status"))
|
|
{
|
|
try
|
|
{
|
|
numero = Convert.ToInt32(origName.Replace("UnOp_", "").Replace("_Status", ""));
|
|
}
|
|
catch
|
|
{ }
|
|
if (numero > 0)
|
|
{
|
|
currGateway.updateItemNodeValue(vettUnOp[numero - 1].statusKey, status);
|
|
}
|
|
}
|
|
}
|
|
|
|
// salvo vettore Eventi...
|
|
currGateway.updateItemNodeValue(elStatus[i], status);
|
|
// accodo ultimi codici in visualizzazione...
|
|
if (currGateway.protocollo == gwProtocol.MTC)
|
|
{
|
|
sb.AppendLine(currGateway.getItemNode(elStatus[i]).ToString().Replace("|", " | "));
|
|
}
|
|
else if (currGateway.protocollo == gwProtocol.SOURS)
|
|
{
|
|
DataItemRed redDI = (DataItemRed)currGateway.getItemNode(elStatus[i]);
|
|
sb.AppendLine(string.Format("{0} | {1}", redDI.Name, redDI.Value));
|
|
}
|
|
}
|
|
// aggiungo i vari status rilevati
|
|
parentForm.dataMonitor_2 += sb.ToString();
|
|
}
|
|
|
|
/// <summary>
|
|
/// procedura di lettura (multistep) dati da memoria x caricare dati utensile
|
|
/// </summary>
|
|
/// <param name="maxNumOp">num max di teste da recuperare</param>
|
|
public virtual void getDatiUt(int maxNumOp)
|
|
{
|
|
// variabili "Indice" utensile e famiglia da decodificare + utils
|
|
int maxMemAddr = numMemUt;
|
|
byte[] elencoUtMem = new byte[2 * 20];
|
|
byte[] tabUt_UT = new byte[2 * maxMemAddr];
|
|
byte[] tabFam_FamUt = new byte[2 * maxMemAddr];
|
|
|
|
// altre variabili
|
|
ushort[] idUtMontato = new ushort[maxNumOp];
|
|
ushort[] idFamUt = new ushort[maxNumOp];
|
|
int[] idTipoVitaUt = new int[maxNumOp];
|
|
uint[] valVitaUtRes = new uint[maxNumOp];
|
|
ushort[] tabUt = new ushort[maxMemAddr];
|
|
ushort[] tabFamUt = new ushort[maxMemAddr];
|
|
int memIndex = 0;
|
|
byte[] int32Mem = new byte[4];
|
|
byte[] int16Mem = new byte[2];
|
|
byte int8Mem = new byte();
|
|
bool found = false;
|
|
|
|
// step 1: lettura ID dell'utensile x ogni testa... leggo area memoria degli UT montati
|
|
memIndex = getDatiUt_step1(ref elencoUtMem);
|
|
// decodifica da byte a int16 dell'ID Utensile
|
|
for (int i = 0; i < maxNumOp; i++)
|
|
{
|
|
idUtMontato[i] = BitConverter.ToUInt16(elencoUtMem, 2 * i);
|
|
}
|
|
|
|
// step 2a: leggo vettore memoria dei maxMemAddr(200) UT in Tabella Utensili
|
|
memIndex = getDatiUt_step2a(ref tabUt_UT);
|
|
// decodifico TUTTI i maxMemAddr utensili
|
|
for (int i = 0; i < maxMemAddr; i++)
|
|
{
|
|
tabUt[i] = BitConverter.ToUInt16(tabUt_UT, 2 * i);
|
|
}
|
|
// step 2b: devo cercare l'UT di ogni UnOp nella Tabella Utensili
|
|
for (int i = 0; i < maxNumOp; i++)
|
|
{
|
|
// poiché potrei trovarlo replicato dopo la prima volta che lo trovo evito di ricontrollare...
|
|
found = false;
|
|
// spazzo la tab Utensili x cercare quelli delle UnOp...
|
|
for (int j = 0; j < maxMemAddr; j++)
|
|
{
|
|
// controllo, se l'id utensile è quello dell'attuale UnOp...
|
|
if (tabUt[j] == idUtMontato[i] && !found)
|
|
{
|
|
// leggo FamUt puntuale..
|
|
memIndex = getDatiUt_step2b(ref int16Mem, j);
|
|
// step 2b: leggo puntualmente la FamUt dal suo indice...
|
|
idFamUt[i] = BitConverter.ToUInt16(int16Mem, 0);
|
|
found = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// step 3a: leggo vettore memoria dei maxMemAddr(200) FamUT in Tabella Famiglie Utensili (x ricavare unità misura vita)
|
|
memIndex = getDatiUt_step3a(ref tabFam_FamUt);
|
|
// decodifico TUTTI i maxMemAddr utensili
|
|
for (int i = 0; i < maxMemAddr; i++)
|
|
{
|
|
tabFamUt[i] = BitConverter.ToUInt16(tabFam_FamUt, 2 * i);
|
|
}
|
|
// step 3b: devo cercare la famiglia dell'UT di ogni UnOp nella Tabella Famiglie
|
|
for (int i = 0; i < maxNumOp; i++)
|
|
{
|
|
// poiché potrei trovarlo replicato dopo la prima volta che lo trovo evito di ricontrollare...
|
|
found = false;
|
|
// spazzo la tab Utensili x cercare quelli delle UnOp...
|
|
for (int j = 0; j < maxMemAddr; j++)
|
|
{
|
|
// controllo, se l'id utensile è quello dell'attuale UnOp...
|
|
if (tabFamUt[j] == idFamUt[i] && !found)
|
|
{
|
|
// leggo FamUt puntuale..
|
|
memIndex = getDatiUt_step3b(ref int8Mem, j);
|
|
// step 3b: leggo puntualmente il TIPO DI vita UT dal suo indice...
|
|
idTipoVitaUt[i] = int8Mem;
|
|
found = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// step 4: recupero la vita residua dell'utensile
|
|
for (int i = 0; i < maxNumOp; i++)
|
|
{
|
|
// poiché potrei trovarlo replicato dopo la prima volta che lo trovo evito di ricontrollare...
|
|
found = false;
|
|
// spazzo la tab Utensili x cercare quelli delle UnOp...
|
|
for (int j = 0; j < maxMemAddr; j++)
|
|
{
|
|
// controllo, se l'id utensile è quello dell'attuale UnOp...
|
|
if (tabUt[j] == idUtMontato[i] && !found)
|
|
{
|
|
// leggo FamUt puntuale..
|
|
memIndex = getDatiUt_step4(ref int32Mem, j);
|
|
// leggo puntualmente valore della vita ut residua da indice utensile...
|
|
valVitaUtRes[i] = BitConverter.ToUInt32(int32Mem, 0);
|
|
found = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// salvo in adapter vita UT residua...
|
|
for (int i = 0; i < maxNumOp; i++)
|
|
{
|
|
currGateway.updateItemNodeValue(vettUnOp[i].toolIdKey, idUtMontato[i]);
|
|
currGateway.updateItemNodeValue(vettUnOp[i].vitaResKey, valVitaUtRes[i]);
|
|
// decodifico valore tipo VitaRes...
|
|
string tipoVitaRes = "ND";
|
|
switch (idTipoVitaUt[i])
|
|
{
|
|
case 1:
|
|
tipoVitaRes = "Time";
|
|
break;
|
|
|
|
case 2:
|
|
tipoVitaRes = "Stroke";
|
|
break;
|
|
|
|
case 3:
|
|
tipoVitaRes = "Distance";
|
|
break;
|
|
|
|
default: break;
|
|
}
|
|
currGateway.updateItemNodeValue(vettUnOp[i].vitaResTypeKey, tipoVitaRes);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Procedura di processing lettura memoria x DatiUt - Step 4
|
|
/// </summary>
|
|
/// <param name="int32Mem"></param>
|
|
/// <param name="j"></param>
|
|
/// <returns></returns>
|
|
public virtual int getDatiUt_step4(ref byte[] int32Mem, int j)
|
|
{
|
|
int memIndex = 13100 + 4 * j;
|
|
//inizio = DateTime.Now;
|
|
//OsaiMemRW(R, FANUC.MemType.D, memIndex, ref int32Mem);
|
|
//if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-TabUT-VitaRes", int32Mem.Length), DateTime.Now.Subtract(inizio).Ticks);
|
|
return memIndex;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Procedura di processing lettura memoria x DatiUt - Step 3b
|
|
/// </summary>
|
|
/// <param name="int8Mem"></param>
|
|
/// <param name="j"></param>
|
|
/// <returns></returns>
|
|
public virtual int getDatiUt_step3b(ref byte int8Mem, int j)
|
|
{
|
|
int memIndex = 10700 + 1 * j;
|
|
//inizio = DateTime.Now;
|
|
//OsaiMemRW(R, FANUC.MemType.D, memIndex, ref int8Mem);
|
|
//if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-TabUT-FamUT", 8), DateTime.Now.Subtract(inizio).Ticks);
|
|
return memIndex;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Procedura di processing lettura memoria x DatiUt - Step 3a
|
|
/// </summary>
|
|
/// <param name="tabFam_FamUt"></param>
|
|
/// <returns></returns>
|
|
public virtual int getDatiUt_step3a(ref byte[] tabFam_FamUt)
|
|
{
|
|
int memIndex = 8900;
|
|
//inizio = DateTime.Now;
|
|
//OsaiMemRW(R, FANUC.MemType.D, memIndex, ref tabFam_FamUt);
|
|
//if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-TabFamUT-FamUT", tabFam_FamUt.Length), DateTime.Now.Subtract(inizio).Ticks);
|
|
return memIndex;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Procedura di processing lettura memoria x DatiUt - Step 2b
|
|
/// </summary>
|
|
/// <param name="int16Mem"></param>
|
|
/// <param name="j"></param>
|
|
/// <returns></returns>
|
|
public virtual int getDatiUt_step2b(ref byte[] int16Mem, int j)
|
|
{
|
|
int memIndex = 11700 + 2 * j;
|
|
//inizio = DateTime.Now;
|
|
//OsaiMemRW(R, FANUC.MemType.D, memIndex, ref int16Mem);
|
|
//if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-TabUT-FamUT", int16Mem.Length), DateTime.Now.Subtract(inizio).Ticks);
|
|
return memIndex;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Procedura di processing lettura memoria x DatiUt - Step 2a
|
|
/// </summary>
|
|
/// <param name="tabUt_UT"></param>
|
|
/// <returns></returns>
|
|
public virtual int getDatiUt_step2a(ref byte[] tabUt_UT)
|
|
{
|
|
int memIndex = 11300;
|
|
//inizio = DateTime.Now;
|
|
//OsaiMemRW(R, FANUC.MemType.D, memIndex, ref tabUt_UT);
|
|
//if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-TabUT-UT", tabUt_UT.Length), DateTime.Now.Subtract(inizio).Ticks);
|
|
return memIndex;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Procedura di processing lettura memoria x DatiUt - Step 1
|
|
/// </summary>
|
|
/// <param name="elencoUtMem"></param>
|
|
/// <returns></returns>
|
|
public virtual int getDatiUt_step1(ref byte[] elencoUtMem)
|
|
{
|
|
int memIndex = 2960;
|
|
//inizio = DateTime.Now;
|
|
//OsaiMemRW(R, FANUC.MemType.D, memIndex, ref elencoUtMem);
|
|
//if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-NUMUT", elencoUtMem.Length), DateTime.Now.Subtract(inizio).Ticks);
|
|
return memIndex;
|
|
}
|
|
|
|
#endregion metodi adapter
|
|
|
|
#region area metodi comunicazione con PLC/CNC
|
|
|
|
public void checkPath()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// FeedRate globale
|
|
/// </summary>
|
|
public int FeedRate { get; set; }
|
|
/// <summary>
|
|
/// FeedRate per singolo PATH
|
|
/// </summary>
|
|
public int[] FeedRatePath { get; set; }
|
|
|
|
/// <summary>
|
|
/// FeedRate di gruppo MAX 20!!!
|
|
/// </summary>
|
|
public int[] FeedRateGrp { get; set; }
|
|
|
|
/// <summary>
|
|
/// SpeedRate mandrino globale
|
|
/// </summary>
|
|
public int SpeedRate { get; set; }
|
|
|
|
/// <summary>
|
|
/// OVERRIDE FeedRate globale
|
|
/// </summary>
|
|
public int FeedRateOver { get; set; }
|
|
/// <summary>
|
|
/// OVERRIDE FeedRate per singolo PATH
|
|
/// </summary>
|
|
public int[] FeedRateOverPath { get; set; }
|
|
|
|
/// <summary>
|
|
/// OVERRIDE dei rapidi
|
|
/// </summary>
|
|
public int RapidOver { get; set; }
|
|
/// <summary>
|
|
/// OVERRIDE Rapid per singolo PATH
|
|
/// </summary>
|
|
public int[] RapidOverPath { get; set; }
|
|
|
|
/// <summary>
|
|
/// OVERRIDE SpeedRate mandrino globale
|
|
/// </summary>
|
|
public int SpeedRateOver { get; set; }
|
|
/// <summary>
|
|
/// OVERRIDE SpeedRate per singolo PATH
|
|
/// </summary>
|
|
public int[] SpeedRateOverPath { get; set; }
|
|
|
|
/// <summary>
|
|
/// LOAD mandrino globale
|
|
/// </summary>
|
|
public int UnOpLoad { get; set; }
|
|
|
|
/// <summary>
|
|
/// recupera Vettore completo PosAct (fare override!)
|
|
/// </summary>
|
|
public virtual position PosAct
|
|
{
|
|
get
|
|
{
|
|
position answ = new position();
|
|
return answ;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// recupera pezzi OK (fare override!)
|
|
/// </summary>
|
|
public virtual int getNumPzOk
|
|
{
|
|
get
|
|
{
|
|
int answ = 0;
|
|
return answ;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// recupera pezzi KO (fare override!)
|
|
/// </summary>
|
|
public virtual int getNumPzKo
|
|
{
|
|
get
|
|
{
|
|
int answ = 0;
|
|
return answ;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Aggiunge nel vettore coda codici M
|
|
/// </summary>
|
|
/// <param name="Coda"></param>
|
|
/// <param name="Codice">Codice da accodare</param>
|
|
/// <param name="idxPath">Path (0,1,...)</param>
|
|
public void appendCodeMST(string Coda, string Codice, int idxPath)
|
|
{
|
|
switch (Coda)
|
|
{
|
|
case "S":
|
|
codaS[idxPath].Add(Codice);
|
|
break;
|
|
|
|
case "T":
|
|
codaT[idxPath].Add(Codice);
|
|
break;
|
|
|
|
case "M":
|
|
default:
|
|
codaM[idxPath].Add(Codice);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// recupera primo elemento coda M
|
|
/// </summary>
|
|
/// <param name="idxPath">Path (0,1,...)</param>
|
|
/// <returns></returns>
|
|
protected string getNextMCode(int idxPath)
|
|
{
|
|
string answ = "";
|
|
if (codaM[idxPath].Count > 0)
|
|
{
|
|
// recupero codice M...
|
|
answ = codaM[idxPath].First();
|
|
// tolgo elemento
|
|
codaM[idxPath].RemoveAt(0);
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// recupera primo elemento coda S
|
|
/// </summary>
|
|
/// <param name="idxPath">Path (0,1,...)</param>
|
|
/// <returns></returns>
|
|
protected string getNextSCode(int idxPath)
|
|
{
|
|
string answ = "";
|
|
if (codaS[idxPath].Count > 0)
|
|
{
|
|
// recupero codice S...
|
|
answ = codaS[idxPath].First();
|
|
// tolgo elemento
|
|
codaS[idxPath].RemoveAt(0);
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// recupera primo elemento coda T
|
|
/// </summary>
|
|
/// <param name="idxPath">Path (0,1,...)</param>
|
|
/// <returns></returns>
|
|
protected string getNextTCode(int idxPath)
|
|
{
|
|
string answ = "";
|
|
if (codaT[idxPath].Count > 0)
|
|
{
|
|
// recupero codice T...
|
|
answ = codaT[idxPath].First();
|
|
// tolgo elemento
|
|
codaT[idxPath].RemoveAt(0);
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
#endregion area metodi comunicazione con PLC/CNC
|
|
|
|
#region metodi che prevedono salvataggio valori su file XML/BIN
|
|
|
|
/// <summary>
|
|
/// Processing delle variabili generiche Counters
|
|
/// </summary>
|
|
/// <param name="needSave"></param>
|
|
/// <returns></returns>
|
|
public bool procCounters(bool needSave)
|
|
{
|
|
uint delta = 0;
|
|
uint valore = 0;
|
|
int valoreInt = 0;
|
|
StringBuilder sb = new StringBuilder();
|
|
string cKey = "";
|
|
if (elCounter != null)
|
|
{
|
|
// processo i counter MONOTONI CRESCENTI
|
|
for (int i = 0; i < elCounter.Count; i++)
|
|
{
|
|
// nome counter
|
|
cKey = string.Format("Counter_{0:000}", i + 1);
|
|
// procedo solo SE HO FINESTRA VALIDA...
|
|
if (istCounters[i].vcValid)
|
|
{
|
|
valore = Convert.ToUInt32(istCounters[i].vcMedian);
|
|
if (valore >= currCounters[i])
|
|
{
|
|
delta = valore - currCounters[i];
|
|
// controllo delta < 50% max...
|
|
if (delta < uint.MaxValue / 2)
|
|
{
|
|
//processo comunque sempre...
|
|
uint contTot = updateValUIntByIncr(i, delta, "Counter_{0:000}");
|
|
// passo valore totale all'adapter
|
|
currGateway.updateItemNodeValue(cKey, contTot);
|
|
// controllo valore riferimento...
|
|
if (delta > 0)
|
|
{
|
|
// segnalo necessità salvataggio!
|
|
needSave = true;
|
|
}
|
|
}
|
|
}
|
|
// ...aggiorno valore riferimento...
|
|
currCounters[i] = valore;
|
|
}
|
|
sb.AppendLine(currGateway.getItemNode(cKey).ToString().Replace("|", " | "));
|
|
}
|
|
}
|
|
if (elRTCounter != null)
|
|
{
|
|
// processo i counter ASSOLUTI
|
|
for (int i = 0; i < elRTCounter.Count; i++)
|
|
{
|
|
// nome counter
|
|
cKey = string.Format("RTCounter_{0:000}", i + 1);
|
|
// procedo solo SE HO FINESTRA VALIDA...
|
|
if (istRTCounters[i].vcValid)
|
|
{
|
|
valore = Convert.ToUInt32(istRTCounters[i].vcMedian);
|
|
if (valore != currRTCounters[i])
|
|
{
|
|
delta = valore - currRTCounters[i];
|
|
// controllo delta < 50% max...
|
|
if (delta < uint.MaxValue / 2)
|
|
{
|
|
//processo comunque sempre...
|
|
updateValUInt(i, valore, "RTCounter_{0:000}");
|
|
// passo valore totale all'adapter
|
|
currGateway.updateItemNodeValue(cKey, valore);
|
|
// controllo valore riferimento...
|
|
if (delta > 0)
|
|
{
|
|
// segnalo necessità salvataggio!
|
|
needSave = true;
|
|
}
|
|
}
|
|
}
|
|
// ...aggiorno valore riferimento...
|
|
currRTCounters[i] = valore;
|
|
}
|
|
sb.AppendLine(currGateway.getItemNode(cKey).ToString().Replace("|", " | "));
|
|
}
|
|
}
|
|
if (elRTVCount != null)
|
|
{
|
|
// processo i counter VALORI RTV
|
|
foreach (var item in elRTVCount)
|
|
{
|
|
// nome counter
|
|
cKey = item.Key;
|
|
// procedo solo SE HO FINESTRA VALIDA...
|
|
if (istRTVCount[item.Value].vcValid)
|
|
{
|
|
valoreInt = Convert.ToInt32(istRTVCount[item.Value].vcMedian);
|
|
// passo valore totale all'adapter
|
|
currGateway.updateItemNodeValue(cKey, valoreInt);
|
|
// ...aggiorno valore riferimento...
|
|
currRTVCount[item.Value] = valoreInt;
|
|
}
|
|
sb.AppendLine(currGateway.getItemNode(cKey).ToString().Replace("|", " | "));
|
|
}
|
|
}
|
|
// salvo su maschera...
|
|
parentForm.dataMonitor_2 += sb.ToString();
|
|
return needSave;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processing delle ore macchina ACCESA
|
|
/// </summary>
|
|
/// <param name="needSave"></param>
|
|
/// <returns></returns>
|
|
public bool procOreMaccOn(bool needSave)
|
|
{
|
|
double delta = 0;
|
|
double valore = 0;
|
|
StringBuilder sb = new StringBuilder();
|
|
if (istOreMaccOn.vcValid)
|
|
{
|
|
valore = istOreMaccOn.vcMedian;
|
|
if (valore >= contOreMaccOn)
|
|
{
|
|
delta = valore - contOreMaccOn;
|
|
// controllo delta < 50% max...
|
|
if (delta < double.MaxValue / 2)
|
|
{
|
|
// processo comunque sempre...
|
|
double contatore = updateValDoubleByIncr(0, delta, "ACC_TIME");
|
|
currAdpConf.ContOreMaccOn += delta;
|
|
// salvo valore
|
|
string newAccTime = contatore.ToString("0.000", CultureInfo.InvariantCulture);
|
|
currGateway.updateItemNodeValue("ACC_TIME", newAccTime);
|
|
// controllo incremento...
|
|
if (delta > 0)
|
|
{
|
|
// segnalo necessità salvataggio!
|
|
needSave = true;
|
|
}
|
|
}
|
|
}
|
|
// ...aggiorno valore riferimento...
|
|
contOreMaccOn = valore;
|
|
}
|
|
// salvo su maschera...
|
|
sb.AppendLine(string.Format("ACC_TIME: {0}", currGateway.getItemNode("ACC_TIME")));
|
|
parentForm.dataMonitor_1 += sb.ToString();
|
|
return needSave;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processing delle ore macchina IN LAVORO
|
|
/// </summary>
|
|
/// <param name="needSave"></param>
|
|
/// <returns></returns>
|
|
public bool procOreMaccLav(bool needSave)
|
|
{
|
|
double delta = 0;
|
|
double valore = 0;
|
|
StringBuilder sb = new StringBuilder();
|
|
if (istOreMaccLav.vcValid)
|
|
{
|
|
valore = istOreMaccLav.vcMedian;
|
|
if (valore >= contOreMaccLav)
|
|
{
|
|
delta = valore - contOreMaccLav;
|
|
// controllo delta < 50% max...
|
|
if (delta < double.MaxValue / 2)
|
|
{
|
|
double contatore = updateValDoubleByIncr(0, delta, "ACC_TIME_WORK");
|
|
currAdpConf.ContOreMaccLav += delta;
|
|
// salvo valore
|
|
string newAccTimeWork = contatore.ToString("0.000", CultureInfo.InvariantCulture);
|
|
currGateway.updateItemNodeValue("ACC_TIME_WORK", newAccTimeWork);
|
|
// controllo valore riferimento...
|
|
if (delta > 0)
|
|
{
|
|
// segnalo necessità salvataggio!
|
|
needSave = true;
|
|
}
|
|
}
|
|
}
|
|
// ...aggiorno valore riferimento...
|
|
contOreMaccLav = valore;
|
|
}
|
|
// salvo su maschera...
|
|
sb.AppendLine(string.Format("ACC_TIME_WORK: {0}", currGateway.getItemNode("ACC_TIME_WORK")));
|
|
parentForm.dataMonitor_1 += sb.ToString();
|
|
return needSave;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processing contatore Slitta Tastatore
|
|
/// </summary>
|
|
/// <param name="needSave"></param>
|
|
/// <returns></returns>
|
|
public bool procSlittaTast(bool needSave)
|
|
{
|
|
double delta = 0;
|
|
double valore = 0;
|
|
StringBuilder sb = new StringBuilder();
|
|
if (istSlittaTast.vcValid)
|
|
{
|
|
valore = istSlittaTast.vcMedian;
|
|
if (valore >= contSlittaTast)
|
|
{
|
|
delta = valore - contSlittaTast;
|
|
// controllo delta < 50% max...
|
|
if (delta < double.MaxValue / 2)
|
|
{
|
|
double contatore = updateValDoubleByIncr(0, delta, "SlittaTastatore_Count");
|
|
currAdpConf.ContSlittaTast += delta;
|
|
// salvo valore
|
|
currGateway.updateItemNodeValue("SlittaTastatore_Count", contatore.ToString("0", CultureInfo.InvariantCulture));
|
|
// controllo valore riferimento...
|
|
if (delta > 0)
|
|
{
|
|
// segnalo necessità salvataggio!
|
|
needSave = true;
|
|
}
|
|
}
|
|
}
|
|
// ...aggiorno valore riferimento...
|
|
contSlittaTast = valore;
|
|
}
|
|
// salvo su maschera...
|
|
sb.AppendLine(string.Format("SlittaTastatore_Count: {0}", currGateway.getItemNode("SlittaTastatore_Count")));// mSlittaTast.Value));
|
|
parentForm.dataMonitor_1 += sb.ToString();
|
|
return needSave;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processing del program name
|
|
/// </summary>
|
|
/// <param name="needSave"></param>
|
|
/// <returns></returns>
|
|
public bool procProgrName(bool needSave)
|
|
{
|
|
// SOLO SE NON sono SOUR...
|
|
if (currGateway.protocollo != gwProtocol.SOURS)
|
|
{
|
|
// controllo valore riferimento x tutti i path se sia cambiato programma...
|
|
for (int i = 0; i < currAdpConf.nPath; i++)
|
|
{
|
|
if (istPathProgrName[i] != null)
|
|
{
|
|
if (istPathProgrName[i] != currPathProgrName[i])
|
|
{
|
|
// prendo nuovo valore programma x path!
|
|
currGateway.updateItemNodeValue(vettPath[i].currProgKey, istPathProgrName[i]);
|
|
// segnalo necessità salvataggio!
|
|
needSave = true;
|
|
// ...aggiorno valore riferimento...
|
|
currPathProgrName[i] = istPathProgrName[i];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return needSave;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processing del particolare
|
|
/// </summary>
|
|
/// <param name="needSave"></param>
|
|
/// <returns></returns>
|
|
public bool procPartId(bool needSave)
|
|
{
|
|
if (currGateway.protocollo != gwProtocol.SOURS)
|
|
{
|
|
// controllo valore riferimento x tutti i path se sia cambiato num pz...
|
|
for (int i = 0; i < currAdpConf.nPath; i++)
|
|
{
|
|
if (istPathPartId[i] != null)
|
|
{
|
|
if (istPathPartId[i] != currPathPartId[i])
|
|
{
|
|
// aggiorno valore in Path RefList
|
|
updateValString(i, istPathPartId[i], "Path_{0:00}_PartId");
|
|
// prendo nuovo valore programma x path!
|
|
currGateway.updateItemNodeValue(vettPath[i].partIdKey, istPathPartId[i]);
|
|
// imposto a ZERO i pezzi del nuovo articolo
|
|
currGateway.updateItemNodeValue(vettPath[i].partCountKey, 0);
|
|
// segnalo necessità salvataggio!
|
|
needSave = true;
|
|
// ...aggiorno valore riferimento...
|
|
currPathPartId[i] = istPathPartId[i];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return needSave;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processing del num pz prodotti
|
|
/// </summary>
|
|
/// <param name="needSave"></param>
|
|
/// <returns></returns>
|
|
public bool procPzProd(bool needSave)
|
|
{
|
|
if (currGateway.protocollo != gwProtocol.SOURS)
|
|
{
|
|
string outString = string.Format("Path_[1-{0}]_PZ_TOT: ", currAdpConf.nPath);
|
|
// controllo valore riferimento x tutti i path se sia cambiato qta pezzi...
|
|
for (int i = 0; i < currAdpConf.nPath; i++)
|
|
{
|
|
// controllo valore riferimento variato...
|
|
if (istPathPartCount[i].vcMedian != currPathPartCount[i])
|
|
{
|
|
if (istPathPartCount[i].vcMedian > currPathPartCount[i])
|
|
{
|
|
uint delta = Convert.ToUInt32(istPathPartCount[i].vcMedian) - currPathPartCount[i];
|
|
uint contatore = updateValUIntByIncr(i, delta, "Path_{0:00}_PZ_TOT");
|
|
// passo valore num pz all'adapter
|
|
currGateway.updateItemNodeValue(vettPath[i].partCountKey, contatore);
|
|
}
|
|
else // variato x difetto... azzero!!!
|
|
{
|
|
uint newVal = Convert.ToUInt32(istPathPartCount[i].vcMedian);
|
|
updateValUInt(i, newVal, "Path_{0:00}_PZ_TOT");
|
|
// passo valore num pz all'adapter
|
|
currGateway.updateItemNodeValue(vettPath[i].partCountKey, newVal);
|
|
}
|
|
|
|
// segnalo necessità salvataggio!
|
|
needSave = true;
|
|
// ...aggiorno valore riferimento...
|
|
currPathPartCount[i] = Convert.ToUInt32(istPathPartCount[i].vcMedian);
|
|
}
|
|
outString += string.Format("{0} | ", currGateway.getItemNode(vettPath[i].partCountKey));
|
|
}
|
|
// salvo su maschera...
|
|
parentForm.dataMonitor_2 += string.Format("{0}{1}", outString.Substring(0, outString.Length - 3), Environment.NewLine);
|
|
}
|
|
return needSave;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processing delle variabili sul numero giri mandrino (totali) + tempo attività...
|
|
/// </summary>
|
|
/// <param name="needSave"></param>
|
|
/// <returns></returns>
|
|
public bool procGiriTotUnOp(bool needSave)
|
|
{
|
|
uint delta = 0;
|
|
uint valore = 0;
|
|
// Contatore giri mandrino
|
|
string outString = string.Format("UnOp_[1-{0}]_KRev: ", currAdpConf.nUnOp);
|
|
for (int i = 0; i < currAdpConf.nUnOp; i++)
|
|
{
|
|
// procedo solo SE HO FINESTRA VALIDA...
|
|
if (istGiriElettrom[i].vcValid)
|
|
{
|
|
valore = Convert.ToUInt32(istGiriElettrom[i].vcMedian);
|
|
if (valore >= contGiriElettrom[i])
|
|
{
|
|
delta = valore - contGiriElettrom[i];
|
|
// controllo delta < 50% max...
|
|
if (delta < uint.MaxValue / 2)
|
|
{
|
|
// processo comunque sempre...
|
|
uint contatore = updateValUIntByIncr(i, delta, "UnOp_{0:00}_KRev");
|
|
// passo valore num giri (migliaia) all'adapter
|
|
currGateway.updateItemNodeValue(vettUnOp[i].kRevKey, contatore);
|
|
// controllo valore riferimento...
|
|
if (delta > 0)
|
|
{
|
|
// segnalo necessità salvataggio!
|
|
needSave = true;
|
|
}
|
|
}
|
|
}
|
|
// ...aggiorno valore riferimento...
|
|
contGiriElettrom[i] = valore;
|
|
}
|
|
//outString += string.Format("{0} | ", currGateway.getItemNode(vettUnOp[i].kRevKey));
|
|
}
|
|
// salvo su maschera...
|
|
parentForm.dataMonitor_2 += string.Format("{0}{1}", outString.Substring(0, outString.Length - 3), Environment.NewLine);
|
|
|
|
// Contatore ORE ATTIVE mandrino
|
|
outString = string.Format("UnOp_[1-{0}]_AccTime: ", currAdpConf.nUnOp);
|
|
for (int i = 0; i < currAdpConf.nUnOp; i++)
|
|
{
|
|
// procedo solo SE HO FINESTRA VALIDA...
|
|
if (istOreElettrom[i].vcValid)
|
|
{
|
|
valore = Convert.ToUInt32(istOreElettrom[i].vcMedian);
|
|
if (valore >= contOreElettrom[i])
|
|
{
|
|
delta = valore - contOreElettrom[i];
|
|
// controllo delta < 50% max...
|
|
if (delta < uint.MaxValue / 2)
|
|
{
|
|
// processo comunque sempre...
|
|
uint contatore = updateValUIntByIncr(i, delta, "UnOp_{0:00}_AccTime");
|
|
// passo valore num giri (migliaia) all'adapter
|
|
currGateway.updateItemNodeValue(vettUnOp[i].accTimeKey, contatore);
|
|
// controllo valore riferimento...
|
|
if (delta > 0)
|
|
{
|
|
// segnalo necessità salvataggio!
|
|
needSave = true;
|
|
}
|
|
}
|
|
}
|
|
// ...aggiorno valore riferimento...
|
|
contOreElettrom[i] = valore;
|
|
}
|
|
//outString += string.Format("{0} | ", currGateway.getItemNode(vettUnOp[i].accTimeKey));
|
|
}
|
|
return needSave;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processing delle variabili sul numero cambi utensile (totali)
|
|
/// </summary>
|
|
/// <param name="needSave"></param>
|
|
/// <returns></returns>
|
|
public bool procNumCU(bool needSave)
|
|
{
|
|
uint delta = 0;
|
|
uint valore = 0;
|
|
string outString = string.Format("UnOp_[1-{0}]_NumCU: ", currAdpConf.nUnOp);
|
|
for (int i = 0; i < currAdpConf.nUnOp; i++)
|
|
{
|
|
// procedo solo SE HO FINESTRA VALIDA...
|
|
if (istNumCambiUt[i].vcValid)
|
|
{
|
|
valore = Convert.ToUInt32(istNumCambiUt[i].vcMedian);
|
|
if (valore >= currNumCambiUt[i])
|
|
{
|
|
delta = valore - currNumCambiUt[i];
|
|
// controllo delta < 50% max...
|
|
if (delta < uint.MaxValue / 2)
|
|
{
|
|
// processo comunque sempre...
|
|
uint contatore = updateValUIntByIncr(i, delta, "UnOp_{0:00}_NumCU");
|
|
// passo valore num CU all'adapter
|
|
currGateway.updateItemNodeValue(vettUnOp[i].numCUKey, contatore);
|
|
// controllo valore riferimento...
|
|
if (delta > 0)
|
|
{
|
|
// segnalo necessità salvataggio!
|
|
needSave = true;
|
|
}
|
|
}
|
|
}
|
|
// ...aggiorno valore riferimento...
|
|
currNumCambiUt[i] = valore;
|
|
}
|
|
outString += string.Format("{0} | ", currGateway.getItemNode(vettUnOp[i].numCUKey));
|
|
}
|
|
// salvo su maschera...
|
|
parentForm.dataMonitor_2 += string.Format("{0}{1}", outString.Substring(0, outString.Length - 3), Environment.NewLine);
|
|
return needSave;
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// Processing delle variabili sul numero di ripetizioni
|
|
/// </summary>
|
|
/// <param name="needSave"></param>
|
|
/// <returns></returns>
|
|
public bool procRepetitions(bool needSave)
|
|
{
|
|
uint delta = 0;
|
|
uint valore = 0;
|
|
string outString = string.Format("UnOp_[1-{0}]_Count: ", currAdpConf.nUnOp);
|
|
for (int i = 0; i < currAdpConf.nUnOp; i++)
|
|
{
|
|
// procedo solo SE HO FINESTRA VALIDA...
|
|
if (istRepetitionUnOp[i].vcValid)
|
|
{
|
|
valore = Convert.ToUInt32(istRepetitionUnOp[i].vcMedian);
|
|
if (valore >= currRepetitionUnOp[i])
|
|
{
|
|
delta = valore - currRepetitionUnOp[i];
|
|
// controllo delta < 50% max...
|
|
if (delta < uint.MaxValue / 2)
|
|
{
|
|
// processo comunque sempre...
|
|
uint contatore = updateValUIntByIncr(i, delta, "UnOp_{0:00}_Count");
|
|
// passo valore num CU all'adapter
|
|
currGateway.updateItemNodeValue(vettUnOp[i].countKey, contatore);
|
|
// controllo valore riferimento...
|
|
if (delta > 0)
|
|
{
|
|
// segnalo necessità salvataggio!
|
|
needSave = true;
|
|
}
|
|
}
|
|
}
|
|
// ...aggiorno valore riferimento...
|
|
currRepetitionUnOp[i] = valore;
|
|
}
|
|
outString += string.Format("{0} | ", currGateway.getItemNode(vettUnOp[i].countKey));
|
|
}
|
|
// salvo su maschera...
|
|
parentForm.dataMonitor_2 += string.Format("{0}{1}", outString.Substring(0, outString.Length - 3), Environment.NewLine);
|
|
return needSave;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Processing delle variabili sul totale m percorsi dagli assi
|
|
/// </summary>
|
|
/// <param name="needSave"></param>
|
|
/// <returns></returns>
|
|
public bool procMovTotAssi(bool needSave)
|
|
{
|
|
double delta = 0;
|
|
uint valore = 0;
|
|
string outString = string.Format("Axis_[1-{0}]_DistDone: ", currAdpConf.nAxis);
|
|
for (int i = 0; i < currAdpConf.nAxis; i++)
|
|
{
|
|
// procedo solo SE HO FINESTRA VALIDA...
|
|
if (istDistMovAssi[i].vcValid)
|
|
{
|
|
valore = Convert.ToUInt32(istDistMovAssi[i].vcMedian);
|
|
if (valore >= contDistMovAssi[i])
|
|
{
|
|
delta = valore - contDistMovAssi[i];
|
|
// controllo delta < 50% max...
|
|
if (delta < double.MaxValue / 2)
|
|
{
|
|
// processo comunque sempre...
|
|
double contTot = updateValDoubleByIncr(i, delta, "Axis_{0:00}_DistDone");
|
|
// passo valore totale all'adapter
|
|
currGateway.updateItemNodeValue(vettAxis[i].distDoneKey, contTot.ToString("0.000", CultureInfo.InvariantCulture));
|
|
// controllo valore riferimento...
|
|
if (delta > 0)
|
|
{
|
|
// segnalo necessità salvataggio!
|
|
needSave = true;
|
|
}
|
|
}
|
|
}
|
|
// ...aggiorno valore riferimento...
|
|
contDistMovAssi[i] = valore;
|
|
}
|
|
outString += string.Format("{0} | ", currGateway.getItemNode(vettAxis[i].distDoneKey));
|
|
}
|
|
// salvo su maschera...
|
|
parentForm.dataMonitor_3 += string.Format("{0}{1}", outString.Substring(0, outString.Length - 3), Environment.NewLine);
|
|
return needSave;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processing delle variabili sul totale tempo lavoro degli assi
|
|
/// </summary>
|
|
/// <param name="needSave"></param>
|
|
/// <returns></returns>
|
|
public bool procAccTimeAssi(bool needSave)
|
|
{
|
|
double delta = 0;
|
|
uint valore = 0;
|
|
string outString = string.Format("Axis_[1-{0}]_AccTime: ", currAdpConf.nAxis);
|
|
for (int i = 0; i < currAdpConf.nAxis; i++)
|
|
{
|
|
// procedo solo SE HO FINESTRA VALIDA...
|
|
if (istAccTimeAssi[i].vcValid)
|
|
{
|
|
valore = Convert.ToUInt32(istAccTimeAssi[i].vcMedian);
|
|
if (valore >= contAccTimeAssi[i])
|
|
{
|
|
delta = valore - contAccTimeAssi[i];
|
|
// controllo delta < 50% max...
|
|
if (delta < double.MaxValue / 2)
|
|
{
|
|
// salvo valore aggiuntivo x ore lavoro assi...
|
|
double oreTot = updateValDoubleByIncr(i, delta, "Axis_{0:00}_AccTime");
|
|
currGateway.updateItemNodeValue(vettAxis[i].accTimeKey, oreTot.ToString("0.000", CultureInfo.InvariantCulture));
|
|
// controllo valore riferimento...
|
|
if (delta > 0)
|
|
{
|
|
// segnalo necessità salvataggio!
|
|
needSave = true;
|
|
}
|
|
}
|
|
}
|
|
// ...aggiorno valore riferimento...
|
|
contAccTimeAssi[i] = valore;
|
|
}
|
|
outString += string.Format("{0} | ", currGateway.getItemNode(vettAxis[i].accTimeKey));
|
|
}
|
|
// salvo su maschera...
|
|
parentForm.dataMonitor_3 += string.Format("{0}{1}", outString.Substring(0, outString.Length - 3), Environment.NewLine);
|
|
return needSave;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processing delle variabili sul totale num inversioni degli assi
|
|
/// </summary>
|
|
/// <param name="needSave"></param>
|
|
/// <returns></returns>
|
|
public bool procNumInvAssi(bool needSave)
|
|
{
|
|
long delta = 0;
|
|
uint valore = 0;
|
|
string outString = string.Format("Axis_[1-{0}]_InvDDone: ", currAdpConf.nAxis);
|
|
for (int i = 0; i < currAdpConf.nAxis; i++)
|
|
{
|
|
// procedo solo SE HO FINESTRA VALIDA...
|
|
if (istNumInvAssi[i].vcValid)
|
|
{
|
|
valore = Convert.ToUInt32(istNumInvAssi[i].vcMedian);
|
|
if (valore >= contNumInvAssi[i])
|
|
{
|
|
delta = valore - contNumInvAssi[i];
|
|
// controllo delta < 50% max...
|
|
if (delta < long.MaxValue / 2)
|
|
{
|
|
// processo comunque sempre...
|
|
long contTot = updateValLongByIncr(i, delta, "Axis_{0:00}_InvDDone");
|
|
// passo valore totale all'adapter
|
|
currGateway.updateItemNodeValue(vettAxis[i].invDDoneKey, contTot);
|
|
// controllo valore riferimento...
|
|
if (delta > 0)
|
|
{
|
|
// segnalo necessità salvataggio!
|
|
needSave = true;
|
|
}
|
|
}
|
|
}
|
|
// ...aggiorno valore riferimento...
|
|
contNumInvAssi[i] = valore;
|
|
}
|
|
outString += string.Format("{0} | ", currGateway.getItemNode(vettAxis[i].invDDoneKey));
|
|
}
|
|
// salvo su maschera...
|
|
parentForm.dataMonitor_3 += string.Format("{0}{1}", outString.Substring(0, outString.Length - 3), Environment.NewLine);
|
|
return needSave;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processing delle variabili sulle VacPump
|
|
/// </summary>
|
|
/// <param name="needSave"></param>
|
|
/// <returns></returns>
|
|
public bool procVacPump(bool needSave)
|
|
{
|
|
uint delta = 0;
|
|
uint valore = 0;
|
|
string outString = string.Format("VacPump_[1-{0}]_WrkTime: ", currAdpConf.nVacuumPump);
|
|
for (int i = 0; i < currAdpConf.nVacuumPump; i++)
|
|
{
|
|
// procedo solo SE HO FINESTRA VALIDA...
|
|
if (istVacPumpWrkTime[i].vcValid)
|
|
{
|
|
valore = Convert.ToUInt32(istVacPumpWrkTime[i].vcMedian);
|
|
if (valore >= currVacPumpWrkTime[i])
|
|
{
|
|
delta = valore - currVacPumpWrkTime[i];
|
|
// controllo delta < 50% max...
|
|
if (delta < uint.MaxValue / 2)
|
|
{
|
|
// processo comunque sempre...
|
|
uint contTot = updateValUIntByIncr(i, delta, "VacPump_{0:00}_WrkTime");
|
|
// passo valore totale all'adapter
|
|
currGateway.updateItemNodeValue(vettVacPump[i].workTimeKey, contTot);
|
|
// controllo valore riferimento...
|
|
if (delta > 0)
|
|
{
|
|
// segnalo necessità salvataggio!
|
|
needSave = true;
|
|
}
|
|
}
|
|
}
|
|
// ...aggiorno valore riferimento...
|
|
currVacPumpWrkTime[i] = valore;
|
|
}
|
|
outString += string.Format("{0} | ", currGateway.getItemNode(vettVacPump[i].workTimeKey));
|
|
}
|
|
// salvo su maschera...
|
|
parentForm.dataMonitor_2 += string.Format("{0}{1}", outString.Substring(0, outString.Length - 3), Environment.NewLine);
|
|
return needSave;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processing delle variabili sulle VacAct
|
|
/// </summary>
|
|
/// <param name="needSave"></param>
|
|
/// <returns></returns>
|
|
public bool procVacAct(bool needSave)
|
|
{
|
|
uint delta = 0;
|
|
uint valore = 0;
|
|
string outString = string.Format("VacPump_[1-{0}]_Count: ", currAdpConf.nVacuumPump);
|
|
for (int i = 0; i < currAdpConf.nVacuumAct; i++)
|
|
{
|
|
// procedo solo SE HO FINESTRA VALIDA...
|
|
if (istVacActCount[i].vcValid)
|
|
{
|
|
valore = Convert.ToUInt32(istVacActCount[i].vcMedian);
|
|
if (valore >= currVacActCount[i])
|
|
{
|
|
delta = valore - currVacActCount[i];
|
|
// controllo delta < 50% max...
|
|
if (delta < uint.MaxValue / 2)
|
|
{
|
|
// processo comunque sempre...
|
|
uint contTot = updateValUIntByIncr(i, delta, "VacAct_{0:00}_Count");
|
|
// passo valore totale all'adapter
|
|
currGateway.updateItemNodeValue(vettVacAct[i].countKey, contTot);
|
|
// controllo valore riferimento...
|
|
if (delta > 0)
|
|
{
|
|
// segnalo necessità salvataggio!
|
|
needSave = true;
|
|
}
|
|
}
|
|
}
|
|
// ...aggiorno valore riferimento...
|
|
currVacActCount[i] = valore;
|
|
}
|
|
outString += string.Format("{0} | ", currGateway.getItemNode(vettVacAct[i].countKey));
|
|
}
|
|
// salvo su maschera...
|
|
parentForm.dataMonitor_2 += string.Format("{0}{1}", outString.Substring(0, outString.Length - 3), Environment.NewLine);
|
|
return needSave;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processing delle variabili sui componenti Lubro
|
|
/// </summary>
|
|
/// <param name="needSave"></param>
|
|
/// <returns></returns>
|
|
public bool procLubro(bool needSave)
|
|
{
|
|
uint delta = 0;
|
|
uint valore = 0;
|
|
string outString = string.Format("Lubro_[1-{0}]_Count: ", currAdpConf.nLubro);
|
|
for (int i = 0; i < currAdpConf.nLubro; i++)
|
|
{
|
|
valore = Convert.ToUInt32(istLubroCount[i].vcMedian);
|
|
if (valore > currLubroCount[i])
|
|
{
|
|
delta = valore - currLubroCount[i];
|
|
// controllo delta < 50% max...
|
|
if (delta < uint.MaxValue / 2)
|
|
{
|
|
//processo comunque sempre...
|
|
uint contTot = updateValUIntByIncr(i, delta, "Lubro_{0:00}_Count");
|
|
// passo valore totale all'adapter
|
|
currGateway.updateItemNodeValue(vettLubro[i].countKey, contTot);
|
|
// controllo valore riferimento...
|
|
if (delta > 0)
|
|
{
|
|
// segnalo necessità salvataggio!
|
|
needSave = true;
|
|
}
|
|
}
|
|
// ...aggiorno valore riferimento...
|
|
currLubroCount[i] = valore;
|
|
}
|
|
else
|
|
{
|
|
currGateway.updateItemNodeValue(vettLubro[i].countKey, currLubroCount[i]);
|
|
}
|
|
outString += string.Format("{0} | ", currGateway.getItemNode(vettLubro[i].countKey));
|
|
}
|
|
// salvo su maschera...
|
|
parentForm.dataMonitor_2 += string.Format("{0}{1}", outString.Substring(0, outString.Length - 3), Environment.NewLine);
|
|
return needSave;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processing delle variabili sui componenti SlittaMag
|
|
/// </summary>
|
|
/// <param name="needSave"></param>
|
|
/// <returns></returns>
|
|
public bool procSlittaMag(bool needSave)
|
|
{
|
|
uint delta = 0;
|
|
uint valore = 0;
|
|
string outString = string.Format("SlittaMagazzino_[1-{0}]_Count: ", currAdpConf.nSlittaMag);
|
|
for (int i = 0; i < currAdpConf.nSlittaMag; i++)
|
|
{
|
|
// procedo solo SE HO FINESTRA VALIDA...
|
|
if (istSlittaMag[i].vcValid)
|
|
{
|
|
valore = Convert.ToUInt32(istSlittaMag[i].vcMedian);
|
|
if (valore >= currSlittaMag[i])
|
|
{
|
|
delta = valore - currSlittaMag[i];
|
|
// controllo delta < 50% max...
|
|
if (delta < uint.MaxValue / 2)
|
|
{
|
|
//processo comunque sempre...
|
|
uint contTot = updateValUIntByIncr(i, delta, "SlittaMagazzino_{0:00}_Count");
|
|
// passo valore totale all'adapter
|
|
currGateway.updateItemNodeValue(vettSlittaMag[i].countKey, contTot);
|
|
// controllo valore riferimento...
|
|
if (delta > 0)
|
|
{
|
|
// segnalo necessità salvataggio!
|
|
needSave = true;
|
|
}
|
|
}
|
|
}
|
|
// ...aggiorno valore riferimento...
|
|
currSlittaMag[i] = valore;
|
|
}
|
|
outString += string.Format("{0} | ", currGateway.getItemNode(vettSlittaMag[i].countKey));
|
|
}
|
|
// salvo su maschera...
|
|
parentForm.dataMonitor_2 += string.Format("{0}{1}", outString.Substring(0, outString.Length - 3), Environment.NewLine);
|
|
return needSave;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processing delle variabili sui componenti ProtMag
|
|
/// </summary>
|
|
/// <param name="needSave"></param>
|
|
/// <returns></returns>
|
|
public bool procProtMag(bool needSave)
|
|
{
|
|
uint delta = 0;
|
|
uint valore = 0;
|
|
string outString = string.Format("ProtMagazzino_[1-{0}]_Count: ", currAdpConf.nProtMag);
|
|
for (int i = 0; i < currAdpConf.nProtMag; i++)
|
|
{// procedo solo SE HO FINESTRA VALIDA...
|
|
if (istProtMag[i].vcValid)
|
|
{
|
|
valore = Convert.ToUInt32(istProtMag[i].vcMedian);
|
|
if (valore >= currProtMag[i])
|
|
{
|
|
delta = valore - currProtMag[i];
|
|
// controllo delta < 50% max...
|
|
if (delta < uint.MaxValue / 2)
|
|
{
|
|
//processo comunque sempre...
|
|
uint contTot = updateValUIntByIncr(i, delta, "ProtMagazzino_{0:00}_Count");
|
|
// passo valore totale all'adapter
|
|
currGateway.updateItemNodeValue(vettProtMag[i].countKey, contTot);
|
|
// controllo valore riferimento...
|
|
if (delta > 0)
|
|
{
|
|
// segnalo necessità salvataggio!
|
|
needSave = true;
|
|
}
|
|
}
|
|
}
|
|
// ...aggiorno valore riferimento...
|
|
currProtMag[i] = valore;
|
|
}
|
|
outString += string.Format("{0} | ", currGateway.getItemNode(vettProtMag[i].countKey));
|
|
}
|
|
// salvo su maschera...
|
|
parentForm.dataMonitor_2 += string.Format("{0}{1}", outString.Substring(0, outString.Length - 3), Environment.NewLine);
|
|
return needSave;
|
|
}
|
|
|
|
#endregion metodi che prevedono salvataggio valori su file XML/BIN
|
|
|
|
#region layer persistenza dati
|
|
|
|
/// <summary>
|
|
/// Dizionario di persistenza per i valori da salvare da/su file
|
|
/// </summary>
|
|
public Dictionary<string, string> persistenceLayer;
|
|
|
|
/// <summary>
|
|
/// recupera valore salvato in persistence layer (se non c'è crea...)
|
|
/// </summary>
|
|
/// <param name="keyVal"></param>
|
|
/// <returns></returns>
|
|
private string getStoredVal(string keyVal)
|
|
{
|
|
string value = "";
|
|
try
|
|
{
|
|
if (persistenceLayer != null)
|
|
{
|
|
if (!persistenceLayer.TryGetValue(keyVal, out value))
|
|
{
|
|
persistenceLayer.Add(keyVal, "0");
|
|
}
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error(string.Format("Eccezione in getStoredVal: {0}{1}", Environment.NewLine, exc));
|
|
}
|
|
return value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// recupera valore salvato in persistence layer (se non c'è crea...) come UINT
|
|
/// </summary>
|
|
/// <param name="keyVal"></param>
|
|
/// <returns></returns>
|
|
private uint getStoredValUInt(string keyVal)
|
|
{
|
|
uint answ = 0;
|
|
try
|
|
{
|
|
answ = Convert.ToUInt32(getStoredVal(keyVal));
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error(string.Format("Eccezione in getStoredValUInt: {0}{1}", Environment.NewLine, exc));
|
|
}
|
|
// verifico che il valore sia minore di 9/10 del valore massimo...
|
|
answ = (answ < (uint.MaxValue / 10 * 9)) ? answ : 0;
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// recupera valore salvato in persistence layer (se non c'è crea...) come INT
|
|
/// </summary>
|
|
/// <param name="keyVal"></param>
|
|
/// <returns></returns>
|
|
private long getStoredValLong(string keyVal)
|
|
{
|
|
long answ = 0;
|
|
try
|
|
{
|
|
answ = Convert.ToInt64(getStoredVal(keyVal));
|
|
}
|
|
catch
|
|
{ }
|
|
// verifico che il valore sia minore di 9/10 del valore massimo...
|
|
answ = (answ < (long.MaxValue / 10 * 9)) ? answ : 0;
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// recupera valore salvato in persistence layer (se non c'è crea...) come double
|
|
/// </summary>
|
|
/// <param name="keyVal"></param>
|
|
/// <returns></returns>
|
|
private double getStoredValDouble(string keyVal)
|
|
{
|
|
double answ = 0;
|
|
try
|
|
{
|
|
answ = Convert.ToDouble(getStoredVal(keyVal));
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error(string.Format("Eccezione in getStoredValDouble: {0}{1}", Environment.NewLine, exc));
|
|
}
|
|
answ = (answ < (double.MaxValue / 10 * 9)) ? answ : 0;
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Aggiorna un valore del dizionario in SOSTITUZIONE
|
|
/// </summary>
|
|
/// <param name="i"></param>
|
|
/// <param name="newVal"></param>
|
|
/// <param name="searchString"></param>
|
|
/// <returns>Nuovo valore incrementato</returns>
|
|
private void updateValString(int i, string newVal, string searchString)
|
|
{
|
|
// stringa da cercare..
|
|
string keyVal = string.Format(searchString, i + 1);
|
|
// salvo in ram!
|
|
persistenceLayer[keyVal] = newVal;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Aggiorna un valore del dizionario in SOSTITUZIONE e lo restituisce
|
|
/// </summary>
|
|
/// <param name="i"></param>
|
|
/// <param name="newVal"></param>
|
|
/// <param name="searchString"></param>
|
|
/// <returns>Nuovo valore incrementato</returns>
|
|
private void updateValUInt(int i, uint newVal, string searchString)
|
|
{
|
|
// stringa da cercare..
|
|
string keyVal = string.Format(searchString, i + 1);
|
|
// salvo in ram!
|
|
persistenceLayer[keyVal] = newVal.ToString();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Aggiorna un valore del dizionario in INCREMENTO e lo restituisce
|
|
/// </summary>
|
|
/// <param name="i"></param>
|
|
/// <param name="delta"></param>
|
|
/// <param name="searchString"></param>
|
|
/// <returns>Nuovo valore incrementato</returns>
|
|
private uint updateValUIntByIncr(int i, uint delta, string searchString)
|
|
{
|
|
// stringa da cercare..
|
|
string keyVal = string.Format(searchString, i + 1);
|
|
// recupero valore precedente...
|
|
uint contAct = getStoredValUInt(keyVal);
|
|
// nuovo valore...
|
|
contAct += delta;
|
|
// salvo in ram!
|
|
persistenceLayer[keyVal] = contAct.ToString();
|
|
// rendo il valore!
|
|
return contAct;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Aggiorna un valore del dizionario in INCREMENTO e lo restituisce
|
|
/// </summary>
|
|
/// <param name="i"></param>
|
|
/// <param name="delta"></param>
|
|
/// <param name="searchString"></param>
|
|
/// <returns>Nuovo valore incrementato</returns>
|
|
private long updateValLongByIncr(int i, long delta, string searchString)
|
|
{
|
|
// stringa da cercare..
|
|
string keyVal = string.Format(searchString, i + 1);
|
|
// recupero valore precedente...
|
|
long contAct = getStoredValLong(keyVal);
|
|
// nuovo valore...
|
|
contAct += delta;
|
|
// salvo in ram!
|
|
persistenceLayer[keyVal] = contAct.ToString();
|
|
// rendo il valore!
|
|
return contAct;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Aggiorna un valore del dizionario in INCREMENTO e lo restituisce
|
|
/// </summary>
|
|
/// <param name="i"></param>
|
|
/// <param name="delta"></param>
|
|
/// <param name="searchString"></param>
|
|
/// <returns>Nuovo valore incrementato</returns>
|
|
private double updateValDoubleByIncr(int i, double delta, string searchString)
|
|
{
|
|
// stringa da cercare..
|
|
string keyVal = string.Format(searchString, i + 1);
|
|
// recupero valore precedente...
|
|
double contAct = getStoredValDouble(keyVal);
|
|
// nuovo valore...
|
|
contAct += delta;
|
|
// salvo in ram!
|
|
persistenceLayer[keyVal] = contAct.ToString();
|
|
// rendo il valore!
|
|
return contAct;
|
|
}
|
|
|
|
#endregion layer persistenza dati
|
|
|
|
#region metodi helper
|
|
|
|
|
|
/// <summary>
|
|
/// Effettua accodamento messaggio sullo string builder indicato (con try/catch e eventuale log...)
|
|
/// </summary>
|
|
/// <param name="strBuild"></param>
|
|
/// <param name="newLine"></param>
|
|
public void tryLogMessage(StringBuilder strBuild, string newLine)
|
|
{
|
|
try
|
|
{
|
|
strBuild.AppendLine(newLine);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error(exc, "Eccezione in accodamento messaggio su stringBuilder");
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
} |