diff --git a/IOB-UT-NEXT/Enums.cs b/IOB-UT-NEXT/Enums.cs index 8e65d7e8..faa39363 100644 --- a/IOB-UT-NEXT/Enums.cs +++ b/IOB-UT-NEXT/Enums.cs @@ -362,6 +362,11 @@ namespace IOB_UT_NEXT /// ND, + /// + /// Adapter MITSUBISHI con EZCnc lib + /// + MITSUBISHI, + /// /// Adapter ModBus TCP generico /// diff --git a/IOB-WIN-NEXT/AdapterForm.cs b/IOB-WIN-NEXT/AdapterForm.cs index 8af62843..09ce9789 100644 --- a/IOB-WIN-NEXT/AdapterForm.cs +++ b/IOB-WIN-NEXT/AdapterForm.cs @@ -1,4 +1,5 @@ using IOB_UT_NEXT; +using IOB_WIN_NEXT.Iob; using IOB_WIN_NEXT.IobSoap; using MapoSDK; using Newtonsoft.Json; @@ -1690,6 +1691,11 @@ namespace IOB_WIN_NEXT start.Enabled = true; break; + case tipoAdapter.MITSUBISHI: + iobObj = new Mitsubishi(this, IOBConf); + start.Enabled = true; + break; + case tipoAdapter.MODBUS_TCP: iobObj = new IobModbusTCP.ModbusTCP(this, IOBConf); start.Enabled = true; diff --git a/IOB-WIN-NEXT/DATA/CONF/MAIN.ini b/IOB-WIN-NEXT/DATA/CONF/MAIN.ini index 39af00fa..7e44ab68 100644 --- a/IOB-WIN-NEXT/DATA/CONF/MAIN.ini +++ b/IOB-WIN-NEXT/DATA/CONF/MAIN.ini @@ -40,14 +40,15 @@ CLI_INST=SteamWareSim ;STARTLIST=PIZ10 ;STARTLIST=IMI_SOITAAB_Z2342_02 ;STARTLIST=IMI_GOMBA -;STARTLIST=PING ;STARTLIST=SIMUL_02 ;STARTLIST=SIM_DP_01 +;STARTLIST=FTP_SONATEST +;STARTLIST=L020 +;STARTLIST=PING +;STARTLIST=VL27 ;NB: mettere copy always ai file di conf x fare test... -;STARTLIST=FTP_SONATEST ;STARTLIST=SIMUL_01 -STARTLIST=VL27 -;STARTLIST=L020 +STARTLIST=VL28 MAXCNC=10 \ No newline at end of file diff --git a/IOB-WIN-NEXT/DATA/CONF/SIMUL_00.ini b/IOB-WIN-NEXT/DATA/CONF/SIMUL_00.ini deleted file mode 100644 index 887f5b73..00000000 --- a/IOB-WIN-NEXT/DATA/CONF/SIMUL_00.ini +++ /dev/null @@ -1,54 +0,0 @@ -;Configurazione IOB-WIN -[IOB] -CNCTYPE=SIMULA -PING_MS_TIMEOUT=500 -MinDeltaSec=5 - -[MACHINE] -VENDOR=STEAMWARE -MODEL=DEMO_SIMULATOR - -[CNC] -IP=127.0.0.1 -PORT=0000 - -[SERVER] -MPIP=http://10.74.82.218 -MPURL=/MP/IO -CMDBASE=/IOB/input/ -CMDFLOG=/IOB/flog/ -CMDALIVE=/IOB -CMDENABLED=/IOB/enabled/ -CMDADV1=?valore= -CMDREBO=/sendReboot.aspx?idxMacchina= - -[MEMORY] - -[BLINK] -MAX_COUNTER_BLINK = 15 -BLINK_FILT=0 - -[OPTPAR] -;PZCOUNT_MODE=STD.[PAR/MEM].info|BIT.indice -PZCOUNT_MODE=BIT -; per il simulatore: 50|1 = WAIT 50, DURATION 1 con riferimento al PERIODO base (PER_BASE in ms, default 1 secondo) -PER_BASE=10200 -SIM_PZCNT=5|1 -SIM_ALARM=500|40 -SIM_MANU=50|7 -;indica gestione e simulazione bit 5 --> slow/emergenza -SIM_SLOW=2500|10 -; indica simulazione delle funzionalità power ON/ OFF -SIM_POW_ON_OFF=true -T_ON=6 -T_OFF=22 - -[BRANCH] -NAME=master - -; Tags manuali -[TAGS] -Customer=Steamware -HostOS=WIN -HostName=IOB-WIN-SIMULA -HostAddr=10.74.82.76 diff --git a/IOB-WIN-NEXT/DATA/CONF/VL28.ini b/IOB-WIN-NEXT/DATA/CONF/VL28.ini new file mode 100644 index 00000000..9ad444c1 --- /dev/null +++ b/IOB-WIN-NEXT/DATA/CONF/VL28.ini @@ -0,0 +1,84 @@ +;Configurazione IOB-WIN +[IOB] +CNCTYPE=MITSUBISHI + +[MACHINE] +; VALVITAL 2024 +VENDOR=DMG MORI +MODEL=NLX4000 + +[CNC] +; FANUC! +IP=192.168.213.199 +PORT=683 +GETPRGNAME=true + +[SERVER] +MPIP=192.168.214.4 +MPURL=/MP/IO +CMDBASE=/IOB/input/ +CMDFLOG=/IOB/flog/ +CMDALIVE=/IOB +CMDENABLED=/IOB/enabled/ +CMDADV1=?valore= +CMDREBO=/sendReboot.aspx?idxMacchina= + +[MEMORY] +; Green Y62=10098 | Red: Y60=10096 | Yellow: Y61=10097 | Blue Y63=10099 | Emerg: ??? (negata???)| +;BIT0=CONN +BIT1=10098 +;BIT2=PZCOUNT.PAR.8002 +BIT3=10096 +BIT4=10097 +;BIT5=!X8.4 +AREAV_START=500 +AREAV_SIZE=3 +PAR_START=8001 +PAR_SIZE=3 +SIGN_START=10096 +SIGN_SIZE=4 + +[BLINK] +;MAX_COUNTER_BLINK = 30 +MAX_COUNTER_BLINK = 15 +;bit0 = 0 +;bit1 = 0 +;bit2 = 1 +;bit3 = 1 +;bit4 = 1 +;bit5 = 0 +;bit6 = 0 +;bit7 = 0 +BLINK_FILT=0 +;BLINK_FILT=28 + +[OPTPAR] +EZNC_SYS=EZNC_SYS_MELDAS700L +ENABLE_PZCOUNT=TRUE +;PZCOUNT_MODE=STD|BIT +;PZCOUNT_MODE=STD.PAR.6711 +;PZGTOT_MODE=STD.PAR.6712 +;;PZREQ_MODE=STD.PAR.6713 +PZCOUNT_MODE=STD.PAR.8002 +PZGTOT_MODE=STD.PAR.8001 +PZREQ_MODE=STD.PAR.8003 +ENABLE_PZ_REQ=TRUE +ENABLE_PZ_RESET=TRUE +ENABLE_PZ_RESET_stopSetup=FALSE +;gestione invio pezzi in blocco +ENABLE_SEND_PZC_BLOCK=TRUE +MIN_SEND_PZC_BLOCK=0 +MAX_SEND_PZC_BLOCK=100 +; conf cablata set Art/Commessa +SET_NUM_COM=STD.VAR.500 +SET_NUM_ART=STD.VAR.501 +SET_NUM_PZ=STD.VAR.502 +MAX_CHAR_DESC=7 +;indica se il numero articolo sia semplicemente il trim dei caratteri alfabetici (chiama comunque server...) +NUM_ART_CHR_TRIM=TRUE +; conf parametri memoria READ/WRITE +PARAM_CONF=VL28.json +DISABLE_SEND_WDST=TRUE + +[BRANCH] +NAME=master \ No newline at end of file diff --git a/IOB-WIN-NEXT/DATA/CONF/VL28.json b/IOB-WIN-NEXT/DATA/CONF/VL28.json new file mode 100644 index 00000000..3991bb77 --- /dev/null +++ b/IOB-WIN-NEXT/DATA/CONF/VL28.json @@ -0,0 +1,91 @@ +{ + "mMapWrite": { + "setArt": { + "name": "setArt", + "description": "Articolo", + "memAddr": "NONE.01", + "tipoMem": "String", + "index": 0, + "size": 20, + "displOrdinal": 1 + }, + "setArtNum": { + "name": "setArtNum", + "description": "# Num Articolo", + "memAddr": "MACRO.966", + "tipoMem": "Int", + "index": 966, + "size": 4, + "displOrdinal": 1 + }, + "setComm": { + "name": "setComm", + "description": "Commessa", + "memAddr": "NONE.02", + "tipoMem": "String", + "index": 0, + "size": 20, + "displOrdinal": 2 + }, + "setCommNum": { + "name": "setCommNum", + "description": "# NumCommessa", + "memAddr": "MACRO.965", + "tipoMem": "Int", + "index": 965, + "size": 4, + "displOrdinal": 2 + }, + "setPzComm": { + "name": "setPzComm", + "description": "Qta Richiesta", + "memAddr": "PAR.8003", + "tipoMem": "Int", + "index": 8003, + "size": 4, + "displOrdinal": 3 + } + }, + "mMapRead": { + "PZ_GTOT": { + "name": "PZ_GTOT", + "description": "Contatore GTot", + "memAddr": "", + "tipoMem": "Int", + "index": 0, + "size": 4, + "func": "MAX", + "period": 60, + "factor": 1, + "displOrdinal": 7 + }, + "PZ_COUNT": { + "name": "PZ_COUNT", + "description": "Contatore", + "memAddr": "", + "tipoMem": "Int", + "index": 0, + "size": 4, + "func": "MAX", + "period": 60, + "factor": 1, + "displOrdinal": 8 + }, + "PROG": { + "name": "PROG", + "description": "Programma", + "memAddr": "", + "tipoMem": "Int", + "index": 0, + "size": 4, + "func": "MAX", + "period": 60, + "factor": 1, + "displOrdinal": 9 + } + }, + "mMapWriteLink": { + "setArt": "setArtNum", + "setComm": "setCommNum" + } +} \ No newline at end of file diff --git a/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj b/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj index 99d0e358..e1c11d0a 100644 --- a/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj +++ b/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj @@ -444,6 +444,7 @@ + @@ -510,16 +511,10 @@ - - Always - + - - Always - - - Always - + + @@ -535,53 +530,28 @@ - - Always - - - Always - + + - - PreserveNewest - + - - PreserveNewest - - - Always - - - Always - - - Always - + + + + + - - Always - - - Always - - - Always - - - Always - - - Always - + + + + + - - Always - + @@ -608,6 +578,12 @@ + + Always + + + Always + @@ -617,12 +593,8 @@ - - Always - - - Always - + + @@ -639,9 +611,7 @@ - - Always - + @@ -700,9 +670,7 @@ - - Always - + Always @@ -853,9 +821,7 @@ - - Always - + @@ -878,12 +844,8 @@ - - Always - - - Always - + + @@ -947,51 +909,21 @@ Always - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - + + + + + + + + + + + + + + + Always @@ -1050,6 +982,17 @@ IOB-UT-NEXT + + + {1B93D6AF-FD32-4281-83FE-533F666FAE6C} + 1 + 0 + 0 + tlbimp + False + True + + "$(ProjectDir)setupTgt.bat" "$(ConfigurationName)" "$(ProjectDir)" diff --git a/IOB-WIN-NEXT/Iob/Fanuc.cs b/IOB-WIN-NEXT/Iob/Fanuc.cs index 90d1553f..80bcc677 100644 --- a/IOB-WIN-NEXT/Iob/Fanuc.cs +++ b/IOB-WIN-NEXT/Iob/Fanuc.cs @@ -24,6 +24,7 @@ namespace IOB_WIN_NEXT.Iob /// public Fanuc(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf) { + lgInfo("Start init Fanuc"); // i dati RAW principali sono 6 byte... RawInput = new byte[6]; @@ -89,7 +90,7 @@ namespace IOB_WIN_NEXT.Iob string memArea = ""; for (int i = 0; i < 8; i++) { - currBit = string.Format("BIT{0}", i); + currBit = $"BIT{i}"; memArea = fIni.ReadString("MEMORY", currBit, ""); // se trovo un valore... if (!string.IsNullOrEmpty(memArea)) @@ -103,7 +104,7 @@ namespace IOB_WIN_NEXT.Iob enablePzCountByIob = (getOptPar("ENABLE_PZCOUNT") == "TRUE"); disablePzCountByIob = (getOptPar("DISABLE_PZCOUNT") == "TRUE"); - // gestione override contatore articoli... + // gestione override idx articoli... if (!string.IsNullOrEmpty(getOptPar("NUM_ART_CHR_TRIM"))) { string NUM_ART_CHR_TRIM = getOptPar("NUM_ART_CHR_TRIM"); @@ -2036,7 +2037,7 @@ namespace IOB_WIN_NEXT.Iob int byte2check = 0; for (int i = 0; i < 8; i++) { - bKey = string.Format("BIT{0}", i); + bKey = $"BIT{i}"; // cerco se ci sia in LUT if (signLUT.ContainsKey(bKey)) { @@ -2376,13 +2377,11 @@ namespace IOB_WIN_NEXT.Iob lgTrace($"inizio getValByMemAddr | memAddr: {memAddr}"); string answ = ""; // verifico quale modalità sia richiesta: STD (6711) oppure BIT (Custom, con indicazione area) -#if true if (memAddr.StartsWith("STD")) { // inizio verifica area memoria/parametro levando prima parte codice memAddr = memAddr.Replace("STD.", ""); } -#endif // var di appoggio int cntAddr = 0; object outputVal = new object(); diff --git a/IOB-WIN-NEXT/Iob/Generic.cs b/IOB-WIN-NEXT/Iob/Generic.cs index c57311e5..795e8d09 100644 --- a/IOB-WIN-NEXT/Iob/Generic.cs +++ b/IOB-WIN-NEXT/Iob/Generic.cs @@ -735,6 +735,46 @@ namespace IOB_WIN_NEXT.Iob } } + /// + /// URL per recupero traduzione CodArt in numerico... + /// + public string urlGetNumArt + { + get + { + string answ = ""; + try + { + answ = $@"{cIobConf.serverData.TRANSP}://{cIobConf.serverData.MPIP}{cIobConf.serverData.MPURL}{cIobConf.serverData.CMDALIVE}/getArtNum/{cIobConf.codIOB}"; + } + catch (Exception exc) + { + lgError(exc, "Errore in composizione urlGetNumArt"); + } + return answ; + } + } + + /// + /// URL per recupero traduzione CodComm in numerico... + /// + public string urlGetNumComm + { + get + { + string answ = ""; + try + { + answ = $@"{cIobConf.serverData.TRANSP}://{cIobConf.serverData.MPIP}{cIobConf.serverData.MPURL}{cIobConf.serverData.CMDALIVE}/getXdlNum/{cIobConf.codIOB}"; + } + catch (Exception exc) + { + lgError(exc, "Errore in composizione urlGetNumComm"); + } + return answ; + } + } + /// /// URL per recupero num pezzi ODL corrente... /// @@ -835,46 +875,6 @@ namespace IOB_WIN_NEXT.Iob } } - /// - /// URL per recupero traduzione CodArt in numerico... - /// - public string urlGetNumArt - { - get - { - string answ = ""; - try - { - answ = $@"{cIobConf.serverData.TRANSP}://{cIobConf.serverData.MPIP}{cIobConf.serverData.MPURL}{cIobConf.serverData.CMDALIVE}/getArtNum/{cIobConf.codIOB}"; - } - catch (Exception exc) - { - lgError(exc, "Errore in composizione urlGetNumArt"); - } - return answ; - } - } - - /// - /// URL per recupero traduzione CodComm in numerico... - /// - public string urlGetNumComm - { - get - { - string answ = ""; - try - { - answ = $@"{cIobConf.serverData.TRANSP}://{cIobConf.serverData.MPIP}{cIobConf.serverData.MPURL}{cIobConf.serverData.CMDALIVE}/getXdlNum/{cIobConf.codIOB}"; - } - catch (Exception exc) - { - lgError(exc, "Errore in composizione urlGetNumComm"); - } - return answ; - } - } - /// /// URL per recupero idle time IOB... /// @@ -1551,7 +1551,8 @@ namespace IOB_WIN_NEXT.Iob break; case taskType.setArtNum: - // in primis faccio una chiamata per tutta la tab SE fosse vuoto il dict di traduzione + // in primis faccio una chiamata per tutta la tab SE fosse vuoto il + // dict di traduzione if (DictNumArt == null || DictNumArt.Count == 0) { getNumArt(""); @@ -2907,7 +2908,7 @@ namespace IOB_WIN_NEXT.Iob } } // verifico parametro sintesi... che ricalcolo ogni volta - if(!currDynData.ContainsKey("DYNDATA")) + if (!currDynData.ContainsKey("DYNDATA")) { currDynData.Add("DYNDATA", ""); } @@ -4463,6 +4464,11 @@ namespace IOB_WIN_NEXT.Iob /// protected bool needRefresh = true; + /// + /// Indica se usare la parte numerica di un articolo come codice INT + /// + protected bool numArtCharTrim = false; + /// /// Variabile numero errori vari (in lettura) --> se supera soglia maxErroriCheck --> disconnette /// @@ -4478,6 +4484,14 @@ namespace IOB_WIN_NEXT.Iob /// protected int pzCountDelay; + /// + /// Periodo di campionamento x refresh info + /// + protected int samplePeriod = 1000; + + /// + /// Sample Period base x campionamenti tpo OCP-UA + /// protected int samplePeriodBase = 600; /// @@ -4557,6 +4571,8 @@ namespace IOB_WIN_NEXT.Iob } } + protected Dictionary DictNumArt { get; set; } = new Dictionary(); + /// /// Folder in cui è presente il tool import excel + file json di conf /// @@ -5275,6 +5291,82 @@ namespace IOB_WIN_NEXT.Iob return answ; } + /// + /// Recupera valore numerico ARTICOLO x salvataggio valori INT + /// + /// + /// + protected string getNumArt(string value) + { + string answ = ""; + // cerco in dizionario corrente... + if (DictNumArt.Count > 0 && DictNumArt.ContainsKey(value)) + { + answ = DictNumArt[value]; + } + // altrimenti chiamo servizio + else + { + // chiamo MP-IO server + if (checkServerAlive) + { + string url2call = $"{urlGetNumArt}?CodArt={value}"; + if (verboseLog) + { + lgInfo("chiamata URL " + url2call); + } + var rawData = utils.callUrlNow(url2call); + // deserializzo e recupero KVP... + var dictArtSrv = JsonConvert.DeserializeObject>(rawData); + // se fosse una chiamata con valore vuoto --> salvo intera tabella... + if (string.IsNullOrEmpty(value)) + { + DictNumArt = dictArtSrv; + } + // altrimenti aggiungo a dizionario + else + { + foreach (var item in dictArtSrv) + { + if (!DictNumArt.ContainsKey(item.Key)) + { + DictNumArt.Add(item.Key, item.Value); + } + } + } + // ora cerco valore e restituisco + if (DictNumArt.ContainsKey(value)) + { + answ = DictNumArt[value]; + } + } + } + return answ; + } + + /// + /// Recupera valore numerico COMMESSA x salvataggio valori INT + /// + /// + /// + protected string getNumComm(string value) + { + string answ = ""; + // chiamo MP-IO server + if (checkServerAlive) + { + string url2call = $"{urlGetNumComm}?CodXdl={value}"; + if (verboseLog) + { + lgInfo("chiamata URL " + url2call); + } + // è direttamente il risultato! + answ = utils.callUrlNow(url2call); + } + // restituisco + return answ; + } + /// /// Stringa raw dei parametri da scrivere... /// @@ -7766,84 +7858,6 @@ namespace IOB_WIN_NEXT.Iob } } - /// - /// Recupera valore numerico ARTICOLO x salvataggio valori INT - /// - /// - /// - protected string getNumArt(string value) - { - string answ = ""; - // cerco in dizionario corrente... - if (DictNumArt.Count > 0 && DictNumArt.ContainsKey(value)) - { - answ = DictNumArt[value]; - } - // altrimenti chiamo servizio - else - { - // chiamo MP-IO server - if (checkServerAlive) - { - string url2call = $"{urlGetNumArt}?CodArt={value}"; - if (verboseLog) - { - lgInfo("chiamata URL " + url2call); - } - var rawData = utils.callUrlNow(url2call); - // deserializzo e recupero KVP... - var dictArtSrv = JsonConvert.DeserializeObject>(rawData); - // se fosse una chiamata con valore vuoto --> salvo intera tabella... - if (string.IsNullOrEmpty(value)) - { - DictNumArt = dictArtSrv; - } - // altrimenti aggiungo a dizionario - else - { - foreach (var item in dictArtSrv) - { - if (!DictNumArt.ContainsKey(item.Key)) - { - DictNumArt.Add(item.Key, item.Value); - } - } - } - // ora cerco valore e restituisco - if (DictNumArt.ContainsKey(value)) - { - answ = DictNumArt[value]; - } - } - } - return answ; - } - - protected Dictionary DictNumArt { get; set; } = new Dictionary(); - - /// - /// Recupera valore numerico COMMESSA x salvataggio valori INT - /// - /// - /// - protected string getNumComm(string value) - { - string answ = ""; - // chiamo MP-IO server - if (checkServerAlive) - { - string url2call = $"{urlGetNumComm}?CodXdl={value}"; - if (verboseLog) - { - lgInfo("chiamata URL " + url2call); - } - // è direttamente il risultato! - answ = utils.callUrlNow(url2call); - } - // restituisco - return answ; - } - #if false /// /// Traduzione del valore chiave configurato dal dizionario RecipeKeyTranslate + BaseKeyTranslate @@ -8094,10 +8108,6 @@ namespace IOB_WIN_NEXT.Iob accodaFLog(sVal, qEncodeFLog("PROG", currPrgName)); } } - /// - /// Indica se usare la parte numerica di un articolo come codice INT - /// - protected bool numArtCharTrim = false; /// /// Processo lettura dati sysinfo diff --git a/IOB-WIN-NEXT/Iob/Mitsubishi.cs b/IOB-WIN-NEXT/Iob/Mitsubishi.cs new file mode 100644 index 00000000..9b4e339d --- /dev/null +++ b/IOB-WIN-NEXT/Iob/Mitsubishi.cs @@ -0,0 +1,2095 @@ +using EgwProxy.MultiCncLib.CNC; +using IOB_UT_NEXT; +using KRcc; +using MapoSDK; +using Newtonsoft.Json; +using Opc.Ua; +using Org.BouncyCastle.Utilities.Collections; +using System; +using System.Collections.Generic; +using System.Data.SqlTypes; +using System.Linq; +using System.Net; +using System.Net.NetworkInformation; +using System.Text; +using System.Threading; + +namespace IOB_WIN_NEXT.Iob +{ + public class Mitsubishi : Iob.Generic + { + #region Public Constructors + + /// + /// Estende l'init della classe base... + /// + /// + /// + public Mitsubishi(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf) + { + lgInfo("Start init Mitsubishi"); + // gestione invio ritardato contapezzi + pzCountDelay = utils.CRI("pzCountDelay"); + lastPzCountSend = DateTime.Now; + lastWarnODL = DateTime.Now; + + // inizializzo correttamente aree memoria secondo CONF - iniFileName + IniFile fIni = new IniFile(IOBConf.iniFileName); + + // inizializzo aree di memoria correnti... + MemVarStart = fIni.ReadInteger("MEMORY", "AREAV_START", 500); + MemVarSize = fIni.ReadInteger("MEMORY", "AREAV_SIZE", 1); + ParamStart = fIni.ReadInteger("MEMORY", "PAR_START", 8001); + ParamSize = fIni.ReadInteger("MEMORY", "PAR_SIZE", 1); + SignStart = fIni.ReadInteger("MEMORY", "SIGN_START", 10096); + SignSize = fIni.ReadInteger("MEMORY", "SIGN_SIZE", 1); + + // loggo aree di memoria avviate... + lgInfo($"Avviata area di memoria Var: {MemVarSize} vars"); + lgInfo($"Avviata area di memoria Param: {ParamSize} params"); + + // fix enable prgName + enablePrgName = fIni.ReadBoolean("CNC", "GETPRGNAME", true); + + // effettuo lettura della conf sigLUT... cercando 1:1 i bit... + string currBit = ""; + string memArea = ""; + for (int i = 0; i < 8; i++) + { + currBit = $"BIT{i}"; + memArea = fIni.ReadString("MEMORY", currBit, ""); + // se trovo un valore... + if (!string.IsNullOrEmpty(memArea)) + { + signLUT.Add(currBit, memArea); + } + } + + // recupero sysType del controllo, sennò default M700L... + string sEZNC_SYS = getOptPar("EZNC_SYS"); + if (!string.IsNullOrEmpty(sEZNC_SYS)) + { + sysType = (SYSTEMTYPE)Enum.Parse(typeof(SYSTEMTYPE), sEZNC_SYS); + } + lgInfo($"Start init Mitsubishi | SysType: {sysType}"); + + // gestione override contapezzi + enablePzCountByApp = utils.CRB("enableContapezzi"); + enablePzCountByIob = (getOptPar("ENABLE_PZCOUNT") == "TRUE"); + disablePzCountByIob = (getOptPar("DISABLE_PZCOUNT") == "FALSE"); + + // gestione override idx articoli... + if (!string.IsNullOrEmpty(getOptPar("NUM_ART_CHR_TRIM"))) + { + string NUM_ART_CHR_TRIM = getOptPar("NUM_ART_CHR_TRIM"); + bool.TryParse(NUM_ART_CHR_TRIM, out numArtCharTrim); + } + if (!string.IsNullOrEmpty(getOptPar("MAX_CHAR_DESC"))) + { + string MAX_CHAR_DESC = getOptPar("MAX_CHAR_DESC"); + int.TryParse(MAX_CHAR_DESC, out maxVarStrLen); + } + + // leggo conf x ricerca valori memoria da tracciare in log di continuo... + mem2trace = fIni.ReadString("OPTPAR", "MEM_2_TRACE", ""); + + // è little endian (NON serve conversione) + hasBigEndian = false; + lgInfoStartup($"Start init Adapter MITSUBISHI | IP {IOBConf.cncIpAddr}:{IOBConf.cncPort} per IOB {IOBConf.codIOB}"); + + // Creo oggetto connessione NC + parentForm.commPlcActive = true; + + // init oggetto + oEZNcAutCom = new EZNCAUTLib.DispEZNcCommunication(); + int.TryParse(IOBConf.cncPort, out ezPort); + ipAddr = IOBConf.cncIpAddr; + + parentForm.commPlcActive = false; + + // effettuo tryConnect... + lgInfo("MITSUBISHI startup: tryConnect"); + tryConnect(); + if ((enablePzCountByApp || enablePzCountByIob) && !(disablePzCountByIob)) + { + lgInfo("MITSUBISHI: inizio gestione contapezzi"); + try + { + // verifico quale modalità sia richiesta: STD (6711) oppure BIT (Custom, con + // indicazione area) + if (cIobConf.optPar.Count > 0 && !string.IsNullOrEmpty(getOptPar("PZCOUNT_MODE"))) + { + if (getOptPar("PZCOUNT_MODE").StartsWith("STD")) + { + lgInfo("Init contapezzi MITSUBISHI: pzCntReload(true)"); + pzCntReload(true); + // refresh associazione Macchina - IOB + SendM2IOB(); + // invio altri dati accessori... + SendMachineConf(); + // per adesso imposto lettura MITSUBISHI == contapezzi (poi farà vera lettura...) + contapezziPLC = contapezziIOB; + } + else + { + contapezziIOB = 0; + lgInfo("Contapezzi STD disabilitato: modalità {0}", getOptPar("PZCOUNT_MODE")); + } + } + else + { + contapezziIOB = 0; + lgInfo("Parametro mancante PZCOUNT_MODE"); + } + } + catch (Exception exc) + { + lgError(exc, "Errore in contapezzi MITSUBISHI 01"); + } + } + // finisco INIT ADAPTER + lgInfo("End init Adapter MITSUBISHI"); + } + + #endregion Public Constructors + + #region Public Methods + + /// + /// Processo i task richiesti e li elimino dalla coda 1:1 + /// + /// + public override Dictionary executeTasks(Dictionary task2exe) + { + // Verificare il protocollo: dovrebbe togliere SOLO i task eseguiti... + Dictionary taskDone = new Dictionary(); + if (task2exe != null) + { + bool taskOk = false; + string taskVal = ""; + string newVal = ""; + string memAddr = ""; + int newValInt = 0; + // cerco task specifici: se ho startSetup --> imposto bit DBB701.DBB0.4 + foreach (var item in task2exe) + { + taskOk = false; + taskVal = ""; + // converto richiesta in enum... + taskType tName = taskType.nihil; + Enum.TryParse(item.Key, out tName); +#if false + switch (tName) + { + case taskType.setArt: + case taskType.setComm: + lgInfo($"Richiesta scrittura {tName}"); + // salvo in memoria il valore richiesto... + if (memMap != null && memMap.mMapWrite != null) + { + if (memMap.mMapWrite.ContainsKey(item.Key)) + { + dataConf currMem = memMap.mMapWrite[item.Key]; + memAddr = currMem.memAddr; + taskVal = $"SET task: {item.Key} --> {newVal} | mem: {currMem.memAddr} - {currMem.size} byte"; + // salvo il nuovo valore nella memoria... così prox invio lo trasmetterà + memMap.mMapWrite[item.Key].value = newVal; + } + else + { + taskVal = $"NO DATA MEM, SET task: {item.Key} --> {newVal} ({item.Value})"; + } + } + else + { + taskVal = $"NO MemMap found, SET task: {item.Key} --> {newVal} ({item.Value})"; + } + // salvo in currProd.. + saveProdData(new KeyValuePair(item.Key, item.Value)); + upsertKey(item.Key, item.Value); + break; + + case taskType.nihil: + case taskType.fixStopSetup: + case taskType.forceResetPzCount: + case taskType.setProg: + case taskType.forceSetPzCount: + case taskType.sendWatchDogMes2Plc: + taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC"; + lgInfo($"Chiamata senza processing: taskOk: {taskOk} | taskVal: {taskVal}"); + break; + + case taskType.setArtNum: + lgInfo($"Richiesta scrittura CodART numerico"); + // in primis faccio una chiamata per tutta la tab SE fosse vuoto il dict + // di traduzione + if (DictNumArt == null || DictNumArt.Count == 0) + { + getNumArt(""); + lgInfo($"Recuperato DictNumArt, trovati {DictNumArt.Count} rec"); + } + // chiamo server x avere decodifica valore INT + newVal = getNumArt(item.Value); + // se c'è gestione semplificata num articolo --> usa trim dei soli + // caratteri alfabetici lasciando numeri.. + if (numArtCharTrim) + { + newVal = baseUtils.GetNumbers(item.Value); + } + // converto int... + int.TryParse(newVal, out newValInt); + // procedo come il resto cercando mappatura in memMap: recupero dati da memMap... + if (memMap != null && memMap.mMapWrite != null) + { + if (memMap.mMapWrite.ContainsKey(item.Key)) + { + dataConf currMem = memMap.mMapWrite[item.Key]; + memAddr = currMem.memAddr; + taskVal = $"SET task: {item.Key} --> {newVal} | mem: {currMem.memAddr} - {currMem.size} byte"; + // salvo il nuovo valore nella memoria... così prox invio lo trasmetterà + memMap.mMapWrite[item.Key].value = newVal; + } + else + { + taskVal = $"NO DATA MEM, SET task: {item.Key} --> {newVal} ({item.Value})"; + } + } + else + { + taskVal = $"NO MemMap found, SET task: {item.Key} --> {newVal} ({item.Value})"; + } + + // invio a controller... + taskOk = setNumArt(newValInt); + //se ho successo rileggo ed eventualmente sistemo valore + if (taskOk) + { + //var rVal = getValByParam("SET_NUM_ART"); + var rVal = getValByMemAddr(memAddr); + if (rVal == newVal) + { + lgInfo("All OK"); + // invio aggiornamento x reset richiesta... test! + sendOptVal(item.Key, newVal); + } + else + { + lgError($"Error | memName: {memAddr} | rVal: {rVal} | newVal: {newVal}"); + } + } + else + { + lgError("Errore in scrittura SetNumArt"); + } + // salvo in currProd.. + saveProdData(new KeyValuePair(item.Key, newVal)); + upsertKey(item.Key, item.Value); + break; + + case taskType.setCommNum: + lgInfo($"Richiesta scrittura cod COMMESSA numerica"); + // chiamo server x avere decodifica valore INT + newVal = getNumComm(item.Value); + // converto int... + int.TryParse(newVal, out newValInt); + //riscrivo senza eventuali zeri... + newVal = newValInt > 0 ? $"{newValInt}" : newVal; + lgTrace($"Conv.Int numComm | newVal: {newVal} | newValInt: {newValInt}"); + // procedo come il resto cercando mappatura in memMap: recupero dati da memMap... + if (memMap != null && memMap.mMapWrite != null) + { + if (memMap.mMapWrite.ContainsKey(item.Key)) + { + dataConf currMem = memMap.mMapWrite[item.Key]; + memAddr = currMem.memAddr; + taskVal = $"SET task: {item.Key} --> {newVal} | mem: {currMem.memAddr} - {currMem.size} byte"; + // salvo il nuovo valore nella memoria... così prox invio lo trasmetterà + memMap.mMapWrite[item.Key].value = newVal; + } + else + { + taskVal = $"NO DATA MEM, SET task: {item.Key} --> {newVal} ({item.Value})"; + } + } + else + { + taskVal = $"NO MemMap found, SET task: {item.Key} --> {newVal} ({item.Value})"; + } + + // invio a controller... + taskOk = setNumCom(newValInt); + //se ho successo rileggo ed eventualmente sistemo valore + if (taskOk) + { + //var rVal = getValByParam("SET_NUM_COM"); + var rVal = getValByMemAddr(memAddr); + if (rVal == newVal) + { + lgInfo("All OK"); + // invio aggiornamento x reset richiesta... test! + sendOptVal(item.Key, newVal); + } + else + { + lgError($"Error | memName: {memAddr} | rVal: {rVal} | newVal: {newVal}"); + } + } + else + { + lgError("Errore in scrittura SetNumCom"); + } + // salvo in currProd.. + saveProdData(new KeyValuePair(item.Key, newVal)); + upsertKey(item.Key, item.Value); + break; + + case taskType.setPzComm: + int pzReq = 0; + int.TryParse(item.Value, out pzReq); + // set pezzi richiesti inizio setup + taskOk = setPzComm(pzReq); + taskVal = taskOk ? "RESET: SETUP START" : "PZ RESET DISABLED | NO EXEC"; + lgInfo($"Chiamata startSetup: taskOk: {taskOk} | taskVal: {taskVal}"); + + // salvo in currProd.. + saveProdData(new KeyValuePair(item.Key, newVal)); + upsertKey(item.Key, item.Value); + break; + + case taskType.startSetup: + // reset contapezzi inizio setup + taskOk = resetContapezziPLC(); + taskVal = taskOk ? "RESET: SETUP START" : "PZ RESET DISABLED | NO EXEC"; + lgInfo($"Chiamata startSetup: taskOk: {taskOk} | taskVal: {taskVal}"); + break; + + case taskType.stopSetup: + // reset contapezzi fine setup SE ESPLICITAMENTE IMPOSTATO + if (cIobConf.optPar.Count > 0 && getOptPar("ENABLE_PZ_RESET_stopSetup") == "TRUE") + { + taskOk = resetContapezziPLC(); + } + taskVal = taskOk ? "RESET: SETUP END" : "PZ RESET DISABLED | NO EXEC"; + lgInfo($"Chiamata stopSetup: taskOk: {taskOk} | taskVal: {taskVal}"); + break; + + case taskType.setParameter: + lgInfo($"Chiamata setParameter | NO processing: taskOk: {taskOk} | taskVal: {taskVal}"); + taskVal = "setParameter | SKIPPED | NO EXEC"; + break; + + default: + lgInfo($"Chiamata default senza processing: taskOk: {taskOk} | taskVal: {taskVal}"); + taskVal = "SKIPPED | NO EXEC"; + break; + } +#endif + // aggiungo task! + taskDone.Add(item.Key, taskVal); + } + } + return taskDone; + } + + /// + /// Recupero dati dinamici... + /// + public override Dictionary getDynData() + { + Dictionary outVal = new Dictionary(); + // processo SOLO SE connected... + if (connectionOk) + { +#if false + if (MITSUBISHI_ref.Connected) + { + stopwatch.Restart(); + EgwProxy.MultiCncLib.Focas1.ODBDY2_1 answ = MITSUBISHI_ref.getAllDynData(); + if (utils.CRB("recTime")) + { + TimingData.addResult(cIobConf.codIOB, string.Format("PROC-DYN-DATA"), stopwatch.ElapsedTicks); + } + + try + { + string actf = answ.actf.ToString(); + string acts = answ.acts.ToString(); + //string numAlarm = memName.alarm.ToString(); + // preparo i singoli valori dell'array... + //outVal.Add("DYNDATA", string.Format("{0}#{1}#{2}", actf, acts, numAlarm)); + outVal.Add("DYNDATA", string.Format("FEED {0}#SPEED_RPM {1}", actf, acts)); + if (utils.CRB("SendFeedSpeed")) + { + outVal.Add("FEED", actf); + outVal.Add("SPEED_RPM", acts); + //outVal.Add("NUM_ALARM", numAlarm); + } + if (utils.CRB("SendAxPos")) + { + // salvo le posizioni... + EgwProxy.MultiCncLib.Focas1.FAXIS posAx = answ.pos; + int[] currPosAbs = posAx.absolute; + int i = 0; + foreach (var item in currPosAbs) + { + i++; + outVal.Add(string.Format("POS_{0:00}", i), item.ToString()); + } + } + } + catch (Exception exc) + { + lgError(exc, "Errore in getDynData"); + } + stopwatch.Stop(); + } +#endif + } + return outVal; + } + + /// + /// Recupero dati override (da area G che è già stata letta...) + /// + /// + public override Dictionary getOverrides() + { + Dictionary outVal = new Dictionary(); + // processo SOLO SE connected... + if (connectionOk) + { +#if false + if (MITSUBISHI_ref.Connected) + { + if (utils.CRB("enableMode") && MemBlockG != null && MemBlockG.Length > 0) + { + outVal.Add("FEED_OVER", MemBlockG[30].ToString()); + outVal.Add("RAPID_OVER", MemBlockG[12].ToString()); + } + } +#endif + } + return outVal; + } + + /// + /// Recupero programma in lavorazione + /// + /// + public override string getPrgName() + { + string prgName = ""; + // recupero NUOVO prgName... + try + { + int iRet = oEZNcAutCom.Program_GetProgramNumber2((Int32)PROGRAMTYPE.EZNC_MAINPRG, out String strProgramNo); + + // recupero nome programma MAIN + prgName = utils.purgedChar2String(strProgramNo); + // trimmo path del programma SE presente + prgName = prgName.Replace(utils.CRS("basePrgMemPath"), ""); + lgInfo("Current PROG: {0}", prgName); + } + catch (Exception exc) + { + lgError(string.Format("Eccezione in recupero PRG NAME MAIN:{0}{1}", Environment.NewLine, exc)); + connectionOk = false; + } + return prgName; + } + + /// + /// Recupero info lavorazione come Dictionary... + /// - SYSINFO: (prima KEY globale) TUTTI i valori separati da # (x fare check modifica) + /// - altre stringhe: ogni singolo parametro / valore + /// + /// + public override Dictionary getSysInfo() + { + Dictionary outVal = new Dictionary(); + stopwatch.Restart(); + try + { + oEZNcAutCom.System_GetSystemInformation(0, out int partSys); + outVal.Add("PartSys", $"{partSys}"); + oEZNcAutCom.System_GetSystemInformation(1, out int numAx); + outVal.Add("NumAxis", $"{numAx}"); + oEZNcAutCom.System_GetSerialNo(out string serNo); + outVal.Add("SerialNo", $"{serNo}"); + for (int i = 0; i < 3; i++) + { + oEZNcAutCom.System_GetVersion(0, i, out string pVers); + outVal.Add($"V_{i}", $"{pVers}"); + } + } + catch (Exception exc) + { + lgError($"Eccezione in getSysInfo{Environment.NewLine}{exc}"); + connectionOk = false; + } + if (utils.CRB("recTime")) + { + TimingData.addResult(cIobConf.codIOB, string.Format("SYS-INFO"), stopwatch.ElapsedTicks); + } + return outVal; + } + + /// + /// Effettua vero processing contapezzi da configurazione + /// PZCOUNT_MODE: pezzi lavorati (parziale) + /// PZGTOT_MODE: pezzi lavorati totali + /// PZREQ_MODE: pezzi richiesti + /// + public override void processContapezzi() + { + if ((enablePzCountByApp || enablePzCountByIob) && !(disablePzCountByIob)) + { + // procedo SOLO SE ho connessione... + if (connectionOk) + { + try + { + // lettura parametri per procedere + ReadMitsubParams(); + // controllo di AVERE parametri opzionali x conteggi vari + if (cIobConf.optPar.Count > 0) + { + // contapezzi ATTUALE + string memAddr = getOptPar("PZCOUNT_MODE"); + if (!string.IsNullOrEmpty(memAddr)) + { + // verifico quale modalità sia richiesta: STD oppure CST (Custom, TBD) + if (memAddr.StartsWith("STD")) + { + // inizio verifica area memoria/parametro levando prima parte codice + memAddr = memAddr.Replace("STD.", ""); + } + + // verifico SE sia di tipo PAR e cerco valore... + int cntAddr = 0; + if (memAddr.StartsWith("PAR.")) + { + // recupero parametro... + int.TryParse(memAddr.Replace("PAR.", ""), out cntAddr); + } + // cerco in dizionario... + if (DictParam.ContainsKey(cntAddr)) + { + string rawVal = DictParam[cntAddr]; + int newVal = -1; + Int32.TryParse(rawVal, out newVal); + contapezziPLC = newVal > -1 ? newVal : contapezziPLC; + } + + stopwatch.Stop(); + } + } + } + catch (Exception exc) + { + lgError(exc, "Errore in contapezzi MITSUBISHI 02"); + connectionOk = false; + } + } + else + { + lgError("Errore: manca connessione in contapezzi MITSUBISHI"); + } + } + } + + /// + /// Recupero altri counters se ci sono + /// + public override void processOtherCounters() + { + try + { + // lettura parametri per procedere + ReadMitsubParams(); + + // controllo di AVERE parametri opzionali x conteggi vari + if (cIobConf.optPar.Count > 0) + { + // gestione con ricerca in memoria Write / optPar... + if (string.IsNullOrEmpty(memAddrPzReq)) + { + lgTrace("PzReq disabilitato | NO memConf.Write | NO optPar"); + } + else + { + sendOptVal(memNamePzReq, getValByMemAddr(memAddrPzReq)); + } + if (string.IsNullOrEmpty(memAddrArt)) + { + lgTrace("Articolo disabilitato | NO memConf.Write | NO optPar"); + } + else + { + sendOptVal(memNameArt, getValByMemAddr(memAddrArt)); + } + if (string.IsNullOrEmpty(memAddrCom)) + { + lgTrace("Commessa disabilitata | NO memConf.Write | NO optPar"); + } + else + { + sendOptVal(memNameCom, getValByMemAddr(memAddrCom)); + } + if (string.IsNullOrEmpty(memAddrPzCnt)) + { + lgTrace("PzCount disabilitato | NO memConf.Write | NO optPar"); + } + else + { + sendOptVal(memNamePzCnt, getValByMemAddr(memAddrPzCnt)); + } + if (string.IsNullOrEmpty(memAddrPzCntTot)) + { + lgTrace("PzCntTOT disabilitato | NO memConf.Write | NO optPar"); + } + else + { + sendOptVal(memNamePzCntTot, getValByMemAddr(memAddrPzCntTot)); + } + if (string.IsNullOrEmpty(memAddrCaden)) + { + lgTrace("Cadenza disabilitata | NO memConf.Write | NO optPar"); + } + else + { + sendOptVal(memNameCaden, getValByMemAddr(memAddrCaden)); + } + } + } + catch (Exception exc) + { + lgError(exc, "Eccezione in processOtherCounters"); + } + } + + /// + /// Effettua lettura semafori principale Parametri da + /// aggiornare x display in form + /// + public override void readSemafori(ref newDisplayData currDispData) + { + DateTime adesso = DateTime.Now; + base.readSemafori(ref currDispData); + // verifico non sia in veto invio iniziale... + if (queueInEnabCurr) + { + try + { + if (verboseLog) + { + lgInfo("inizio read semafori"); + } + + currDispData.semIn = Semaforo.SV; + // in primis: leggo i valor in sequenza e salvo in dizionario... + object pvRead = "bbb"; + // sezione segnali: cablata 53... + int sec = 53; + // Start da Y60 (Hex) --> 10000+96 + for (int i = SignStart; i < SignStart + SignSize; i++) + { + oEZNcAutCom.Generic_ReadData(0, sec, i, ref pvRead); + UpsertSign(i, $"{pvRead}"); + if (verboseLog) + { + lgTrace($"Sign | {i} : {pvRead}"); + } + } + // recording tempi + if (utils.CRB("recTime")) + { + TimingData.addResult(cIobConf.codIOB, $"Sign{SignSize}-R", stopwatch.ElapsedTicks); + } + stopwatch.Stop(); + // salvo il solo BYTE dell'input decifrando il semaforo... + decodeToBitmap(); + reportRawInput(ref currDispData); + } + catch (Exception exc) + { + lgError(string.Format("Eccezione in readSemafori:{0}{1}", Environment.NewLine, exc)); + connectionOk = false; + currDispData.semIn = Semaforo.SR; + } + } + else + { + lgDebug($"[VETO readSemafori] | veto attivo alle {adesso:yyyy.MM.dd HH:mm:ss}"); + checkVetoQueueIn(); + } + } + + /// + /// Effettua reset del contapezzi + /// + /// + public override bool resetContapezziPLC() + { + bool answ = false; + // ...SE abilitato da conf IOB + if (cIobConf.optPar.Count > 0 && getOptPar("ENABLE_PZ_RESET") == "TRUE") + { + // scrivo valore 0 x il contapezzi + try + { + // contapezzi ATTUALE + if (!string.IsNullOrEmpty(getOptPar("PZCOUNT_MODE"))) + { + // verifico quale modalità sia richiesta: STD (6711) oppure BIT (Custom, con + // indicazione area) + string memAddr = getOptPar("PZCOUNT_MODE"); + if (memAddr.StartsWith("STD")) + { + // inizio verifica area memoria/parametro levando prima parte codice + memAddr = memAddr.Replace("STD.", ""); + } + // var di appoggio + int cntAddr = 0; + // var contapezzi a zero.... + object newVal = new object(); + newVal = 0; +#if false + // verifico se si tratta di lettura parametro... formato tipo STD.PAR.6711 + if (memAddr.StartsWith("PAR.")) + { + // recupero parametro... + int.TryParse(memAddr.Replace("PAR.", ""), out cntAddr); + if (cntAddr == 0) + { + cntAddr = 6711; + } + + // processo RESET contapezzi (lavorati) + stopwatch.Restart(); + MITSUBISHI_ref.F_RW_Param_Integer(true, cntAddr, 3, ref newVal); + if (utils.CRB("recTime")) + { + TimingData.addResult(cIobConf.codIOB, string.Format("W{0}-PAR", 4), stopwatch.ElapsedTicks); + } + } + else if (memAddr.StartsWith("MACRO.")) + { + // recupero parametro... + int.TryParse(memAddr.Replace("MACRO.", ""), out cntAddr); + if (cntAddr == 0) + { + cntAddr = 9999; + } + // processo SET contapezzi (lavorati) + stopwatch.Restart(); + double vTransf = (double)0; + answ = MITSUBISHIMemMacroRW(true, cntAddr, ref vTransf); + if (utils.CRB("recTime")) + { + TimingData.addResult(cIobConf.codIOB, "MACRO-SHORT", stopwatch.ElapsedTicks); + } + } + // altrimenti se legge da area memoria specifica leggo da li... formto tipo STD.D.1604.DW + else + { + memAddressMITSUBISHI areaCounter = new memAddressMITSUBISHI(memAddr); + + if (isVerboseLog) + { + lgInfo("resetContapezziPLC [0] area memoria: {0}.{1}.{2}", areaCounter.mType, areaCounter.mPos, areaCounter.vType); + } + // leggo! + stopwatch.Restart(); + // switch x tipo dati --> tipo lettura... e salvo ultimo conteggio rilevato + switch (areaCounter.vType) + { + case "B": + byte valB = 0; + MITSUBISHI_ref.F_RW_Byte(true, areaCounter.mType, areaCounter.mPos, ref valB); + newVal = valB; + break; + + case "D": + ushort valW = 0; + MITSUBISHI_ref.F_RW_Word(true, areaCounter.mType, areaCounter.mPos, ref valW); + newVal = valW; + break; + + case "DW": + uint valDW = 0; + MITSUBISHI_ref.F_RW_DWord(true, areaCounter.mType, areaCounter.mPos, ref valDW); + break; + + default: + break; + } + if (utils.CRB("recTime")) + { + TimingData.addResult(cIobConf.codIOB, string.Format("W-{0}.{1}.{2}", areaCounter.mType, areaCounter.mPos, areaCounter.vType), stopwatch.ElapsedTicks); + } + } +#endif + stopwatch.Stop(); + } + } + catch (Exception exc) + { + lgError(exc, "Errore in RESET contapezzi MITSUBISHI"); + connectionOk = false; + } + answ = true; + } + return answ; + } + + /// + /// Override salvataggio valori in memoria... + /// + /// tipo di DUMP + public override void saveMemDump(dumpType tipo) + { +#if false + // se l'area ha una size > 0... + if (areaD.arraySize > 0) + { + dump_MemArea(tipo, MITSUBISHI.MemType.D, areaD.startIdx, areaD.arraySize); + } + // se l'area ha una size > 0... + if (areaR.arraySize > 0) + { + dump_MemArea(tipo, MITSUBISHI.MemType.R, areaR.startIdx, areaR.arraySize); + } + // se l'area ha una size > 0... + if (areaX.arraySize > 0) + { + dump_MemArea(tipo, MITSUBISHI.MemType.X, areaX.startIdx, areaX.arraySize); + } + // se l'area ha una size > 0... + if (areaY.arraySize > 0) + { + dump_MemArea(tipo, MITSUBISHI.MemType.Y, areaY.startIdx, areaY.arraySize); + } + // se l'area ha una size > 0... + if (areaPAR.arraySize > 0) + { + dump_ParArea(tipo, areaPAR.startIdx, areaPAR.arraySize); + } +#endif + } + + /// + /// Effettua impostazione del valore numerico ARTICOLO (specifico MITSUBISHI) + /// + /// + public bool setNumArt(int valReq) + { + bool answ = false; + string memAddr = memAddrArt; + lgTrace($"INIT setNumArt | memName: {memAddr}"); + if (cIobConf.optPar.Count > 0 && !string.IsNullOrEmpty(memAddr)) + { + // scrivo valore richiesto in area configurata + try + { + // var di appoggio + int cntAddr = 0; + // verifico se si tratta di lettura MACRO... formato tipo MACRO.6711 + if (memAddr.StartsWith("MACRO.")) + { + // recupero parametro... + int.TryParse(memAddr.Replace("MACRO.", ""), out cntAddr); + if (cntAddr == 0) + { + cntAddr = 9999; + } + lgTrace($"MACRO | ART Write 01 | memName: {memAddr} | idx: {cntAddr}"); + // processo SET contapezzi (lavorati) + stopwatch.Restart(); +#if false + double vTransf = (double)valReq; + answ = MITSUBISHIMemMacroRW(true, cntAddr, ref vTransf); + lgTrace($"MACRO | ART Write 02 | memName: {memAddr} | valReq: {valReq} | vTransf: {vTransf}"); + if (utils.CRB("recTime")) + { + TimingData.addResult(cIobConf.codIOB, "MACRO-SHORT", stopwatch.ElapsedTicks); + } +#endif + } + stopwatch.Stop(); + } + catch (Exception exc) + { + lgError(exc, "Errore in setNumArt MITSUBISHI"); + connectionOk = false; + } + } + return answ; + } + + /// + /// Effettua impostazione del valore numerico COMMESSA (specifico MITSUBISHI) + /// + /// + public bool setNumCom(int valReq) + { + bool answ = false; + // verifico quale modalità sia richiesta + string memAddr = memAddrCom; + lgTrace($"INIT setNumCom | memName: {memAddr}"); + if (cIobConf.optPar.Count > 0 && !string.IsNullOrEmpty(memAddr)) + { + lgTrace($"setNumCom | memName: {memAddr} | valReq: {valReq}"); + // scrivo valore richiesto in area configurata + try + { + // var di appoggio + int cntAddr = 0; + // verifico se si tratta di lettura MACRO... formato tipo MACRO.6711 + if (memAddr.StartsWith("MACRO.")) + { + // recupero parametro... + int.TryParse(memAddr.Replace("MACRO.", ""), out cntAddr); + if (cntAddr == 0) + { + cntAddr = 9999; + } +#if false + lgTrace($"MACRO | Com Write 01 | memName: {memAddr} | idx: {cntAddr}"); + // processo SET contapezzi (lavorati) + stopwatch.Restart(); + double vTransf = (double)valReq; + answ = MITSUBISHIMemMacroRW(true, cntAddr, ref vTransf); + lgTrace($"MACRO | Com Write 02 | memName: {memAddr} | valReq: {valReq} | vTransf: {vTransf}"); + if (utils.CRB("recTime")) + { + TimingData.addResult(cIobConf.codIOB, "MACRO-SHORT", stopwatch.ElapsedTicks); + } +#endif + } + stopwatch.Stop(); + } + catch (Exception exc) + { + lgError(exc, "Errore in setNumCom MITSUBISHI"); + connectionOk = false; + } + answ = true; + } + return answ; + } + + /// + /// Effettua impostazione del conteggio pezzi richiesti + /// + /// + public override bool setPzComm(int pzReq) + { + bool answ = false; + // ...SE abilitato da conf IOB + if (cIobConf.optPar.Count > 0 && getOptPar("ENABLE_PZ_REQ") == "TRUE") + { + // scrivo valore 0 x il contapezzi + try + { + string memAddr = memAddrPzReq; + lgTrace($"INIT setPzComm | memName: {memAddr}"); + // contapezzi ATTUALE + if (!string.IsNullOrEmpty(memAddr)) + { + // verifico quale modalità sia richiesta: STD (6711) oppure BIT (Custom, con + // indicazione area) + if (memAddr.StartsWith("STD")) + { + // inizio verifica area memoria/parametro levando prima parte codice + memAddr = memAddr.Replace("STD.", ""); + } + // var di appoggio + int cntAddr = 0; + // var contapezzi a zero.... + object newVal = new object(); + newVal = pzReq; + // verifico se si tratta di lettura parametro... formato tipo STD.PAR.6711 +#if false + if (memAddr.StartsWith("PAR.")) + { + // recupero parametro... + int.TryParse(memAddr.Replace("PAR.", ""), out cntAddr); + if (cntAddr == 0) + { + cntAddr = 6711; + } + + // processo SET contapezzi (lavorati) + stopwatch.Restart(); + MITSUBISHI_ref.F_RW_Param_Integer(true, cntAddr, 3, ref newVal); + if (utils.CRB("recTime")) + { + TimingData.addResult(cIobConf.codIOB, string.Format("W{0}-PAR", 4), stopwatch.ElapsedTicks); + } + } + else if (memAddr.StartsWith("MACRO.")) + { + // recupero parametro... + int.TryParse(memAddr.Replace("MACRO.", ""), out cntAddr); + if (cntAddr == 0) + { + cntAddr = 9999; + } + lgTrace($"MACRO | Pz Write 01 | memName: {memAddr} | idx: {cntAddr}"); + // processo SET contapezzi (lavorati) + stopwatch.Restart(); + // se > 2^16 scrivo con INT, sennò con double... + short valTrShr = 0; + double valTrDbl = 0; + if (pzReq < Math.Pow(2, 16)) + { + valTrShr = (short)pzReq; + answ = MITSUBISHIMemMacroRW(true, cntAddr, ref valTrShr); + //answ = MITSUBISHI_ref.F_RW_Macro_Short(true, cntAddr, ref valTrShr); + lgTrace($"MACRO | Com Write 02 SHORT | memName: {memAddr} | pzReq: {pzReq} | valTrShr: {valTrShr}"); + } + // sennò double! + else + { + valTrDbl = (double)pzReq; + answ = MITSUBISHIMemMacroRW(true, cntAddr, ref valTrDbl); + //answ = MITSUBISHI_ref.F_RW_Macro_Double(true, cntAddr, ref valTrDbl); + lgTrace($"MACRO | Com Write 02 DOUBLE | memName: {memAddr} | pzReq: {pzReq} | valTrDbl: {valTrDbl}"); + } + if (utils.CRB("recTime")) + { + TimingData.addResult(cIobConf.codIOB, "MACRO-SHORT", stopwatch.ElapsedTicks); + } + } + // altrimenti se legge da area memoria specifica leggo da li... formto tipo STD.D.1604.DW + else + { + memAddressMITSUBISHI areaCounter = new memAddressMITSUBISHI(memAddr); + + if (isVerboseLog) + { + lgInfo("setPzComm [0] area memoria: {0}.{1}.{2}", areaCounter.mType, areaCounter.mPos, areaCounter.vType); + } + // leggo! + stopwatch.Restart(); + // switch x tipo dati --> tipo lettura... e salvo ultimo conteggio rilevato + switch (areaCounter.vType) + { + case "B": + byte valB = (byte)pzReq; + MITSUBISHI_ref.F_RW_Byte(true, areaCounter.mType, areaCounter.mPos, ref valB); + newVal = valB; + break; + + case "D": + ushort valW = (ushort)pzReq; + MITSUBISHI_ref.F_RW_Word(true, areaCounter.mType, areaCounter.mPos, ref valW); + newVal = valW; + break; + + case "DW": + uint valDW = (uint)pzReq; + MITSUBISHI_ref.F_RW_DWord(true, areaCounter.mType, areaCounter.mPos, ref valDW); + break; + + default: + break; + } + if (utils.CRB("recTime")) + { + TimingData.addResult(cIobConf.codIOB, string.Format("W-{0}.{1}.{2}", areaCounter.mType, areaCounter.mPos, areaCounter.vType), stopwatch.ElapsedTicks); + } + } +#endif + stopwatch.Stop(); + } + } + catch (Exception exc) + { + lgError($"Errore in SET PzReq Commessa MITSUBISHI{Environment.NewLine}{exc}"); + connectionOk = false; + } + answ = true; + } + return answ; + } + + /// + /// Override connessione + /// + public override void tryConnect() + { + if (!connectionOk) + { + // controllo che il ping sia stato tentato almeno pingTestSec fa... + if (DateTime.Now.Subtract(lastPING).TotalSeconds > utils.CRI("pingTestSec")) + { + if (verboseLog || periodicLog) + { + lgInfo("MITSUBISHI: ConnKO - tryConnect"); + } + // in primis salvo data ping... + lastPING = DateTime.Now; + // ora PING!!! + Ping pingSender = new Ping(); + IPAddress address = IPAddress.Loopback; + IPAddress.TryParse(cIobConf.cncIpAddr, out address); + PingReply reply; + try + { + // se != null --> uso address... + if (address != null) + { + reply = pingSender.Send(address, 100); + } + else + { + reply = pingSender.Send(cIobConf.cncIpAddr, 100); + } + } + catch + { + reply = pingSender.Send(IPAddress.Loopback, 100); + } + // se passa il ping faccio il resto... + if (reply.Status == IPStatus.Success) + { + string szStatusConnection = ""; + try + { + // ora provo connessione... + parentForm.commPlcActive = true; + + // Open communication + int iRet = 0; + iRet = oEZNcAutCom.SetTCPIPProtocol(ipAddr, ezPort); + iRet = oEZNcAutCom.Open3((int)sysType, 1, 10, hostName); + parentForm.commPlcActive = false; + lgInfo($"Mitubishi | open Result: {iRet}"); + connectionOk = iRet == 0; + connectionOk = true; + // refresh stato allarmi!!! + if (connectionOk) + { + checkVetoQueueIn(); + dtAvvioAdp = DateTime.Now; + if (adpRunning) + { + lgInfo("Connessione OK"); + } + } + else + { + lgError("Impossibile procedere, connessione mancante..."); + } + } + catch (Exception exc) + { + lgFatal(string.Format("Errore nella connessione all'adapter MITSUBISHI: {0}{1}{2}", szStatusConnection, Environment.NewLine, exc)); + connectionOk = false; + lgInfo(string.Format("Eccezione in TryConnect, Adapter NON running, pausa di {0} msec prima di ulteriori tentativi di riconnessione", utils.CRI("waitRecMSec"))); + } + } + else + { + // loggo no risposta ping ... + connectionOk = false; + if (verboseLog || periodicLog) + { + lgInfo(string.Format("Attenzione: controllo PING fallito per IP {0} - {1}", cIobConf.cncPingAddr, reply.Status)); + } + } + } + } + // se non è ancora connesso faccio procesisng memoria caso disconnesso... + if (!connectionOk) + { + // processo semafori ed invio... + processMemoryDiscon(); + } + } + + /// + /// Override disconnessione + /// + public override void tryDisconnect() + { + if (connectionOk) + { + string szStatusConnection = ""; + try + { + // Close. + var iRet = oEZNcAutCom.Close(); + //Release object + oEZNcAutCom = null; + connectionOk = false; + // resetto timing! + TimingData.resetData(); + lgInfo(szStatusConnection); + lgInfo("Effettuata disconnessione adapter MITSUBISHI!"); + } + catch (Exception exc) + { + lgFatal(exc, "Errore nella disconnessione dall'adapter MITSUBISHI"); + } + } + else + { + lgError("IMPOSSIBILE effettuare disconnessione: Connessione non disponibile..."); + } + queueInEnabCurr = false; + } + + #endregion Public Methods + + #region Internal Fields + + /// + /// LookUpTable di decodifica da CNC a segnali tipo bitmap MAPO + /// + internal Dictionary signLUT = new Dictionary(); + + #endregion Internal Fields + + #region Internal Enums + + internal enum MemType + { + /// + /// Valori generico (es Y60 )x60, hex) --> 10'000 + 96 = 10'096 + /// + GenData, + + /// + /// Parametri # + /// + Param, + + /// + /// Var100 + /// + Var100, + + /// + /// Var500 + /// + Var500 + } + + internal enum PROGRAMTYPE + { + /// + /// Main Program メインプログラム + /// + EZNC_MAINPRG = 0, + + /// + /// Sub Program サブプログラム + /// + EZNC_SUBPRG = 1, + } + + /// + /// Controllo specifico da gestire + /// + internal enum SYSTEMTYPE + { + /// + /// M700L + /// + EZNC_SYS_MELDAS700L = 5, + + /// + /// M700M + /// + EZNC_SYS_MELDAS700M = 6, + + /// + /// C70 + /// + EZNC_SYS_MELDASC70 = 7, + + /// + /// M800L + /// + EZNC_SYS_MELDAS800L = 8, + + /// + /// M800M + /// + EZNC_SYS_MELDAS800M = 9, + + /// + /// C80 + /// + EZNC_SYS_CNCC80 = 10, + } + + #endregion Internal Enums + + #region Protected Fields + + /// + /// Porta di comunicazione INT + /// + protected int ezPort = 683; + + /// + /// Nome amcchina x connessione + /// + protected string hostName = "EZNC_LOCALHOST"; + + /// + /// Nome/IP del CN + /// + protected string ipAddr = ""; + + /// + /// Obj di comunicazione Mitsubishi + /// + protected EZNCAUTLib.DispEZNcCommunication oEZNcAutCom = null; + + #endregion Protected Fields + + #region Protected Methods + + /// + /// Metodo da overridare x scrivere DAVVERO i parametri sul PLC + /// + /// + protected override void plcWriteParams(ref List updatedPar) + { + lgTrace($"plcWriteParams: richiesta per {updatedPar.Count} params"); + foreach (var item in updatedPar) + { + lgInfo($"ITEM | {item.uid} | {item.value}"); + // salvo i valori ricevuti + upsertKey(item.uid, item.reqValue); + // se i valori richiesto e fatto corrispondono... resetto! + if (item.reqValue.Trim() == item.value.Trim()) + { + // resetto richiesta! + item.reqValue = ""; + } + } + } + + #endregion Protected Methods + + #region Private Fields + + private DateTime lastParRefr = DateTime.Now; + private DateTime lastSigRefr = DateTime.Now; + private DateTime lastVarRefr = DateTime.Now; + + /// + /// Max num caratteri string ammessi VAR label + /// + private int maxVarStrLen = 7; + + /// + /// Num celle Var da leggere + /// + private int MemVarSize = 1; + + /// + /// Indirizzo partenza lettura Var(100/500) + /// + private int MemVarStart = 500; + + /// + /// Num celle Param da leggere + /// + private int ParamSize = 1; + + /// + /// Indirizzo partenza lettura Param + /// + private int ParamStart = 8000; + + /// + /// Num celle Signal da leggere + /// + private int SignSize = 3; + + /// + /// Indirizzo partenza lettura Signal + /// + private int SignStart = 10096; + + /// + /// Tipo di controllo gestito + /// + private SYSTEMTYPE sysType = SYSTEMTYPE.EZNC_SYS_MELDAS700L; + + #endregion Private Fields + + #region Private Properties + + /// + /// Dictionary contenuto memorie Param + /// + private Dictionary DictParam { get; set; } = new Dictionary(); + + /// + /// Dictionary contenuto dati Signal (es Y) + /// + private Dictionary DictSign { get; set; } = new Dictionary(); + + /// + /// Dictionary contenuto memorie Var + /// + private Dictionary DictVar { get; set; } = new Dictionary(); + + private string memAddrArt + { + get + { + string memAddr = ""; + if (memMap != null && memMap.mMapWrite != null) + { + //cerco in primis modalità NUM altrimenti standard... + if (memMap.mMapWrite.ContainsKey("setArtNum")) + { + memAddr = memMap.mMapWrite["setArtNum"].memAddr; + } + // se vuoto provo altra alternativa... + if (string.IsNullOrEmpty(memAddr) && memMap.mMapWrite.ContainsKey("setArt")) + { + memAddr = memMap.mMapWrite["setArt"].memAddr; + } + } + // se non trovato... leggo da OPT_PAR + if (string.IsNullOrEmpty(memAddr)) + { + memAddr = getOptPar("SET_NUM_ART"); + } + // bonifica variabile da definizione STD iniziale... + if (memAddr.StartsWith("STD")) + { + memAddr = memAddr.Replace("STD.", ""); + } + return memAddr; + } + } + + private string memAddrCaden + { + get + { + string memAddr = ""; + if (memMap != null && memMap.mMapWrite != null) + { + //cerco in primis modalità NUM altrimenti standard... + if (memMap.mMapWrite.ContainsKey("Cadenza")) + { + memAddr = memMap.mMapWrite["Cadenza"].memAddr; + } + } + // se non trovato... leggo da OPT_PAR + if (string.IsNullOrEmpty(memAddr)) + { + memAddr = getOptPar("PZCAD_MODE"); + } + // bonifica variabile da definizione STD iniziale... + if (memAddr.StartsWith("STD")) + { + memAddr = memAddr.Replace("STD.", ""); + } + return memAddr; + } + } + + private string memAddrCom + { + get + { + string memAddr = ""; + if (memMap != null && memMap.mMapWrite != null) + { + //cerco in primis modalità NUM altrimenti standard... + if (memMap.mMapWrite.ContainsKey("setCommNum")) + { + memAddr = memMap.mMapWrite["setCommNum"].memAddr; + } + // se vuoto provo altra alternativa... + if (string.IsNullOrEmpty(memAddr) && memMap.mMapWrite.ContainsKey("setComm")) + { + memAddr = memMap.mMapWrite["setComm"].memAddr; + } + } + // se non trovato... leggo da OPT_PAR + if (string.IsNullOrEmpty(memAddr)) + { + memAddr = getOptPar("SET_NUM_COM"); + } + // bonifica variabile da definizione STD iniziale... + if (memAddr.StartsWith("STD")) + { + memAddr = memAddr.Replace("STD.", ""); + } + return memAddr; + } + } + + private string memAddrPzCnt + { + get + { + string memAddr = ""; + if (memMap != null && memMap.mMapWrite != null) + { + //cerco in primis modalità NUM altrimenti standard... + if (memMap.mMapWrite.ContainsKey("ContatoreParziale")) + { + memAddr = memMap.mMapWrite["ContatoreParziale"].memAddr; + } + } + // se non trovato... leggo da OPT_PAR + if (string.IsNullOrEmpty(memAddr)) + { + memAddr = getOptPar("PZCOUNT_MODE"); + } + // bonifica variabile da definizione STD iniziale... + if (memAddr.StartsWith("STD")) + { + memAddr = memAddr.Replace("STD.", ""); + } + return memAddr; + } + } + + private string memAddrPzCntTot + { + get + { + string memAddr = ""; + if (memMap != null && memMap.mMapWrite != null) + { + //cerco in primis modalità NUM altrimenti standard... + if (memMap.mMapWrite.ContainsKey("ContatoreAssoluto")) + { + memAddr = memMap.mMapWrite["ContatoreAssoluto"].memAddr; + } + } + // se non trovato... leggo da OPT_PAR + if (string.IsNullOrEmpty(memAddr)) + { + memAddr = getOptPar("PZGTOT_MODE"); + } + // bonifica variabile da definizione STD iniziale... + if (memAddr.StartsWith("STD")) + { + memAddr = memAddr.Replace("STD.", ""); + } + return memAddr; + } + } + + private string memAddrPzReq + { + get + { + string memAddr = ""; + if (memMap != null && memMap.mMapWrite != null) + { + //cerco in primis modalità NUM altrimenti standard... + if (memMap.mMapWrite.ContainsKey("setPzComm")) + { + memAddr = memMap.mMapWrite["setPzComm"].memAddr; + } + } + // se non trovato... leggo da OPT_PAR + if (string.IsNullOrEmpty(memAddr)) + { + memAddr = getOptPar("PZREQ_MODE"); + } + // bonifica variabile da definizione STD iniziale... + if (memAddr.StartsWith("STD")) + { + memAddr = memAddr.Replace("STD.", ""); + } + return memAddr; + } + } + + private string memNameArt + { + get + { + string memName = ""; + if (memMap != null && memMap.mMapWrite != null) + { + //cerco in primis modalità NUM altrimenti standard... + if (memMap.mMapWrite.ContainsKey("setArtNum")) + { + memName = "setArtNum"; + } + // se vuoto provo altra alternativa... + if (string.IsNullOrEmpty(memName) && memMap.mMapWrite.ContainsKey("setArt")) + { + memName = "setArt"; + } + } + // se non trovato... leggo da OPT_PAR + if (string.IsNullOrEmpty(memName)) + { + memName = "PZ_COUNT"; + } + return memName; + } + } + + private string memNameCaden + { + get + { + string memName = ""; + if (memMap != null && memMap.mMapWrite != null) + { + //cerco in primis modalità NUM altrimenti standard... + if (memMap.mMapWrite.ContainsKey("Cadenza")) + { + memName = "Cadenza"; + } + } + // se non trovato... leggo da OPT_PAR + if (string.IsNullOrEmpty(memName)) + { + memName = "CICLE_CAD"; + } + return memName; + } + } + + private string memNameCom + { + get + { + string memName = ""; + if (memMap != null && memMap.mMapWrite != null) + { + //cerco in primis modalità NUM altrimenti standard... + if (memMap.mMapWrite.ContainsKey("setCommNum")) + { + memName = "setCommNum"; + } + // se vuoto provo altra alternativa... + if (string.IsNullOrEmpty(memName) && memMap.mMapWrite.ContainsKey("setComm")) + { + memName = "setComm"; + } + } + // se non trovato... leggo da OPT_PAR + if (string.IsNullOrEmpty(memName)) + { + memName = "SET_NUM_COM"; + } + return memName; + } + } + + private string memNamePzCnt + { + get + { + string memName = ""; + if (memMap != null && memMap.mMapWrite != null) + { + //cerco in primis modalità NUM altrimenti standard... + if (memMap.mMapWrite.ContainsKey("ContatoreParziale")) + { + memName = "ContatoreParziale"; + } + } + // se non trovato... leggo da OPT_PAR + if (string.IsNullOrEmpty(memName)) + { + memName = "PZ_COUNT"; + } + return memName; + } + } + + private string memNamePzCntTot + { + get + { + string memName = ""; + if (memMap != null && memMap.mMapWrite != null) + { + //cerco in primis modalità NUM altrimenti standard... + if (memMap.mMapWrite.ContainsKey("ContatoreAssoluto")) + { + memName = "ContatoreAssoluto"; + } + } + // se non trovato... leggo da OPT_PAR + if (string.IsNullOrEmpty(memName)) + { + memName = "PZ_GTOT"; + } + return memName; + } + } + + private string memNamePzReq + { + get + { + string memName = ""; + if (memMap != null && memMap.mMapWrite != null) + { + //cerco in primis modalità NUM altrimenti standard... + if (memMap.mMapWrite.ContainsKey("setPzComm")) + { + memName = "setPzComm"; + } + } + // se non trovato... leggo da OPT_PAR + if (string.IsNullOrEmpty(memName)) + { + memName = "PZ_REQ"; + } + return memName; + } + } + + #endregion Private Properties + + #region Private Methods + + /// + /// Effettua decodifica aree memoria alla bitmap usata x MAPO + /// + private void decodeToBitmap() + { + /*------------------------------------------ + * Bitmap MAPO STD 54 + * B0: POWER_ON + * B1: RUN + * B2: pzCount + * B3: allarme + * B4: manuale + * B5: EmergArmed (1 = emergenza, 0 = NON emergenza) + * + *------------------------------------------*/ + // init a zero... + B_input = 0; + if (connectionOk) + { + // vedere conf: + // Y60: RED + // Y61: YELLOW + // Y62: GREEN + // Y63: BLUE + + // default connesso = poweron, valutare se blue? + B_input += 1 << 0; + + string bKey = ""; + string bVal = ""; + // decodifico impiegando dictionary... cercando il TIPO di memoria & co... + char area; + // valore INVERTED (default è false) + bool invSignal = false; + string memArea = ""; + string cVal = ""; + string[] memIdx; + int bitNum = 0; + int byteNum = 0; + int byte2check = 0; + for (int i = 0; i < 8; i++) + { + bKey = $"BIT{i}"; + // cerco se ci sia in LUT + if (signLUT.ContainsKey(bKey)) + { + // recupero nome variabile... + bVal = signLUT[bKey]; + // se l'area è PZCOUNT... processo PUNTUALMENTE il CONTAPEZZI... + if (bVal.StartsWith("PZCOUNT")) + { + // disabilito pzcount singolo +#if false + // procedo SOLO SE è enabled IOB + if (IobOnline) + { + try + { + currODL = utils.callUrl(urlGetCurrODL); + // solo SE HO un ODL... + if (string.IsNullOrEmpty(currODL) || currODL == "0") + { + if (periodicLog) + { + lgInfo(string.Format("MITSUBISHI | Lettura ODL andata a vuoto: currODL: {0}", currODL)); + } + } + else + { + // se variato o scaduto timeout log... + if (periodicLog || ($"{currIdxODL}" != currODL)) + { + lgInfo(string.Format("MITSUBISHI | Lettura ODL, currODL: {0} --> currIdxODL prec: {1}", currODL, currIdxODL)); + } + // provo a salvare nuovo ODL + int.TryParse(currODL, out currIdxODL); + } + } + catch (Exception exc) + { + if (DateTime.Now.Subtract(lastWarnODL).TotalSeconds > 15) + { + lgError(exc, "Errore in fase di chiamata URL x ODL corrente | URL chiamato: {0}", urlGetCurrODL); + lastWarnODL = DateTime.Now; + } + } + } + else + { + // imposto currODL a vuoto! + currODL = ""; + if (periodicLog) + { + lgInfo($"MITSUBISHI | Lettura ODL non effettuata: IobOnline: {IobOnline} | currODL impostato a vuoto"); + } + } + if (!string.IsNullOrEmpty(currODL) && currODL != "0") + { + // controllo se è passato intervallo minimo tra 2 + // controlli/elaborazioni x distanziare invio e ridurre letture + if (DateTime.Now >= lastPzCountSend.AddMilliseconds(pzCountDelay)) + { + // se sono differenti MOSTRO... + if (contapezziPLC != contapezziIOB) + { + // registro contapezzi + lgInfo($"Differenza Contapezzi: contapezziPLC: {contapezziPLC} | contapezziIOB {contapezziIOB}"); + } + + if ((enablePzCountByApp || enablePzCountByIob) && !(disablePzCountByIob)) + { + // verifico se variato contapezzi... + if (contapezziPLC > contapezziIOB) + { + // salvo nuovo contapezzi (incremento di 1...) + + // richiesta refresh conteggio + contapezziIOB++; + needRefreshPzCount = true; + // salvo in semaforo! + B_input += 1 << 2; + // registro contapezzi + lgInfo($"contapezziPLC MITSUBISHI: {contapezziPLC} | contapezziIOB {contapezziIOB}"); + } + // invio a server contapezzi (aggiornato) + string retVal = utils.callUrl(urlSetPzCount + contapezziIOB.ToString()); + // verifica se tutto OK + if (retVal != contapezziIOB.ToString()) + { + // errore salvataggio contapezzi + lgInfo($"Errore salvataggio Contapezzi MITSUBISHI: contapezziPLC {contapezziPLC} | contapezziIOB {contapezziIOB} | risposta: {retVal}"); + // rileggo il counter pezzi da server + pzCntReload(true); + } + // resetto timer... + lastPzCountSend = DateTime.Now; + } + } + } + else + { + if (DateTime.Now >= lastPzCountSend.AddMilliseconds(pzCountDelay)) + { + lgInfo($"Attenzione: mancanza ODL non procedo con gestione contapezzi. contapezziPLC MITSUBISHI: {contapezziPLC} | contapezziIOB {contapezziIOB}"); + // resetto timer... + lastPzCountSend = DateTime.Now; + } + } +#endif + } + else // area "normale" byte.bit + { + // di norma è segnale normale => 1, altrimenti inverse => 0... + invSignal = false; + // cerco se sia inverse (primo char "!") --> registro e elimino char... + invSignal = bVal.StartsWith("!"); + // se è da tracciare... + if (mem2trace.Contains($"|{bKey}|")) + { + if (invSignal) + { + lgTrace($"Segnale invertito | bVal: {bVal}"); + } + } + // tolgo comunque inversione... + bVal = bVal.Replace("!", ""); + + // recupero int key + int iKey = 0; + int.TryParse(bVal, out iKey); + // leggo dizionario richiesto + if (DictSign.ContainsKey(iKey)) + { + cVal = DictSign[iKey]; + } + + // a secondo che sia segnale normale o inverso... + if (invSignal) + { + // controllo se il bit sia NON attivo (basso)... == 0 + if (cVal == "0") + { + B_input += 1 << i; + } + } + else + { + // controllo se il bit sia attivo (alto)... == 1 + if (cVal == "1") + { + B_input += 1 << i; + } + } + + // se è da tracciare... + if (mem2trace.Contains($"|{bKey}|")) + { + var bMapAct = Convert.ToString(byte2check, 2).PadLeft(8, '0'); + var bMapReq = Convert.ToString((1 << bitNum), 2).PadLeft(8, '0'); + lgTrace($"Valore | bKey: {bKey} | bVal: {bVal} | byte: {bMapAct} | tgt: {bMapReq} | B_input: {B_input}"); + } + } + } + } + } + // log opzionale! + if (verboseLog) + { + lgInfo(string.Format("Trasformazione B_input: {0}", B_input)); + } + } + + /// + /// Recupera il valore INT dal nome del parametro per successivo processing + /// + /// + /// + private string getValByMemAddr(string memAddr) + { + lgTrace($"inizio getValByMemAddr | memAddr: {memAddr}"); + string answ = ""; + // verifico quale modalità sia richiesta: STD (6711) oppure BIT (Custom, con indicazione area) + if (memAddr.StartsWith("STD")) + { + // inizio verifica area memoria/parametro levando prima parte codice + memAddr = memAddr.Replace("STD.", ""); + } + // var di appoggio + int cntAddr = 0; + // verifico se si tratta di lettura parametro... formato tipo STD.PAR.8001 + if (memAddr.StartsWith("PAR.")) + { + // recupero parametro... + int.TryParse(memAddr.Replace("PAR.", ""), out cntAddr); + // processo parametro + stopwatch.Restart(); + // cerco in dizionario... + if (DictParam.ContainsKey(cntAddr)) + { + answ = DictParam[cntAddr]; + } + } + stopwatch.Stop(); + return answ; + } + + /// + /// Recupera il valore INT dal nome del parametro per successivo processing + /// + /// + /// + private string getValByParam(string varName) + { + string memAddr = getOptPar(varName); + string answ = getValByMemAddr(memAddr); + if (isVerboseLog) + { + lgInfo($"[3] PAR letto: {varName} | {answ}"); + } + return answ; + } + + /// + /// Lettura area parametri mitsubishi come configurato + /// + private void ReadMitsubParams() + { + DateTime adesso = DateTime.Now; + int parSPeriod = samplePeriod * 3; + // controllo se sia passato il samplePeriod minimo... + if (adesso.Subtract(lastParRefr.AddMilliseconds(parSPeriod)).TotalSeconds > 0) + { + lastParRefr = adesso; + // per prima cosa processo la lettura parametri e li salvo in DICT + int lAxis = 0; + object parValue = ""; + stopwatch.Restart(); + int iRet = oEZNcAutCom.Parameter_GetData3(0, ParamStart, ParamSize, lAxis, out parValue); + if (utils.CRB("recTime")) + { + TimingData.addResult(cIobConf.codIOB, $"R{ParamSize}-PAR", stopwatch.ElapsedTicks); + } + // converto in array di string... + string[] rawData = (string[])parValue; + // salvo in dict... + for (int i = 0; i < ParamSize; i++) + { + UpsertParam(ParamStart + i, rawData[i]); + } + } + else + { + lgTrace($"Saltata ReadMitsubParams x periodo minimo {parSPeriod} ms"); + } + } + + /// + /// Upsert info in DICT dei Params (es 8001..8003 contatori pezzi) + /// + /// + /// + private void UpsertParam(int key, string value) + { + if (DictParam.ContainsKey(key)) + { + DictParam[key] = value; + } + else + { + DictParam.Add(key, value); + } + } + + /// + /// Upsert info in DICT dei SIGNAL (es Y) + /// + /// + /// + private void UpsertSign(int key, string value) + { + if (DictSign.ContainsKey(key)) + { + DictSign[key] = value; + } + else + { + DictSign.Add(key, value); + } + } + + #endregion Private Methods + } +} \ No newline at end of file diff --git a/IOB-WIN-NEXT/IobRest/Base.cs b/IOB-WIN-NEXT/IobRest/Base.cs index e3046a50..c24ca897 100644 --- a/IOB-WIN-NEXT/IobRest/Base.cs +++ b/IOB-WIN-NEXT/IobRest/Base.cs @@ -270,8 +270,6 @@ namespace IOB_WIN_NEXT.IobRest /// protected Dictionary RestDataLUT = new Dictionary(); - protected int samplePeriod = 1000; - /// /// Timeout chiamate REST /// diff --git a/IOB-WIN-NEXT/utils.cs b/IOB-WIN-NEXT/utils.cs index f39b2b30..7f9774a6 100644 --- a/IOB-WIN-NEXT/utils.cs +++ b/IOB-WIN-NEXT/utils.cs @@ -131,6 +131,15 @@ namespace IOB_WIN_NEXT string answ = new string(input.Where(c => char.IsLetter(c) || char.IsDigit(c)).ToArray()); return answ; } + /// + /// Converte una stringa libera in una stringa valida (ovvero SOLO numeri/lettere) + /// + /// + /// + public static string purgedChar2String(string input) + { + return purgedChar2String(input.ToCharArray()); + } #endregion Public Methods } diff --git a/TestPrelimCli/Mitsubishi/Program.cs b/TestPrelimCli/Mitsubishi/Program.cs index a77ada93..e449eae5 100644 --- a/TestPrelimCli/Mitsubishi/Program.cs +++ b/TestPrelimCli/Mitsubishi/Program.cs @@ -38,11 +38,11 @@ namespace Mitsubishi // [Local variable declaration] object BlockValue = ""; - int Ret = 0; + int iRet = 0; //Open communication - Ret = oEZNcAutCom.SetTCPIPProtocol("192.168.213.199", 683); - //Console.WriteLine($"R: {Ret}"); - Ret = oEZNcAutCom.Open3(5, 1, 10, "EZNC_LOCALHOST"); + iRet = oEZNcAutCom.SetTCPIPProtocol("192.168.213.199", 683); + //Console.WriteLine($"R: {iRet}"); + iRet = oEZNcAutCom.Open3(5, 1, 10, "EZNC_LOCALHOST"); DoLog(sep); DoLog("Retrieve Serial/Vers"); @@ -90,6 +90,12 @@ namespace Mitsubishi // preparo memorie string prgText = ""; int prgState = 0; + // solo nome... + iRet = oEZNcAutCom.Program_GetProgramNumber2((Int32)PROGRAMTYPE.EZNC_MAINPRG, out String strProgramNo); + DoLog($"ProgramName: {strProgramNo}"); + DoLog(""); + + // leggo contenuto try { oEZNcAutCom.Program_CurrentBlockRead(10, out prgText, out prgState); @@ -125,7 +131,7 @@ namespace Mitsubishi double pdPosit = 0; for (int i = 1; i < 4; i++) { - Ret = oEZNcAutCom.Position_GetCurrentPosition(i, out pdPosit); + iRet = oEZNcAutCom.Position_GetCurrentPosition(i, out pdPosit); DoLog($"Pos: {i} | {pdPosit}"); } DoLog(sep); @@ -287,7 +293,7 @@ namespace Mitsubishi DoLog(""); // Close. - Ret = oEZNcAutCom.Close(); + iRet = oEZNcAutCom.Close(); //Release object oEZNcAutCom = null; @@ -302,6 +308,12 @@ namespace Mitsubishi Console.WriteLine(logMessage); } + public enum PROGRAMTYPE + { + EZNC_MAINPRG = 0, //メインプログラム + EZNC_SUBPRG = 1, //サブプログラム + } + protected static string outPath = ""; private static string sep = "------------------------";