using MTC; using MTConnect; using SCMA.AdapterCom; using System; namespace SCMA.AdapterPLC { public class Demo : Generic { DateTime nextChange; /// /// estende l'init della classe base... /// /// FORM chaimante /// CONFIGURAZIONE adapter /// OGGETTO gestione comunicazione OUT (tipologia e metodi) public Demo(MainForm caller, AdapterConf adpConf, Gateway gatewayObj) : base(caller, adpConf, gatewayObj) { // !!!HARD CODED!!! aggiunto banco STATUS del 2 processo IN CODA... (4+1)DW=20byte x strobes...!!! Strobes = new byte[20]; // fix dimensione memorie MST: 52 Byte = 26 short(16bit) x (12+7+7) aree (attenzione: secondo set di 2 bit è VUOTO...) MemBlock_MST = new byte[52]; saltoMST = 0; // è little endian (NON serve conversione) hasBigEndian = false; lg.Info("Start init Adapter DEMO all'IP {0}", utils.CRS("ipPLC")); // inizializzo posizioni assi... prevPosAxis = new double[adpConf.nAxis]; prevDirAxis = new int[adpConf.nAxis]; nextChange = DateTime.Now.AddSeconds(10); } /// /// Connessione sempre OK... /// /// public override bool connectionOk { get { return true; } } public override void startAdapter() { lg.Info("Start DEMO adapter"); base.startAdapter(); } public override void getSlowChangingData() { // recupero SEMPRE dati ulteriori: status ON/OFF, clock, ... currGateway.updateItemNodeValue("STATUS", parentForm.datiProd.Status); currGateway.updateItemNodeValue("ACC_TIME", parentForm.datiProd.AccTime); currGateway.updateItemNodeValue("OperatorId", parentForm.datiProd.Operator); currGateway.updateItemNodeValue("POWER", parentForm.datiProd.Power); currGateway.updateItemNodeValue("CLOCK", DateTime.Now.Date.ToFileTimeUtc()); } public override void getStrobeAndAckStatus() { base.getStrobeAndAckStatus(); byte[] newStrobes = new byte[20]; // per 50 sec/min (circa) simulo LAVORO... if (nextChange > DateTime.Now) { newStrobes[4] = 8; newStrobes[8] = 16; newStrobes[9] = 2; } else { // imposto cambio newStrobes[4] = 4; newStrobes[8] = 8; newStrobes[9] = 4; Random rand = new Random(); int numSec = rand.Next(7, 16); nextChange = DateTime.Now.AddSeconds(numSec); } Buffer.BlockCopy(newStrobes, 0, Strobes, 0, 20); // controllo bool allarmi... if (parentForm.datiProd.EmrStop) { currGateway.updateItemNodeValue("E_STOP", emStatus.TRIGGERED.ToString()); } else { currGateway.updateItemNodeValue("E_STOP", emStatus.ARMED.ToString()); } // imposto func mode... currGateway.updateItemNodeValue("FUNCT_MODE", parentForm.datiProd.FuncMode); // se ho un messaggio... if (parentForm.datiProd.MessageText.Length > 0) { currGateway.updateItemNodeCodeValue("MESSAGE", parentForm.datiProd.MessageCode, parentForm.datiProd.MessageText); } } public override void getConfigParam() { base.getConfigParam(); } public override void processStrobe() { // qui forzo la gestione di update dei path & co... getPath(); getUnOp(); getAxis(); } /// /// non fa nulla perché recupera allarmi in vettore al singolo cambio... /// /// /// public override void refreshAlarmState(StFlag32 Alarm2Refresh, bool giveAck) { base.refreshAlarmState(Alarm2Refresh, giveAck); } public override void getPath() { base.getPath(); PathData PtData = parentForm.CurrPath; } public override void getUnOp() { base.getUnOp(); UnOpData uoData = parentForm.CurrUnOp; if (uoData.UnOpSel >= 0) { currGateway.updateItemNodeValue(vettUnOp[uoData.UnOpSel].toolIdKey, uoData.UnOpToolId); currGateway.updateItemNodeValue(vettUnOp[uoData.UnOpSel].numCUKey, uoData.UnOpNumCU); currGateway.updateItemNodeValue(vettUnOp[uoData.UnOpSel].statusKey, uoData.UnOpStatus); currGateway.updateItemNodeValue(vettUnOp[uoData.UnOpSel].vitaResKey, uoData.UnOpVitaRes); currGateway.updateItemNodeValue(vettUnOp[uoData.UnOpSel].speedKey, uoData.UnOpSpeed); currGateway.updateItemNodeValue(vettUnOp[uoData.UnOpSel].loadKey, uoData.UnOpLoad); currGateway.updateItemNodeValue(vettUnOp[uoData.UnOpSel].accTimeKey, uoData.UnOpAccTime); } } public override void getAxis() { base.getAxis(); AxisData AxData = parentForm.CurrAxis; if (AxData.AxisSel >= 0) { // USO asse selezionato + dati visualizzati e di conseguenza aggiorno... currGateway.updateItemNodeValue(vettAxis[AxData.AxisSel].mainProcKey, AxData.AxisMainProc); } } } }