diff --git a/IOB-UT-NEXT/Enums.cs b/IOB-UT-NEXT/Enums.cs index c35354d0..bf61c247 100644 --- a/IOB-UT-NEXT/Enums.cs +++ b/IOB-UT-NEXT/Enums.cs @@ -347,6 +347,11 @@ namespace IOB_UT_NEXT /// MODBUS_TCP_CENTERFRIGO, + /// + /// Adapter modbus (+ file) x FIMAT (Tenditalia) + /// + MODBUS_TCP_FIMAT, + /// /// Adapter ModBus TCP versione HAM (Pizzaferri) /// @@ -362,6 +367,11 @@ namespace IOB_UT_NEXT /// MODBUS_TCP_IMAS_AEROMEC, + /// + /// Adapter Modubus TCP versione Rimor (IMI Remosa) + /// + MODBUS_TCP_RIMOR, + /// /// Adapter Modubus TCP versione Saim (Giacovelli) /// diff --git a/IOB-WIN-NEXT/AdapterForm.cs b/IOB-WIN-NEXT/AdapterForm.cs index 265003a0..5cb08852 100644 --- a/IOB-WIN-NEXT/AdapterForm.cs +++ b/IOB-WIN-NEXT/AdapterForm.cs @@ -1679,6 +1679,11 @@ namespace IOB_WIN_NEXT start.Enabled = true; break; + case tipoAdapter.MODBUS_TCP_FIMAT: + iobObj = new IobModbusTCPFimat(this, IOBConf); + start.Enabled = true; + break; + case tipoAdapter.MODBUS_TCP_HAM: iobObj = new IobModbusTCPHam(this, IOBConf); start.Enabled = true; @@ -1694,6 +1699,11 @@ namespace IOB_WIN_NEXT start.Enabled = true; break; + case tipoAdapter.MODBUS_TCP_RIMOR: + iobObj = new IobModbusTCPRimor(this, IOBConf); + start.Enabled = true; + break; + case tipoAdapter.MODBUS_TCP_SAIM: iobObj = new IobModbusTCPSaim(this, IOBConf); start.Enabled = true; diff --git a/IOB-WIN-NEXT/DATA/CONF/3026-MBus.ini b/IOB-WIN-NEXT/DATA/CONF/3026-MBus.ini index 93d60e70..5eb3be65 100644 --- a/IOB-WIN-NEXT/DATA/CONF/3026-MBus.ini +++ b/IOB-WIN-NEXT/DATA/CONF/3026-MBus.ini @@ -1,6 +1,6 @@ ;Configurazione IOB-WIN [IOB] -;Impianto Cedax di Turi (test) - Giacovelli +;Impianto IMAX Aeromec - Jetco (non va, sostituito con OPC-UA) CNCTYPE=MODBUS_TCP_IMAX_AEROMEC PING_MS_TIMEOUT=1000 MinDeltaSec=5 diff --git a/IOB-WIN-NEXT/DATA/CONF/IMI_RIMOR_SAB_01.ini b/IOB-WIN-NEXT/DATA/CONF/IMI_RIMOR_SAB_01.ini new file mode 100644 index 00000000..ae1c96cd --- /dev/null +++ b/IOB-WIN-NEXT/DATA/CONF/IMI_RIMOR_SAB_01.ini @@ -0,0 +1,78 @@ +;Configurazione IOB-WIN +[IOB] +;Impianto Rimor sabbiatura - IMI Remosa +CNCTYPE=MODBUS_TCP_RIMOR +PING_MS_TIMEOUT=1000 +MinDeltaSec=5 + +[MACHINE] +VENDOR=RIMOR +MODEL=Sabbiatura - PLC + +[CNC] +IP=192.168.10.5 +PORT=502 + +[SERVER] +MPIP=http://192.168.0.110 +MPURL=/MP/IO +CMDBASE=/IOB/input/ +CMDFLOG=/IOB/flog/ +CMDALIVE=/IOB +CMDENABLED=/IOB/enabled/ +CMDADV1=?valore= +CMDREBO=/sendReboot.aspx?idxMacchina= + +[MEMORY] +ADDR_READ=40001 +ADDR_WRITE=40001 +SIZE_READ=10 +SIZE_WRITE=0 +HR_BASE_ADDR=400000 +DELTA_BASE=0 + + +[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] +;PZCOUNT_MODE=STD.[PAR/MEM].info|BIT.indice +PZCOUNT_MODE=STD.DB85.DBRE16 +DISABLE_PZCOUNT=TRUE +ENABLE_SEND_PZC_BLOCK=TRUE +MIN_SEND_PZC_BLOCK=0 +MAX_SEND_PZC_BLOCK=100 +; GEST DATI DYN +ENABLE_DYN_DATA=TRUE +FORCE_DYN_DATA=TRUE +; gestione delta minimo accettabile tra min/MAX +DELTA_VAL=0.1 + +; clock base (da 10ms) +timerIntMs=10 + +; conf parametri memoria READ/WRITE +PARAM_CONF=IMI_RIMOR_SAB_01.json + +NO_PING=FALSE +; conf blocchi memoria x READ +MEM_BLOCK=IMI_RIMOR_SAB_01_MBlock.json +; conf aree allarme +ALARM_CONF=IMI_RIMOR_SAB_01_alarm.json + +; rimozione check limiti min/max dynData +disDynDataRangeCheck=true + +[BRANCH] +NAME=master \ No newline at end of file diff --git a/IOB-WIN-NEXT/DATA/CONF/IMI_RIMOR_SAB_01.json b/IOB-WIN-NEXT/DATA/CONF/IMI_RIMOR_SAB_01.json new file mode 100644 index 00000000..0819d07b --- /dev/null +++ b/IOB-WIN-NEXT/DATA/CONF/IMI_RIMOR_SAB_01.json @@ -0,0 +1,207 @@ +{ + "mMapWrite": { }, + "mMapRead": { + "OreFunzFiltro1": { + "name": "OreFunzFiltro1", + "description": "Ore funzionamento filtro 1", + "memAddr": "420201", + "tipoMem": "Int", + "index": 20201, + "size": 1, + "func": "MAX", + "period": 90, + "factor": 0.01, + "minVal": 0, + "maxVal": 999999, + "unit": "h" + }, + "MinFunzFiltro1": { + "name": "MinFunzFiltro1", + "description": "Minuti funzionamento filtro 1", + "memAddr": "420205", + "tipoMem": "Int", + "index": 20205, + "size": 1, + "func": "MAX", + "period": 90, + "factor": 0.01, + "minVal": 0, + "maxVal": 999999, + "unit": "m" + }, + "OreFunzFiltroPar1": { + "name": "OreFunzFiltroPar1", + "description": "Ore funzionamento filtro 1 (contatore parziale azzerabile)", + "memAddr": "420203", + "tipoMem": "Int", + "index": 20203, + "size": 1, + "func": "MAX", + "period": 90, + "factor": 0.01, + "minVal": 0, + "maxVal": 999999, + "unit": "h" + }, + "MinFunzFiltroPar1": { + "name": "MinFunzFiltroPar1", + "description": "Minuti funzionamento filtro 1 (contatore parziale azzerabile)", + "memAddr": "420206", + "tipoMem": "Int", + "index": 20206, + "size": 1, + "func": "MAX", + "period": 90, + "factor": 0.01, + "minVal": 0, + "maxVal": 999999, + "unit": "m" + }, + "OreFunzFiltro2": { + "name": "OreFunzFiltro2", + "description": "Ore funzionamento filtro 2", + "memAddr": "420301", + "tipoMem": "Int", + "index": 20301, + "size": 1, + "func": "MAX", + "period": 90, + "factor": 0.01, + "minVal": 0, + "maxVal": 999999, + "unit": "h" + }, + "MinFunzFiltro2": { + "name": "MinFunzFiltro2", + "description": "Minuti funzionamento filtro 2", + "memAddr": "420305", + "tipoMem": "Int", + "index": 20305, + "size": 1, + "func": "MAX", + "period": 90, + "factor": 0.01, + "minVal": 0, + "maxVal": 999999, + "unit": "m" + }, + "OreFunzFiltroPar2": { + "name": "OreFunzFiltroPar2", + "description": "Ore funzionamento filtro 1 (contatore parziale azzerabile)", + "memAddr": "420303", + "tipoMem": "Int", + "index": 20303, + "size": 1, + "func": "MAX", + "period": 90, + "factor": 0.01, + "minVal": 0, + "maxVal": 999999, + "unit": "h" + }, + "MinFunzFiltroPar2": { + "name": "MinFunzFiltroPar2", + "description": "Minuti funzionamento filtro 1 (contatore parziale azzerabile)", + "memAddr": "420306", + "tipoMem": "Int", + "index": 20306, + "size": 1, + "func": "MAX", + "period": 90, + "factor": 0.01, + "minVal": 0, + "maxVal": 999999, + "unit": "m" + }, + "OreFunzAspiratore": { + "name": "OreFunzAspiratore", + "description": "Ore funzionamento Aspiratore", + "memAddr": "420401", + "tipoMem": "Int", + "index": 20401, + "size": 1, + "func": "MAX", + "period": 90, + "factor": 0.01, + "minVal": 0, + "maxVal": 999999, + "unit": "h" + }, + "MinFunzAspiratore": { + "name": "MinFunzAspiratore", + "description": "Minuti funzionamento Aspiratore", + "memAddr": "420405", + "tipoMem": "Int", + "index": 20405, + "size": 1, + "func": "MAX", + "period": 90, + "factor": 0.01, + "minVal": 0, + "maxVal": 999999, + "unit": "m" + }, + "OreFunzAspiratorePar": { + "name": "OreFunzAspiratorePar", + "description": "Ore funzionamento Aspiratore (contatore parziale azzerabile)", + "memAddr": "420403", + "tipoMem": "Int", + "index": 20403, + "size": 1, + "func": "MAX", + "period": 90, + "factor": 0.01, + "minVal": 0, + "maxVal": 999999, + "unit": "h" + }, + "MinFunzAspiratorePar": { + "name": "MinFunzAspiratorePar", + "description": "Minuti funzionamento Aspiratore (contatore parziale azzerabile)", + "memAddr": "420406", + "tipoMem": "Int", + "index": 20406, + "size": 1, + "func": "MAX", + "period": 90, + "factor": 0.01, + "minVal": 0, + "maxVal": 999999, + "unit": "m" + }, + "DurataLavorazione": { + "name": "DurataLavorazione", + "description": "Durata Lavorazione", + "memAddr": "421002", + "tipoMem": "Int", + "index": 21002, + "size": 1, + "func": "MAX", + "period": 90, + "factor": 0.01, + "minVal": 0, + "maxVal": 999999, + "unit": "h/m" + }, + "StatoLavorazione": { + "name": "StatoLavorazione", + "description": "Stato Lavorazione", + "memAddr": "421004", + "tipoMem": "Int", + "index": 21004, + "size": 1, + "func": "MAX", + "period": 90, + "factor": 0.01, + "minVal": 0, + "maxVal": 999999, + "unit": "#" + } + }, + "optMemPar": { + "AlarmIntCond": "40000|0=0", + "ManualIntCond": "40000|0=1", + "EStopBitCond": "40001.0=1", + "WorkIntCond": "421004|0=2,4" + } +} \ No newline at end of file diff --git a/IOB-WIN-NEXT/DATA/CONF/IMI_RIMOR_SAB_01_MBlock.json b/IOB-WIN-NEXT/DATA/CONF/IMI_RIMOR_SAB_01_MBlock.json new file mode 100644 index 00000000..ccd2b5e4 --- /dev/null +++ b/IOB-WIN-NEXT/DATA/CONF/IMI_RIMOR_SAB_01_MBlock.json @@ -0,0 +1,5 @@ +{ + "ReadBlocks": { + "40000": 10 + } +} \ No newline at end of file diff --git a/IOB-WIN-NEXT/DATA/CONF/IMI_RIMOR_SAB_01_alarm.json b/IOB-WIN-NEXT/DATA/CONF/IMI_RIMOR_SAB_01_alarm.json new file mode 100644 index 00000000..7dd02384 --- /dev/null +++ b/IOB-WIN-NEXT/DATA/CONF/IMI_RIMOR_SAB_01_alarm.json @@ -0,0 +1,52 @@ +[ + { + "description": "Allarmi Impianto", + "tipoMem": "DInt", + "memAddr": "40000", + "index": 0, + "size": 2, + "messages": [ + "##", + "##", + "##", + "##", + "##", + "##", + "##", + "##", + "##EMERGENZA GENERALE", + "##TERMICO SCATTATO", + "##FAULT INVERTER", + "##FAULT STEPPER", + "##CARTER APERTI", + "##PORTA SX APERTA", + "##PORTA DX APERTA", + "##CARTER APERTI" + ] + }, + { + "description": "Allarmi Impianto", + "tipoMem": "DInt", + "memAddr": "40002", + "index": 2, + "size": 2, + "messages": [ + "##TOUT BF NASTRO 1", + "##TOUT BF NASTRO 2", + "##TOUT BF NASTRO 3", + "##TOUT BF NASTRO 4", + "##TOUT BF NASTRO 5", + "##TOUT BF NASTRO 6", + "##ALL MOTORULLO 1", + "##ALL MOTORULLO 2", + "##ALL MOTORULLO 3", + "##ALL MOTORULLO 4", + "##ALL MOTORULLO 5", + "##ALL MOTORULLO 6", + "##", + "##", + "##", + "##" + ] + } +] \ No newline at end of file diff --git a/IOB-WIN-NEXT/DATA/CONF/IMI_RIMOR_SAB_02.ini b/IOB-WIN-NEXT/DATA/CONF/IMI_RIMOR_SAB_02.ini new file mode 100644 index 00000000..de5bcb41 --- /dev/null +++ b/IOB-WIN-NEXT/DATA/CONF/IMI_RIMOR_SAB_02.ini @@ -0,0 +1,78 @@ +;Configurazione IOB-WIN +[IOB] +;Impianto Rimor sabbiatura - IMI Remosa +CNCTYPE=MODBUS_TCP_RIMOR +PING_MS_TIMEOUT=1000 +MinDeltaSec=5 + +[MACHINE] +VENDOR=RIMOR +MODEL=Sabbiatura - PLC + +[CNC] +IP=192.168.10.5 +PORT=502 + +[SERVER] +MPIP=http://192.168.0.110 +MPURL=/MP/IO +CMDBASE=/IOB/input/ +CMDFLOG=/IOB/flog/ +CMDALIVE=/IOB +CMDENABLED=/IOB/enabled/ +CMDADV1=?valore= +CMDREBO=/sendReboot.aspx?idxMacchina= + +[MEMORY] +ADDR_READ=40001 +ADDR_WRITE=40001 +SIZE_READ=10 +SIZE_WRITE=0 +HR_BASE_ADDR=40000 +DELTA_BASE=0 + + +[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] +;PZCOUNT_MODE=STD.[PAR/MEM].info|BIT.indice +PZCOUNT_MODE=STD.DB85.DBRE16 +DISABLE_PZCOUNT=TRUE +ENABLE_SEND_PZC_BLOCK=TRUE +MIN_SEND_PZC_BLOCK=0 +MAX_SEND_PZC_BLOCK=100 +; GEST DATI DYN +ENABLE_DYN_DATA=TRUE +FORCE_DYN_DATA=TRUE +; gestione delta minimo accettabile tra min/MAX +DELTA_VAL=0.1 + +; clock base (da 10ms) +timerIntMs=10 + +; conf parametri memoria READ/WRITE +PARAM_CONF=IMI_RIMOR_SAB_01.json + +NO_PING=FALSE +; conf blocchi memoria x READ +MEM_BLOCK=IMI_RIMOR_SAB_01_MBlock.json +; conf aree allarme +ALARM_CONF=IMI_RIMOR_SAB_01_alarm.json + +; rimozione check limiti min/max dynData +disDynDataRangeCheck=true + +[BRANCH] +NAME=master \ No newline at end of file diff --git a/IOB-WIN-NEXT/DATA/CONF/IMI_RIMOR_SAB_02.json b/IOB-WIN-NEXT/DATA/CONF/IMI_RIMOR_SAB_02.json new file mode 100644 index 00000000..40ae8860 --- /dev/null +++ b/IOB-WIN-NEXT/DATA/CONF/IMI_RIMOR_SAB_02.json @@ -0,0 +1,90 @@ +{ + "mMapWrite": { + "setComm": { + "name": "setComm", + "description": "Commessa", + "memAddr": "40050", + "tipoMem": "String", + "index": 50, + "size": 20 + } + }, + "mMapRead": { + "AmpMot1": { + "name": "AmpMot1", + "description": "Assorbimento (MAX) motore 1 - catena linea1 motore 1 tazze A4.2", + "memAddr": "40003", + "tipoMem": "Int", + "index": 3, + "size": 1, + "func": "MAX", + "period": 90, + "factor": 0.01, + "minVal": 0, + "maxVal": 999, + "unit": "%" + }, + "AmpMot2": { + "name": "AmpMot2", + "description": "Assorbimento (MAX) motore 2 - catena linea2 motore 2 tazze A4.2", + "memAddr": "40004", + "tipoMem": "Int", + "index": 4, + "size": 1, + "func": "MAX", + "period": 90, + "factor": 0.01, + "minVal": 0, + "maxVal": 999, + "unit": "%" + }, + "AmpMot3": { + "name": "AmpMot3", + "description": "Assorbimento (MAX) motore 3 - nastro uscita cesti motore 3 A2.4", + "memAddr": "40005", + "tipoMem": "Int", + "index": 5, + "size": 1, + "func": "MAX", + "period": 90, + "factor": 0.01, + "minVal": 0, + "maxVal": 999, + "unit": "%" + }, + "AmpMot4": { + "name": "AmpMot4", + "description": "Assorbimento (MAX) motore 4 - curva uscita cesti motore 4 A2.4", + "memAddr": "40006", + "tipoMem": "Int", + "index": 6, + "size": 1, + "func": "MAX", + "period": 90, + "factor": 0.01, + "minVal": 0, + "maxVal": 999, + "unit": "%" + }, + "AmpMot5": { + "name": "AmpMot5", + "description": "Assorbimento (MAX) motore 5 - nastro ingresso casse vuote motore 5 A2.4", + "memAddr": "40007", + "tipoMem": "Int", + "index": 7, + "size": 1, + "func": "MAX", + "period": 90, + "factor": 0.01, + "minVal": 0, + "maxVal": 999, + "unit": "%" + } + }, + "optMemPar": { + "AlarmIntCond": "40000|0=0", + "ManualIntCond": "40000|0=1", + "EStopBitCond": "40001.0=1", + "WorkIntCond": "40000|0=2,4" + } +} \ No newline at end of file diff --git a/IOB-WIN-NEXT/DATA/CONF/IMI_RIMOR_SAB_02_MBlock.json b/IOB-WIN-NEXT/DATA/CONF/IMI_RIMOR_SAB_02_MBlock.json new file mode 100644 index 00000000..ccd2b5e4 --- /dev/null +++ b/IOB-WIN-NEXT/DATA/CONF/IMI_RIMOR_SAB_02_MBlock.json @@ -0,0 +1,5 @@ +{ + "ReadBlocks": { + "40000": 10 + } +} \ No newline at end of file diff --git a/IOB-WIN-NEXT/DATA/CONF/IMI_RIMOR_SAB_02_alarm.json b/IOB-WIN-NEXT/DATA/CONF/IMI_RIMOR_SAB_02_alarm.json new file mode 100644 index 00000000..3503d427 --- /dev/null +++ b/IOB-WIN-NEXT/DATA/CONF/IMI_RIMOR_SAB_02_alarm.json @@ -0,0 +1,52 @@ +[ + { + "description": "Allarmi Impianto", + "tipoMem": "DInt", + "memAddr": "40000", + "index": 0, + "size": 2, + "messages": [ + "##", + "##", + "##", + "##", + "##", + "##", + "##", + "##", + "EMERGENZA GENERALE", + "TERMICO SCATTATO", + "FAULT INVERTER", + "FAULT STEPPER", + "CARTER APERTI", + "PORTA SX APERTA", + "PORTA DX APERTA", + "CARTER APERTI" + ] + }, + { + "description": "Allarmi Impianto", + "tipoMem": "DInt", + "memAddr": "40002", + "index": 2, + "size": 2, + "messages": [ + "TOUT BF NASTRO 1", + "TOUT BF NASTRO 2", + "TOUT BF NASTRO 3", + "TOUT BF NASTRO 4", + "TOUT BF NASTRO 5", + "TOUT BF NASTRO 6", + "ALL MOTORULLO 1", + "ALL MOTORULLO 2", + "ALL MOTORULLO 3", + "ALL MOTORULLO 4", + "ALL MOTORULLO 5", + "ALL MOTORULLO 6", + "", + "", + "", + "" + ] + } +] \ 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 421e573c..437695de 100644 --- a/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj +++ b/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj @@ -232,6 +232,8 @@ + + @@ -313,6 +315,14 @@ + + + + + + + + Always diff --git a/IOB-WIN-NEXT/IobModbusTCP.cs b/IOB-WIN-NEXT/IobModbusTCP.cs index a06412fa..aac887cb 100644 --- a/IOB-WIN-NEXT/IobModbusTCP.cs +++ b/IOB-WIN-NEXT/IobModbusTCP.cs @@ -21,76 +21,6 @@ namespace IOB_WIN_NEXT public class IobModbusTCP : IobGeneric { - #region Protected Fields - - /// - /// Copia locale dei valori in COIL (OUT) | 0.000/09.999, oppure 0.000/65.536 = 0xFFFF, come - /// array chiave (int) valori int[] letti tramite ModBus, da convertire secondo tipo - /// - protected Dictionary CoilLUT = new Dictionary(); - - protected ModbusClient currPLC; - - /// - /// Copia locale dei valori in Discrete Inputs (IN) | 10.000/19.999, oppure 100.000/165.536 - /// = 1xFFFF, come array chiave (int) valori int[] letti tramite ModBus, da convertire - /// secondo tipo - /// - protected Dictionary DiscreteInputLUT = new Dictionary(); - - /// - /// Copia locale dei valori in Holding Registers | 40.000/49.999, oppure 400.000/465.536 = - /// 4xFFFF, come array chiave (int) valori int[] letti tramite ModBus, da convertire secondo tipo - /// - protected Dictionary HoldingRegisterLUT = new Dictionary(); - - /// - /// Copia locale dei valori in Input Registers | 30.000/39.999, oppure 300.000/365.536 = - /// 3xFFFF, come array chiave (int) valori int[] letti tramite ModBus, da convertire secondo tipo - /// - protected Dictionary InputRegisterLUT = new Dictionary(); - - /// - /// Ultimo controllo ping x evitare ping flood... - /// - protected DateTime lastPingConn = DateTime.Now.AddMinutes(-10); - - /// - /// Esito ultimo ping - /// - protected bool lastPingOk = false; - - /// - /// num max di errori lettura permessi prima di disconnettere - /// - protected int maxErrorRead = 10; - - /// - /// Setup blocchi memorie read (indirizzo inizio, size) - /// - protected Dictionary memSetR = new Dictionary(); - - /// - /// parametri di connessione - /// - protected connParamModBusTCP parametri; - - /// - /// Oggetto cronometro x test vari... - /// - protected Stopwatch sw = new Stopwatch(); - - #endregion Protected Fields - - #region Private Fields - - /// - /// Valore delta x gestione min/MAX e valore rilevato - /// - private double deltaVal = 0; - - #endregion Private Fields - #region Public Constructors /// Classe base con i metodi x ModBusTCP @@ -138,36 +68,6 @@ namespace IOB_WIN_NEXT #endregion Public Constructors - #region Protected Properties - - /// - /// Dizionario delle ultime operazioni di scrittura per OGNI memoria (in modo che fa log - /// ogni x sec...) - /// - protected Dictionary lastMemWrite { get; set; } = new Dictionary(); - - #endregion Protected Properties - - #region Private Properties - - /// - /// Valore da gestire come delta degli indirizzi configurati - /// - private int deltaBase { get; set; } = 0; - - /// - /// Valore da gestire come delta degli index x lettura LUT - /// - private int indexLutCorr { get; set; } = 0; - - /// - /// Indica se usare gli indirizzi estesi per ogni blocco: false = 0...10'000 true = - /// 0...65'536 (= xFFFF) - /// - private bool modbusExtReg { get; set; } = false; - - #endregion Private Properties - #region Public Methods /// @@ -695,6 +595,77 @@ namespace IOB_WIN_NEXT #endregion Public Methods + #region Protected Fields + + /// + /// Copia locale dei valori in COIL (OUT) | 0.000/09.999, oppure 0.000/65.536 = 0xFFFF, come + /// array chiave (int) valori int[] letti tramite ModBus, da convertire secondo tipo + /// + protected Dictionary CoilLUT = new Dictionary(); + + protected ModbusClient currPLC; + + /// + /// Copia locale dei valori in Discrete Inputs (IN) | 10.000/19.999, oppure 100.000/165.536 + /// = 1xFFFF, come array chiave (int) valori int[] letti tramite ModBus, da convertire + /// secondo tipo + /// + protected Dictionary DiscreteInputLUT = new Dictionary(); + + /// + /// Copia locale dei valori in Holding Registers | 40.000/49.999, oppure 400.000/465.536 = + /// 4xFFFF, come array chiave (int) valori int[] letti tramite ModBus, da convertire secondo tipo + /// + protected Dictionary HoldingRegisterLUT = new Dictionary(); + + /// + /// Copia locale dei valori in Input Registers | 30.000/39.999, oppure 300.000/365.536 = + /// 3xFFFF, come array chiave (int) valori int[] letti tramite ModBus, da convertire secondo tipo + /// + protected Dictionary InputRegisterLUT = new Dictionary(); + + /// + /// Ultimo controllo ping x evitare ping flood... + /// + protected DateTime lastPingConn = DateTime.Now.AddMinutes(-10); + + /// + /// Esito ultimo ping + /// + protected bool lastPingOk = false; + + /// + /// num max di errori lettura permessi prima di disconnettere + /// + protected int maxErrorRead = 10; + + /// + /// Setup blocchi memorie read (indirizzo inizio, size) + /// + protected Dictionary memSetR = new Dictionary(); + + /// + /// parametri di connessione + /// + protected connParamModBusTCP parametri; + + /// + /// Oggetto cronometro x test vari... + /// + protected Stopwatch sw = new Stopwatch(); + + #endregion Protected Fields + + #region Protected Properties + + /// + /// Dizionario delle ultime operazioni di scrittura per OGNI memoria (in modo che fa log + /// ogni x sec...) + /// + protected Dictionary lastMemWrite { get; set; } = new Dictionary(); + + #endregion Protected Properties + #region Protected Methods /// @@ -1105,34 +1076,6 @@ namespace IOB_WIN_NEXT return answ; } - - /// - /// Testa la condition modbus da LUT + configurazione, valori tipo BIT tramite DiscreteInput (0x02 - 10000+) - /// - /// - /// - protected bool testDisInBitCondition(string cKey) - { - bool answ = false; - if (OptCheckCondBit.ContainsKey(cKey)) - { - if (DiscreteInputLUT.Count > 0) - { - int idxMem = OptCheckCondBit[cKey].BaseAddr + indexLutCorr; - if (DiscreteInputLUT.ContainsKey(idxMem)) - { - answ = DiscreteInputLUT[idxMem] == (OptCheckCondBit[cKey].ValOk != 0); - lgTrace($"testDisInBitCondition for {cKey} | BaseAddr: {OptCheckCondBit[cKey].BaseAddr} | BitNum: {OptCheckCondBit[cKey].BitNum} | ValOk: {OptCheckCondBit[cKey].ValOk} | actual: {answ}"); - } - } - } - else - { - lgTrace($"testDiscrInputBitCondition error: {cKey} not found"); - } - return answ; - } - /// /// Effettua ciclo letture di ogni area configurata /// @@ -1274,6 +1217,34 @@ namespace IOB_WIN_NEXT return answ; } + /// + /// Testa la condition modbus da LUT + configurazione, valori tipo BIT tramite DiscreteInput + /// (0x02 - 10000+) + /// + /// + /// + protected bool testDisInBitCondition(string cKey) + { + bool answ = false; + if (OptCheckCondBit.ContainsKey(cKey)) + { + if (DiscreteInputLUT.Count > 0) + { + int idxMem = OptCheckCondBit[cKey].BaseAddr + indexLutCorr; + if (DiscreteInputLUT.ContainsKey(idxMem)) + { + answ = DiscreteInputLUT[idxMem] == (OptCheckCondBit[cKey].ValOk != 0); + lgTrace($"testDisInBitCondition for {cKey} | BaseAddr: {OptCheckCondBit[cKey].BaseAddr} | BitNum: {OptCheckCondBit[cKey].BitNum} | ValOk: {OptCheckCondBit[cKey].ValOk} | actual: {answ}"); + } + } + } + else + { + lgTrace($"testDiscrInputBitCondition error: {cKey} not found"); + } + return answ; + } + /// /// Testa la condition modbus da LUT + configurazione, valori tipo INT /// @@ -1322,6 +1293,35 @@ namespace IOB_WIN_NEXT #endregion Protected Methods + #region Private Fields + + /// + /// Valore delta x gestione min/MAX e valore rilevato + /// + private double deltaVal = 0; + + #endregion Private Fields + + #region Private Properties + + /// + /// Valore da gestire come delta degli indirizzi configurati + /// + private int deltaBase { get; set; } = 0; + + /// + /// Valore da gestire come delta degli index x lettura LUT + /// + private int indexLutCorr { get; set; } = 0; + + /// + /// Indica se usare gli indirizzi estesi per ogni blocco: false = 0...10'000 true = + /// 0...65'536 (= xFFFF) + /// + private bool modbusExtReg { get; set; } = false; + + #endregion Private Properties + #region Private Methods /// diff --git a/IOB-WIN-NEXT/IobModbusTCPFimat.cs b/IOB-WIN-NEXT/IobModbusTCPFimat.cs new file mode 100644 index 00000000..de9d84f6 --- /dev/null +++ b/IOB-WIN-NEXT/IobModbusTCPFimat.cs @@ -0,0 +1,187 @@ +using System; + +namespace IOB_WIN_NEXT +{ + /* -------------------------------------------------------------------------------- + * Controlli ModBusTCP FIMAT + * - protocollo ModBus TCP + * - gestione stato via Modbus + * - resto gestioen via file + * + * G:\Drive condivisi\30_Clienti\Tenditalia\Macchina Fimat + * + * -------------------------------------------------------------------------------- */ + + public class IobModbusTCPFimat : IobModbusTCP + { + #region Public Constructors + + /// + /// Classe base con i metodi x ModBusTCP + /// + /// + /// + public IobModbusTCPFimat(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf) + { + lgInfo("NEW IOB ModBus TCP Saim"); + + // provo lettura una prima volta i dati DYN + if (currPLC != null && currPLC.Connected) + { + try + { + processDynData(); + if (EnableTest) + { + processDataSync(); + testReadExt(); + } + } + catch (Exception exc) + { + lgError($"Eccezione in processDynData iniziale x ModBus TCP SAIM:{Environment.NewLine}{exc}"); + } + } + } + + #endregion Public Constructors + + #region Protected Properties + + /// + /// Restituisce controllo IN ALLARME + /// + protected bool AlarmState + { + get + { + return testDisInBitCondition("AlarmBitCond"); + } + } + + /// + /// Restituisce status di ESTOP triggered (triggered = premuta, altrimenti armed) + /// + protected bool EStopTriggered + { + get + { + return testDisInBitCondition("EStopBitCond"); + } + } + + /// + /// Restituisce status di Manuale, hard coded + /// + protected bool ManualState + { + get + { + return testDisInBitCondition("ManualBitCond"); + } + } + + /// + /// Restituisce status di LAVORA, hard coded + /// + protected bool Work + { + get + { + return testDisInBitCondition("WorkBitCond"); + } + } + + /// + /// Restituisce status di WORK (auto + lavora), hard coded + /// + protected bool WorkState + { + get + { + return testDisInBitCondition("WorkBitCond"); + } + } + + #endregion Protected Properties + + #region Protected Methods + + /// + /// Effettua decodifica aree memoria alla bitmap usata x MAPO + /// + protected override void decodeToBaseBitmap() + { + // init a zero... + B_input = 0; + + /* ----------------------------------------------------- + * bitmap MAPO STANDARD 60 + * B0: POWER_ON + * B1: RUN + * B2: pzCount + * B3: allarme + * B4: manuale + * B5: slowTC + * B6: WarmUpCoolDown + * B7: EmergArmata + * + ----------------------------------------------------- */ + + var MemInt = new byte[2]; + + int byteSignals = 0; + // bit 0 (poweron) imposto a 1 SE connected... + if (currPLC.Connected) + { + byteSignals += (1 << 0); + } + // se ho qualcosa nella holding register... + if (HoldingRegisterLUT != null && HoldingRegisterLUT.Count > 0) + { + // se emergenza NON premuta (triggered) indico OK (armata...) FARE !!! togliere true + //if (!EStopTriggered) + if (true) + { + byteSignals += (1 << 7); + } + + // impiego controlli da setup IntConditions... processo dagli stati + gravi... + if (AlarmState || hasAlarms()) + { + byteSignals += (1 << 3); + } + else if (ManualState) + { + byteSignals += (1 << 4); + } + else if (WorkState) + { + byteSignals += (1 << 1); + } + } + else + { + lgInfo("HoldingRegisterLUT vuoto!"); + } + + // salvo! + B_input = byteSignals; + } + + /// + /// Effettua sync dati + /// + protected override void processDataSync() + { + // richiesta check autoODL + processAutoOdl(); + // richiesta generazione quotidiana dossiers + processAutoDossier(); + // effettua gestione import file... + processFileImport(); + } + + #endregion Protected Methods + } +} \ No newline at end of file diff --git a/IOB-WIN-NEXT/IobModbusTCPRimor.cs b/IOB-WIN-NEXT/IobModbusTCPRimor.cs new file mode 100644 index 00000000..cbaa9e9e --- /dev/null +++ b/IOB-WIN-NEXT/IobModbusTCPRimor.cs @@ -0,0 +1,214 @@ +using System; + +namespace IOB_WIN_NEXT +{ + /* -------------------------------------------------------------------------------- + * Controlli ModBusTCP Rimor + * - protocollo ModBus TCP + * - specifico comportamento sabbiatura e ossitaglio x IMI Remosa + * - gestione stato + * - gestione allarmi + * - gestione parametri (ore/minuti funzionamento) + * + * G:\Drive condivisi\30_Clienti\IMI-Remosa\Richieste nuove integrazioni\RIMOR + * + * -------------------------------------------------------------------------------- */ + + public class IobModbusTCPRimor : IobModbusTCP + { + #region Public Constructors + + /// + /// Classe base con i metodi x ModBusTCP + /// + /// + /// + public IobModbusTCPRimor(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf) + { + lgInfo("NEW IOB ModBus TCP Rimor"); + + // provo lettura una prima volta i dati DYN + if (currPLC != null && currPLC.Connected) + { + try + { + processDynData(); + if (EnableTest) + { + processDataSync(); + testReadExt(); + } + } + catch (Exception exc) + { + lgError($"Eccezione in processDynData iniziale x ModBus TCP Rimor:{Environment.NewLine}{exc}"); + } + } + } + + #endregion Public Constructors + + #region Protected Properties + + /// + /// Restituisce controllo IN ALLARME + /// + protected bool AlarmState + { + get + { + bool answ = false; + if (memMap.optMemPar.ContainsKey("AlarmBitCond")) + { + answ = testDisInBitCondition("AlarmBitCond"); + } + else if (memMap.optMemPar.ContainsKey("AlarmIntCond")) + { + answ = testIntCondition("AlarmIntCond"); + } + return answ; + } + } + + /// + /// Restituisce status di ESTOP triggered (triggered = premuta, altrimenti armed) + /// + protected bool EStopTriggered + { + get + { + bool answ = false; + if (memMap.optMemPar.ContainsKey("EStopBitCond")) + { + answ = testDisInBitCondition("EStopBitCond"); + } + else if (memMap.optMemPar.ContainsKey("EStopIntCond")) + { + answ = testIntCondition("EStopIntCond"); + } + return answ; + } + } + + /// + /// Restituisce status di Manuale, hard coded + /// + protected bool ManualState + { + get + { + bool answ = false; + if (memMap.optMemPar.ContainsKey("ManualBitCond")) + { + answ = testDisInBitCondition("ManualBitCond"); + } + else if (memMap.optMemPar.ContainsKey("ManualIntCond")) + { + answ = testIntCondition("ManualIntCond"); + } + return answ; + } + } + + /// + /// Restituisce status di WORK (auto + lavora), hard coded + /// + protected bool WorkState + { + get + { + bool answ = false; + if (memMap.optMemPar.ContainsKey("WorkBitCond")) + { + answ = testDisInBitCondition("WorkBitCond"); + } + else if (memMap.optMemPar.ContainsKey("WorkIntCond")) + { + answ = testIntCondition("WorkIntCond"); + } + return answ; + } + } + + #endregion Protected Properties + + #region Protected Methods + + /// + /// Effettua decodifica aree memoria alla bitmap usata x MAPO + /// + protected override void decodeToBaseBitmap() + { + // init a zero... + B_input = 0; + + /* ----------------------------------------------------- + * bitmap MAPO STANDARD 60 + * B0: POWER_ON + * B1: RUN + * B2: pzCount + * B3: allarme + * B4: manuale + * B5: slowTC + * B6: WarmUpCoolDown + * B7: EmergArmata + * + ----------------------------------------------------- */ + + var MemInt = new byte[2]; + + int byteSignals = 0; + // bit 0 (poweron) imposto a 1 SE connected... + if (currPLC.Connected) + { + byteSignals += (1 << 0); + } + // se ho qualcosa nella holding register... + if (HoldingRegisterLUT != null && HoldingRegisterLUT.Count > 0) + { + // se emergenza NON premuta (triggered) indico OK (armata...) FARE !!! togliere true + //if (!EStopTriggered) + if (true) + { + byteSignals += (1 << 7); + } + + // impiego controlli da setup IntConditions... processo dagli stati + gravi... + if (AlarmState || hasAlarms()) + { + byteSignals += (1 << 3); + } + else if (ManualState) + { + byteSignals += (1 << 4); + } + else if (WorkState) + { + byteSignals += (1 << 1); + } + } + else + { + lgInfo("HoldingRegisterLUT vuoto!"); + } + + // salvo! + B_input = byteSignals; + } + + /// + /// Effettua sync dati + /// + protected override void processDataSync() + { + // richiesta check autoODL + processAutoOdl(); + // richiesta generazione quotidiana dossiers + processAutoDossier(); + // effettua gestione import file... + processFileImport(); + } + + #endregion Protected Methods + } +} \ No newline at end of file