Files
CMS-MTConn/MTC_Adapter/MTC_Adapter/AdapterGeneric.cs
T
2017-05-19 17:49:45 +02:00

4474 lines
178 KiB
C#

using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
using CMSCncLib.CNC;
namespace MTC_Adapter
{
using MTC;
using MTConnect;
using System.Globalization;
using System.IO;
using System.Text;
#region macro oggetti da istanziare a blocchi da configurazione XML
/// <summary>
/// Singola pompa da vuoto, 0..n
/// </summary>
public class VacuumPump : element
{
/// <summary>
/// valore indca stato aperto/chiuso
/// </summary>
public Event mVacPumpStatus;
/// <summary>
/// valore work time della pompa vuoto
/// </summary>
public Event mVacPumpWrkTime;
/// <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;
mVacPumpStatus = new Event(string.Format("{0}_Status", ident));
mVacPumpWrkTime = new Event(string.Format("{0}_WrkTime", ident));
}
}
/// <summary>
/// Singolo attuatore vuoto, 0..n
/// </summary>
public class VacuumAct : element
{
/// <summary>
/// valore numero attivazioni/disattivazioni valvola
/// </summary>
public Event mVacActCount;
/// <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;
mVacActCount = new Event(string.Format("{0}_Count", ident));
}
}
/// <summary>
/// Singolo attuatore per lubrificazione, 0..n
/// </summary>
public class Lubro : element
{
/// <summary>
/// numero pompate necessarie per far scattare sensore
/// </summary>
public Event mLubroNum;
/// <summary>
/// Status
/// </summary>
public Event mLubroStatus;
/// <summary>
/// Classe Lubrorefrigerante
/// </summary>
/// <param name="baseElem">element base contenente parametri (da XML)</param>
public Lubro(element baseElem)
{
ident = baseElem.ident;
dataRefList = baseElem.dataRefList;
mLubroNum = new Event(string.Format("{0}_Num", ident));
mLubroStatus = new Event(string.Format("{0}_Status", ident));
}
}
/// <summary>
/// Singola Slitta Mag, 0..n
/// </summary>
public class SlittaMag : element
{
/// <summary>
/// valore numero attivazioni/disattivazioni slitta magazzino
/// </summary>
public Event mSlittaMagCount;
/// <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;
mSlittaMagCount = new Event(string.Format("{0}_Count", ident));
}
}
/// <summary>
/// Singolo attuatore Protezione Magazzino, 0..n
/// </summary>
public class ProtMag : element
{
/// <summary>
/// valore numero attivazioni/disattivazioni valvola
/// </summary>
public Event mProtMagCount;
/// <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;
mProtMagCount = new Event(string.Format("{0}_Count", ident));
}
}
/// <summary>
/// Singolo refrigeratore, 0..n
/// </summary>
public class Cooler : element
{
/// <summary>
/// Stato istantaneo (evento aperto/chiuso)
/// </summary>
public Event mCoolStatus;
/// <summary>
/// Classe refrigeratore
/// </summary>
/// <param name="baseElem">element base contenente parametri (da XML)</param>
public Cooler(element baseElem)
{
ident = baseElem.ident;
dataRefList = baseElem.dataRefList;
mCoolStatus = new Event(string.Format("{0}_Status", ident));
}
}
/// <summary>
/// Singola Pressione rilevata, 0..n
/// </summary>
public class Press : element
{
/// <summary>
/// valore pressione istantaneo
/// </summary>
public Sample mPressValIst;
/// <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;
mPressValIst = new Sample(string.Format("{0}_Value", ident));
}
}
/// <summary>
/// Singola temperatura rilevata, 0..n
/// </summary>
public class Tempe : element
{
/// <summary>
/// valore temperatura istantaneo
/// </summary>
public Sample mTempValIst;
/// <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;
mTempValIst = new Sample(string.Format("{0}_Value", ident));
}
}
/// <summary>
/// Singola Area Memoria (Kvara 1..4)
/// </summary>
public class MemArea : element
{
/// <summary>
/// Programma caricato
/// </summary>
public MTConnect.Message mMemAreaProgName;
/// <summary>
/// Programma Running (in esecuzione) - ON/OFF
/// </summary>
public MTConnect.Message mMemAreaRunning;
/// <summary>
/// Num esecuzioni programma
/// </summary>
public Event mMemAreaProgNumExe;
/// <summary>
/// Num esecuzioni programma
/// </summary>
public Event mMemAreaProgNumRep;
/// <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;
mMemAreaProgName = new MTConnect.Message(string.Format("{0}_PROG_NAME", ident));
mMemAreaRunning = new MTConnect.Message(string.Format("{0}_RUNNING", ident));
mMemAreaProgNumExe = new Event(string.Format("{0}_NUM_EXE", ident));
mMemAreaProgNumRep = new Event(string.Format("{0}_NUM_REP", ident));
}
}
/// <summary>
/// Singolo path, da 1..20
/// </summary>
public class Path : element
{
/// <summary>
/// Tipo Path (LAVOR/ASSERV)
/// </summary>
public MTConnect.Message mPathType;
/// <summary>
/// Cod Particolare su Path
/// </summary>
public Event mPathPartId;
/// <summary>
/// Contapezzi x PATH
/// </summary>
public Event mPathPartCount;
/// <summary>
/// Codici M sul PATH
/// </summary>
public MTConnect.Message mPathCodM;
/// <summary>
/// Codici S sul PATH
/// </summary>
public MTConnect.Message mPathCodS;
/// <summary>
/// Codici T sul PATH
/// </summary>
public MTConnect.Message mPathCodT;
/// <summary>
/// Modalità RUN del PATH: AUTO/EDIT/MDI/JOG/JOGINC/REF/HANDLE
/// </summary>
public Event mPathRunMode;
/// <summary>
/// Modalità execution del path: RUN/HOLD/FEED_HOLD/...
/// </summary>
public Event mPathExeMode;
/// <summary>
/// Programma corrente
/// </summary>
public Event mPathCurrProg;
/// <summary>
/// Area Programma corrente/selezionata
/// </summary>
public Event mPathCurrArea;
/// <summary>
/// num riga corrente
/// </summary>
public Event mPathCurrProgRowNum;
/// <summary>
/// Assi attivi per path
/// </summary>
public Event mPathActiveAxes;
/// <summary>
/// Feedrate
/// </summary>
public Sample mPathFeed;
/// <summary>
/// Override feed
/// </summary>
public Sample mPathFeedOver;
/// <summary>
/// Override speed
/// </summary>
public Sample mPathRapidOver;
/// <summary>
/// Override Jog
/// </summary>
public Sample mPathJogOver;
/// <summary>
/// Override Spindle_01
/// </summary>
public Sample mPathSpindleOver_01;
/// <summary>
/// Override Spindle_02
/// </summary>
public Sample mPathSpindleOver_02;
/// <summary>
/// Override Spindle_03
/// </summary>
public Sample mPathSpindleOver_03;
/// <summary>
/// Override Spindle_04
/// </summary>
public Sample mPathSpindleOver_04;
/// <summary>
/// Posizione X
/// </summary>
public Sample mPathPosActX;
/// <summary>
/// Posizione Y
/// </summary>
public Sample mPathPosActY;
/// <summary>
/// Posizione Z
/// </summary>
public Sample mPathPosActZ;
/// <summary>
/// Angolo I
/// </summary>
public Sample mPathPosActI;
/// <summary>
/// Angolo J
/// </summary>
public Sample mPathPosActJ;
/// <summary>
/// Angolo K
/// </summary>
public Sample mPathPosActK;
/// <summary>
/// Stato dei codici G attivi
/// </summary>
public MTConnect.Message mPathCodG_Act;
/// <summary>
/// Stato dei SubMode attivi
/// </summary>
public MTConnect.Message mPathSubMode;
/// <summary>
/// Allarmi CNC del PATH
/// </summary>
public Condition mPathAlarmCNC;
/// <summary>
/// Allarmi PCL del PATH
/// </summary>
public Condition mPathAlarmPLC;
/// <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;
mPathFeed = new Sample(string.Format("{0}_FeedRate", ident));
mPathFeedOver = new Sample(string.Format("{0}_FeedOverr", ident));
mPathRapidOver = new Sample(string.Format("{0}_RapidOverr", ident));
mPathJogOver = new Sample(string.Format("{0}_JogOverr", ident));
mPathSpindleOver_01 = new Sample(string.Format("{0}_SpindleOver_01", ident));
mPathSpindleOver_02 = new Sample(string.Format("{0}_SpindleOver_02", ident));
mPathSpindleOver_03 = new Sample(string.Format("{0}_SpindleOver_03", ident));
mPathSpindleOver_04 = new Sample(string.Format("{0}_SpindleOver_04", ident));
mPathPosActX = new Sample(string.Format("{0}_PosActX", ident));
mPathPosActY = new Sample(string.Format("{0}_PosActY", ident));
mPathPosActZ = new Sample(string.Format("{0}_PosActZ", ident));
mPathPosActI = new Sample(string.Format("{0}_PosActI", ident));
mPathPosActJ = new Sample(string.Format("{0}_PosActJ", ident));
mPathPosActK = new Sample(string.Format("{0}_PosActK", ident));
// aggiunta x revisione 2016.05.05
mPathType = new MTConnect.Message(string.Format("{0}_Type", ident));
mPathPartId = new Event(string.Format("{0}_PartId", ident));
mPathPartCount = new Event(string.Format("{0}_PZ_TOT", ident));
mPathCodM = new MTConnect.Message(string.Format("{0}_Cod_M", ident));
mPathCodS = new MTConnect.Message(string.Format("{0}_Cod_S", ident));
mPathCodT = new MTConnect.Message(string.Format("{0}_Cod_T", ident));
mPathRunMode = new Event(string.Format("{0}_RUN_MODE", ident));
mPathExeMode = new Event(string.Format("{0}_EXE_MODE", ident));
mPathCurrProg = new Event(string.Format("{0}_CurrProg", ident));
mPathCurrArea = new Event(string.Format("{0}_CurrArea", ident));
mPathCurrProgRowNum = new Event(string.Format("{0}_CurrProg_RowNum", ident));
mPathActiveAxes = new Event(string.Format("{0}_ActiveAxes", ident));
mPathCodG_Act = new MTConnect.Message(string.Format("{0}_CodG_Act", ident));
mPathSubMode = new MTConnect.Message(string.Format("{0}_SubMode", ident));
mPathAlarmCNC = new Condition(string.Format("{0}_AlarmCNC", ident));
mPathAlarmPLC = new Condition(string.Format("{0}_AlarmPLC", ident));
}
}
/// <summary>
/// Singolo mandrino, 1..n
/// </summary>
public class UnOp : element
{
/// <summary>
/// ToolID
/// </summary>
public Event mUnOpToolId;
/// <summary>
/// valore numero Cambi Utensili effettuato
/// </summary>
public Event mUnOpNumCU;
/// <summary>
/// status utensil
/// </summary>
public Event mUnOpStatus;
/// <summary>
/// valore vita residua utensile
/// </summary>
public Event mUnOpVitaRes;
/// <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 MTConnect.Message mUnOpVitaResType;
/// <summary>
/// valore speed
/// </summary>
public Sample mUnOpSpeed;
/// <summary>
/// valore speed override
/// </summary>
public Sample mUnOpSpeedOverr;
/// <summary>
/// valore load
/// </summary>
public Sample mUnOpLoad;
/// <summary>
/// valore tempo cumulato di impiego
/// </summary>
public Sample mUnOpAccTime;
/// <summary>
/// contatore cumulato di giri mandrino (migliaia)
/// </summary>
public Sample mUnOpKRev;
/// <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;
mUnOpToolId = new Event(string.Format("{0}_ToolId", ident));
mUnOpNumCU = new Event(string.Format("{0}_NumCU", ident));
mUnOpStatus = new Event(string.Format("{0}_Status", ident));
mUnOpVitaRes = new Event(string.Format("{0}_VitaRes", ident));
mUnOpSpeed = new Sample(string.Format("{0}_Speed", ident));
mUnOpSpeedOverr = new Sample(string.Format("{0}_SpeedOverr", ident));
mUnOpLoad = new Sample(string.Format("{0}_Load", ident));
mUnOpAccTime = new Sample(string.Format("{0}_AccTime", ident));
mUnOpVitaResType = new MTConnect.Message(string.Format("{0}_VitaResType", ident));
mUnOpKRev = new Sample(string.Format("{0}_KRev", ident));
}
}
/// <summary>
/// Asse singolo, 1..n
/// </summary>
public class Axis : element
{
/// <summary>
/// Processo di appartenenza
/// </summary>
public MTConnect.Message mAxMainProc;
/// <summary>
/// Bit se sia master (=1) o slave (=0)
/// </summary>
public MTConnect.Message mAxIsMaster;
/// <summary>
/// ID del master
/// </summary>
public Event mAxMastId;
/// <summary>
/// Gruppo di appartenenza dell'asse
/// </summary>
public Event mAxGrp;
/// <summary>
/// Event tipo asse: lineare, rotazionale...
/// </summary>
public Event mAxType;
/// <summary>
/// Bit direzione: 1 = avanti/clockwise, 0 indietro/counterclockwise
/// </summary>
public Event mAxDir;
/// <summary>
/// Load
/// </summary>
public Sample mAxLoad;
/// <summary>
/// Posizione Attuale
/// </summary>
public Sample mAxPosAct;
/// <summary>
/// Posizione Target
/// </summary>
public Sample mAxPosTgt;
/// <summary>
/// Feed Attuale
/// </summary>
public Sample mAxFeedAct;
/// <summary>
/// Feed Override
/// </summary>
public Sample mAxFeedOver;
/// <summary>
/// Accelerazione Attuale
/// </summary>
public Sample mAxAccelAct;
/// <summary>
/// Tempo Lavoro cumulato
/// </summary>
public Sample mAxAccTime;
/// <summary>
/// Carica batteria
/// </summary>
public Sample mAxBattery;
/// <summary>
/// Distanza compiuta nell'intervallo di tempo
/// </summary>
public Sample mAxDistDone;
/// <summary>
/// numero di inversioni di direzione fatte nell'intervallo di tempo
/// </summary>
public Sample mAxInvDDone;
/// <summary>
/// Allarmi CNC del PATH
/// </summary>
public Condition mAxAlarmCNC;
/// <summary>
/// Allarmi PCL del PATH
/// </summary>
public Condition mAxAlarmPLC;
/// <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;
try
{
mAxType = new Event(dataRefList[0].Key);
mAxType.Value = dataRefList[0].Value;
}
catch
{
mAxType = new Event(string.Format("{0}_Type", ident));
mAxType.Value = "LINEAR";
}
try
{
mAxGrp = new Event(dataRefList[1].Key);
mAxGrp.Value = dataRefList[1].Value;
}
catch
{
mAxGrp = new Event(string.Format("{0}_Grp", ident));
mAxGrp.Value = "00";
}
// valori standard
mAxMainProc = new MTConnect.Message(string.Format("{0}_MainProc", ident));
mAxIsMaster = new MTConnect.Message(string.Format("{0}_IsMast", ident));
mAxMastId = new Event(string.Format("{0}_MastId", ident));
mAxDir = new Event(string.Format("{0}_Dir", ident));
mAxLoad = new Sample(string.Format("{0}_Load", ident));
mAxPosAct = new Sample(string.Format("{0}_PosAct", ident));
mAxPosTgt = new Sample(string.Format("{0}_PosTgt", ident));
mAxFeedAct = new Sample(string.Format("{0}_FeedAct", ident));
mAxFeedOver = new Sample(string.Format("{0}_FeedOver", ident));
mAxAccelAct = new Sample(string.Format("{0}_AccelAct", ident));
mAxAccTime = new Sample(string.Format("{0}_AccTime", ident));
mAxBattery = new Sample(string.Format("{0}_Battery", ident));
mAxDistDone = new Sample(string.Format("{0}_DistDone", ident));
mAxInvDDone = new Sample(string.Format("{0}_InvDDone", ident));
mAxAlarmCNC = new Condition(string.Format("{0}_AlarmCNC", ident));
mAxAlarmPLC = new Condition(string.Format("{0}_AlarmPLC", ident));
}
}
#endregion
public class AdapterGeneric
{
/// <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 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 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 double istOreMaccOn;
/// <summary>
/// isteggio ISTANTANEO ore macchina IN LAVORO
/// </summary>
public double istOreMaccLav;
/// <summary>
/// Conteggio ISTANTANEO contatore del numero movimenti Slitta Tastatore
/// </summary>
public double istSlittaTast;
/// <summary>
/// Vettore ISTANTANEO dei contatori giri cumulati elettromandrino (migliaia)
/// </summary>
public uint[] istGiriElettrom;
/// <summary>
/// Vettore ISTANTANEO dei contatori del movimento degli assi
/// </summary>
public double[] istDistMovAssi;
/// <summary>
/// Vettore ISTANTANEO dei contatori del LOAD degli assi
/// </summary>
public double[] istLoadAssi;
/// <summary>
/// Vettore ISTANTANEO dei contatori del tempo cumulato degli assi
/// </summary>
public double[] istAccTimeAssi;
/// <summary>
/// Vettore ISTANTANEO dei contatori del num inv degli assi
/// </summary>
public uint[] 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 uint[] istPathPartCount;
/// <summary>
/// Vettore ISTANTANEO dei contatori del work time x VacPump
/// </summary>
public uint[] istVacPumpWrkTime;
/// <summary>
/// Vettore ISTANTANEO dei contatori del numero impieghi VacAct
/// </summary>
public uint[] istVacActCount;
/// <summary>
/// Vettore ISTANTANEO dei contatori del Lubro
/// </summary>
public uint[] istLubroCount;
/// <summary>
/// Vettore ISTANTANEO dei contatori del numero cambi utensili x UnOp
/// </summary>
public uint[] istNumCambiUt;
/// <summary>
/// Vettore ISTANTANEO dei contatori del numero movimenti Slitta Magazzino
/// </summary>
public uint[] istSlittaMag;
/// <summary>
/// Vettore ISTANTANEO dei contatori del numero movimenti Protezione Magazzino
/// </summary>
public uint[] 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 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>
/// adapter globale
/// </summary>
public Adapter mAdapter = new Adapter();
/// <summary>
/// Form chiamante
/// </summary>
protected MainForm parentForm;
/// <summary>
/// Conf adapter corrente
/// </summary>
public AdapterConf currAdpConf;
#region altri oggetti
// 16 byte di strobe (4 word da 32 bit di flags...)
public byte[] Strobes = new byte[16];
// 16 byte di strobe in risposta (4 word da 32 bit di flags...)
public byte[] Acknowl = new byte[16];
// 1024 bit di strobe degli allarmi attivi (32 word da 4byte/32 bit di flags...)
public byte[] AlarmFlags;
/// <summary>
/// Oggetto elenco allarmi
/// </summary>
public allarme[] elencoAllarmi;
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>
/// Quarta word di strobe da array flag completo
/// </summary>
public StFlag32 STRB_DW3
{
get
{
return (StFlag32)BitConverter.ToUInt32(Strobes, 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;
#endregion
#region Events & samples
/// <summary>
/// Asset Changed - cambio asset
/// </summary>
public Event mAssetChg = new Event("MTC_asset_chg");
/// <summary>
/// Asset Removed - cambio asset
/// </summary>
public Event mAssetRem = new Event("MTC_asset_rem");
/// <summary>
/// D.D1.AVAIL - disponibilità
/// </summary>
public Event mAvail = new Event("AVAIL");
/// <summary>
/// XX.XX.STOP - stop per pressione emergenze
/// </summary>
public Event mEStop = new Event("E_STOP");
/// <summary>
/// STATUS "logico" adapter macchina (ON/OFF)
/// </summary>
public Event mStatus = new Event("STATUS");
/// <summary>
/// Minuti accensione globale macchina
/// </summary>
public Sample mAccTime = new Sample("ACC_TIME");
/// <summary>
/// Minuti funzionamento globale macchina (IN LAVORO)
/// </summary>
public Sample mAccTimeWork = new Sample("ACC_TIME_WORK");
/// <summary>
/// Conteggio Impieghi Slitta Tastatore
/// </summary>
public Sample mSlittaTast = new Sample("SlittaTastatore_Count");
/// <summary>
/// Orologio
/// </summary>
public Sample mClock = new Sample("CLOCK");
/// <summary>
/// Status macchina accesa/spenta
/// </summary>
public Event mPower = new Event("POWER");
/// <summary>
/// processo selezionato
/// </summary>
public Event mProcSel = new Event("PROC_SEL");
/// <summary>
/// ID operatore?!?
/// </summary>
public Event mOperator = new Event("OperatorId");
/// <summary>
/// Stato protezioni (0/1, off/on)
/// </summary>
public Event mProtectionStatus = new Event("PROTECTION_STATUS");
#endregion
#region Conditions
// vettori vari: allarmi sistema, PLC, CNC
public Condition mAlarmCNC = new Condition("CNC");
public Condition mAlarmPLC = new Condition("PLC");
#endregion
#region Messages
/// <summary>
/// modalità funzionale
/// </summary>
public MTConnect.Message mFunctionalMode = new MTConnect.Message("FUNCT_MODE");
/// <summary>
/// Azioni operatore (Start/Stop/reset)
/// </summary>
public MTConnect.Message mUserAction = new MTConnect.Message("USER_ACTION");
/// <summary>
/// Testing macchina
/// </summary>
public MTConnect.Message mTestingData = new MTConnect.Message("TESTING_DATA");
/// <summary>
/// Strobe rilevati ma non qualificati
/// </summary>
public MTConnect.Message mUnkStrobe = new MTConnect.Message("UNK_STROBE");
/// <summary>
/// Status rilevati ma non qualificati
/// </summary>
public MTConnect.Message mUnkStatus = new MTConnect.Message("UNK_STATUS");
/// <summary>
/// Messaggi generali
/// </summary>
public MTConnect.Message mMessage = new MTConnect.Message("MESSAGE");
#endregion
#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;
#endregion
public event EventHandler eh_refreshed;
/// <summary>
/// inizializzo l'oggetto sulla form SULLA BASE DEL FILE DI CONFIGURAZIONE letto
/// </summary>
/// <param name="caller"></param>
/// <param name="adpConf"></param>
public AdapterGeneric(MainForm caller, AdapterConf adpConf)
{
lg = LogManager.GetCurrentClassLogger();
lg.Info("Avvio preliminare AdapterGeneric");
procIotMem = utils.CRB("procIotMem");
currAdpConf = adpConf;
// inizializzo vettore gruppi assi, MAX 20!!!
FeedRateGrp = new int[20];
// salvo il form chiamante
parentForm = caller;
// item disponibilità
mAdapter.AddDataItem(mAvail);
mAvail.Value = "AVAILABLE";
mMessage.Value = "";
// assets
mAdapter.AddDataItem(mAssetChg);
mAdapter.AddDataItem(mAssetRem);
mAssetChg.Value = "";
mAssetRem.Value = "";
// status, clock, emergency stop
mAdapter.AddDataItem(mStatus);
mAdapter.AddDataItem(mAccTime);
mAdapter.AddDataItem(mAccTimeWork);
mAdapter.AddDataItem(mSlittaTast);
mAdapter.AddDataItem(mClock);
mAdapter.AddDataItem(mPower);
mAdapter.AddDataItem(mProcSel);
mAdapter.AddDataItem(mEStop);
// programma e produzione
mAdapter.AddDataItem(mOperator);
// modalità esecutiva e funzionale
mFunctionalMode.Value = "";
mAdapter.AddDataItem(mFunctionalMode);
// testing e autodiagnostica
mAdapter.AddDataItem(mTestingData);
// stato protezioni
mAdapter.AddDataItem(mProtectionStatus);
// strobe/status non riconosciuti
mAdapter.AddDataItem(mUnkStatus);
mAdapter.AddDataItem(mUnkStrobe);
// Aree memoria
vettMemArea = new MemArea[adpConf.nMemArea];
for (int i = 0; i < adpConf.nMemArea; i++)
{
vettMemArea[i] = new MemArea(adpConf.MemArea[i]);
mAdapter.AddDataItem(vettMemArea[i].mMemAreaProgName);
mAdapter.AddDataItem(vettMemArea[i].mMemAreaRunning);
mAdapter.AddDataItem(vettMemArea[i].mMemAreaProgNumExe);
mAdapter.AddDataItem(vettMemArea[i].mMemAreaProgNumRep);
}
// Pompe vuoto
vettVacPump = new VacuumPump[adpConf.nVacuumPump];
for (int i = 0; i < adpConf.nVacuumPump; i++)
{
vettVacPump[i] = new VacuumPump(adpConf.VacuumPump[i]);
mAdapter.AddDataItem(vettVacPump[i].mVacPumpStatus);
mAdapter.AddDataItem(vettVacPump[i].mVacPumpWrkTime);
}
// Attuatori vuoto
vettVacAct = new VacuumAct[adpConf.nVacuumAct];
for (int i = 0; i < adpConf.nVacuumAct; i++)
{
vettVacAct[i] = new VacuumAct(adpConf.VacuumAct[i]);
mAdapter.AddDataItem(vettVacAct[i].mVacActCount);
}
// Lubrorefrigeranti
vettLubro = new Lubro[adpConf.nLubro];
for (int i = 0; i < adpConf.nLubro; i++)
{
vettLubro[i] = new Lubro(adpConf.Lubro[i]);
mAdapter.AddDataItem(vettLubro[i].mLubroNum);
mAdapter.AddDataItem(vettLubro[i].mLubroStatus);
}
// Slitta Mag
vettSlittaMag = new SlittaMag[adpConf.nSlittaMag];
for (int i = 0; i < adpConf.nSlittaMag; i++)
{
vettSlittaMag[i] = new SlittaMag(adpConf.SlittaMag[i]);
mAdapter.AddDataItem(vettSlittaMag[i].mSlittaMagCount);
}
// Protezione Mag
vettProtMag = new ProtMag[adpConf.nProtMag];
for (int i = 0; i < adpConf.nProtMag; i++)
{
vettProtMag[i] = new ProtMag(adpConf.ProtMag[i]);
mAdapter.AddDataItem(vettProtMag[i].mProtMagCount);
}
// Cooler
vettCooler = new Cooler[adpConf.nCooler];
for (int i = 0; i < adpConf.nCooler; i++)
{
vettCooler[i] = new Cooler(adpConf.Cooler[i]);
mAdapter.AddDataItem(vettCooler[i].mCoolStatus);
}
// Press
vettPress = new Press[adpConf.nPress];
for (int i = 0; i < adpConf.nPress; i++)
{
vettPress[i] = new Press(adpConf.Press[i]);
mAdapter.AddDataItem(vettPress[i].mPressValIst);
}
// Temp
vettTempe = new Tempe[adpConf.nTemp];
for (int i = 0; i < adpConf.nTemp; i++)
{
vettTempe[i] = new Tempe(adpConf.Temp[i]);
mAdapter.AddDataItem(vettTempe[i].mTempValIst);
}
// Path
vettPath = new Path[adpConf.nPath];
for (int i = 0; i < adpConf.nPath; i++)
{
vettPath[i] = new Path(adpConf.Path[i]);
mAdapter.AddDataItem(vettPath[i].mPathFeed);
mAdapter.AddDataItem(vettPath[i].mPathFeedOver);
mAdapter.AddDataItem(vettPath[i].mPathRapidOver);
mAdapter.AddDataItem(vettPath[i].mPathJogOver);
mAdapter.AddDataItem(vettPath[i].mPathSpindleOver_01);
mAdapter.AddDataItem(vettPath[i].mPathSpindleOver_02);
mAdapter.AddDataItem(vettPath[i].mPathSpindleOver_03);
mAdapter.AddDataItem(vettPath[i].mPathSpindleOver_04);
mAdapter.AddDataItem(vettPath[i].mPathPosActX);
mAdapter.AddDataItem(vettPath[i].mPathPosActY);
mAdapter.AddDataItem(vettPath[i].mPathPosActZ);
mAdapter.AddDataItem(vettPath[i].mPathPosActI);
mAdapter.AddDataItem(vettPath[i].mPathPosActJ);
mAdapter.AddDataItem(vettPath[i].mPathPosActK);
// aggiunta x revisione 2016.05.05
mAdapter.AddDataItem(vettPath[i].mPathType);
mAdapter.AddDataItem(vettPath[i].mPathPartId);
mAdapter.AddDataItem(vettPath[i].mPathPartCount);
mAdapter.AddDataItem(vettPath[i].mPathCodM);
mAdapter.AddDataItem(vettPath[i].mPathCodS);
mAdapter.AddDataItem(vettPath[i].mPathCodT);
mAdapter.AddDataItem(vettPath[i].mPathRunMode);
mAdapter.AddDataItem(vettPath[i].mPathExeMode);
mAdapter.AddDataItem(vettPath[i].mPathCurrProg);
mAdapter.AddDataItem(vettPath[i].mPathCurrArea);
mAdapter.AddDataItem(vettPath[i].mPathCurrProgRowNum);
mAdapter.AddDataItem(vettPath[i].mPathActiveAxes);
mAdapter.AddDataItem(vettPath[i].mPathCodG_Act);
mAdapter.AddDataItem(vettPath[i].mPathSubMode);
// aggiungo condizioni allarme...
mAdapter.AddDataItem(vettPath[i].mPathAlarmCNC);
mAdapter.AddDataItem(vettPath[i].mPathAlarmPLC);
}
// UnOp
vettUnOp = new UnOp[adpConf.nUnOp];
for (int i = 0; i < adpConf.nUnOp; i++)
{
vettUnOp[i] = new UnOp(adpConf.UnOp[i]);
mAdapter.AddDataItem(vettUnOp[i].mUnOpToolId);
mAdapter.AddDataItem(vettUnOp[i].mUnOpNumCU);
mAdapter.AddDataItem(vettUnOp[i].mUnOpStatus);
mAdapter.AddDataItem(vettUnOp[i].mUnOpVitaRes);
mAdapter.AddDataItem(vettUnOp[i].mUnOpVitaResType);
mAdapter.AddDataItem(vettUnOp[i].mUnOpSpeed);
mAdapter.AddDataItem(vettUnOp[i].mUnOpSpeedOverr);
mAdapter.AddDataItem(vettUnOp[i].mUnOpLoad);
mAdapter.AddDataItem(vettUnOp[i].mUnOpAccTime);
mAdapter.AddDataItem(vettUnOp[i].mUnOpKRev);
}
// Assi
vettAxis = new Axis[adpConf.nAxis];
for (int i = 0; i < adpConf.nAxis; i++)
{
vettAxis[i] = new Axis(adpConf.Axis[i]);
mAdapter.AddDataItem(vettAxis[i].mAxMainProc);
mAdapter.AddDataItem(vettAxis[i].mAxIsMaster);
mAdapter.AddDataItem(vettAxis[i].mAxMastId);
mAdapter.AddDataItem(vettAxis[i].mAxType);
mAdapter.AddDataItem(vettAxis[i].mAxDir);
mAdapter.AddDataItem(vettAxis[i].mAxLoad);
mAdapter.AddDataItem(vettAxis[i].mAxPosAct);
mAdapter.AddDataItem(vettAxis[i].mAxPosTgt);
mAdapter.AddDataItem(vettAxis[i].mAxFeedAct);
mAdapter.AddDataItem(vettAxis[i].mAxFeedOver);
mAdapter.AddDataItem(vettAxis[i].mAxAccelAct);
mAdapter.AddDataItem(vettAxis[i].mAxAccTime);
mAdapter.AddDataItem(vettAxis[i].mAxBattery);
mAdapter.AddDataItem(vettAxis[i].mAxDistDone);
mAdapter.AddDataItem(vettAxis[i].mAxInvDDone);
mAdapter.AddDataItem(vettAxis[i].mAxAlarmCNC);
mAdapter.AddDataItem(vettAxis[i].mAxAlarmPLC);
}
// messaggi ulteriori
mAdapter.AddDataItem(mMessage);
// allarmi "base"
mAdapter.AddDataItem(mAlarmCNC);
mAdapter.AddDataItem(mAlarmPLC);
// azioni utente
mAdapter.AddDataItem(mUserAction);
// 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>
/// 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...
elencoAllarmi = new allarme[File.ReadLines(fileName).Count()];
// carica da file...
System.IO.StreamReader file = new System.IO.StreamReader(fileName);
// leggo 1 linea alla volta...
int rumRiga = 0;
while ((linea = file.ReadLine()) != null)
{
// SE non è un commento...
if (linea.Substring(0, 1) != "#")
{
//elencoAllarmi[rumRiga] = decodeAlarmLine(linea, ':');
elencoAllarmi[rumRiga] = decodeAlarmLine(linea, utils.CRC("testCharSep"));
rumRiga++;
}
}
// chiudo file
file.Close();
// ora trimmo vettore al solo numero VERO degli allarmi caricati...
Array.Resize<allarme>(ref elencoAllarmi, rumRiga);
// inizializzo a zero il vettore allarmi...
int numByte = (int)Math.Ceiling(Convert.ToDecimal(rumRiga) / 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;
AlarmFlags = new byte[numByte];
if (utils.CRB("verbose")) lg.Info(string.Format("Fine caricamento vettore allarmi: {0} allarmi caricati!", rumRiga));
}
/// <summary>
/// Caricamento altri file necessari epr adapter all'avvio
/// </summary>
protected virtual void loadOtherFile()
{
}
/// <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;
string fileName = string.Format(@"{0}\{1}", utils.confDir, utils.CRS("CounterListFilePath"));
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 è un commento...
if (linea.Substring(0, 1) != "#")
{
maintData[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 maintData, numRiga);
if (utils.CRB("verbose")) lg.Info(string.Format("Fine caricamento vettore di {0} variabili manutenzione gestite", 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 = string.Format(@"{0}\{1}", utils.confDir, utils.CRS("AnalogDataFilePath"));
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 è 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));
}
/// <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;
string fileName = string.Format(@"{0}\{1}", utils.confDir, utils.CRS("StatusListFilePath"));
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 è un commento...
if (linea.Substring(0, 1) != "#")
{
statusData[numRiga] = decodeBitData(linea, utils.CRC("testCharSep"), memPre, baseAddr, memSize, numRiga);
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));
}
/// <summary>
/// caricamento allarmi da file
/// </summary>
protected void loadSubMode()
{
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");
}
/// <summary>
/// Decodifica file allarme
/// </summary>
/// <param name="linea"></param>
/// <param name="separator"></param>
/// <returns></returns>
protected allarme decodeAlarmLine(string linea, char separator)
{
string[] valori = linea.Split(separator);
return new allarme(valori[0], valori[1], valori[2], valori[3]);
}
/// <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);
return new otherData(valori[0], memAddr, valori[1].Trim(), valori[2].Trim());
}
/// <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>
/// <param name="numRiga">indirizzo bit: numero riga x calcolo indice bit</param>
/// <returns></returns>
protected otherData decodeBitData(string linea, char separator, string memPre, int baseAddr, int memSize, int numRiga)
{
string[] valori = linea.Split(separator);
int shift = 0;
try
{
shift = (Convert.ToInt32(valori[0]) - 1) / (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));
currNumCambiUt[i] = getStoredValUInt(string.Format("UnOp_{0:00}_NumCU", 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));
}
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 sulla porta richiesta
/// </summary>
/// <param name="port"></param>
public virtual void startAdapter(int port)
{
lg.Info("Starting adapter...");
parentForm.commPlcActive = false;
adpRunning = true;
dtAvvioAdp = DateTime.Now;
TimingData.resetData();
// inizializzo vettori di utility..
loadAllarmi();
loadSubMode();
loadOtherFile();
// salvo porta!
mAdapter.Port = port;
adpPortNum = port;
// avvio!
mAdapter.Start();
// setto status a ON
mStatus.Value = "ON";
// resetto running flag...
adpCommAct = false;
// carico valori da adapter x i conteggi
contOreMaccOn = currAdpConf.ContOreMaccOn;
contOreMaccLav = currAdpConf.ContOreMaccLav;
contSlittaTast = currAdpConf.ContSlittaTast;
contGiriElettrom = new uint[currAdpConf.nUnOp];
istGiriElettrom = new uint[currAdpConf.nUnOp];
currNumCambiUt = new uint[currAdpConf.nUnOp];
istNumCambiUt = new uint[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> riContRpm = 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));
// recupero valore giri...
UInt32 contTotGiri = Convert.ToUInt32(riContRpm.Value);
// recupero valore num cambi ut...
UInt32 contNumCU = Convert.ToUInt32(riContNumCU.Value);
// salvo valore letto
contGiriElettrom[i] = contTotGiri;
currNumCambiUt[i] = contNumCU;
}
// imposto num assi e leggo valori salvati...
contDistMovAssi = new double[currAdpConf.nAxis];
istDistMovAssi = new double[currAdpConf.nAxis];
istLoadAssi = new double[currAdpConf.nAxis];
contNumInvAssi = new uint[currAdpConf.nAxis];
istAccTimeAssi = new double[currAdpConf.nAxis];
contAccTimeAssi = new double[currAdpConf.nAxis];
istNumInvAssi = new uint[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);
vettAxis[i].mAxAlarmCNC.Normal();
vettAxis[i].mAxAlarmPLC.Normal();
}
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 uint[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] = "";
vettPath[i].mPathAlarmCNC.Normal();
vettPath[i].mPathAlarmPLC.Normal();
}
currVacPumpWrkTime = new uint[currAdpConf.nVacuumPump];
istVacPumpWrkTime = new uint[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);
}
currVacActCount = new uint[currAdpConf.nVacuumAct];
istVacActCount = new uint[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);
}
currLubroCount = new uint[currAdpConf.nLubro];
istLubroCount = new uint[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);
}
currSlittaMag = new uint[currAdpConf.nSlittaMag];
istSlittaMag = new uint[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);
}
currProtMag = new uint[currAdpConf.nProtMag];
istProtMag = new uint[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);
}
//mAlarmSystem.Normal();
mAlarmCNC.Normal();
mAlarmPLC.Normal();
//mAlarmGeneral.Normal();
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;
mStatus.Value = "INACTIVE";
// 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
{
mAdapter.Stop();
}
catch (Exception exc)
{
lg.Error(exc, "Eccezione in chiusura Adapter");
}
dtStopAdp = DateTime.Now;
adpPortNum = mAdapter.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
mAdapter.Begin();
// 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();
// 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 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)
{
// 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();
}
}
// 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();
}
// processo e svuoto eventuali code di invio per Codici M/S/T
trySendCodMST();
}
// INVIO dati variati!
mAdapter.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>
/// recupero dati globali (e comuni)
/// </summary>
public virtual void getGlobalData()
{
}
/// <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 != "")
{
vettPath[i].mPathCodM.Value = string.Format("[M{0}]", codiceM);
}
if (codiceS != "")
{
vettPath[i].mPathCodS.Value = string.Format("[S{0}]", codiceS);
}
if (codiceT != "")
{
vettPath[i].mPathCodT.Value = 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("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;
// !!! FARE verifica se convenga leggere SEMPRE 128 byte allarmi x avere MENO letture (in caso di concorrenza...) --> decidere post test SIEMENS, OSAI sembrerebbe giustificarlo...
// 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 (AlarmFlags != null)
{
try
{
// aggiorno vettore allarmi x intero! size del vettore di destinazione (in byte!!!!)
Buffer.BlockCopy(MemBlock, 0, AlarmFlags, 0, 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, 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
#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;
byte[] retACK_DW = new byte[1];
// 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, 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
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
/// <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++)
{
vettPath[i].mPathFeed.Value = FeedRate;
vettPath[i].mPathFeedOver.Value = FeedRateOver;
vettPath[i].mPathRapidOver.Value = RapidOver;
}
}
/// <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];
vettUnOp[i].mUnOpSpeed.Value = locSpeedRate;
vettUnOp[i].mUnOpLoad.Value = UnOpLoad;
vettUnOp[i].mUnOpSpeedOverr.Value = SpeedRateOver;
sb.AppendLine(string.Format("UnOp_{0}: SpeedRate {1} rpm | Load {2} | SpOv: {3}", i + 1, SpeedRate, 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)
{
int numEv = 0;
int codEv = 0;
if (currStrobe.HasFlag((StFlag8)Math.Pow(2, bitNum)))
{
// verifico sia > 0 il numero di valori da leggere - indice 0 sull'area...
numEv = BitConverter.ToUInt16(MemBlock, 2 * memShift);
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++)
{
// leggo valore Codice
codEv = BitConverter.ToUInt16(MemBlock, 2 * (i + 2 + memShift));
// 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 (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");
}
}
catch
{
lg.Info("Errore in lettura dati da file");
}
// ora salvo valori letti...
foreach (KeyValuePair<string, string> item in generalStatus)
{
// verifico la chiave e nel caso aggiorno...
switch (item.Key)
{
case "OperatorId":
mOperator.Value = 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()
{
// update status da DW2/ DW3
// EMstop: verifico BIT e di conseguenza imposto
if (STRB_DW2.HasFlag(StFlag32.B00))
{
mEStop.Value = "TRIGGERED";
}
else
{
mEStop.Value = "ARMED";
}
// verifico POWER ON...
if (STRB_DW2.HasFlag(StFlag32.B01))
{
mPower.Value = "ON";
}
else
{
mPower.Value = "OFF";
}
// Processo selezionato 0=P1, 1=P2
string procSel = "";
if (STRB_DW2.HasFlag(StFlag32.B02))
{
procSel = "P2";
}
else
{
procSel = "P1";
}
if (mProcSel.Value.ToString() != procSel)
{
mProcSel.Value = 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();
}
}
/// <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))
{
pathType = "LAVORO";
}
else
{
pathType = "ASSERV";
}
// switch su RUN mode...
string runMode = "";
if (STRB_DW2.HasFlag(StFlag32.B04))
{
runMode = "AUTOMATIC";
}
else if (STRB_DW2.HasFlag(StFlag32.B05))
{
runMode = "EDIT";
}
else if (STRB_DW2.HasFlag(StFlag32.B06))
{
runMode = "MANUAL_DATA_INPUT";
}
else if (STRB_DW2.HasFlag(StFlag32.B07))
{
runMode = "MANUAL";
}
else if (STRB_DW2.HasFlag(StFlag32.B08))
{
runMode = "SEMI_AUTO";
}
// switch su EXE mode...
string exeMode = "";
if (STRB_DW2.HasFlag(StFlag32.B09))
{
exeMode = "ACTIVE";
}
else if (STRB_DW2.HasFlag(StFlag32.B10))
{
exeMode = "READY";
}
else if (STRB_DW2.HasFlag(StFlag32.B11))
{
exeMode = "STOPPED";
}
else if (STRB_DW2.HasFlag(StFlag32.B12))
{
exeMode = "FEED_HOLD";
}
else if (STRB_DW2.HasFlag(StFlag32.B13))
{
exeMode = "OPTIONAL_STOP";
}
else if (STRB_DW2.HasFlag(StFlag32.B14))
{
exeMode = "PROGRAM_STOPPED";
}
else if (STRB_DW2.HasFlag(StFlag32.B15))
{
exeMode = "PROGRAM_COMPLETED";
}
// 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_DW2.HasFlag(StFlag32.B16))
{
pathType = "LAVORO";
}
else
{
pathType = "ASSERV";
}
// switch su RUN mode...
string runMode = "";
if (STRB_DW2.HasFlag(StFlag32.B17))
{
runMode = "AUTOMATIC";
}
else if (STRB_DW2.HasFlag(StFlag32.B18))
{
runMode = "EDIT";
}
else if (STRB_DW2.HasFlag(StFlag32.B19))
{
runMode = "MANUAL_DATA_INPUT";
}
else if (STRB_DW2.HasFlag(StFlag32.B20))
{
runMode = "MANUAL";
}
else if (STRB_DW2.HasFlag(StFlag32.B21))
{
runMode = "SEMI_AUTO";
}
// switch su EXE mode...
string exeMode = "";
if (STRB_DW2.HasFlag(StFlag32.B22))
{
exeMode = "ACTIVE";
}
else if (STRB_DW2.HasFlag(StFlag32.B23))
{
exeMode = "READY";
}
else if (STRB_DW2.HasFlag(StFlag32.B24))
{
exeMode = "STOPPED";
}
else if (STRB_DW2.HasFlag(StFlag32.B25))
{
exeMode = "FEED_HOLD";
}
else if (STRB_DW2.HasFlag(StFlag32.B26))
{
exeMode = "OPTIONAL_STOP";
}
else if (STRB_DW2.HasFlag(StFlag32.B27))
{
exeMode = "PROGRAM_STOPPED";
}
else if (STRB_DW2.HasFlag(StFlag32.B28))
{
exeMode = "PROGRAM_COMPLETED";
}
// 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 (vettPath[idxPath].mPathType.Value.ToString() != pathType)
{
vettPath[idxPath].mPathType.Value = pathType;
}
// salvo RUN mode
if (vettPath[idxPath].mPathRunMode.Value.ToString() != pathRunMode)
{
vettPath[idxPath].mPathRunMode.Value = pathRunMode;
}
// salvo EXE mode
if (vettPath[idxPath].mPathExeMode.Value.ToString() != pathExeMode)
{
vettPath[idxPath].mPathExeMode.Value = pathExeMode;
}
// salvo i submode..
if (vettPath[idxPath].mPathSubMode.Value.ToString() != pathSubMode)
{
vettPath[idxPath].mPathSubMode.Value = 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))
{
// blocco memoria x lettura TUTTI i dati di buffer M/S/T: 26 short(16bit) x (12+7+7) aree (attenzione: secondo set di 2 bit è VUOTO...)
ushort[] MemBlock_W = new ushort[26];
// leggo memoria!
readMST_data(idxPath, memIndexMST, ref MemBlock_W);
// converto a byte x compatibilità...
byte[] MemBlock = new byte[MemBlock_W.Length * 2];
Buffer.BlockCopy(MemBlock_W, 0, MemBlock, 0, MemBlock.Length);
// check COD_M
bitNum = 0;
gestStrobeCodMST(currStrobe, bitNum, ref currACK_DW, 0, MemBlock, "M", idxPath);
// check COD_S
bitNum = 1;
gestStrobeCodMST(currStrobe, bitNum, ref currACK_DW, 12, MemBlock, "S", idxPath);
// check COD_T
bitNum = 2;
gestStrobeCodMST(currStrobe, bitNum, ref currACK_DW, 19, MemBlock, "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>
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 (mTestingData.Value.ToString() != TestingData.Trim())
{
mTestingData.Value = 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_W"></param>
/// <returns></returns>
public virtual bool readMST_data(int idxPath, int memIndexMST, ref ushort[] MemBlock_W)
{
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()
{
if (AlarmFlags != null)
{
// variabili helper
StFlag32 AlarmBlock = 0;
allarme currAllarm;
// controllo TUTTI i bit della variabile COMPLETA degli status allarmi: se ce ne sono di alzati DEVO processare...
for (int i = 0; i < AlarmFlags.Length / 4; i++)
{
// leggo 32bit alla volta...
AlarmBlock = (StFlag32)BitConverter.ToUInt32(AlarmFlags, i * 4);
for (int j = 0; j < 32; j++)
{
// converto! e aggiungo allarmi sollevati al corretto controller allarmi...
if (AlarmBlock.HasFlag((StFlag32)Math.Pow(2, j)))
{
// recupero allarme da oggetto in memoria...
currAllarm = elencoAllarmi[i * 32 + j];
// in base al tipo di allarme decodifico condizione...
Condition.Level livello = Condition.Level.NORMAL;
switch (currAllarm.livello)
{
case "WARNING":
livello = Condition.Level.WARNING;
break;
case "FAULT":
default:
livello = Condition.Level.FAULT;
break;
}
// in base al gruppo decido dove assegnare come CONDITION...
switch (currAllarm.gruppo)
{
case "PLC":
mAlarmPLC.Add(livello, currAllarm.descrizione, currAllarm.codNum, "", "");
break;
case "CNC":
default:
mAlarmCNC.Add(livello, currAllarm.descrizione, currAllarm.codNum, "", "");
break;
}
}
}
}
}
}
/// <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()
{
// dati da PC
mClock.Value = string.Format("{0:yyyy-MM-dd} {0:HH:mm:ss}", 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>
/// 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;
uint valRead = 0;
for (int i = 0; i < maintData.Length; i++)
{
numero = 0;
valRead = 0;
// decodifico...
if (maintData[i].varName == "ACC_TIME")
{
istOreMaccOn = tabDatiMtz[i];
}
else if (maintData[i].varName == "ACC_TIME_WORK")
{
istOreMaccLav = tabDatiMtz[i];
}
else if (maintData[i].varName == "SlittaTastatore_Count")
{
istSlittaTast = tabDatiMtz[i];
}
else if (maintData[i].varName.StartsWith("Path_"))
{
if (maintData[i].varName.EndsWith("_PZ_TOT"))
{
try
{
numero = Convert.ToInt32(maintData[i].varName.Replace("Path_", "").Replace("_PZ_TOT", ""));
}
catch
{
}
if (numero > 0)
{
vettPath[numero - 1].mPathPartCount.Value = tabDatiMtz[i];
}
}
}
else if (maintData[i].varName.StartsWith("Axis_"))
{
if (maintData[i].varName.EndsWith("_DistDone"))
{
try
{
numero = Convert.ToInt32(maintData[i].varName.Replace("Axis_", "").Replace("_DistDone", ""));
}
catch
{ }
if (numero > 0)
{
istDistMovAssi[numero - 1] = tabDatiMtz[i];
}
}
else if (maintData[i].varName.EndsWith("_Invers"))
{
try
{
numero = Convert.ToInt32(maintData[i].varName.Replace("Axis_", "").Replace("_Invers", ""));
}
catch
{ }
if (numero > 0)
{
// 2016.07.06 debug di valori che potrebbero essere nulli...
try
{
valRead = tabDatiMtz[i];
}
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] = valRead;
}
}
else if (maintData[i].varName.EndsWith("_AccTime"))
{
try
{
numero = Convert.ToInt32(maintData[i].varName.Replace("Axis_", "").Replace("_AccTime", ""));
}
catch
{ }
if (numero > 0)
{
// 2016.07.06 debug di valori che potrebbero essere nulli...
try
{
valRead = tabDatiMtz[i];
}
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));
}
istAccTimeAssi[numero - 1] = valRead;
}
}
}
else if (maintData[i].varName.StartsWith("UnOp_"))
{
if (maintData[i].varName.EndsWith("_AccTime"))
{
try
{
numero = Convert.ToInt32(maintData[i].varName.Replace("UnOp_", "").Replace("_AccTime", ""));
}
catch
{ }
if (numero > 0)
{
istGiriElettrom[numero - 1] = tabDatiMtz[i];
}
}
else if (maintData[i].varName.EndsWith("_NumCambiUT"))
{
try
{
numero = Convert.ToInt32(maintData[i].varName.Replace("UnOp_", "").Replace("_NumCambiUT", ""));
}
catch
{ }
if (numero > 0)
{
istNumCambiUt[numero - 1] = tabDatiMtz[i];
}
}
}
else if (maintData[i].varName.StartsWith("VacPump_"))
{
if (maintData[i].varName.EndsWith("_WrkTime"))
{
try
{
numero = Convert.ToInt32(maintData[i].varName.Replace("VacPump_", "").Replace("_WrkTime", ""));
}
catch
{ }
if (numero > 0)
{
istVacPumpWrkTime[numero - 1] = tabDatiMtz[i];
}
}
}
else if (maintData[i].varName.StartsWith("VacAct_"))
{
if (maintData[i].varName.EndsWith("_Count"))
{
try
{
numero = Convert.ToInt32(maintData[i].varName.Replace("VacAct_", "").Replace("_Count", ""));
}
catch
{ }
if (numero > 0)
{
istVacActCount[numero - 1] = tabDatiMtz[i];
}
}
}
else if (maintData[i].varName.StartsWith("Lubro_"))
{
if (maintData[i].varName.EndsWith("_Num"))
{
try
{
numero = Convert.ToInt32(maintData[i].varName.Replace("Lubro_", "").Replace("_Num", ""));
}
catch
{ }
if (numero > 0)
{
istLubroCount[numero - 1] = tabDatiMtz[i];
}
}
}
else if (maintData[i].varName.StartsWith("SlittaMagazzino_"))
{
if (maintData[i].varName.EndsWith("_Count"))
{
try
{
numero = Convert.ToInt32(maintData[i].varName.Replace("SlittaMagazzino_", "").Replace("_Count", ""));
}
catch
{ }
if (numero > 0)
{
istSlittaMag[numero - 1] = tabDatiMtz[i];
}
}
}
else if (maintData[i].varName.StartsWith("ProtMagazzino_"))
{
if (maintData[i].varName.EndsWith("_Count"))
{
try
{
numero = Convert.ToInt32(maintData[i].varName.Replace("ProtMagazzino_", "").Replace("_Count", ""));
}
catch
{ }
if (numero > 0)
{
istProtMag[numero - 1] = tabDatiMtz[i];
}
}
}
}
}
/// <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...
int numero = 0;
uint valRead;
for (int i = 0; i < analogData.Length; i++)
{
numero = 0;
valRead = 0;
// decodifico...
if (analogData[i].varName.StartsWith("Axis_"))
{
if (analogData[i].varName.EndsWith("_Load"))
{
try
{
numero = Convert.ToInt32(analogData[i].varName.Replace("Axis_", "").Replace("_Load", ""));
}
catch
{ }
if (numero > 0)
{
try
{
valRead = tabDatiAnag[i];
}
catch (Exception exc)
{
valRead = 0;
lg.Error(string.Format("Errore in recupero load assi:{0}parametro: {1}{0}i: {2}{0}Exc: {3}", Environment.NewLine, analogData[i].varName, i, exc));
}
istLoadAssi[numero - 1] = valRead;
}
}
}
}
}
/// <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 = vettPath[i].mPathCodM.Value.ToString().Replace("UNAVAILABLE", "n.d.");
codS = vettPath[i].mPathCodS.Value.ToString().Replace("UNAVAILABLE", "n.d.");
codT = vettPath[i].mPathCodT.Value.ToString().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 = 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>
/// 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;
// uno ad uno vado a inserirli nella mappa dei dati dell'adapter...
int numero = 0;
string status = "";
for (int i = 0; i < statusData.Length; i++)
{
numero = 0;
status = "";
// calcolo quale byte e quale bit devo leggere..
byteNum = i / 8;
bitNum = i - (8 * byteNum); // indice zero dei bit nel byte ( da cui -1 )
// faccio vera lettura
byteVal = tabDatiStatus[byteNum];
// leggo bit come ACTIVE/INACTIVE
if (((StFlag8)byteVal).HasFlag((StFlag8)Math.Pow(2, bitNum)))
{
status = "ACTIVE";
}
else
{
status = "INACTIVE";
}
if (statusData[i].varName == "PROTECTION_STATUS")
{
mProtectionStatus.Value = status;
}
else if (statusData[i].varName.StartsWith("VacPump_"))
{
if (statusData[i].varName.EndsWith("_Status"))
{
try
{
numero = Convert.ToInt32(statusData[i].varName.Replace("VacPump_", "").Replace("_Status", ""));
}
catch
{
}
if (numero > 0)
{
vettVacPump[numero - 1].mVacPumpStatus.Value = status;
}
}
}
else if (statusData[i].varName.StartsWith("Cooler_"))
{
if (statusData[i].varName.EndsWith("_Status"))
{
try
{
numero = Convert.ToInt32(statusData[i].varName.Replace("Cooler_", "").Replace("_Status", ""));
}
catch
{ }
if (numero > 0)
{
vettCooler[numero - 1].mCoolStatus.Value = status;
}
}
}
else if (statusData[i].varName.StartsWith("UnOp_"))
{
if (statusData[i].varName.EndsWith("_Status"))
{
try
{
numero = Convert.ToInt32(statusData[i].varName.Replace("UnOp_", "").Replace("_Status", ""));
}
catch
{ }
if (numero > 0)
{
vettUnOp[numero - 1].mUnOpStatus.Value = status;
}
}
}
}
}
/// <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 = 200;
byte[] elencoUtMem = new byte[2 * maxNumOp];
byte[] tabUt_UT = new byte[2 * maxMemAddr];
byte[] tabFam_FamUt = new byte[2 * maxMemAddr];
// altre variabili
int[] idUtMontato = new int[maxNumOp];
int[] idFamUt = new int[maxNumOp];
int[] idTipoVitaUt = new int[maxNumOp];
int[] valVitaUtRes = new int[maxNumOp];
int[] tabUt = new int[maxMemAddr];
int[] tabFamUt = new int[maxMemAddr];
int memIndex = 0;
byte[] int32Mem = new byte[4];
byte[] int16Mem = new byte[2];
byte int8Mem = new byte();
// 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++)
{
// 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])
{
// leggo FamUt puntuale..
memIndex = getDatiUt_step2b(ref int16Mem, j);
// step 2b: leggo puntualmente la FamUt dal suo indice...
idFamUt[i] = BitConverter.ToUInt16(int16Mem, 0);
}
}
}
// 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...
bool 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'utente
for (int i = 0; i < maxNumOp; i++)
{
// 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])
{
// leggo FamUt puntuale..
memIndex = getDatiUt_step4(ref int32Mem, j);
// leggo puntualmente valore della vita ut residua da indice utensile...
valVitaUtRes[i] = BitConverter.ToInt32(int32Mem, 0);
}
}
}
// salvo in adapter vita UT residua...
for (int i = 0; i < maxNumOp; i++)
{
vettUnOp[i].mUnOpToolId.Value = idUtMontato[i];
vettUnOp[i].mUnOpVitaRes.Value = 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;
}
vettUnOp[i].mUnOpVitaResType.Value = 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
#region area metodi comunicazione con PLC/CNC
public void checkPath()
{
}
/// <summary>
/// FeedRate globale
/// </summary>
public int FeedRate { 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 dei rapidi
/// </summary>
public int RapidOver { get; set; }
/// <summary>
/// OVERRIDE SpeedRate mandrino globale
/// </summary>
public int SpeedRateOver { 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
#region metodi che prevedono salvataggio valori su file XML/BIN
/// <summary>
/// Processing delle ore macchina ACCESA
/// </summary>
/// <param name="needSave"></param>
/// <returns></returns>
public bool procOreMaccOn(bool needSave)
{
double delta = istOreMaccOn - contOreMaccOn;
// processo comunque sempre...
double contatore = updateValDoubleByIncr(0, delta, "ACC_TIME");
currAdpConf.ContOreMaccOn += delta;
// salvo valore su persistent layer
mAccTime.Value = contatore.ToString("0.000", CultureInfo.InvariantCulture);
// controllo incremento...
if (delta > 0)
{
// segnalo necessità salvataggio!
needSave = true;
}
// salvo su maschera...
StringBuilder sb = new StringBuilder();
sb.AppendLine(string.Format("ACC_TIME: {0}", mAccTime.Value));
parentForm.dataMonitor_1 += sb.ToString();
// ...aggiorno valore riferimento...
contOreMaccOn = istOreMaccOn;
return needSave;
}
/// <summary>
/// Processing delle ore macchina IN LAVORO
/// </summary>
/// <param name="needSave"></param>
/// <returns></returns>
public bool procOreMaccLav(bool needSave)
{
double delta = istOreMaccLav - contOreMaccLav;
double contatore = updateValDoubleByIncr(0, delta, "ACC_TIME_WORK");
currAdpConf.ContOreMaccLav += delta;
// salvo valore su persistent layer
mAccTimeWork.Value = contatore.ToString("0.000", CultureInfo.InvariantCulture);
// controllo valore riferimento...
if (delta > 0)
{
// segnalo necessità salvataggio!
needSave = true;
}
// salvo su maschera...
StringBuilder sb = new StringBuilder();
sb.AppendLine(string.Format("ACC_TIME_WORK: {0}", mAccTimeWork.Value));
parentForm.dataMonitor_1 += sb.ToString();
// ...aggiorno valore riferimento...
contOreMaccLav = istOreMaccLav;
return needSave;
}
/// <summary>
/// Processing contatore Slitta Tastatore
/// </summary>
/// <param name="needSave"></param>
/// <returns></returns>
public bool procSlittaTast(bool needSave)
{
double delta = istSlittaTast - contSlittaTast;
double contatore = updateValDoubleByIncr(0, delta, "SlittaTastatore_Count");
currAdpConf.ContSlittaTast += delta;
// salvo valore su persistent layer
mSlittaTast.Value = contatore.ToString("0", CultureInfo.InvariantCulture);
// controllo valore riferimento...
if (delta > 0)
{
// segnalo necessità salvataggio!
needSave = true;
}
// salvo su maschera...
StringBuilder sb = new StringBuilder();
sb.AppendLine(string.Format("SlittaTastatore_Count: {0}", mSlittaTast.Value));
parentForm.dataMonitor_1 += sb.ToString();
// ...aggiorno valore riferimento...
contSlittaTast = istSlittaTast;
return needSave;
}
/// <summary>
/// Processing del program name
/// </summary>
/// <param name="needSave"></param>
/// <returns></returns>
public bool procProgrName(bool needSave)
{
// 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!
vettPath[i].mPathCurrProg.Value = 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)
{
// 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!
vettPath[i].mPathPartId.Value = istPathPartId[i];
// imposto a ZERO i pezzi del nuovo articolo
vettPath[i].mPathPartCount.Value = 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)
{
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] != currPathPartCount[i])
{
if (istPathPartCount[i] > currPathPartCount[i])
{
uint delta = istPathPartCount[i] - currPathPartCount[i];
//uint contatore = updatePathRefListByIncr(i, delta, "Path_{0:00}_PZ_TOT");
uint contatore = updateValUIntByIncr(i, delta, "Path_{0:00}_PZ_TOT");
// passo valore num pz all'adapter
vettPath[i].mPathPartCount.Value = contatore;
}
else // variato x difetto... azzero!!!
{
uint newVal = istPathPartCount[i];
updateValUInt(i, newVal, "Path_{0:00}_PZ_TOT");
// passo valore num pz all'adapter
vettPath[i].mPathPartCount.Value = newVal;
}
// segnalo necessità salvataggio!
needSave = true;
// ...aggiorno valore riferimento...
currPathPartCount[i] = istPathPartCount[i];
}
outString += string.Format("{0} | ", vettPath[i].mPathPartCount.Value);
}
// 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)
/// </summary>
/// <param name="needSave"></param>
/// <returns></returns>
public bool procGiriTotUnOp(bool needSave)
{
uint delta = 0;
string outString = string.Format("UnOp_[1-{0}]_KRev: ", currAdpConf.nUnOp);
for (int i = 0; i < currAdpConf.nUnOp; i++)
{
delta = istGiriElettrom[i] - contGiriElettrom[i];
// processo comunque sempre...
uint contatore = updateValUIntByIncr(i, delta, "UnOp_{0:00}_AccTime");
// passo valore num giri (migliaia) all'adapter
vettUnOp[i].mUnOpAccTime.Value = contatore;
// controllo valore riferimento...
if (delta > 0)
{
// segnalo necessità salvataggio!
needSave = true;
}
// ...aggiorno valore riferimento...
contGiriElettrom[i] = istGiriElettrom[i];
outString += string.Format("{0} | ", vettUnOp[i].mUnOpAccTime.Value);
}
// 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 cambi utensile (totali)
/// </summary>
/// <param name="needSave"></param>
/// <returns></returns>
public bool procNumCU(bool needSave)
{
uint delta = 0;
string outString = string.Format("UnOp_[1-{0}]_NumCU: ", currAdpConf.nUnOp);
for (int i = 0; i < currAdpConf.nUnOp; i++)
{
delta = istNumCambiUt[i] - currNumCambiUt[i];
// processo comunque sempre...
uint contatore = updateValUIntByIncr(i, delta, "UnOp_{0:00}_NumCU");
// passo valore num CU all'adapter
vettUnOp[i].mUnOpNumCU.Value = contatore;
// controllo valore riferimento...
if (delta > 0)
{
// segnalo necessità salvataggio!
needSave = true;
}
// ...aggiorno valore riferimento...
currNumCambiUt[i] = istNumCambiUt[i];
outString += string.Format("{0} | ", vettUnOp[i].mUnOpNumCU.Value);
}
// 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;
string outString = string.Format("Axis_[1-{0}]_DistDone: ", currAdpConf.nAxis);
for (int i = 0; i < currAdpConf.nAxis; i++)
{
delta = istDistMovAssi[i] - contDistMovAssi[i];
// processo comunque sempre...
double contTot = updateValDoubleByIncr(i, delta, "Axis_{0:00}_DistDone");
// passo valore totale all'adapter
vettAxis[i].mAxDistDone.Value = contTot.ToString("0.000", CultureInfo.InvariantCulture);
// controllo valore riferimento...
if (delta > 0)
{
// segnalo necessità salvataggio!
needSave = true;
}
// ...aggiorno valore riferimento...
contDistMovAssi[i] = istDistMovAssi[i];
outString += string.Format("{0} | ", vettAxis[i].mAxDistDone.Value);
}
// 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;
string outString = string.Format("Axis_[1-{0}]_AccTime: ", currAdpConf.nAxis);
for (int i = 0; i < currAdpConf.nAxis; i++)
{
delta = istAccTimeAssi[i] - contAccTimeAssi[i];
// salvo valore aggiuntivo x ore lavoro assi...
double oreTot = updateValDoubleByIncr(i, delta, "Axis_{0:00}_AccTime");
vettAxis[i].mAxAccTime.Value = oreTot.ToString("0.000", CultureInfo.InvariantCulture);
// controllo valore riferimento...
if (delta > 0)
{
// segnalo necessità salvataggio!
needSave = true;
}
// ...aggiorno valore riferimento...
contAccTimeAssi[i] = istAccTimeAssi[i];
outString += string.Format("{0} | ", vettAxis[i].mAxAccTime.Value);
}
// 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;
string outString = string.Format("Axis_[1-{0}]_InvDDone: ", currAdpConf.nAxis);
for (int i = 0; i < currAdpConf.nAxis; i++)
{
delta = istNumInvAssi[i] - contNumInvAssi[i];
// processo comunque sempre...
long contTot = updateValLongByIncr(i, delta, "Axis_{0:00}_InvDDone");
// passo valore totale all'adapter
vettAxis[i].mAxInvDDone.Value = contTot;
// controllo valore riferimento...
if (delta > 0)
{
// segnalo necessità salvataggio!
needSave = true;
}
// ...aggiorno valore riferimento...
contNumInvAssi[i] = istNumInvAssi[i];
outString += string.Format("{0} | ", vettAxis[i].mAxInvDDone.Value);
}
// 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;
string outString = string.Format("VacPump_[1-{0}]_WrkTime: ", currAdpConf.nVacuumPump);
for (int i = 0; i < currAdpConf.nVacuumPump; i++)
{
delta = istVacPumpWrkTime[i] - currVacPumpWrkTime[i];
// processo comunque sempre...
uint contTot = updateValUIntByIncr(i, delta, "VacPump_{0:00}_WrkTime");
// passo valore totale all'adapter
vettVacPump[i].mVacPumpWrkTime.Value = contTot;
// controllo valore riferimento...
if (delta > 0)
{
// segnalo necessità salvataggio!
needSave = true;
}
// ...aggiorno valore riferimento...
currVacPumpWrkTime[i] = istVacPumpWrkTime[i];
outString += string.Format("{0} | ", vettVacPump[i].mVacPumpWrkTime.Value);
}
// 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;
string outString = string.Format("VacPump_[1-{0}]_Count: ", currAdpConf.nVacuumPump);
for (int i = 0; i < currAdpConf.nVacuumAct; i++)
{
delta = istVacActCount[i] - currVacActCount[i];
// processo comunque sempre...
uint contTot = updateValUIntByIncr(i, delta, "VacAct_{0:00}_Count");
// passo valore totale all'adapter
vettVacAct[i].mVacActCount.Value = contTot;
// controllo valore riferimento...
if (delta > 0)
{
// segnalo necessità salvataggio!
needSave = true;
}
// ...aggiorno valore riferimento...
currVacActCount[i] = istVacActCount[i];
outString += string.Format("{0} | ", vettVacAct[i].mVacActCount.Value);
}
// 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;
string outString = string.Format("Lubro_[1-{0}]_Count: ", currAdpConf.nLubro);
for (int i = 0; i < currAdpConf.nLubro; i++)
{
delta = istLubroCount[i] - currLubroCount[i];
//processo comunque sempre...
uint contTot = updateValUIntByIncr(i, delta, "Lubro_{0:00}_Count");
// passo valore totale all'adapter
vettLubro[i].mLubroNum.Value = contTot;
// controllo valore riferimento...
if (delta > 0)
{
// segnalo necessità salvataggio!
needSave = true;
}
// ...aggiorno valore riferimento...
currLubroCount[i] = istLubroCount[i];
outString += string.Format("{0} | ", vettLubro[i].mLubroNum.Value);
}
// 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;
string outString = string.Format("SlittaMagazzino_[1-{0}]_Count: ", currAdpConf.nSlittaMag);
for (int i = 0; i < currAdpConf.nSlittaMag; i++)
{
delta = istSlittaMag[i] - currSlittaMag[i];
//processo comunque sempre...
uint contTot = updateValUIntByIncr(i, delta, "SlittaMagazzino_{0:00}_Count");
// passo valore totale all'adapter
vettSlittaMag[i].mSlittaMagCount.Value = contTot;
// controllo valore riferimento...
if (delta > 0)
{
// segnalo necessità salvataggio!
needSave = true;
}
// ...aggiorno valore riferimento...
currSlittaMag[i] = istSlittaMag[i];
outString += string.Format("{0} | ", vettSlittaMag[i].mSlittaMagCount.Value);
}
// 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;
string outString = string.Format("ProtMagazzino_[1-{0}]_Count: ", currAdpConf.nProtMag);
for (int i = 0; i < currAdpConf.nProtMag; i++)
{
delta = istProtMag[i] - currProtMag[i];
//processo comunque sempre...
uint contTot = updateValUIntByIncr(i, delta, "ProtMagazzino_{0:00}_Count");
// passo valore totale all'adapter
vettProtMag[i].mProtMagCount.Value = contTot;
// controllo valore riferimento...
if (delta > 0)
{
// segnalo necessità salvataggio!
needSave = true;
}
// ...aggiorno valore riferimento...
currProtMag[i] = istProtMag[i];
outString += string.Format("{0} | ", vettProtMag[i].mProtMagCount.Value);
}
// salvo su maschera...
parentForm.dataMonitor_2 += string.Format("{0}{1}", outString.Substring(0, outString.Length - 3), Environment.NewLine);
return needSave;
}
#endregion
#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));
}
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
{ }
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));
}
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
}
}