using NLog; using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using System.Text; namespace SCMA { using MTC; using MTConnect; using SCMA.AdapterCom; #region macro oggetti da istanziare a blocchi da configurazione XML /// /// Singola pompa da vuoto, 0..n /// public class VacuumPump : element { /// /// valore indca stato aperto/chiuso /// public Event mVacPumpStatus; /// /// valore work time della pompa vuoto /// public Event mVacPumpWrkTime; /// /// Classe Vacuum Pump (pompa) /// /// element base contenente parametri (da XML) 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)); } } /// /// Singolo attuatore vuoto, 0..n /// public class VacuumAct : element { /// /// valore numero attivazioni/disattivazioni valvola /// public Event mVacActCount; /// /// Classe Vacuum Actuator (valvola) /// /// element base contenente parametri (da XML) public VacuumAct(element baseElem) { ident = baseElem.ident; dataRefList = baseElem.dataRefList; mVacActCount = new Event(string.Format("{0}_Count", ident)); } } /// /// Singolo attuatore per lubrificazione, 0..n /// public class Lubro : element { /// /// numero pompate necessarie per far scattare sensore /// public Event mLubroNum; /// /// Status /// public Event mLubroStatus; /// /// Classe Lubrorefrigerante /// /// element base contenente parametri (da XML) public Lubro(element baseElem) { ident = baseElem.ident; dataRefList = baseElem.dataRefList; mLubroNum = new Event(string.Format("{0}_Count", ident)); mLubroStatus = new Event(string.Format("{0}_Status", ident)); } } /// /// Singola Slitta Mag, 0..n /// public class SlittaMag : element { /// /// valore numero attivazioni/disattivazioni slitta magazzino /// public Event mSlittaMagCount; /// /// Classe Slitta Magazzino /// /// element base contenente parametri (da XML) public SlittaMag(element baseElem) { ident = baseElem.ident; dataRefList = baseElem.dataRefList; mSlittaMagCount = new Event(string.Format("{0}_Count", ident)); } } /// /// Singolo attuatore Protezione Magazzino, 0..n /// public class ProtMag : element { /// /// valore numero attivazioni/disattivazioni valvola /// public Event mProtMagCount; /// /// Classe Protezione Magazzino /// /// element base contenente parametri (da XML) public ProtMag(element baseElem) { ident = baseElem.ident; dataRefList = baseElem.dataRefList; mProtMagCount = new Event(string.Format("{0}_Count", ident)); } } /// /// Singolo refrigeratore, 0..n /// public class Cooler : element { /// /// Stato istantaneo (evento aperto/chiuso) /// public Event mCoolStatus; /// /// Classe refrigeratore /// /// element base contenente parametri (da XML) public Cooler(element baseElem) { ident = baseElem.ident; dataRefList = baseElem.dataRefList; mCoolStatus = new Event(string.Format("{0}_Status", ident)); } } /// /// Singola Pressione rilevata, 0..n /// public class Press : element { /// /// valore pressione istantaneo /// public Sample mPressValIst; /// /// Classe pressione con Idx e descrizione /// /// element base contenente parametri (da XML) public Press(element baseElem) { ident = baseElem.ident; dataRefList = baseElem.dataRefList; mPressValIst = new Sample(string.Format("{0}_Value", ident)); } } /// /// Singola temperatura rilevata, 0..n /// public class Tempe : element { /// /// valore temperatura istantaneo /// public Sample mTempValIst; /// /// Classe temperatura con Idx e descrizione /// /// element base contenente parametri (da XML) public Tempe(element baseElem) { ident = baseElem.ident; dataRefList = baseElem.dataRefList; mTempValIst = new Sample(string.Format("{0}_Value", ident)); } } /// /// Singola Area Memoria (Kvara 1..4) /// public class MemArea : element { /// /// Programma caricato /// public MTConnect.Message mMemAreaProgName; /// /// Programma Running (in esecuzione) - ON/OFF /// public MTConnect.Message mMemAreaRunning; /// /// Num esecuzioni programma /// public Event mMemAreaProgNumExe; /// /// Num esecuzioni programma /// public Event mMemAreaProgNumRep; /// /// INIT Classe Memory Area /// /// element base contenente parametri (da XML) 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)); } } /// /// Singolo path, da 1..20 /// public class Path : element { /// /// Tipo Path (LAVOR/ASSERV) /// public MTConnect.Message mPathType; /// /// Cod Particolare su Path /// public Event mPathPartId; /// /// Contapezzi x PATH /// public Event mPathPartCount; /// /// Codici M sul PATH /// public MTConnect.Message mPathCodM; /// /// Codici S sul PATH /// public MTConnect.Message mPathCodS; /// /// Codici T sul PATH /// public MTConnect.Message mPathCodT; /// /// Modalità RUN del PATH: AUTO/EDIT/MDI/JOG/JOGINC/REF/HANDLE /// public Event mPathRunMode; /// /// Modalità execution del path: RUN/HOLD/FEED_HOLD/... /// public Event mPathExeMode; /// /// Programma corrente /// public Event mPathCurrProg; /// /// Area Programma corrente/selezionata /// public Event mPathCurrArea; /// /// num riga corrente /// public Event mPathCurrProgRowNum; /// /// Assi attivi per path /// public Event mPathActiveAxes; /// /// Feedrate /// public Sample mPathFeed; /// /// Override feed /// public Sample mPathFeedOver; /// /// Override speed /// public Sample mPathRapidOver; /// /// Override Jog /// public Sample mPathJogOver; /// /// Override Spindle_01 /// public Sample mPathSpindleOver_01; /// /// Override Spindle_02 /// public Sample mPathSpindleOver_02; /// /// Override Spindle_03 /// public Sample mPathSpindleOver_03; /// /// Override Spindle_04 /// public Sample mPathSpindleOver_04; /// /// Posizione X /// public Sample mPathPosActX; /// /// Posizione Y /// public Sample mPathPosActY; /// /// Posizione Z /// public Sample mPathPosActZ; /// /// Angolo I /// public Sample mPathPosActI; /// /// Angolo J /// public Sample mPathPosActJ; /// /// Angolo K /// public Sample mPathPosActK; /// /// Stato dei codici G attivi /// public MTConnect.Message mPathCodG_Act; /// /// Stato dei SubMode attivi /// public MTConnect.Message mPathSubMode; /// /// Allarmi CNC del PATH /// public Condition mPathAlarmCNC; /// /// Allarmi PCL del PATH /// public Condition mPathAlarmPLC; /// /// Classe Path con Idx e descrizione /// /// element base contenente parametri (da XML) 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)); } } /// /// Singolo mandrino, 1..n /// public class UnOp : element { /// /// ToolID /// public Event mUnOpToolId; /// /// valore numero Cambi Utensili effettuato /// public Event mUnOpNumCU; /// /// status utensil /// public Event mUnOpStatus; /// /// valore vita residua utensile /// public Event mUnOpVitaRes; /// /// 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) /// public MTConnect.Message mUnOpVitaResType; /// /// valore speed /// public Sample mUnOpSpeed; /// /// valore speed override /// public Sample mUnOpSpeedOverr; /// /// valore load /// public Sample mUnOpLoad; /// /// valore tempo cumulato di impiego /// public Sample mUnOpAccTime; /// /// contatore cumulato di giri mandrino (migliaia) /// public Sample mUnOpKRev; /// /// Classe Unita Operatrice (Mandrino) con Idx e descrizione /// /// element base contenente parametri (da XML) 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)); } } /// /// Asse singolo, 1..n /// public class Axis : element { /// /// Descrizione asse (nome assegnato) /// public MTConnect.Message mAxDescr; /// /// Processo di appartenenza /// public MTConnect.Message mAxMainProc; /// /// Bit se sia master (=1) o slave (=0) /// public MTConnect.Message mAxIsMaster; /// /// ID del master /// public MTConnect.Message mAxMastId; /// /// Gruppo di appartenenza dell'asse /// public MTConnect.Message mAxGrp; /// /// Event tipo asse: lineare, rotazionale... /// public Event mAxType; /// /// Bit direzione: 1 = avanti/clockwise, 0 indietro/counterclockwise /// public Event mAxDir; /// /// Load /// public Sample mAxLoad; /// /// Posizione Attuale /// public Sample mAxPosAct; /// /// Posizione Target /// public Sample mAxPosTgt; /// /// Feed Attuale /// public Sample mAxFeedAct; /// /// Feed Override /// public Sample mAxFeedOver; /// /// Accelerazione Attuale /// public Sample mAxAccelAct; /// /// Tempo Lavoro cumulato /// public Sample mAxAccTime; /// /// Carica batteria /// public Sample mAxBattery; /// /// Distanza compiuta nell'intervallo di tempo /// public Sample mAxDistDone; /// /// numero di inversioni di direzione fatte nell'intervallo di tempo /// public Event mAxInvDDone; /// /// Allarmi CNC del PATH /// public Condition mAxAlarmCNC; /// /// Allarmi PCL del PATH /// public Condition mAxAlarmPLC; /// /// Classe Asse con relativo ID UNIVOCO /// /// element base contenente parametri (da XML) 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 Message(dataRefList[1].Key); mAxGrp.Value = dataRefList[1].Value; } catch { mAxGrp = new Message(string.Format("{0}_Grp", ident)); mAxGrp.Value = "00"; } // valori standard mAxDescr = new Message(string.Format("{0}_Descr", ident)); mAxMainProc = new Message(string.Format("{0}_MainProc", ident)); mAxIsMaster = new Message(string.Format("{0}_IsMast", ident)); mAxMastId = new Message(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 Event(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 { /// /// inizializzo l'oggetto sulla form SULLA BASE DEL FILE DI CONFIGURAZIONE letto /// /// FORM chaimante /// CONFIGURAZIONE adapter /// OGGETTO gestione comunicazione OUT (tipologia e metodi) public AdapterGeneric(MainForm caller, AdapterConf adpConf, Gateway gatewayObj) { lg = LogManager.GetCurrentClassLogger(); lg.Info("Avvio preliminare AdapterGeneric"); currGateway = gatewayObj; lg.Info(string.Format("Impostato protocollo di comunicazione {0}", currGateway.protocollo)); procIotMem = utils.CRB("procIotMem"); currAdpConf = adpConf; // inizializzo vettore gruppi assi, MAX 20!!! FeedRateGrp = new int[20]; // 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); // 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].mAxDescr); 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[adpConf.nPath]; codaS = new List[adpConf.nPath]; codaT = new List[adpConf.nPath]; for (int i = 0; i < adpConf.nPath; i++) { codaM[i] = new List(); codaS[i] = new List(); codaT[i] = new List(); } // concluso! lg.Info("Istanziata classe preliminare AdapterGeneric"); } /// /// alias booleano false = R /// public bool R = false; /// /// alias booleano true = W /// public bool W = true; /// /// wrapper di log /// public static Logger lg; /// /// valore booleano di check se sia in fase di COMUNICAZIONE ATTIVA con il PLC/NC /// protected bool adpCommAct; /// /// valore booleano di check se sia stato AVVIATO l'adapter (Running) /// public bool adpRunning = false; /// /// valore booleano di check se l'adapter STIA SALVANDO /// public bool adpSaving = false; /// /// valore booleano (richiesta di riavvio automatico) /// public bool adpTryRestart; /// /// Ultimo valore watchdog rilevato /// public bool lastWatchDog = false; /// /// Determina se utilizzare blocchi di memoria IOT contigui (e quindi processing "monoblocco" semplificato"= /// public bool procIotMem = false; /// /// porta x adapter (x restart) /// protected int adpPortNum; /// /// DataOra ultimo avvio adapter x watchdog /// protected DateTime adpStartRun; /// /// Data/ora ultimo avvio adapter /// public DateTime dtAvvioAdp = DateTime.Now; /// /// Data/ora ultimo spegnimento adapter /// public DateTime dtStopAdp = DateTime.Now; /// /// vettore gestione cronometraggi /// public DateTime inizio; /// /// Conteggio ATTUALE ore macchina ON /// public double contOreMaccOn; /// /// Conteggio ATTUALE ore macchina IN LAVORO /// public double contOreMaccLav; /// /// Conteggio ATTUALE numero movimenti Slitta Tastatore /// public double contSlittaTast; /// /// Vettore ATTUALE dei contatori giri cumulati elettromandrino (migliaia) /// public uint[] contGiriElettrom; /// /// Vettore ATTUALE dei contatori del movimento degli assi /// public double[] contDistMovAssi; /// /// Vettore ATTUALE dei contatori del tempo cumulato degli assi /// public double[] contAccTimeAssi; /// /// Vettore ATTUALE dei contatori del num inv degli assi /// public uint[] contNumInvAssi; /// /// vettore dei ProgramName dei path ATTIVI /// public string[] currPathProgrName; /// /// vettore dei PartId dei path ATTIVI /// public string[] currPathPartId; /// /// Vettore ATTUALE dei contatori del num pezzi fatti x PartId /// public uint[] currPathPartCount; /// /// Vettore ATTUALE dei contatori del work time x VacPump /// public uint[] currVacPumpWrkTime; /// /// Vettore ATTUALE dei contatori del numero impieghi VacAct /// public uint[] currVacActCount; /// /// Vettore ATTUALE dei contatori del Lubro /// public uint[] currLubroCount; /// /// Vettore ATTUALE dei contatori del numero cambi utensili x UnOp /// public uint[] currNumCambiUt; /// /// Vettore ATTUALE dei contatori GENERICI /// public uint[] currCounters; /// /// Vettore ATTUALE dei contatori del numero movimenti Slitta Magazzino /// public uint[] currSlittaMag; /// /// Vettore ATTUALE dei contatori del numero movimenti Protezione Magazzino /// public uint[] currProtMag; /// /// Conteggio ISTANTANEO ore macchina ON /// public sampleVect istOreMaccOn; /// /// isteggio ISTANTANEO ore macchina IN LAVORO /// public sampleVect istOreMaccLav; /// /// Conteggio ISTANTANEO contatore del numero movimenti Slitta Tastatore /// public sampleVect istSlittaTast; /// /// Vettore ISTANTANEO dei contatori giri cumulati elettromandrino (migliaia) /// public sampleVect[] istGiriElettrom; /// /// Vettore ISTANTANEO dei contatori del movimento degli assi /// public sampleVect[] istDistMovAssi; /// /// Vettore ISTANTANEO dei contatori del LOAD degli assi /// public sampleVect[] istLoadAssi; /// /// Vettore ISTANTANEO dei contatori del tempo cumulato degli assi /// public sampleVect[] istAccTimeAssi; /// /// Vettore ISTANTANEO dei contatori del num inv degli assi /// public sampleVect[] istNumInvAssi; /// /// vettore dei Program Name dei path ISTANTANEI (nuovi/letti) /// public string[] istPathProgrName; /// /// vettore dei PartId dei path ISTANTANEI (nuovi/letti) /// public string[] istPathPartId; /// /// Vettore ISTANTANEO dei contatori del num pezzi fatti x PartId /// public sampleVect[] istPathPartCount; /// /// Vettore ISTANTANEO dei contatori del work time x VacPump /// public sampleVect[] istVacPumpWrkTime; /// /// Vettore ISTANTANEO dei contatori del numero impieghi VacAct /// public sampleVect[] istVacActCount; /// /// Vettore ISTANTANEO dei contatori del Lubro /// public sampleVect[] istLubroCount; /// /// Vettore ISTANTANEO dei contatori del numero cambi utensili x UnOp /// public sampleVect[] istNumCambiUt; /// /// Vettore ISTANTANEO dei contatori generici /// public sampleVect[] istCounters; /// /// Vettore ISTANTANEO dei contatori del numero movimenti Slitta Magazzino /// public sampleVect[] istSlittaMag; /// /// Vettore ISTANTANEO dei contatori del numero movimenti Protezione Magazzino /// public sampleVect[] istProtMag; /// /// vettore valori in file interscambio /// public Dictionary generalStatus; /// /// Contenuto valori contatori manutenzione da PLC /// public otherData[] maintData; /// /// Contenuto valori variabili analogiche da PLC /// public otherData[] analogData; /// /// Contenuto valori status data da PLC /// public otherData[] statusData; /// /// data-ora ultimo controllo movimento assi /// public DateTime lastChekAccumTimeAxis; /// /// posizione precedente assi per calcolo distanze... /// public double[] prevPosAxis; /// /// direzione precedente assi per calcolo inversioni... /// public int[] prevDirAxis; /// /// blocco memoria BYTE x lettura TUTTI i dati di buffer M/S/T /// public byte[] MemBlock_MST; /// /// Indica se sia necessario il salto x array codici MST (OSAI = 1, FANUC/SIEMENS=0) /// public int saltoMST = 0; /// /// Determina se sia encessario convertire valori little/big endian (SIEMENS=true, OSAI=FALSE) /// public bool hasBigEndian = false; /// /// Verifica se siano stati già mostrati gli allarmi x debug... /// public bool alarmMsgDispl = true; /// /// dimensione massima vettore memorie UT /// public short numMemUt = 200; /// /// adapter globale /// public Adapter mAdapter = new Adapter(); /// /// Form chiamante /// protected MainForm parentForm; /// /// Conf adapter corrente /// public AdapterConf currAdpConf; /// /// Obj gestione la comunicazione a valle (secondo standard LOGFILE / MTC / SOURS) /// public Gateway currGateway; #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; /// /// Oggetto elenco allarmi /// public allarme[] elencoAllarmi; public Dictionary elencoSubMode; /// /// Prima word di strobe da array flag completo /// public StFlag32 STRB_DW0 { get { return (StFlag32)BitConverter.ToUInt32(Strobes, 0); } } /// /// Seconda word di strobe da array flag completo /// public StFlag32 STRB_DW1 { get { return (StFlag32)BitConverter.ToUInt32(Strobes, 4); } } /// /// Terza word di strobe da array flag completo /// public StFlag32 STRB_DW2 { get { return (StFlag32)BitConverter.ToUInt32(Strobes, 8); } } /// /// Quarta word di strobe da array flag completo /// public StFlag32 STRB_DW3 { get { return (StFlag32)BitConverter.ToUInt32(Strobes, 12); } } /// /// Quarta word di strobe da array flag completo /// public StFlag32 STRB_DW4 { get { return (StFlag32)BitConverter.ToUInt32(Strobes, 16); } } /// /// Prima word di ACKnowledgment da array flag completo /// public StFlag32 ACK_DW0 { get { return (StFlag32)BitConverter.ToUInt32(Acknowl, 0); } } /// /// Seconda word di ACKnowledgment da array flag completo /// public StFlag32 ACK_DW1 { get { return (StFlag32)BitConverter.ToUInt32(Acknowl, 4); } } /// /// Terza word di ACKnowledgment da array flag completo /// public StFlag32 ACK_DW2 { get { return (StFlag32)BitConverter.ToUInt32(Acknowl, 8); } } /// /// Quarta word di ACKnowledgment da array flag completo /// public StFlag32 ACK_DW3 { get { return (StFlag32)BitConverter.ToUInt32(Acknowl, 12); } } /// /// Strobe mask PLC /// public Strobe STROBE_PLC = 0; /// /// Strobe mask adapter /// public Strobe STROBE_ADP = 0; /// /// Status flag /// public StatusBitMap STATUS_FLAG = 0; /// /// Variabili stato macchina principali /// public StFlag8 ST_MACCH = 0; public List[] codaM; public List[] codaS; public List[] codaT; #endregion #region Events & samples /// /// Asset Changed - cambio asset /// public Event mAssetChg = new Event("MTC_asset_chg"); /// /// Asset Removed - cambio asset /// public Event mAssetRem = new Event("MTC_asset_rem"); /// /// D.D1.AVAIL - disponibilità /// public Event mAvail = new Event("AVAIL"); /// /// XX.XX.STOP - stop per pressione emergenze /// public Event mEStop = new Event("E_STOP"); /// /// STATUS "logico" adapter macchina (ON/OFF) /// public Event mStatus = new Event("STATUS"); /// /// Minuti accensione globale macchina /// public Sample mAccTime = new Sample("ACC_TIME"); /// /// Minuti funzionamento globale macchina (IN LAVORO) /// public Sample mAccTimeWork = new Sample("ACC_TIME_WORK"); /// /// Conteggio Impieghi Slitta Tastatore /// public Sample mSlittaTast = new Sample("SlittaTastatore_Count"); /// /// Orologio /// public Sample mClock = new Sample("CLOCK"); /// /// Status macchina accesa/spenta /// public Event mPower = new Event("POWER"); /// /// processo selezionato /// public Event mProcSel = new Event("PROC_SEL"); /// /// ID operatore?!? /// public Event mOperator = new Event("OperatorId"); /// /// Vettore CONTATORI generici /// public Event[] mCounters; /// /// Vettore EVENTS letti da area status /// public Event[] mStatusEvents; /// /// Vettore SAMPLES letti da area AnalogData /// public Sample[] mAnalogDataSamples; #endregion #region Conditions // vettori vari: allarmi sistema, PLC, CNC public Condition mAlarmCNC = new Condition("CNC"); public Condition mAlarmPLC = new Condition("PLC"); #endregion #region Messages /// /// modalità funzionale /// public MTConnect.Message mFunctionalMode = new MTConnect.Message("FUNCT_MODE"); /// /// Azioni operatore (Start/Stop/reset) /// public MTConnect.Message mUserAction = new MTConnect.Message("USER_ACTION"); /// /// Testing macchina /// public MTConnect.Message mTestingData = new MTConnect.Message("TESTING_DATA"); /// /// Strobe rilevati ma non qualificati /// public MTConnect.Message mUnkStrobe = new MTConnect.Message("UNK_STROBE"); /// /// Status rilevati ma non qualificati /// public MTConnect.Message mUnkStatus = new MTConnect.Message("UNK_STATUS"); /// /// Messaggi generali /// 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; /// /// caricamento allarmi da file /// 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(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)); } /// /// Caricamento altri file necessari epr adapter all'avvio /// protected virtual void loadOtherFile() { } /// /// Lettura file gestione dati manutenzione da PLC /// /// /// /// public void loadMaintData(string memPre, int baseAddr, int memSize) { // carico dati x Maintenance if (utils.CRB("verbose")) lg.Info("Inizio caricamento vettore variabili manutenzione gestite"); int totRighe = 0; int numCounters = 0; 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); // se è un counter lo processo come tale.. if (maintData[numRiga].varName.StartsWith("Counter_")) { numCounters++; } numRiga++; } } // chiudo file file.Close(); // ora trimmo vettore al solo numero VERO dei valori caricati... Array.Resize(ref maintData, numRiga); if (utils.CRB("verbose")) lg.Info(string.Format("Fine caricamento vettore di {0} variabili manutenzione gestite", numRiga)); // ora inizializzo l'insieme degli events dei COUNTERS generici... mCounters = new Event[numCounters]; currCounters = new uint[numCounters]; istCounters = new sampleVect[numCounters]; int idx = 0; foreach (otherData item in maintData) { if (item.varName.StartsWith("Counter_")) { mCounters[idx] = new Event(item.varName); mAdapter.AddDataItem(mCounters[idx]); istCounters[idx] = new sampleVect(); idx++; } } if (utils.CRB("verbose")) lg.Info(string.Format("inizializzato vettore di {0} MTC.EVENTS delle variabili CONTATORI generiche", numRiga)); } /// /// Lettura file gestione dati analogici da PLC /// /// /// /// 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(ref analogData, numRiga); if (utils.CRB("verbose")) lg.Info(string.Format("Fine caricamento vettore di {0} variabili analogiche gestite", numRiga)); // ora inizializzo l'insieme dei samples delle var analogiche mAnalogDataSamples = new Sample[numRiga]; for (int i = 0; i < numRiga; i++) { mAnalogDataSamples[i] = new Sample("AV_" + analogData[i].varName); mAdapter.AddDataItem(mAnalogDataSamples[i]); } if (utils.CRB("verbose")) lg.Info(string.Format("inizializzato vettore di {0} MTC.SAMPLES delle variabili analogiche", numRiga)); } /// /// Lettura file gestione dati status da PLC /// /// /// /// 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(ref statusData, numRiga); if (utils.CRB("verbose")) lg.Info(string.Format("Fine caricamento vettore di {0} variabili status gestite", numRiga)); // ora inizializzo l'insieme degli eventi di status mStatusEvents = new Event[numRiga]; for (int i = 0; i < numRiga; i++) { mStatusEvents[i] = new Event("ST_" + statusData[i].varName); mAdapter.AddDataItem(mStatusEvents[i]); } if (utils.CRB("verbose")) lg.Info(string.Format("inizializzato vettore di {0} MTC.EVENTS di status", numRiga)); } /// /// caricamento allarmi da file /// 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(); // 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"); } /// /// Decodifica file allarme /// /// /// /// protected allarme decodeAlarmLine(string linea, char separator) { string[] valori = linea.Split(separator); return new allarme(valori[0], valori[1], valori[2], valori[3]); } /// /// Recupera il numero (iniziale) da una stringa prendendo la aprte sino al separatore... /// /// /// /// protected int startNumb(string linea, char separator) { int answ = 0; try { answ = Convert.ToInt32(linea.Substring(0, linea.IndexOf(separator))); } catch { } return answ; } /// /// Decodifica file datiProdSCM /// /// /// /// 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; } /// /// Decodifica file allarme /// /// /// /// tipo memoria (R/D/...) /// indirizzo di partenza memoria /// dimensione singolo slot in byte /// 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()); } /// /// Decodifica file MAP (caso ESA/IOT) /// /// /// /// indirizzo Byte: indirizzo di partenza memoria /// dimensione singolo slot in byte /// indirizzo bit: numero riga x calcolo indice bit /// 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()); } /// /// Decodifica file MAP (caso FANUC/OSAI/...) /// /// /// /// tipo memoria (R/D/...) /// indirizzo Byte: indirizzo di partenza memoria /// dimensione singolo slot in byte /// indirizzo bit: numero riga x calcolo indice bit /// 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 /// /// lettura file di persistenza /// 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 < mCounters.Length; i++) { currCounters[i] = getStoredValUInt(string.Format("Counter_{0:000}", i + 1)); } for (int i = 0; i < currAdpConf.nProtMag; i++) { currProtMag[i] = getStoredValUInt(string.Format("ProtMagazzino_{0:00}_Count", i + 1)); } } catch (Exception exc) { lg.Error(string.Format("Eccezione in decodifica valori PersLayer: {0}{1}", Environment.NewLine, exc)); } } /// /// Avvia l'adapter sulla porta richiesta /// /// 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 ACTIVE mStatus.Value = "ACTIVE"; // resetto running flag... adpCommAct = false; // avvio i sample vectors... istOreMaccOn = new sampleVect(); istOreMaccLav = new sampleVect(); istSlittaTast = new sampleVect(); // carico valori da adapter x i conteggi contOreMaccOn = currAdpConf.ContOreMaccOn; contOreMaccLav = currAdpConf.ContOreMaccLav; contSlittaTast = currAdpConf.ContSlittaTast; contGiriElettrom = new uint[currAdpConf.nUnOp]; istGiriElettrom = new sampleVect[currAdpConf.nUnOp]; currNumCambiUt = new uint[currAdpConf.nUnOp]; istNumCambiUt = new sampleVect[currAdpConf.nUnOp]; for (int i = 0; i < currAdpConf.nUnOp; i++) { // leggo tutti i dati... List> listaDR = currAdpConf.UnOp[i].dataRefList; // punto all'item DataRefItem riContRpm = listaDR.Find(x => x.Key == string.Format("UnOp_{0:00}_AccTime", i + 1)); DataRefItem 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; istGiriElettrom[i] = new sampleVect(); istNumCambiUt[i] = new sampleVect(); } // imposto num assi e leggo valori salvati... contDistMovAssi = new double[currAdpConf.nAxis]; istDistMovAssi = new sampleVect[currAdpConf.nAxis]; istLoadAssi = new sampleVect[currAdpConf.nAxis]; contNumInvAssi = new uint[currAdpConf.nAxis]; istAccTimeAssi = new sampleVect[currAdpConf.nAxis]; contAccTimeAssi = new double[currAdpConf.nAxis]; istNumInvAssi = new sampleVect[currAdpConf.nAxis]; lastChekAccumTimeAxis = DateTime.Now; for (int i = 0; i < currAdpConf.nAxis; i++) { // leggo tutti i dati... List> listaDR = currAdpConf.Axis[i].dataRefList; // punto all'item DataRefItem riContDist = listaDR.Find(x => x.Key == string.Format("Axis_{0:00}_DistDone", i + 1)); DataRefItem riNumInv = listaDR.Find(x => x.Key == string.Format("Axis_{0:00}_Invers", i + 1)); DataRefItem 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(); istDistMovAssi[i] = new sampleVect(); istLoadAssi[i] = new sampleVect(); istAccTimeAssi[i] = new sampleVect(); istNumInvAssi[i] = new sampleVect(); } currPathPartId = new string[currAdpConf.nPath]; istPathPartId = new string[currAdpConf.nPath]; currPathProgrName = new string[currAdpConf.nPath]; istPathProgrName = new string[currAdpConf.nPath]; currPathPartCount = new uint[currAdpConf.nPath]; istPathPartCount = new sampleVect[currAdpConf.nPath]; for (int i = 0; i < currAdpConf.nPath; i++) { // leggo tutti i dati... List> listaDR = currAdpConf.Path[i].dataRefList; // punto all'item DataRefItem riPathProgr = listaDR.Find(x => x.Key == string.Format("Path_{0:00}_PartId", i + 1)); DataRefItem 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(); istPathPartCount[i] = new sampleVect(); } currVacPumpWrkTime = new uint[currAdpConf.nVacuumPump]; istVacPumpWrkTime = new sampleVect[currAdpConf.nVacuumPump]; for (int i = 0; i < currAdpConf.nVacuumPump; i++) { // leggo tutti i dati... List> listaDR = currAdpConf.VacuumPump[i].dataRefList; // punto all'item DataRefItem riVacPumpWrk = listaDR.Find(x => x.Key == string.Format("VacPump_{0:00}_WrkTime", i + 1)); // recupero valori... currVacPumpWrkTime[i] = Convert.ToUInt32(riVacPumpWrk.Value); istVacPumpWrkTime[i] = new sampleVect(); } currVacActCount = new uint[currAdpConf.nVacuumAct]; istVacActCount = new sampleVect[currAdpConf.nVacuumAct]; for (int i = 0; i < currAdpConf.nVacuumAct; i++) { // leggo tutti i dati... List> listaDR = currAdpConf.VacuumAct[i].dataRefList; // punto all'item DataRefItem riVacActCount = listaDR.Find(x => x.Key == string.Format("VacAct_{0:00}_Count", i + 1)); // recupero valori... currVacActCount[i] = Convert.ToUInt32(riVacActCount.Value); istVacActCount[i] = new sampleVect(); } currLubroCount = new uint[currAdpConf.nLubro]; istLubroCount = new sampleVect[currAdpConf.nLubro]; for (int i = 0; i < currAdpConf.nLubro; i++) { // leggo tutti i dati... List> listaDR = currAdpConf.Lubro[i].dataRefList; // punto all'item DataRefItem riLubro = listaDR.Find(x => x.Key == string.Format("Lubro_{0:00}_Count", i + 1)); // recupero valori... currLubroCount[i] = Convert.ToUInt32(riLubro.Value); istLubroCount[i] = new sampleVect(); } currSlittaMag = new uint[currAdpConf.nSlittaMag]; istSlittaMag = new sampleVect[currAdpConf.nSlittaMag]; for (int i = 0; i < currAdpConf.nSlittaMag; i++) { // leggo tutti i dati... List> listaDR = currAdpConf.SlittaMag[i].dataRefList; // punto all'item DataRefItem riSlittaMag = listaDR.Find(x => x.Key == string.Format("SlittaMagazzino_{0:00}_Count", i + 1)); // recupero valori... currSlittaMag[i] = Convert.ToUInt32(riSlittaMag.Value); istSlittaMag[i] = new sampleVect(); } currProtMag = new uint[currAdpConf.nProtMag]; istProtMag = new sampleVect[currAdpConf.nProtMag]; for (int i = 0; i < currAdpConf.nProtMag; i++) { // leggo tutti i dati... List> listaDR = currAdpConf.ProtMag[i].dataRefList; // punto all'item DataRefItem riProtMag = listaDR.Find(x => x.Key == string.Format("ProtMagazzino_{0:00}_Count", i + 1)); // recupero valori... currProtMag[i] = Convert.ToUInt32(riProtMag.Value); istProtMag[i] = new sampleVect(); } //mAlarmSystem.Normal(); mAlarmCNC.Normal(); mAlarmPLC.Normal(); //mAlarmGeneral.Normal(); adpTryRestart = true; parentForm.displayTaskAndWait("Adapter Started!"); } /// /// ferma l'adapter... /// /// indica se si debba tentare di riavviare l'adapter (con caduta connessione viene fermato in automatico) 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; } /// /// effettua recupero dati ed invio valori modificati... /// /// 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(); bool showDebugData = false; // verifico se processare tutto "in un colpo solo" if (procIotMem) { processAllMemory(); // ciclo lento x log... if (ciclo == gatherCycle.LF) { // eventuale log! if (utils.CRB("recTime")) logTimeResults(); } } // oppure in "modalità classica" con multistep... else { // ciclo VHF x invii... if (ciclo == gatherCycle.VHF) { // processo e svuoto eventuali code di invio per Codici M/S/T trySendCodMST(); } // POI CONTROLLO cicli + lenti di lettura... // ciclo HF: recupero update status & strobes vari if (ciclo == gatherCycle.HF) { // parte che eseguo SEMPRE: RECUPERO stato di tutti gli strobe/status e degli ack attualmente noti getStrobeAndAckStatus(); // faccio refresh degli allarmi segnalati (da strobe su vettore locale) refreshAlarmState(STRB_DW0, true); // acquisizione degli status processStatus(); // processing degli strobes processStrobe(); } else if (ciclo == gatherCycle.MF) { resetDebugConsole(); // leggo parametri a media freq (dati globali, path, assi, Unità Operatrice) getGlobalData(); getUnOp(); getPath(); getAxis(); // se NON in modalità PROD eseguo chiamate "extra" x allarmi if (utils.CRS("mode") == "debug") { // SOLO in modalità testing forzo il controllo continuo allarmi... forceAlarmCheck(); } // salva richiesta update x dati debug showDebugData = true; } // ciclo lento else if (ciclo == gatherCycle.LF) { // leggo EVENTUALI parametri da config file getConfigParam(); ///acquisisco dati su programma in esecuzione e dati generali (stato, orologio, power...) getSlowChangingData(); // eventuale log! if (utils.CRB("recTime")) logTimeResults(); } // ciclo lentissimo else if (ciclo == gatherCycle.VLF) { lg.Info("Richiesta lettura completa allarmi attivi"); // faccio comunque rilettura completa allarmi... forceAlarmCheck(); } } if (showDebugData) { // verifica se debba salvare e mostrare dati checkSavePersDataLayer(); } // INVIO dati variati! 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()); } } public void resetDebugConsole() { // resetto console debug... parentForm.dataMonitor_1 = ""; parentForm.dataMonitor_2 = ""; parentForm.dataMonitor_3 = ""; // indico msg allarme NON inviati alarmMsgDispl = false; } /// /// recupero dati globali (e comuni) /// public virtual void getGlobalData() { // accodo dati path in DataMonitor...... StringBuilder sb1 = new StringBuilder(); StringBuilder sb2 = new StringBuilder(); // dati base... sb1.AppendLine(string.Format("POWER {0}: | EmStop:{1:N3} | ProcSel: {2}", mPower.Value, mEStop.Value, mProcSel.Value)); // leggo dati globali... readGlobalData(); // legge overrides... readOverrides(ref sb1); procCncAlarm(); // accodo dati base! parentForm.dataMonitor_1 += sb1.ToString(); // accodo dati UT... for (int i = 0; i < currAdpConf.nUnOp; i++) { sb2.AppendLine(string.Format("UT: ToolId {0} | VitaRes {1} | TipoVita {2} ", vettUnOp[i].mUnOpToolId.Value, vettUnOp[i].mUnOpVitaRes.Value, vettUnOp[i].mUnOpVitaResType.Value)); } parentForm.dataMonitor_2 = sb2.ToString(); // gestisco lettura dati manutenzione da PLC... getMtzDataFromPlc(); // gestisco lettura dati status da PLC... getStatusDataFromPlc(); // gestisco lettura dati analogici da PLC... getAnalogDataFromPlc(); } /// /// Legge dati globali... /// public virtual void readGlobalData() { } /// /// legge dati override... /// /// /// public virtual bool readOverrides(ref StringBuilder sb1) { bool fatto = false; return fatto; } /// /// processa allarmi CNC... /// public virtual bool procCncAlarm() { bool fatto = false; return fatto; } /// /// Gestione lettura dati manutenzione /// public virtual bool getMtzDataFromPlc() { bool fatto = false; return fatto; } /// /// Gestione lettura dati analogici /// public virtual bool getAnalogDataFromPlc() { bool fatto = false; return fatto; } /// /// Gestione lettura dati status da PLC /// public virtual bool getStatusDataFromPlc() { bool fatto = false; return fatto; } /// /// Processa i dati di override di un path /// /// idx path (zero based) /// vettore 7 valori dei dati (valori int16 jog/feed/rapid/spindle[1..4]) /// StringBuilder da aggiornare public bool procPathOverride(int currIdx, ushort[] dataVector, ref StringBuilder sb) { bool fatto = false; try { // prendo quella GLOBALE... vettPath[currIdx].mPathFeed.Value = FeedRate; // leggo da vettore... CABLATO DIVISO PER 100!!! vettPath[currIdx].mPathJogOver.Value = dataVector[0] / 100; vettPath[currIdx].mPathFeedOver.Value = dataVector[1] / 100; vettPath[currIdx].mPathRapidOver.Value = dataVector[2] / 100; vettPath[currIdx].mPathSpindleOver_01.Value = dataVector[3] / 100; vettPath[currIdx].mPathSpindleOver_02.Value = dataVector[4] / 100; vettPath[currIdx].mPathSpindleOver_03.Value = dataVector[5] / 100; vettPath[currIdx].mPathSpindleOver_04.Value = dataVector[6] / 100; // SE il processo è quello corrente... string processo = string.Format("P{0}", currIdx + 1); if (mProcSel.Value.ToString() == processo) { // se da conf richeisto salvo override globale come max tra i 4 letti... if (utils.CRB("getMaxSpOver")) { int maxSpeedOver = 0; maxSpeedOver = ((dataVector[3] / 100) > maxSpeedOver) ? dataVector[3] / 100 : maxSpeedOver; maxSpeedOver = ((dataVector[4] / 100) > maxSpeedOver) ? dataVector[4] / 100 : maxSpeedOver; maxSpeedOver = ((dataVector[5] / 100) > maxSpeedOver) ? dataVector[5] / 100 : maxSpeedOver; maxSpeedOver = ((dataVector[6] / 100) > maxSpeedOver) ? dataVector[6] / 100 : maxSpeedOver; // includo lettura override spindle... è la massima tra quelle che ho letto (dai path) SpeedRateOver = maxSpeedOver; } } // salvo stringa! sb.AppendLine(string.Format("P{0} - Override % Jog | Feed | Rapid: {1} | {2} | {3}", currIdx + 1, dataVector[0] / 100, dataVector[1] / 100, dataVector[2] / 100)); sb.AppendLine(string.Format("P{0} - Override % Spindle 1 | 2 | 3 | 4: {1} | {2} | {3} | {4}", currIdx + 1, dataVector[3] / 100, dataVector[4] / 100, dataVector[5] / 100, dataVector[6] / 100)); fatto = true; } catch { } return fatto; } /// /// riporta il log di tutti i dati di results temporali registrati /// 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)); } } /// /// verifico se ho dati M/S/T e li invio nel caso /// 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); } } } /// /// Metodo base connessione... /// public virtual void tryConnect() { } /// /// Metodo base disconnessione... /// public virtual void tryDisconnect() { } protected bool _connOk = false; /// /// Salva verifica stato connessione OK /// /// public virtual bool connectionOk { get { return _connOk; } set { _connOk = value; } } #region gestione allarmi /// /// effettua ogni log period una rilettura di TUTTI gli allarmi... /// 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(); } /// /// Effettua refresh del vettore privato degli allarmi attivi /// /// flag mask degli allarmi da aggiornare /// boolean: se si debba tornare ACK 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); } } } /// /// Scrive vettore ACK degli allarmi /// /// /// public virtual bool writeAlarmAck(ref byte[] retACK_DW0) { return false; } /// /// Legge vettore di TUTTE memorie tipo DWord dato vettore memorie (completo) /// /// /// public virtual bool readAllAlarms(ref uint[] MemBlock) { return false; } /// /// Legge vettore di TUTTE memorie tipo DWord dato indice di partenza e vettore memorie /// /// /// /// public virtual bool readAlarmBlock(ref uint[] MemBlock, int blockIndex) { return false; } #endregion #region gestione altri strobe/ack /// /// Invia (se necessario) il watchdog di stato in vita... blink 0/1 ogni secondo /// public void sendWatchDog() { bool setFlag = false; // 2017.07.24 gestisco 32 bit perché c'è la aprte finale del doppio watchdog incrociato... byte[] retACK_DW = new byte[4]; //// COPIO! //retACK_DW = BitConverter.GetBytes(Convert.ToUInt32(ACK_DW2)); // gestione su ultimi 2 bit della DW2 STR/ACK: il PRIMO bit è gestito in master da ADAPTER, il secondo da PLC; in primis io COPIO il valore del bit finale (di cui è slave...) retACK_DW = utils.setBitOnStFlag(retACK_DW, STRB_DW2.HasFlag(StFlag32.B31), 31); // ...poi gestisco il penultimo bit di cui è master... if (STRB_DW2.HasFlag(StFlag32.B30) == ACK_DW2.HasFlag(StFlag32.B30)) { // ... SE in ingresso ho strobe uguale lo cambio!!! retACK_DW = utils.setBitOnStFlag(retACK_DW, !ACK_DW2.HasFlag(StFlag32.B30), 30); } else { retACK_DW = utils.setBitOnStFlag(retACK_DW, ACK_DW2.HasFlag(StFlag32.B30), 30); } // 2016.10.18 aggiungo scrittura del bit di "watchdog" al primo bit della DW2... come resto tra secondi / 2 if (utils.CRB("sendWatchDog")) { int resto = 0; Math.DivRem(DateTime.Now.Second / utils.CRI("cycleWatchDog"), 2, out resto); setFlag = resto != 0; // se watchdog è cambiato lo invio, altrimenti lascio come è... if (setFlag != lastWatchDog) { lastWatchDog = setFlag; } retACK_DW = utils.setBitOnStFlag(retACK_DW, setFlag, 0); // imposto primo bit!!! // scrivo su area PLC SE variato if (ACK_DW2 != (StFlag32)BitConverter.ToUInt32(retACK_DW, 0)) { inizio = DateTime.Now; writeWatchDog(ref retACK_DW); if (utils.CRB("recTime")) TimingData.addResult(string.Format("W{0}-WatchDog", retACK_DW.Length), DateTime.Now.Subtract(inizio).Ticks); } } } /// /// Scrive watchdog /// /// /// public virtual bool writeWatchDog(ref byte[] retACK_DW) { return false; } #endregion /// /// recupero dati PATH /// 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; } } /// /// Recupero dati Unità Operatrici / Mandrini /// public virtual void getUnOp() { } /// /// Processing dati UnOp /// /// public void procUnOp(byte[] unOpSpeedMem) { StringBuilder sb = new StringBuilder(); int numUnOp = currAdpConf.nUnOp; int locSpeedRate = 0; // cicl su path x leggere le velocità dell'UnOp for (int i = 0; i < numUnOp; i++) { // leggo valore Codice locSpeedRate = BitConverter.ToUInt16(unOpSpeedMem, 2 * i); // leggo 41° byte = indice 40 + 2*i x le var del carico UnOp UnOpLoad = unOpSpeedMem[40 + i]; // eventuale fix bigEndian... if (hasBigEndian) { locSpeedRate = Endian.SwapUInt16((ushort)locSpeedRate); } 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, locSpeedRate, UnOpLoad, SpeedRateOver)); } parentForm.dataMonitor_2 += sb.ToString(); } /// /// recupero dati ASSI /// public virtual void getAxis() { } /// /// Gestione STROBE --> ACK per codici M/S/T /// /// byte di strobe corrente /// 0/1/2 /// vettore da restituire di ACK /// shift memoria x buffer dati da leggere /// Vettore completo dei valori + buffer code M/S/T /// Quale coda: M/S/T /// Path (0,1,...) public void gestStrobeCodMST(StFlag8 currStrobe, int bitNum, ref byte[] retACK_DW1, int memShift, byte[] MemBlock, string Coda, int idxPath) { UInt16 numEv = 0; UInt16 codEv = 0; if (currStrobe.HasFlag((StFlag8)Math.Pow(2, bitNum))) { // verifico sia > 0 il numero di valori da leggere - indice 0 sull'area... numEv = BitConverter.ToUInt16(MemBlock, 2 * memShift); // se è bigEndian devo swappare! if (hasBigEndian) { numEv = Endian.SwapUInt16(numEv); } if (numEv > 0) { // il num ev rappresenta quanti slot 16bit (da 2 byte) sono stati valorizzati, VA FATTO CICLO E LETTI TUTTI for (int i = 0; i < numEv; i++) { // leggo valore Codice codEv = BitConverter.ToUInt16(MemBlock, 2 * (1 + saltoMST + i + memShift)); if (hasBigEndian) { codEv = Endian.SwapUInt16(codEv); } // accodo evento Codice appendCodeMST(Coda, codEv.ToString(), idxPath); } } // memorizzo allarme nel vettore ack.... retACK_DW1 = utils.setBitOnStFlag(retACK_DW1, true, bitNum); } } /// /// Gestione strobe UserAction: salva dati e gestione ACK /// /// /// /// /// /// 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); } } /// /// Ricarica dati da file di scambio con CMSConnect /// 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(); 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 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; } } } /// /// verifica gli status attivi /// 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(); } } /// /// Processa status del path 01... /// 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()); } /// /// Processa status del path 02... /// 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()); } /// /// Salva i valori per il path indicato SE variati... /// /// /// /// /// /// 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; } } /// /// processo tutti gli strobe attivi /// public virtual void processStrobe() { // ...da gestire su ogni adapter... } /// /// Processa strobe x un dato path /// /// path corrente /// Byte di strobe del path corrente /// Byte di strobe del path corrente /// indice x lettura memoria MST del path /// indice x scrittura ACK x path /// stringa COMPLESSIVA azioni utente public void procPathStrobes(int idxPath, StFlag8 currStrobe, StFlag8 currAck, int memIndexMST, int memIndexAck, ref string UserAction) { // byte di strobe e di acknowledge... inizializzo!!! byte[] currACK_DW = new byte[1]; // altre variabili int bitNum = 0; inizio = DateTime.Now; // incomincio vera e propria gestione... try { // controllo TUTTI i flag: se ce ne sono di alzati DEVO processare... if (currStrobe != StFlag8.NONE) { // se ho un M/S/T leggo area... if (currStrobe.HasFlag(StFlag8.B0) || currStrobe.HasFlag(StFlag8.B1) || currStrobe.HasFlag(StFlag8.B2)) { // leggo memoria (direttamente a Byte...)! readMST_data(idxPath, memIndexMST, ref MemBlock_MST); // check COD_M bitNum = 0; gestStrobeCodMST(currStrobe, bitNum, ref currACK_DW, 0, MemBlock_MST, "M", idxPath); // check COD_S bitNum = 1; gestStrobeCodMST(currStrobe, bitNum, ref currACK_DW, 11 + saltoMST, MemBlock_MST, "S", idxPath); // check COD_T bitNum = 2; gestStrobeCodMST(currStrobe, bitNum, ref currACK_DW, 17 + 2 * saltoMST, MemBlock_MST, "T", idxPath); } // check FILE DATI MODIFICATO: ricaricare... bitNum = 3; if (STRB_DW1.HasFlag((StFlag32)Math.Pow(2, bitNum))) { lg.Info("Notifica file modificato"); try { // reload dati da file... reloadDataFromFile(); // memorizzo allarme nel vettore ack.... currACK_DW = utils.setBitOnStFlag(currACK_DW, true, bitNum); } catch { lg.Info("Errore lettura dati da file"); } } // AREA strobe USER ACTION // chiamato Start... bitNum = 4; gestStrobeUserAction(idxPath, bitNum, ref currACK_DW, ref UserAction, string.Format(" (P{0:00} START) ", idxPath + 1)); // chiamato Stop... bitNum = 5; gestStrobeUserAction(idxPath, bitNum, ref currACK_DW, ref UserAction, string.Format(" (P{0:00} STOP) ", idxPath + 1)); // chiamato Reset... bitNum = 6; gestStrobeUserAction(idxPath, bitNum, ref currACK_DW, ref UserAction, string.Format(" (P{0:00} RESET) ", idxPath + 1)); } else { // inizializzo 4 byte a zero!!! currACK_DW = new byte[1]; } } catch (Exception exc) { lg.Error(string.Format("Errore in strobe:{0}{1}", Environment.NewLine, exc)); } // scrivo update ad ack SE VARIATO!!! if (currAck != (StFlag8)currACK_DW[0]) { writeMST_ACK(memIndexAck, ref currACK_DW); } } /// /// Verifica strobe autotest /// /// /// /// 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); } } /// /// Recupero info su test: numero + elenco parametri IN/OUT /// /// /// 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; } /// /// Effettua lettura dati TESTING /// /// /// public virtual bool readTestData(ref uint[] MemBlockTestData) { bool fatto = false; return fatto; } /// /// Legge area memoria dati MST /// /// /// /// /// public virtual bool readMST_data(int idxPath, int memIndexMST, ref byte[] MemBlock_MST) { bool fatto = false; return fatto; } /// /// Scrive ACK x dati MST /// /// /// /// /// public virtual bool writeMST_ACK(int memIndexAck, ref byte[] currACK_DW) { bool fatto = false; return fatto; } /// /// processo il vettore LOCALE degli allarmi /// 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; } } } } } } /// /// Classe fittizia in caso di processing GLOBALE di tutto in 1 solo colpo... /// public virtual void processAllMemory() { } /// /// metodo di recupero dei dati di identificativo macchina - DA CONF!!! /// public virtual void getConfigParam() { } /// /// dati "lenti" relativi al device /// 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); } /// /// recupero di TUTTI gli strobes/status attivi /// public virtual void getStrobeAndAckStatus() { // da gestire su ogni adapter... legge tutto array STROBE!!! } /// /// Processa la tabella di memoria dei dati di manutenzione /// /// /// 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.addValue(DateTime.Now, Convert.ToInt32(tabDatiMtz[i])); } else if (maintData[i].varName == "ACC_TIME_WORK") { istOreMaccLav.addValue(DateTime.Now, Convert.ToInt32(tabDatiMtz[i])); } else if (maintData[i].varName == "SlittaTastatore_Count") { istSlittaTast.addValue(DateTime.Now, Convert.ToInt32(tabDatiMtz[i])); } else if (maintData[i].varName.StartsWith("Counter_")) { try { numero = Convert.ToInt32(maintData[i].varName.Replace("Counter_", "")); } catch { } if (numero > 0 && istCounters.Length >= numero) { istCounters[numero - 1].addValue(DateTime.Now, Convert.ToInt32(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.Length >= numero) { 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.Length >= numero) { istDistMovAssi[numero - 1].addValue(DateTime.Now, Convert.ToInt32(tabDatiMtz[i])); } } else if (maintData[i].varName.EndsWith("_Invers")) { try { numero = Convert.ToInt32(maintData[i].varName.Replace("Axis_", "").Replace("_Invers", "")); } catch { } if (numero > 0 && istNumInvAssi.Length >= numero) { // 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].addValue(DateTime.Now, Convert.ToInt32(valRead)); } } else if (maintData[i].varName.EndsWith("_AccTime")) { try { numero = Convert.ToInt32(maintData[i].varName.Replace("Axis_", "").Replace("_AccTime", "")); } catch { } if (numero > 0 && istAccTimeAssi.Length >= numero) { // 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].addValue(DateTime.Now, Convert.ToInt32(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.Length >= numero) { istGiriElettrom[numero - 1].addValue(DateTime.Now, Convert.ToInt32(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.Length >= numero) { istNumCambiUt[numero - 1].addValue(DateTime.Now, Convert.ToInt32(tabDatiMtz[i])); } } else if (maintData[i].varName.EndsWith("_NumCU")) { try { numero = Convert.ToInt32(maintData[i].varName.Replace("UnOp_", "").Replace("_NumCU", "")); } catch { } if (numero > 0 && istNumCambiUt.Length >= numero) { istNumCambiUt[numero - 1].addValue(DateTime.Now, Convert.ToInt32(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.Length >= numero) { istVacPumpWrkTime[numero - 1].addValue(DateTime.Now, Convert.ToInt32(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.Length >= numero) { istVacActCount[numero - 1].addValue(DateTime.Now, Convert.ToInt32(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.Length >= numero) { istLubroCount[numero - 1].addValue(DateTime.Now, Convert.ToInt32(tabDatiMtz[i])); } } else if (maintData[i].varName.EndsWith("_Count")) { try { numero = Convert.ToInt32(maintData[i].varName.Replace("Lubro_", "").Replace("_Count", "")); } catch { } if (numero > 0 && istLubroCount.Length >= numero) { istLubroCount[numero - 1].addValue(DateTime.Now, Convert.ToInt32(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.Length >= numero) { istSlittaMag[numero - 1].addValue(DateTime.Now, Convert.ToInt32(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.Length >= numero) { istProtMag[numero - 1].addValue(DateTime.Now, Convert.ToInt32(tabDatiMtz[i])); } } } } } /// /// Processa la tabella di memoria dei dati analogici /// /// /// public void processAnalogData(uint[] tabDatiAnag, otherData[] analogData) { // uno ad uno vado a inserirli nella mappa dei dati dell'adapter... StringBuilder sb = new StringBuilder(); double analogVal = 0; for (int i = 0; i < analogData.Length; i++) { // gestisco in modalità "lazy" qualsiasi variabile (dividendo x opportuno fattore conversione...) try { analogVal = ((double)tabDatiAnag[i]) / utils.CRI("fattDecVA"); } catch (Exception exc) { analogVal = 0; lg.Error(string.Format("Errore in recupero valore analogico:{0}parametro: {1}{0}i: {2}{0}Exc: {3}", Environment.NewLine, analogData[i].varName, i, exc)); } // salvo vettore eventi... mAnalogDataSamples[i].Value = analogVal; // accodo ultimi codici in visualizzazione... sb.AppendLine(string.Format("{0}", mAnalogDataSamples[i]).Replace("|", " | ")); } // aggiungo i vari analogici rilevati parentForm.dataMonitor_3 += sb.ToString(); } /// /// processa dataLayer e se necessario salva/mostra /// 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 = procCounters(needSave); needSave = procMovTotAssi(needSave); needSave = procAccTimeAssi(needSave); needSave = procNumInvAssi(needSave); needSave = procVacPump(needSave); needSave = procVacAct(needSave); needSave = procLubro(needSave); needSave = procSlittaMag(needSave); needSave = procProtMag(needSave); // salvo se necessario! if (needSave) parentForm.persistData(); // ------------------------------------------- } } /// /// Processa la tabella di memoria degli status di manutenzione /// /// /// public void processStatusData(byte[] tabDatiStatus, otherData[] statusData) { int bitNum = 0; int byteNum = 0; byte byteVal; StringBuilder sb = new StringBuilder(); // uno ad uno vado a inserirli nella mappa dei dati dell'adapter... int numero = 0; string status = ""; 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"; } // gestione AGGIUNTIVA vettori memorie "vecchie" per retrocompatibilità... 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; } } } // salvo vettore eventi... mStatusEvents[i].Value = status; // accodo ultimi codici in visualizzazione... sb.AppendLine(string.Format("{0}", mStatusEvents[i]).Replace("|", " | ")); //sb.AppendLine(string.Format("STS | {0}", mStatusEvents[i]).Replace("|", " | ")); } // aggiungo i vari status rilevati parentForm.dataMonitor_2 += sb.ToString(); } /// /// procedura di lettura (multistep) dati da memoria x caricare dati utensile /// /// num max di teste da recuperare public virtual void getDatiUt(int maxNumOp) { // variabili "Indice" utensile e famiglia da decodificare + utils int maxMemAddr = numMemUt; byte[] elencoUtMem = new byte[2 * 20]; byte[] tabUt_UT = new byte[2 * maxMemAddr]; byte[] tabFam_FamUt = new byte[2 * maxMemAddr]; // altre variabili ushort[] idUtMontato = new ushort[maxNumOp]; ushort[] idFamUt = new ushort[maxNumOp]; int[] idTipoVitaUt = new int[maxNumOp]; uint[] valVitaUtRes = new uint[maxNumOp]; ushort[] tabUt = new ushort[maxMemAddr]; ushort[] tabFamUt = new ushort[maxMemAddr]; int memIndex = 0; byte[] int32Mem = new byte[4]; byte[] int16Mem = new byte[2]; byte int8Mem = new byte(); bool found = false; // step 1: lettura ID dell'utensile x ogni testa... leggo area memoria degli UT montati memIndex = getDatiUt_step1(ref elencoUtMem); // decodifica da byte a int16 dell'ID Utensile for (int i = 0; i < maxNumOp; i++) { idUtMontato[i] = BitConverter.ToUInt16(elencoUtMem, 2 * i); } // step 2a: leggo vettore memoria dei maxMemAddr(200) UT in Tabella Utensili memIndex = getDatiUt_step2a(ref tabUt_UT); // decodifico TUTTI i maxMemAddr utensili for (int i = 0; i < maxMemAddr; i++) { tabUt[i] = BitConverter.ToUInt16(tabUt_UT, 2 * i); } // step 2b: devo cercare l'UT di ogni UnOp nella Tabella Utensili for (int i = 0; i < maxNumOp; i++) { // poiché potrei trovarlo replicato dopo la prima volta che lo trovo evito di ricontrollare... found = false; // spazzo la tab Utensili x cercare quelli delle UnOp... for (int j = 0; j < maxMemAddr; j++) { // controllo, se l'id utensile è quello dell'attuale UnOp... if (tabUt[j] == idUtMontato[i] && !found) { // leggo FamUt puntuale.. memIndex = getDatiUt_step2b(ref int16Mem, j); // step 2b: leggo puntualmente la FamUt dal suo indice... idFamUt[i] = BitConverter.ToUInt16(int16Mem, 0); found = true; } } } // step 3a: leggo vettore memoria dei maxMemAddr(200) FamUT in Tabella Famiglie Utensili (x ricavare unità misura vita) memIndex = getDatiUt_step3a(ref tabFam_FamUt); // decodifico TUTTI i maxMemAddr utensili for (int i = 0; i < maxMemAddr; i++) { tabFamUt[i] = BitConverter.ToUInt16(tabFam_FamUt, 2 * i); } // step 3b: devo cercare la famiglia dell'UT di ogni UnOp nella Tabella Famiglie for (int i = 0; i < maxNumOp; i++) { // poiché potrei trovarlo replicato dopo la prima volta che lo trovo evito di ricontrollare... found = false; // spazzo la tab Utensili x cercare quelli delle UnOp... for (int j = 0; j < maxMemAddr; j++) { // controllo, se l'id utensile è quello dell'attuale UnOp... if (tabFamUt[j] == idFamUt[i] && !found) { // leggo FamUt puntuale.. memIndex = getDatiUt_step3b(ref int8Mem, j); // step 3b: leggo puntualmente il TIPO DI vita UT dal suo indice... idTipoVitaUt[i] = int8Mem; found = true; } } } // step 4: recupero la vita residua dell'utensile for (int i = 0; i < maxNumOp; i++) { // poiché potrei trovarlo replicato dopo la prima volta che lo trovo evito di ricontrollare... found = false; // spazzo la tab Utensili x cercare quelli delle UnOp... for (int j = 0; j < maxMemAddr; j++) { // controllo, se l'id utensile è quello dell'attuale UnOp... if (tabUt[j] == idUtMontato[i] && !found) { // leggo FamUt puntuale.. memIndex = getDatiUt_step4(ref int32Mem, j); // leggo puntualmente valore della vita ut residua da indice utensile... valVitaUtRes[i] = BitConverter.ToUInt32(int32Mem, 0); found = true; } } } // salvo in adapter vita UT residua... for (int i = 0; i < maxNumOp; i++) { 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; } } /// /// Procedura di processing lettura memoria x DatiUt - Step 4 /// /// /// /// 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; } /// /// Procedura di processing lettura memoria x DatiUt - Step 3b /// /// /// /// 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; } /// /// Procedura di processing lettura memoria x DatiUt - Step 3a /// /// /// 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; } /// /// Procedura di processing lettura memoria x DatiUt - Step 2b /// /// /// /// 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; } /// /// Procedura di processing lettura memoria x DatiUt - Step 2a /// /// /// 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; } /// /// Procedura di processing lettura memoria x DatiUt - Step 1 /// /// /// 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() { } /// /// FeedRate globale /// public int FeedRate { get; set; } /// /// FeedRate di gruppo MAX 20!!! /// public int[] FeedRateGrp { get; set; } /// /// SpeedRate mandrino globale /// public int SpeedRate { get; set; } /// /// OVERRIDE FeedRate globale /// public int FeedRateOver { get; set; } /// /// OVERRIDE dei rapidi /// public int RapidOver { get; set; } /// /// OVERRIDE SpeedRate mandrino globale /// public int SpeedRateOver { get; set; } /// /// LOAD mandrino globale /// public int UnOpLoad { get; set; } /// /// recupera Vettore completo PosAct (fare override!) /// public virtual position PosAct { get { position answ = new position(); return answ; } } /// /// recupera pezzi OK (fare override!) /// public virtual int getNumPzOk { get { int answ = 0; return answ; } } /// /// recupera pezzi KO (fare override!) /// public virtual int getNumPzKo { get { int answ = 0; return answ; } } /// /// Aggiunge nel vettore coda codici M /// /// /// Codice da accodare /// Path (0,1,...) 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; } } /// /// recupera primo elemento coda M /// /// Path (0,1,...) /// 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; } /// /// recupera primo elemento coda S /// /// Path (0,1,...) /// 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; } /// /// recupera primo elemento coda T /// /// Path (0,1,...) /// 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 /// /// Processing delle variabili generiche Counters /// /// /// public bool procCounters(bool needSave) { uint delta = 0; uint valore = 0; StringBuilder sb = new StringBuilder(); for (int i = 0; i < mCounters.Length; i++) { // procedo solo SE HO FINESTRA VALIDA... if (istCounters[i].vcValid) { valore = Convert.ToUInt32(istCounters[i].vcMedian); if (valore >= currCounters[i]) { delta = valore - currCounters[i]; // controllo delta < 50% max... if (delta < uint.MaxValue / 2) { //processo comunque sempre... uint contTot = updateValUIntByIncr(i, delta, "Counter_{0:000}"); // passo valore totale all'adapter mCounters[i].Value = contTot; // controllo valore riferimento... if (delta > 0) { // segnalo necessità salvataggio! needSave = true; } } } // ...aggiorno valore riferimento... currCounters[i] = valore; } sb.AppendLine(mCounters[i].ToString().Replace("|", " | ")); } // salvo su maschera... parentForm.dataMonitor_2 += sb.ToString(); return needSave; } /// /// Processing delle ore macchina ACCESA /// /// /// public bool procOreMaccOn(bool needSave) { double delta = 0; double valore = 0; StringBuilder sb = new StringBuilder(); if (istOreMaccOn.vcValid) { valore = istOreMaccOn.vcMedian; if (valore >= contOreMaccOn) { delta = valore - contOreMaccOn; // controllo delta < 50% max... if (delta < double.MaxValue / 2) { // processo comunque sempre... double contatore = updateValDoubleByIncr(0, delta, "ACC_TIME"); currAdpConf.ContOreMaccOn += delta; // salvo valore su persistent layer mAccTime.Value = contatore.ToString("0.000", CultureInfo.InvariantCulture); // controllo incremento... if (delta > 0) { // segnalo necessità salvataggio! needSave = true; } } } // ...aggiorno valore riferimento... contOreMaccOn = valore; } // salvo su maschera... sb.AppendLine(string.Format("ACC_TIME: {0}", mAccTime.Value)); parentForm.dataMonitor_1 += sb.ToString(); return needSave; } /// /// Processing delle ore macchina IN LAVORO /// /// /// public bool procOreMaccLav(bool needSave) { double delta = 0; double valore = 0; StringBuilder sb = new StringBuilder(); if (istOreMaccLav.vcValid) { valore = istOreMaccLav.vcMedian; if (valore >= contOreMaccLav) { delta = valore - contOreMaccLav; // controllo delta < 50% max... if (delta < double.MaxValue / 2) { double contatore = updateValDoubleByIncr(0, delta, "ACC_TIME_WORK"); currAdpConf.ContOreMaccLav += delta; // salvo valore su persistent layer mAccTimeWork.Value = contatore.ToString("0.000", CultureInfo.InvariantCulture); // controllo valore riferimento... if (delta > 0) { // segnalo necessità salvataggio! needSave = true; } } } // ...aggiorno valore riferimento... contOreMaccLav = valore; } // salvo su maschera... sb.AppendLine(string.Format("ACC_TIME_WORK: {0}", mAccTimeWork.Value)); parentForm.dataMonitor_1 += sb.ToString(); return needSave; } /// /// Processing contatore Slitta Tastatore /// /// /// public bool procSlittaTast(bool needSave) { double delta = 0; double valore = 0; StringBuilder sb = new StringBuilder(); if (istSlittaTast.vcValid) { valore = istSlittaTast.vcMedian; if (valore >= contSlittaTast) { delta = valore - contSlittaTast; // controllo delta < 50% max... if (delta < double.MaxValue / 2) { double contatore = updateValDoubleByIncr(0, delta, "SlittaTastatore_Count"); currAdpConf.ContSlittaTast += delta; // salvo valore su persistent layer mSlittaTast.Value = contatore.ToString("0", CultureInfo.InvariantCulture); // controllo valore riferimento... if (delta > 0) { // segnalo necessità salvataggio! needSave = true; } } } // ...aggiorno valore riferimento... contSlittaTast = valore; } // salvo su maschera... sb.AppendLine(string.Format("SlittaTastatore_Count: {0}", mSlittaTast.Value)); parentForm.dataMonitor_1 += sb.ToString(); return needSave; } /// /// Processing del program name /// /// /// 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; } /// /// Processing del particolare /// /// /// 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; } /// /// Processing del num pz prodotti /// /// /// 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].vcMedian != currPathPartCount[i]) { if (istPathPartCount[i].vcMedian > currPathPartCount[i]) { uint delta = Convert.ToUInt32(istPathPartCount[i].vcMedian) - currPathPartCount[i]; uint contatore = updateValUIntByIncr(i, delta, "Path_{0:00}_PZ_TOT"); // passo valore num pz all'adapter vettPath[i].mPathPartCount.Value = contatore; } else // variato x difetto... azzero!!! { uint newVal = Convert.ToUInt32(istPathPartCount[i].vcMedian); updateValUInt(i, newVal, "Path_{0:00}_PZ_TOT"); // passo valore num pz all'adapter vettPath[i].mPathPartCount.Value = newVal; } // segnalo necessità salvataggio! needSave = true; // ...aggiorno valore riferimento... currPathPartCount[i] = Convert.ToUInt32(istPathPartCount[i].vcMedian); } 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; } /// /// Processing delle variabili sul numero giri mandrino (totali) /// /// /// public bool procGiriTotUnOp(bool needSave) { uint delta = 0; uint valore = 0; string outString = string.Format("UnOp_[1-{0}]_KRev: ", currAdpConf.nUnOp); for (int i = 0; i < currAdpConf.nUnOp; i++) { // procedo solo SE HO FINESTRA VALIDA... if (istGiriElettrom[i].vcValid) { valore = Convert.ToUInt32(istGiriElettrom[i].vcMedian); if (valore >= contGiriElettrom[i]) { delta = valore - contGiriElettrom[i]; // controllo delta < 50% max... if (delta < uint.MaxValue / 2) { // processo comunque sempre... uint contatore = updateValUIntByIncr(i, delta, "UnOp_{0:00}_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] = valore; } 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; } /// /// Processing delle variabili sul numero cambi utensile (totali) /// /// /// public bool procNumCU(bool needSave) { uint delta = 0; uint valore = 0; string outString = string.Format("UnOp_[1-{0}]_NumCU: ", currAdpConf.nUnOp); for (int i = 0; i < currAdpConf.nUnOp; i++) { // procedo solo SE HO FINESTRA VALIDA... if (istNumCambiUt[i].vcValid) { valore = Convert.ToUInt32(istNumCambiUt[i].vcMedian); if (valore >= currNumCambiUt[i]) { delta = valore - currNumCambiUt[i]; // controllo delta < 50% max... if (delta < uint.MaxValue / 2) { // processo comunque sempre... uint contatore = updateValUIntByIncr(i, delta, "UnOp_{0:00}_NumCU"); // passo valore num CU all'adapter vettUnOp[i].mUnOpNumCU.Value = contatore; // controllo valore riferimento... if (delta > 0) { // segnalo necessità salvataggio! needSave = true; } } } // ...aggiorno valore riferimento... currNumCambiUt[i] = valore; } 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; } /// /// Processing delle variabili sul totale m percorsi dagli assi /// /// /// public bool procMovTotAssi(bool needSave) { double delta = 0; uint valore = 0; string outString = string.Format("Axis_[1-{0}]_DistDone: ", currAdpConf.nAxis); for (int i = 0; i < currAdpConf.nAxis; i++) { // procedo solo SE HO FINESTRA VALIDA... if (istDistMovAssi[i].vcValid) { valore = Convert.ToUInt32(istDistMovAssi[i].vcMedian); if (valore >= contDistMovAssi[i]) { delta = valore - contDistMovAssi[i]; // controllo delta < 50% max... if (delta < double.MaxValue / 2) { // processo comunque sempre... double contTot = updateValDoubleByIncr(i, delta, "Axis_{0:00}_DistDone"); // passo valore totale all'adapter 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] = valore; } 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; } /// /// Processing delle variabili sul totale tempo lavoro degli assi /// /// /// public bool procAccTimeAssi(bool needSave) { double delta = 0; uint valore = 0; string outString = string.Format("Axis_[1-{0}]_AccTime: ", currAdpConf.nAxis); for (int i = 0; i < currAdpConf.nAxis; i++) { // procedo solo SE HO FINESTRA VALIDA... if (istAccTimeAssi[i].vcValid) { valore = Convert.ToUInt32(istAccTimeAssi[i].vcMedian); if (valore >= contAccTimeAssi[i]) { delta = valore - contAccTimeAssi[i]; // controllo delta < 50% max... if (delta < double.MaxValue / 2) { // salvo valore aggiuntivo x ore lavoro assi... double oreTot = updateValDoubleByIncr(i, delta, "Axis_{0:00}_AccTime"); 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] = valore; } 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; } /// /// Processing delle variabili sul totale num inversioni degli assi /// /// /// public bool procNumInvAssi(bool needSave) { long delta = 0; uint valore = 0; string outString = string.Format("Axis_[1-{0}]_InvDDone: ", currAdpConf.nAxis); for (int i = 0; i < currAdpConf.nAxis; i++) { // procedo solo SE HO FINESTRA VALIDA... if (istNumInvAssi[i].vcValid) { valore = Convert.ToUInt32(istNumInvAssi[i].vcMedian); if (valore >= contNumInvAssi[i]) { delta = valore - contNumInvAssi[i]; // controllo delta < 50% max... if (delta < long.MaxValue / 2) { // processo comunque sempre... long contTot = updateValLongByIncr(i, delta, "Axis_{0:00}_InvDDone"); // passo valore totale all'adapter vettAxis[i].mAxInvDDone.Value = contTot; // controllo valore riferimento... if (delta > 0) { // segnalo necessità salvataggio! needSave = true; } } } // ...aggiorno valore riferimento... contNumInvAssi[i] = valore; } 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; } /// /// Processing delle variabili sulle VacPump /// /// /// public bool procVacPump(bool needSave) { uint delta = 0; uint valore = 0; string outString = string.Format("VacPump_[1-{0}]_WrkTime: ", currAdpConf.nVacuumPump); for (int i = 0; i < currAdpConf.nVacuumPump; i++) { // procedo solo SE HO FINESTRA VALIDA... if (istVacPumpWrkTime[i].vcValid) { valore = Convert.ToUInt32(istVacPumpWrkTime[i].vcMedian); if (valore >= currVacPumpWrkTime[i]) { delta = valore - currVacPumpWrkTime[i]; // controllo delta < 50% max... if (delta < uint.MaxValue / 2) { // processo comunque sempre... uint contTot = updateValUIntByIncr(i, delta, "VacPump_{0:00}_WrkTime"); // passo valore totale all'adapter vettVacPump[i].mVacPumpWrkTime.Value = contTot; // controllo valore riferimento... if (delta > 0) { // segnalo necessità salvataggio! needSave = true; } } } // ...aggiorno valore riferimento... currVacPumpWrkTime[i] = valore; } 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; } /// /// Processing delle variabili sulle VacAct /// /// /// public bool procVacAct(bool needSave) { uint delta = 0; uint valore = 0; string outString = string.Format("VacPump_[1-{0}]_Count: ", currAdpConf.nVacuumPump); for (int i = 0; i < currAdpConf.nVacuumAct; i++) { // procedo solo SE HO FINESTRA VALIDA... if (istVacActCount[i].vcValid) { valore = Convert.ToUInt32(istVacActCount[i].vcMedian); if (valore >= currVacActCount[i]) { delta = valore - currVacActCount[i]; // controllo delta < 50% max... if (delta < uint.MaxValue / 2) { // processo comunque sempre... uint contTot = updateValUIntByIncr(i, delta, "VacAct_{0:00}_Count"); // passo valore totale all'adapter vettVacAct[i].mVacActCount.Value = contTot; // controllo valore riferimento... if (delta > 0) { // segnalo necessità salvataggio! needSave = true; } } } // ...aggiorno valore riferimento... currVacActCount[i] = valore; } 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; } /// /// Processing delle variabili sui componenti Lubro /// /// /// public bool procLubro(bool needSave) { uint delta = 0; uint valore = 0; string outString = string.Format("Lubro_[1-{0}]_Count: ", currAdpConf.nLubro); for (int i = 0; i < currAdpConf.nLubro; i++) { valore = Convert.ToUInt32(istLubroCount[i].vcMedian); if (valore > currLubroCount[i]) { delta = valore - currLubroCount[i]; // controllo delta < 50% max... if (delta < uint.MaxValue / 2) { //processo comunque sempre... uint contTot = updateValUIntByIncr(i, delta, "Lubro_{0:00}_Count"); // passo valore totale all'adapter vettLubro[i].mLubroNum.Value = contTot; // controllo valore riferimento... if (delta > 0) { // segnalo necessità salvataggio! needSave = true; } } // ...aggiorno valore riferimento... currLubroCount[i] = valore; } 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; } /// /// Processing delle variabili sui componenti SlittaMag /// /// /// public bool procSlittaMag(bool needSave) { uint delta = 0; uint valore = 0; string outString = string.Format("SlittaMagazzino_[1-{0}]_Count: ", currAdpConf.nSlittaMag); for (int i = 0; i < currAdpConf.nSlittaMag; i++) { // procedo solo SE HO FINESTRA VALIDA... if (istSlittaMag[i].vcValid) { valore = Convert.ToUInt32(istSlittaMag[i].vcMedian); if (valore >= currSlittaMag[i]) { delta = valore - currSlittaMag[i]; // controllo delta < 50% max... if (delta < uint.MaxValue / 2) { //processo comunque sempre... uint contTot = updateValUIntByIncr(i, delta, "SlittaMagazzino_{0:00}_Count"); // passo valore totale all'adapter vettSlittaMag[i].mSlittaMagCount.Value = contTot; // controllo valore riferimento... if (delta > 0) { // segnalo necessità salvataggio! needSave = true; } } } // ...aggiorno valore riferimento... currSlittaMag[i] = valore; } 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; } /// /// Processing delle variabili sui componenti ProtMag /// /// /// public bool procProtMag(bool needSave) { uint delta = 0; uint valore = 0; string outString = string.Format("ProtMagazzino_[1-{0}]_Count: ", currAdpConf.nProtMag); for (int i = 0; i < currAdpConf.nProtMag; i++) {// procedo solo SE HO FINESTRA VALIDA... if (istProtMag[i].vcValid) { valore = Convert.ToUInt32(istProtMag[i].vcMedian); if (valore >= currProtMag[i]) { delta = valore - currProtMag[i]; // controllo delta < 50% max... if (delta < uint.MaxValue / 2) { //processo comunque sempre... uint contTot = updateValUIntByIncr(i, delta, "ProtMagazzino_{0:00}_Count"); // passo valore totale all'adapter vettProtMag[i].mProtMagCount.Value = contTot; // controllo valore riferimento... if (delta > 0) { // segnalo necessità salvataggio! needSave = true; } } } // ...aggiorno valore riferimento... currProtMag[i] = valore; } 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 /// /// Dizionario di persistenza per i valori da salvare da/su file /// public Dictionary persistenceLayer; /// /// recupera valore salvato in persistence layer (se non c'è crea...) /// /// /// 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; } /// /// recupera valore salvato in persistence layer (se non c'è crea...) come UINT /// /// /// private uint getStoredValUInt(string keyVal) { uint answ = 0; try { answ = Convert.ToUInt32(getStoredVal(keyVal)); } catch (Exception exc) { lg.Error(string.Format("Eccezione in getStoredValUInt: {0}{1}", Environment.NewLine, exc)); } // verifico che il valore sia minore di 9/10 del valore massimo... answ = (answ < (uint.MaxValue / 10 * 9)) ? answ : 0; return answ; } /// /// recupera valore salvato in persistence layer (se non c'è crea...) come INT /// /// /// private long getStoredValLong(string keyVal) { long answ = 0; try { answ = Convert.ToInt64(getStoredVal(keyVal)); } catch { } // verifico che il valore sia minore di 9/10 del valore massimo... answ = (answ < (long.MaxValue / 10 * 9)) ? answ : 0; return answ; } /// /// recupera valore salvato in persistence layer (se non c'è crea...) come double /// /// /// private double getStoredValDouble(string keyVal) { double answ = 0; try { answ = Convert.ToDouble(getStoredVal(keyVal)); } catch (Exception exc) { lg.Error(string.Format("Eccezione in getStoredValDouble: {0}{1}", Environment.NewLine, exc)); } answ = (answ < (double.MaxValue / 10 * 9)) ? answ : 0; return answ; } /// /// Aggiorna un valore del dizionario in SOSTITUZIONE /// /// /// /// /// Nuovo valore incrementato 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; } /// /// Aggiorna un valore del dizionario in SOSTITUZIONE e lo restituisce /// /// /// /// /// Nuovo valore incrementato 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(); } /// /// Aggiorna un valore del dizionario in INCREMENTO e lo restituisce /// /// /// /// /// Nuovo valore incrementato 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; } /// /// Aggiorna un valore del dizionario in INCREMENTO e lo restituisce /// /// /// /// /// Nuovo valore incrementato 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; } /// /// Aggiorna un valore del dizionario in INCREMENTO e lo restituisce /// /// /// /// /// Nuovo valore incrementato 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 } }