Files
CMS-MTConn/MTC_Sim/MTC_Sim/AdapterGeneric.cs
T
Samuele E. Locatelli 550c58bbe8 Fix errore report assi
x distanza con nuovo metodo generico (era su UnOp al posto di assi...)
2016-07-12 12:33:36 +02:00

2239 lines
80 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NLog;
namespace MTC_Adapter
{
using MTConnect;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;
#region macro oggetti da istanziare a blocchi da configurazione XML
/// <summary>
/// Singola pompa da vuoto, 0..n
/// </summary>
public class VacuumPomp : element
{
/// <summary>
/// Alias
/// </summary>
public Event mVacPumpAlias;
/// <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 VacuumPomp(element baseElem)
{
ident = baseElem.ident;
alias = baseElem.alias;
fonte = baseElem.fonte;
dataRefList = baseElem.dataRefList;
// genero elementi specifici MTConnect
mVacPumpAlias = new Event(string.Format("{0}_Alias", ident));
mVacPumpAlias.Value = alias;
mVacPumpStatus = new Event(dataRefList[0].Key);
mVacPumpWrkTime = new Event(dataRefList[1].Key);
}
}
/// <summary>
/// Singolo attuatore vuoto, 0..n
/// </summary>
public class VacuumAct : element
{
/// <summary>
/// Alias
/// </summary>
public Event mVacActAlias;
/// <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;
alias = baseElem.alias;
fonte = baseElem.fonte;
dataRefList = baseElem.dataRefList;
mVacActAlias = new Event(string.Format("{0}_Alias", ident));
mVacActAlias.Value = alias;
mVacActCount = new Event(dataRefList[0].Key);
}
}
/// <summary>
/// Singolo attuatore per lubrificazione, 0..n
/// </summary>
public class Lubro : element
{
/// <summary>
/// Alias
/// </summary>
public Event mLubroAlias;
/// <summary>
/// numero pompate necessarie per far scattare sensore
/// </summary>
public Event mLubroNum;
/// <summary>
/// Classe Lubrorefrigerante
/// </summary>
/// <param name="baseElem">element base contenente parametri (da XML)</param>
public Lubro(element baseElem)
{
ident = baseElem.ident;
alias = baseElem.alias;
fonte = baseElem.fonte;
dataRefList = baseElem.dataRefList;
mLubroAlias = new Event(string.Format("{0}_Alias", ident));
mLubroAlias.Value = alias;
mLubroNum = new Event(dataRefList[0].Key);
}
}
/// <summary>
/// Singolo refrigeratore, 0..n
/// </summary>
public class Cooler : element
{
/// <summary>
/// Alias
/// </summary>
public Event mCoolAlias;
/// <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;
alias = baseElem.alias;
fonte = baseElem.fonte;
dataRefList = baseElem.dataRefList;
mCoolAlias = new Event(string.Format("{0}_Alias", ident));
mCoolAlias.Value = alias;
mCoolStatus = new Event(dataRefList[0].Key);
}
}
/// <summary>
/// Singola Pressione rilevata, 0..n
/// </summary>
public class Press : element
{
/// <summary>
/// Alias
/// </summary>
public Event mPressAlias;
/// <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;
alias = baseElem.alias;
fonte = baseElem.fonte;
dataRefList = baseElem.dataRefList;
mPressAlias = new Event(string.Format("{0}_Alias", ident));
mPressAlias.Value = alias;
mPressValIst = new Sample(dataRefList[0].Key);
}
}
/// <summary>
/// Singola temperatura rilevata, 0..n
/// </summary>
public class Tempe : element
{
/// <summary>
/// Alias
/// </summary>
public Event mTempAlias;
/// <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;
alias = baseElem.alias;
fonte = baseElem.fonte;
dataRefList = baseElem.dataRefList;
mTempAlias = new Event(string.Format("{0}_Alias", ident));
mTempAlias.Value = alias;
mTempValIst = new Sample(dataRefList[0].Key);
}
}
/// <summary>
/// Singolo path, da 1..20
/// </summary>
public class Path : element
{
/// <summary>
/// Alias
/// </summary>
public Event mPathAlias;
/// <summary>
/// Tipo Path (LAVOR/ASSERV)
/// </summary>
public Event 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 Event mPathCodM;
/// <summary>
/// Codici S sul PATH
/// </summary>
public Event mPathCodS;
/// <summary>
/// Codici T sul PATH
/// </summary>
public Event 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>
/// 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>
/// 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 Event mPathCodG_Act;
/// <summary>
/// Stato dei SubMode attivi
/// </summary>
public Event 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;
alias = baseElem.alias;
fonte = baseElem.fonte;
dataRefList = baseElem.dataRefList;
mPathAlias = new Event(string.Format("{0}_Alias", ident));
mPathAlias.Value = alias;
mPathFeed = new Sample(dataRefList[0].Key);
mPathFeedOver = new Sample(dataRefList[1].Key);
mPathRapidOver = new Sample(dataRefList[2].Key);
mPathPosActX = new Sample(dataRefList[3].Key);
mPathPosActY = new Sample(dataRefList[4].Key);
mPathPosActZ = new Sample(dataRefList[5].Key);
mPathPosActI = new Sample(dataRefList[6].Key);
mPathPosActJ = new Sample(dataRefList[7].Key);
mPathPosActK = new Sample(dataRefList[8].Key);
// aggiunta x revisione 2016.05.05
mPathType = new Event(dataRefList[9].Key);
mPathPartId = new Event(dataRefList[10].Key);
mPathPartCount = new Event(dataRefList[11].Key);
mPathCodM = new Event(dataRefList[12].Key);
mPathCodS = new Event(dataRefList[13].Key);
mPathCodT = new Event(dataRefList[14].Key);
mPathRunMode = new Event(dataRefList[15].Key);
mPathExeMode = new Event(dataRefList[16].Key);
mPathCurrProg = new Event(dataRefList[17].Key);
mPathCurrProgRowNum = new Event(dataRefList[18].Key);
mPathActiveAxes = new Event(dataRefList[19].Key);
mPathCodG_Act = new Event(dataRefList[20].Key);
mPathSubMode = new Event(dataRefList[21].Key);
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>
/// Alias
/// </summary>
public Event mUnOpAlias;
/// <summary>
/// Alias
/// </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 Event mUnOpVitaResType;
/// <summary>
/// valore speed
/// </summary>
public Sample mUnOpSpeed;
/// <summary>
/// valore load
/// </summary>
public Sample mUnOpLoad;
/// <summary>
/// valore tempo cumulato di impiego
/// </summary>
public Sample mUnOpAccTime;
/// <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;
alias = baseElem.alias;
fonte = baseElem.fonte;
dataRefList = baseElem.dataRefList;
mUnOpAlias = new Event(string.Format("{0}_Alias", ident));
mUnOpAlias.Value = alias;
mUnOpToolId = new Event(dataRefList[0].Key);
mUnOpNumCU = new Event(dataRefList[1].Key);
mUnOpStatus = new Event(dataRefList[2].Key);
mUnOpVitaRes = new Event(dataRefList[3].Key);
mUnOpSpeed = new Sample(dataRefList[4].Key);
mUnOpLoad = new Sample(dataRefList[5].Key);
mUnOpAccTime = new Sample(dataRefList[6].Key);
mUnOpVitaResType = new Event(dataRefList[7].Key);
}
}
/// <summary>
/// Asse singolo, 1..n
/// </summary>
public class Axis : element
{
/// <summary>
/// Descrizione / Alias
/// </summary>
public Event mAxAlias;
/// <summary>
/// Processo di appartenenza
/// </summary>
public Event mAxMainProc;
/// <summary>
/// Bit se sia master (=1) o slave (=0)
/// </summary>
public Event mAxIsMaster;
/// <summary>
/// ID del master
/// </summary>
public Event mAxMastId;
/// <summary>
/// Event tipo asse: lineare, rotazionale...
/// </summary>
public Event mAxType;
/// <summary>
/// Bit direzione: 1 = avanti/clockwise, 0 indietro/counterclockwise
/// </summary>
public Sample 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 ed alias
/// </summary>
/// <param name="baseElem">element base contenente parametri (da XML)</param>
public Axis(element baseElem)
{
ident = baseElem.ident;
alias = baseElem.alias;
fonte = baseElem.fonte;
dataRefList = baseElem.dataRefList;
// inizializzo vari eventi, sample, condizioni
mAxAlias = new Event(string.Format("{0}_Alias", ident));
mAxAlias.Value = alias;
mAxMainProc = new Event(dataRefList[0].Key);
mAxIsMaster = new Event(dataRefList[1].Key);
mAxMastId = new Event(dataRefList[2].Key);
mAxType = new Event(dataRefList[3].Key);
mAxDir = new Sample(dataRefList[4].Key);
mAxLoad = new Sample(dataRefList[5].Key);
mAxPosAct = new Sample(dataRefList[6].Key);
mAxPosTgt = new Sample(dataRefList[7].Key);
mAxFeedAct = new Sample(dataRefList[8].Key);
mAxFeedOver = new Sample(dataRefList[9].Key);
mAxAccelAct = new Sample(dataRefList[10].Key);
mAxAccTime = new Sample(dataRefList[11].Key);
mAxBattery = new Sample(dataRefList[12].Key);
mAxDistDone = new Sample(dataRefList[13].Key);
mAxInvDDone = new Sample(dataRefList[14].Key);
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 running
/// </summary>
protected bool adpRunning;
/// <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>
/// Vettore ATTUALE dei contatori giri cumulati elettromandrino (migliaia)
/// </summary>
public uint[] contGiriElettrom;
/// <summary>
/// Vettore ATTUALE dei contatori del movimento degli assi
/// </summary>
public uint[] contDistMovAssi;
/// <summary>
/// Vettore ATTUALE dei contatori del num inv degli assi
/// </summary>
public uint[] contNumInvAssi;
/// <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>
/// Conteggio ISTANTANEO ore macchina ON
/// </summary>
public double istOreMaccOn;
/// <summary>
/// isteggio ISTANTANEO ore macchina IN LAVORO
/// </summary>
public double istOreMaccLav;
/// <summary>
/// Vettore ISTANTANEO dei contatori giri cumulati elettromandrino (migliaia)
/// </summary>
public uint[] istGiriElettrom;
/// <summary>
/// Vettore ISTANTANEO dei contatori del movimento degli assi
/// </summary>
public uint[] istDistMovAssi;
/// <summary>
/// Vettore ISTANTANEO dei contatori del num inv degli assi
/// </summary>
public uint[] istNumInvAssi;
/// <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>
/// 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 bit di strobe (4 word da 32 bit di flags...)
public byte[] Strobes = new byte[16];
// 16 bit 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
{
//byte[] answ = new byte[4];
//answ = (byte[])Strobes.Skip(0).Take(4);
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>
/// 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);
}
}
#if true
/// <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;
#endif
public List<string> codaM = new List<string>();
public List<string> codaS = new List<string>();
public List<string> codaT = new List<string>();
#endregion
#region Events
/// <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 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>
/// Orologio
/// </summary>
public Sample mClock = new Sample("CLOCK");
/// <summary>
/// Consumo elettrico globale
/// </summary>
public Sample mPower = new Sample("POWER");
/// <summary>
/// ID operatore?!?
/// </summary>
public Event mOperator = new Event("OperatorId");
/// <summary>
/// modalità funzionale
/// </summary>
public Event mFunctionalMode = new Event("FUNCT_MODE");
/// <summary>
/// Azioni operatore (Start/Stop/reset)
/// </summary>
public Event mUserAction = new Event("USER_ACTION");
/// <summary>
/// Testing macchina
/// </summary>
public Event mTestingData = new Event("TESTING_DATA");
/// <summary>
/// Strobe rilevati ma non qualificati
/// </summary>
public Event mUnkStrobe = new Event("UNK_STROBE");
/// <summary>
/// Status rilevati ma non qualificati
/// </summary>
public Event mUnkStatus = new Event("UNK_STATUS");
#endregion
#region Conditions
// vettori vari: allarmi sistema, PLC, CNC ed allarmi HMI
public Condition mAlarmSystem = new Condition("System");
public Condition mAlarmCNC = new Condition("CNC");
public Condition mAlarmPLC = new Condition("PLC");
public Condition mAlarmHMI = new Condition("HMI");
public Condition mAlarmGeneral = new Condition("General");
#endregion
#region Messages
public MTConnect.Message mMessage = new MTConnect.Message("Message");
#endregion
#region oggetti complessi/completi
public VacuumPomp[] vettVacPump;
public VacuumAct[] vettVacAct;
public Lubro[] vettLubro;
public Cooler[] vettCooler;
public Press[] vettPress;
public Tempe[] vettTempe;
public Path[] vettPath;
public UnOp[] vettUnOp;
public Axis[] vettAxis;
#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 AdapterGeneric");
currAdpConf = adpConf;
// salvo al form chiamante
parentForm = caller;
// item disponibilità
mAdapter.AddDataItem(mAvail);
mAvail.Value = "AVAILABLE";
// status, clock, emergency stop
mAdapter.AddDataItem(mStatus);
mAdapter.AddDataItem(mAccTime);
mAdapter.AddDataItem(mAccTimeWork);
mAdapter.AddDataItem(mClock);
mAdapter.AddDataItem(mPower);
mAdapter.AddDataItem(mEStop);
// programma e produzione
mAdapter.AddDataItem(mOperator);
// modalità esecutiva e funzionale
mAdapter.AddDataItem(mFunctionalMode);
// azioni utente
mAdapter.AddDataItem(mUserAction);
// testing e autodiagnostica
mAdapter.AddDataItem(mTestingData);
// strobe/status non riconosciuti
mAdapter.AddDataItem(mUnkStatus);
mAdapter.AddDataItem(mUnkStrobe);
// Pompe vuoto
vettVacPump = new VacuumPomp[adpConf.nVacuumPump];
for (int i = 0; i < adpConf.nVacuumPump; i++)
{
vettVacPump[i] = new VacuumPomp(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].mVacActAlias);
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].mLubroAlias);
mAdapter.AddDataItem(vettLubro[i].mLubroNum);
}
// 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].mCoolAlias);
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].mPressAlias);
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].mTempAlias);
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].mPathAlias);
mAdapter.AddDataItem(vettPath[i].mPathFeed);
mAdapter.AddDataItem(vettPath[i].mPathFeedOver);
mAdapter.AddDataItem(vettPath[i].mPathRapidOver);
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].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);
// altre aggiunte
}
// 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].mUnOpAlias);
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].mUnOpLoad);
mAdapter.AddDataItem(vettUnOp[i].mUnOpAccTime);
}
// 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].mAxAlias);
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);
}
// messaggi ulteriori
mAdapter.AddDataItem(mMessage);
// allarmi "base"
mAdapter.AddDataItem(mAlarmSystem);
mAdapter.AddDataItem(mAlarmCNC);
mAdapter.AddDataItem(mAlarmPLC);
mAdapter.AddDataItem(mAlarmHMI);
mAdapter.AddDataItem(mAlarmGeneral);
// concluso!
lg.Info("Istanziata classe 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}", Application.StartupPath, 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);
AlarmFlags = new byte[numByte];
if (utils.CRB("verbose")) lg.Info("Fine caricamento vettore allarmi");
}
/// <summary>
/// Caricamento altri file necessari epr adapter all'avvio
/// </summary>
protected virtual void loadOtherFile()
{
}
/// <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}", Application.StartupPath, utils.CRS("SubMode"));
string linea;
totRighe = File.ReadLines(fileName).Count();
// inizializzo
elencoSubMode = new Dictionary<string, string>();
// carica da file...
System.IO.StreamReader file = new System.IO.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>
/// 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());
}
#region metodi adapter
/// <summary>
/// Avvia l'adapter sulla porta richiesta
/// </summary>
/// <param name="port"></param>
public virtual void startAdapter(int port)
{
lg.Info("Starting adapter...");
dtAvvioAdp = DateTime.Now;
// inizializzo vettori di utility..
loadAllarmi();
loadSubMode();
loadOtherFile();
// Start the adapter lib with the port number in the text box
mAdapter.Port = port;
mAdapter.Start();
// setto status a ON
mStatus.Value = "ON";
// resetto running flag...
adpRunning = false;
// carico valori da adapter x i conteggi
contOreMaccOn = currAdpConf.ContOreMaccOn;
contOreMaccLav = currAdpConf.ContOreMaccLav;
contGiriElettrom = new uint[currAdpConf.nUnOp];
istGiriElettrom = 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));
// recupero valore giri...
UInt32 contTotGiri = Convert.ToUInt32(riContRpm.Value);
// salvo valore letto
contGiriElettrom[i] = contTotGiri;
}
// imposto num assi...
contDistMovAssi = new uint[currAdpConf.nAxis];
istDistMovAssi = new uint[currAdpConf.nAxis];
contNumInvAssi = new uint[currAdpConf.nAxis];
istNumInvAssi = new uint[currAdpConf.nAxis];
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));
// recupero valori...
contDistMovAssi[i] = Convert.ToUInt32(riContDist.Value);
contNumInvAssi[i] = Convert.ToUInt32(riNumInv.Value);
}
currPathPartId = new string[currAdpConf.nPath];
istPathPartId = 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);
}
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);
}
mAlarmSystem.Normal();
mAlarmCNC.Normal();
mAlarmPLC.Normal();
mAlarmGeneral.Normal();
parentForm.displayTaskAndWait("Adapter Started!");
}
/// <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)
{
// carico lo stato di tutti gli allarmi... forzo a 1 il flag degli allarmi
}
/// <summary>
/// ferma l'adapter...
/// </summary>
public void stopAdapter()
{
mStatus.Value = "OFF";
parentForm.displayTaskAndWait("Stopping adapter...");
// chiudo la connessione all'adapter...
tryDisconnect();
// Stop everything...
mAdapter.Stop();
dtStopAdp = DateTime.Now;
parentForm.displayTaskAndWait("Adapter Stopped!");
}
/// <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 (!adpRunning)
{
// provo ad avviare
try
{
// avvio fase raccolta dati
mAdapter.Begin();
// imposto flag adapter running..
adpRunning = true;
adpStartRun = DateTime.Now;
}
catch (Exception exc)
{
parentForm.displayTaskAndWait(string.Format("Adapter NOT STARTED!!!{0}{1}", Environment.NewLine, exc));
adpRunning = false;
adpStartRun = DateTime.Now;
}
if (adpRunning)
{
// processing degli strobes di allarme (da ULTIMA rappresentazione vettore dell'ADP)
processAlarm();
// processo e svuoto eventuali code di invio per Codici M/S/T
trySendCodMST();
// 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();
}
// 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();
}
// INVIO dati variati!
mAdapter.SendChanged();
// tolgo flag running
adpRunning = 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
adpRunning = false;
adpStartRun = DateTime.Now;
}
}
}
else
{
// log connessione KO
lg.Error("CicloMF - Connessione non disponibile, provo a riconnettere");
// provo a riconnettere...
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", item.codCall, item.numCall, item.avgMsec);
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 MEDIO del 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);
}
}
/// <summary>
/// verifico se ho dati M/S/T e li invio nel caso
/// </summary>
public virtual void trySendCodMST()
{
// !!!FARE!!! ciclo su + path
int idxPath = 1;
for (int i = 0; i < idxPath; i++)
{
// verifico SE ho codici M/S/T da inviare...
string codiceM = getNextMCode;
string codiceS = getNextSCode;
string codiceT = getNextTCode;
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()
{
}
/// <summary>
/// Dummy method: verifica stato conensisone OK
/// </summary>
/// <returns></returns>
public virtual bool connectionOk
{
get
{
return true;
}
}
/// <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>
/// recupero dati PATH
/// </summary>
public virtual void getPath()
{
// SE presente recupero dati path
checkPath();
}
/// <summary>
/// Recupero dati Unità Operatrici / Mandrini
/// </summary>
public virtual void getUnOp()
{
}
/// <summary>
/// recupero dati ASSI
/// </summary>
public virtual void getAxis()
{
}
/// <summary>
/// verifica gli status attivi
/// </summary>
public virtual void processStatus()
{
// da gestire su ogni adapter...
}
/// <summary>
/// processo tutti gli strobe attivi
/// </summary>
public virtual void processStrobe()
{
// da gestire su ogni adapter...
}
/// <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>
/// 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()
{
// da gestire su ogni adapter...
}
/// <summary>
/// recupero di TUTTI gli strobes/status attivi
/// </summary>
public virtual void getStrobeAndAckStatus()
{
// da gestire su ogni adapter... legge tutto array STROBE!!!
}
#endregion
#region area metodi comunicazione con PLC/CNC
public void checkPath()
{
}
/// <summary>
/// FeedRate globale
/// </summary>
public int FeedRate { 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>
/// 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;
}
}
#if false
public void checkCodM()
{
if (utils.IsSetAll(STROBE_PLC, Strobe.M_CODE))
{
mCod_M.Value = getNextMCode;
// se il valore è "" allora alzo flag lettura...
if (mCod_M.Value.ToString() == "") STROBE_ADP = STROBE_ADP | Strobe.M_CODE;
}
else
{
// resetto eventuali flag di lettura...
if (utils.IsSetAll(STROBE_ADP, Strobe.M_CODE))
{
STROBE_ADP -= Strobe.M_CODE;
}
}
}
public void checkCodS()
{
if (utils.IsSetAll(STROBE_PLC, Strobe.S_CODE))
{
mCod_S.Value = getNextSCode;
// se il valore è "" allora alzo flag lettura...
if (mCod_S.Value.ToString() == "") STROBE_ADP = STROBE_ADP | Strobe.S_CODE;
}
else
{
// resetto eventuali flag di lettura...
if (utils.IsSetAll(STROBE_ADP, Strobe.S_CODE))
{
STROBE_ADP -= Strobe.S_CODE;
}
}
}
public void checkCodT()
{
if (utils.IsSetAll(STROBE_PLC, Strobe.T_CODE))
{
mCod_T.Value = getNextTCode;
// se il valore è "" allora alzo flag lettura...
if (mCod_T.Value.ToString() == "") STROBE_ADP = STROBE_ADP | Strobe.T_CODE;
}
else
{
// resetto eventuali flag di lettura...
if (utils.IsSetAll(STROBE_ADP, Strobe.T_CODE))
{
STROBE_ADP -= Strobe.T_CODE;
}
}
}
#endif
/// <summary>
/// Aggiunge nel vettore coda codici M
/// </summary>
/// <param name="Coda"></param>
/// <param name="Codice da accodare"></param>
public void appendCodeMST(string Coda, string Codice)
{
switch (Coda)
{
case "S":
codaS.Add(Codice);
break;
case "T":
codaT.Add(Codice);
break;
case "M":
default:
codaM.Add(Codice);
break;
}
}
/// <summary>
/// recupera primo elemento codaM
/// </summary>
protected string getNextMCode
{
get
{
string answ = "";
if (codaM.Count > 0)
{
// recupero codice M...
answ = codaM.First();
// tolgo elemento
codaM.RemoveAt(0);
}
return answ;
}
}
/// <summary>
/// recupera primo elemento codaS
/// </summary>
protected string getNextSCode
{
get
{
string answ = "";
if (codaS.Count > 0)
{
// recupero codice S...
answ = codaS.First();
// tolgo elemento
codaS.RemoveAt(0);
}
return answ;
}
}
/// <summary>
/// recupera primo elemento codaT
/// </summary>
protected string getNextTCode
{
get
{
string answ = "";
if (codaT.Count > 0)
{
// recupero codice T...
answ = codaT.First();
// tolgo elemento
codaT.RemoveAt(0);
}
return answ;
}
}
#endregion
#region metodi che prevedono salvataggio valori su file XML
/// <summary>
/// Aggiorna un valore RefList del vettore PATH in OVERWRITE
/// </summary>
/// <param name="i"></param>
/// <param name="searchString"></param>
/// <param name="newVal"></param>
private void updatePathRefList(int i, string searchString, string newVal)
{
// leggo tutti i dati...
List<DataRefItem<string, string>> listaDR = currAdpConf.Path[i].dataRefList;
// punto all'item
DataRefItem<string, string> riValore = listaDR.Find(x => x.Key == string.Format(searchString, i + 1));
// tolgo vecchio item
listaDR.Remove(riValore);
// lo aggiorno...
riValore.Value = newVal;
// ri-aggiungo item
listaDR.Add(riValore);
// salvo in adapter!
currAdpConf.Path[i].dataRefList = listaDR;
}
/// <summary>
/// Aggiornamento vettore RefList generico
/// </summary>
/// <param name="i"></param>
/// <param name="deltaPz"></param>
/// <param name="searchString"></param>
/// <param name="listaDR"></param>
/// <returns></returns>
private static uint updateRefListByIncr(int i, uint deltaPz, string searchString, ref List<DataRefItem<string, string>> listaDR)
{
// punto all'item
DataRefItem<string, string> riValore = listaDR.Find(x => x.Key == string.Format(searchString, i + 1));
// recupero valore giri...
uint contTotPz = Convert.ToUInt32(riValore.Value);
// aggiungo giri...
contTotPz += deltaPz;
// tolgo vecchio item
listaDR.Remove(riValore);
// lo aggiorno...
riValore.Value = contTotPz.ToString();
// ri-aggiungo item
listaDR.Add(riValore);
return contTotPz;
}
/// <summary>
/// Aggiorna un valore RefList del vettore Axis 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 updateAxisRefListByIncr(int i, uint delta, string searchString)
{
// leggo tutti i dati...
List<DataRefItem<string, string>> listaDR = currAdpConf.Axis[i].dataRefList;
// recupero valore giri...
uint contTot = updateRefListByIncr(i, delta, searchString, ref listaDR);
// salvo in adapter!
currAdpConf.Axis[i].dataRefList = listaDR;
return contTot;
}/// <summary>
/// Aggiorna un valore RefList del vettore PATH 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 updatePathRefListByIncr(int i, uint delta, string searchString)
{
// leggo tutti i dati...
List<DataRefItem<string, string>> listaDR = currAdpConf.Path[i].dataRefList;
// recupero valore tot..
uint contTot = updateRefListByIncr(i, delta, searchString, ref listaDR);
// salvo in adapter!
currAdpConf.Path[i].dataRefList = listaDR;
return contTot;
}
/// <summary>
/// Aggiorna un valore RefList del vettore UnOp 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 updateUnOpRefListByIncr(int i, uint delta, string searchString)
{
// leggo tutti i dati...
List<DataRefItem<string, string>> listaDR = currAdpConf.UnOp[i].dataRefList;
// recupero valore giri...
uint contTot = updateRefListByIncr(i, delta, searchString, ref listaDR);
// salvo in adapter!
currAdpConf.UnOp[i].dataRefList = listaDR;
return contTot;
}
/// <summary>
/// Aggiorna un valore RefList del vettore VacPump 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 updateVacPumpRefListByIncr(int i, uint delta, string searchString)
{
// leggo tutti i dati...
List<DataRefItem<string, string>> listaDR = currAdpConf.VacuumPump[i].dataRefList;
// recupero valore giri...
uint contTot = updateRefListByIncr(i, delta, searchString, ref listaDR);
// salvo in adapter!
currAdpConf.VacuumPump[i].dataRefList = listaDR;
return contTot;
}
/// <summary>
/// Aggiorna un valore RefList del vettore VacAct 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 updateVacActRefListByIncr(int i, uint delta, string searchString)
{
// leggo tutti i dati...
List<DataRefItem<string, string>> listaDR = currAdpConf.VacuumAct[i].dataRefList;
// recupero valore giri...
uint contTot = updateRefListByIncr(i, delta, searchString, ref listaDR);
// salvo in adapter!
currAdpConf.VacuumAct[i].dataRefList = listaDR;
return contTot;
}
/// <summary>
/// Aggiorna un valore RefList del vettore Lubro 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 updateLubroRefListByIncr(int i, uint delta, string searchString)
{
// leggo tutti i dati...
List<DataRefItem<string, string>> listaDR = currAdpConf.Lubro[i].dataRefList;
// recupero valore giri...
uint contTot = updateRefListByIncr(i, delta, searchString, ref listaDR);
// salvo in adapter!
currAdpConf.Lubro[i].dataRefList = listaDR;
return contTot;
}
/// <summary>
/// Processing delle ore macchina ACCESA
/// </summary>
/// <param name="needSave"></param>
/// <returns></returns>
public bool procOreMaccOn(bool needSave)
{
// controllo valore riferimento...
if (istOreMaccOn > contOreMaccOn)
{
double deltaTime = istOreMaccOn - contOreMaccOn;
currAdpConf.ContOreMaccOn += deltaTime;
// segnalo necessità salvataggio!
needSave = true;
}
// ...aggiorno valore riferimento...
contOreMaccOn = istOreMaccOn;
// passo valore in ORE (float) all'adapter
mAccTime.Value = currAdpConf.ContOreMaccOn;
return needSave;
}
/// <summary>
/// Processing delle ore macchina IN LAVORO
/// </summary>
/// <param name="needSave"></param>
/// <returns></returns>
public bool procOreMaccLav(bool needSave)
{
// controllo valore riferimento...
if (istOreMaccLav > contOreMaccLav)
{
double deltaTime = istOreMaccLav - contOreMaccLav;
currAdpConf.ContOreMaccLav += deltaTime;
// segnalo necessità salvataggio!
needSave = true;
}
// ...aggiorno valore riferimento...
contOreMaccLav = istOreMaccLav;
// passo valore in ORE (float) all'adapter
mAccTimeWork.Value = currAdpConf.ContOreMaccLav;
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 programma...
for (int i = 0; i < currAdpConf.nPath; i++)
{
if (istPathPartId[i] != currPathPartId[i])
{
// aggiorno valore in Path RefList
updatePathRefList(i, "Path_{0:00}_PartId", istPathPartId[i]);
// 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)
{
// controllo valore riferimento x tutti i path se sia cambiato programma...
for (int i = 0; i < currAdpConf.nPath; i++)
{
// controllo valore riferimento...
if (istPathPartCount[i] > currPathPartCount[i])
{
uint deltaPz = istPathPartCount[i] - currPathPartCount[i];
uint contTotPz = updatePathRefListByIncr(i, deltaPz, "Path_{0:00}_PZ_TOT");
// passo valore num pz all'adapter
vettPath[i].mPathPartCount.Value = contTotPz;
// segnalo necessità salvataggio!
needSave = true;
}
// ...aggiorno valore riferimento...
currPathPartCount[i] = istPathPartCount[i];
}
return needSave;
}
/// <summary>
/// Processing delle variabili sul numero giri mandrino (totali)
/// </summary>
/// <param name="needSave"></param>
/// <returns></returns>
public bool procGiriTotUnOp(bool needSave)
{
for (int i = 0; i < currAdpConf.nUnOp; i++)
{
// controllo valore riferimento...
if (istGiriElettrom[i] > contGiriElettrom[i])
{
uint deltaGiri = istGiriElettrom[i] - contGiriElettrom[i];
uint contTotGiri = updateUnOpRefListByIncr(i, deltaGiri, "UnOp_{0:00}_AccTime");
// passo valore num giri (migliaia) all'adapter
vettUnOp[i].mUnOpAccTime.Value = contTotGiri.ToString();
// segnalo necessità salvataggio!
needSave = true;
}
// ...aggiorno valore riferimento...
contGiriElettrom[i] = istGiriElettrom[i];
}
return needSave;
}
/// <summary>
/// Processing delle variabili sul totale m percorsi dagli assi
/// </summary>
/// <param name="needSave"></param>
/// <returns></returns>
public bool procMovTotAssi(bool needSave)
{
for (int i = 0; i < currAdpConf.nAxis; i++)
{
// controllo valore riferimento...
if (istDistMovAssi[i] > contDistMovAssi[i])
{
uint delta = istDistMovAssi[i] - contDistMovAssi[i];
uint contTot = updateAxisRefListByIncr(i, delta, "Axis_{0:00}_DistDone");
// passo valore totale all'adapter
vettAxis[i].mAxDistDone.Value = contTot.ToString();
// segnalo necessità salvataggio!
needSave = true;
}
// ...aggiorno valore riferimento...
contDistMovAssi[i] = istDistMovAssi[i];
}
return needSave;
}
/// <summary>
/// Processing delle variabili sul totale num inversioni degli assi
/// </summary>
/// <param name="needSave"></param>
/// <returns></returns>
public bool procNumInvAssi(bool needSave)
{
for (int i = 0; i < currAdpConf.nAxis; i++)
{
// controllo valore riferimento...
if (istNumInvAssi[i] > contNumInvAssi[i])
{
uint delta = istNumInvAssi[i] - contNumInvAssi[i];
uint contTot = updateUnOpRefListByIncr(i, delta, "Axis_{0:00}_Invers");
// passo valore totale all'adapter
vettAxis[i].mAxInvDDone.Value = contTot.ToString();
// segnalo necessità salvataggio!
needSave = true;
}
// ...aggiorno valore riferimento...
contNumInvAssi[i] = istNumInvAssi[i];
}
return needSave;
}
/// <summary>
/// Processing delle variabili sulle VacPump
/// </summary>
/// <param name="needSave"></param>
/// <returns></returns>
public bool procVacPump(bool needSave)
{
for (int i = 0; i < currAdpConf.nVacuumPump; i++)
{
// controllo valore riferimento...
if (istVacPumpWrkTime[i] > currVacPumpWrkTime[i])
{
uint delta = istVacPumpWrkTime[i] - currVacPumpWrkTime[i];
uint contTot = updateVacPumpRefListByIncr(i, delta, "VacPump_{0:00}_WrkTime");
// passo valore totale all'adapter
vettVacPump[i].mVacPumpWrkTime.Value = contTot;
// segnalo necessità salvataggio!
needSave = true;
}
// ...aggiorno valore riferimento...
currVacPumpWrkTime[i] = istVacPumpWrkTime[i];
}
return needSave;
}
/// <summary>
/// Processing delle variabili sulle VacAct
/// </summary>
/// <param name="needSave"></param>
/// <returns></returns>
public bool procVacAct(bool needSave)
{
for (int i = 0; i < currAdpConf.nVacuumAct; i++)
{
// controllo valore riferimento...
if (istVacActCount[i] > currVacActCount[i])
{
uint delta = istVacActCount[i] - currVacActCount[i];
uint contTot = updateVacPumpRefListByIncr(i, delta, "VacAct_{0:00}_Count");
// passo valore totale all'adapter
vettVacAct[i].mVacActCount.Value = contTot;
// segnalo necessità salvataggio!
needSave = true;
}
// ...aggiorno valore riferimento...
currVacActCount[i] = istVacActCount[i];
}
return needSave;
}
/// <summary>
/// Processing delle variabili sui componenti Lubro
/// </summary>
/// <param name="needSave"></param>
/// <returns></returns>
public bool procLubro(bool needSave)
{
for (int i = 0; i < currAdpConf.nLubro; i++)
{
// controllo valore riferimento...
if (istLubroCount[i] > currLubroCount[i])
{
uint delta = istLubroCount[i] - currLubroCount[i];
uint contTot = updateVacPumpRefListByIncr(i, delta, "Lubro_{0:00}_Count");
// passo valore totale all'adapter
vettLubro[i].mLubroNum.Value = contTot;
// segnalo necessità salvataggio!
needSave = true;
}
// ...aggiorno valore riferimento...
currLubroCount[i] = istLubroCount[i];
}
return needSave;
}
#endregion
}
}