Merge branch 'release/ModBusBlockRead'

This commit is contained in:
Samuele Locatelli
2021-11-04 16:11:09 +01:00
15 changed files with 490 additions and 493 deletions
+12 -76
View File
@@ -189,82 +189,6 @@ namespace IOB_UT_NEXT
#endregion Public Methods
}
#if false
/// <summary>
/// Struttura della conf memoria ModBus
/// </summary>
public class BaseModbusConf
{
public enum DataType
{
ND = 0,
BIT,
INT,
REAL
}
public enum MemType
{
ND = 0,
DiscreteInput = 1,
Coil = 2,
InputRegister = 3,
HoldingRegister = 4
}
/// <summary>
/// Elenco aree memoria ModBus in lettura
/// </summary>
public List<ModbusMemArea> mMapRead { get; set; } = new List<ModbusMemArea>();
/// <summary>
/// Elenco aree memoria ModBus in scrittura
/// </summary>
public List<ModbusMemArea> mMapWrite { get; set; } = new List<ModbusMemArea>();
/// <summary>
/// struttura di base memoria ModBus
/// </summary>
public class ModbusMemArea
{
public ushort BaseAddr { get; set; } = 0;
public string RawAddr { get; set; } = "";
public ushort Size { get; set; } = 0;
[JsonConverter(typeof(StringEnumConverter))]
public MemType Type { get; set; } = MemType.ND;
public List<VarConf> VarList { get; set; } = new List<VarConf>();
}
public class VarConf
{
public string description { get; set; } = "";
public int factor { get; set; } = 1;
public bool hasRange
{
get
{
return !this.minVal.Equals(this.maxVal);
}
}
public ushort index { get; set; } = 0;
public int maxVal { get; set; } = 0;
public string memAddr { get; set; } = "";
public int minVal { get; set; } = 0;
public string name { get; set; } = "none";
public ushort size { get; set; } = 0;
[JsonConverter(typeof(StringEnumConverter))]
public DataType tipoMem { get; set; } = DataType.ND;
public string value { get; set; } = "";
}
}
#endif
/// <summary>
/// Classe gestione configurazione parametri di base x configuraizone estesa (es MTConnect, OPC-UA, ...)
/// </summary>
@@ -377,6 +301,18 @@ namespace IOB_UT_NEXT
#endregion Public Properties
}
/// <summary>
/// COnfigurazione blocchi x accesso memoria ottimizzato
/// </summary>
public class MemBlockConf
{
#region Public Properties
public Dictionary<int, int> ReadBlocks { get; set; } = new Dictionary<int, int>();
#endregion Public Properties
}
/// <summary>
/// Classe gestione configurazione parametri specifici MTC da BaseParamConf
/// </summary>
+152 -152
View File
@@ -1,155 +1,155 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
</startup>
<appSettings>
<add key="appName" value="IOB-WIN-NEXT" />
<!--<add key="appVers" value="develop" />-->
<add key="enableTest" value="true" />
<add key="enableContapezzi" value="true" />
<add key="enableMode" value="true" />
<add key="enableOverrides" value="false" />
<add key="enableTSVC" value="true" />
<add key="enableDynData" value="false" />
<add key="enableSysInfo" value="false" />
<add key="enableAlarms" value="true" />
<add key="doStartMemDump" value="false" />
<add key="doSampleMemory" value="false" />
<add key="basePrgMemPath" value="CNCMEMUSER" />
<add key="pingMsTimeout" value="1500" />
<add key="serverPingDisabled" value="false" />
<add key="urlCallTOut" value="1000" />
<!-- ciclo corto x invio a server: ms -->
<add key="timerIntMs" value="10" />
<add key="fastCount" value="20" />
<add key="normCount" value="200" />
<add key="slowCount" value="500" />
<add key="verySlowCount" value="3000" />
<add key="sampleMemCount" value="6000" />
<add key="waitEndCycle" value="0" />
<add key="comCheckTOut" value="10" />
<!-- watchdog, ping, check disconnesso -->
<add key="nMaxSend" value="10" />
<add key="pingTestSec" value="5" />
<add key="watchdogMaxSec" value="90" />
<add key="disconMaxSec" value="30" />
<add key="defIOB" value="2999" />
<add key="pauseSendMSec" value="1000" />
<!--gestione coda-->
<add key="maxQueueFLog" value="16384" />
<!--parametri SIM-->
<add key="waitSimPar" value="30" />
<!--<add key="waitSimPar" value="45" />-->
<!--gestione REDIS-->
<add key="RedisConn" value="localhost,abortConnect=false,ssl=false" />
<add key="RedisConnAdmin" value="localhost,abortConnect=false,ssl=false" />
<add key="redisDb" value="10" />
<!--gestione invio dati in blocchi Json-->
<add key="minJsonData" value="2" />
<add key="maxJsonData" value="100" />
<add key="maxJsonDataEv" value="25" />
<!--gestione multithread-->
<add key="sendDataByThread" value="false" />
<!--Modalità DEMO: DemoOUT indica che NON invia davvero al server e DemoIN che simula e NON legge da PLC-->
<add key="DemoIn" value="false" />
<add key="DemoInSample" value="false" />
<add key="DemoOut" value="false" />
<!--definizione invio dati molto variabili-->
<add key="SendAxPos" value="false" />
<add key="SendFeedSpeed" value="false" />
<!--Definizione avvio Adapter-->
<add key="autoLoadConf" value="true" />
<add key="autoStartOnLoad" value="true" />
<add key="startMinimized" value="false" />
<add key="windowCanMax" value="true" />
<add key="trayClose" value="true" />
<add key="autoSaveSec" value="60" />
<add key="waitRecMSec" value="20000" />
<add key="testCharSep" value="|" />
<add key="delayShowLogMs" value="500" />
<add key="vetoSeconds" value="5" />
<!--conf file-->
<add key="dataPath" value="DATA" />
<add key="dataConfPath" value="DATA\CONF" />
<add key="dataDatPath" value="DATA\DAT" />
<add key="resxPath" value="Resources" />
<add key="mainConfFile" value="MAIN.ini" />
<add key="defaultPersLayerFile" value="PersistData.dat" />
<add key="simDataFile" value="SimData.dat" />
<add key="memDumpFile" value="MemoryDump.dat" />
<add key="numSim" value="1" />
<add key="MMapR" value="MMapR.map" />
<add key="MMapW" value="MMapW.map" />
<add key="AUpdAsAdm" value="true" />
<add key="ConfToCloud" value="true" />
<!--logging-->
<add key="recTime" value="true" />
<add key="verbose" value="true" />
<add key="logEvery" value="100" />
<add key="zipLogOldDay" value="1" />
<add key="maxLogDirSize" value="300" />
<add key="maxLogDays" value="120" />
<add key="numRowConsole" value="50" />
<add key="verboseLogTOut" value="60" />
<!--conf x FANUC-->
<add key="ClientSettingsProvider.ServiceUri" value="" />
<add key="pzCountDelay" value="2000" />
</appSettings>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="lib;libs" />
<probing privatePath="lib;libs" xmlns="" />
<dependentAssembly>
<assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.6.10.0" newVersion="2.6.10.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.6.10.0" newVersion="2.6.10.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.IO.Compression" publicKeyToken="b77a5c561934e089" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.IO.Pipelines" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.1" newVersion="5.0.0.1" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="BouncyCastle.Crypto" publicKeyToken="0e99375e54769942" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.9.0.0" newVersion="1.9.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<system.web>
<membership defaultProvider="ClientAuthenticationMembershipProvider">
<providers>
<add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" />
</providers>
</membership>
<roleManager defaultProvider="ClientRoleProvider" enabled="true">
<providers>
<add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" cacheTimeout="86400" />
</providers>
</roleManager>
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="OPENcontrol" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://192.168.20.2:8080" binding="basicHttpBinding" bindingConfiguration="OPENcontrol" contract="OpenControl.OPENcontrolPortType" name="OPENcontrol" />
</client>
</system.serviceModel>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
</startup>
<appSettings>
<add key="appName" value="IOB-WIN-NEXT" />
<!--<add key="appVers" value="develop" />-->
<add key="enableTest" value="true" />
<add key="enableContapezzi" value="true" />
<add key="enableMode" value="true" />
<add key="enableOverrides" value="false" />
<add key="enableTSVC" value="true" />
<add key="enableDynData" value="false" />
<add key="enableSysInfo" value="false" />
<add key="enableAlarms" value="true" />
<add key="doStartMemDump" value="false" />
<add key="doSampleMemory" value="false" />
<add key="basePrgMemPath" value="CNCMEMUSER" />
<add key="pingMsTimeout" value="1500" />
<add key="serverPingDisabled" value="false" />
<add key="urlCallTOut" value="1000" />
<!-- ciclo corto x invio a server: ms -->
<add key="timerIntMs" value="10" />
<add key="fastCount" value="20" />
<add key="normCount" value="200" />
<add key="slowCount" value="500" />
<add key="verySlowCount" value="3000" />
<add key="sampleMemCount" value="6000" />
<add key="waitEndCycle" value="0" />
<add key="comCheckTOut" value="10" />
<!-- watchdog, ping, check disconnesso -->
<add key="nMaxSend" value="10" />
<add key="pingTestSec" value="5" />
<add key="watchdogMaxSec" value="90" />
<add key="disconMaxSec" value="30" />
<add key="defIOB" value="2999" />
<add key="pauseSendMSec" value="1000" />
<!--gestione coda-->
<add key="maxQueueFLog" value="16384" />
<!--parametri SIM-->
<add key="waitSimPar" value="30" />
<!--<add key="waitSimPar" value="45" />-->
<!--gestione REDIS-->
<add key="RedisConn" value="localhost,abortConnect=false,ssl=false" />
<add key="RedisConnAdmin" value="localhost,abortConnect=false,ssl=false" />
<add key="redisDb" value="10" />
<!--gestione invio dati in blocchi Json-->
<add key="minJsonData" value="2" />
<add key="maxJsonData" value="100" />
<add key="maxJsonDataEv" value="25" />
<!--gestione multithread-->
<add key="sendDataByThread" value="false" />
<!--Modalità DEMO: DemoOUT indica che NON invia davvero al server e DemoIN che simula e NON legge da PLC-->
<add key="DemoIn" value="false" />
<add key="DemoInSample" value="false" />
<add key="DemoOut" value="false" />
<!--definizione invio dati molto variabili-->
<add key="SendAxPos" value="false" />
<add key="SendFeedSpeed" value="false" />
<!--Definizione avvio Adapter-->
<add key="autoLoadConf" value="true" />
<add key="autoStartOnLoad" value="true" />
<add key="startMinimized" value="false" />
<add key="windowCanMax" value="true" />
<add key="trayClose" value="true" />
<add key="autoSaveSec" value="60" />
<add key="waitRecMSec" value="20000" />
<add key="testCharSep" value="|" />
<add key="delayShowLogMs" value="500" />
<add key="vetoSeconds" value="5" />
<!--conf file-->
<add key="dataPath" value="DATA" />
<add key="dataConfPath" value="DATA\CONF" />
<add key="dataDatPath" value="DATA\DAT" />
<add key="resxPath" value="Resources" />
<add key="mainConfFile" value="MAIN.ini" />
<add key="defaultPersLayerFile" value="PersistData.dat" />
<add key="simDataFile" value="SimData.dat" />
<add key="memDumpFile" value="MemoryDump.dat" />
<add key="numSim" value="1" />
<add key="MMapR" value="MMapR.map" />
<add key="MMapW" value="MMapW.map" />
<add key="AUpdAsAdm" value="true" />
<add key="ConfToCloud" value="true" />
<!--logging-->
<add key="recTime" value="true" />
<add key="verbose" value="false" />
<add key="logEvery" value="100" />
<add key="zipLogOldDay" value="1" />
<add key="maxLogDirSize" value="300" />
<add key="maxLogDays" value="120" />
<add key="numRowConsole" value="50" />
<add key="verboseLogTOut" value="60" />
<!--conf x FANUC-->
<add key="ClientSettingsProvider.ServiceUri" value="" />
<add key="pzCountDelay" value="2000" />
</appSettings>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="lib;libs" />
<probing privatePath="lib;libs" xmlns="" />
<dependentAssembly>
<assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.6.10.0" newVersion="2.6.10.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.6.10.0" newVersion="2.6.10.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.IO.Compression" publicKeyToken="b77a5c561934e089" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.IO.Pipelines" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.1" newVersion="5.0.0.1" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="BouncyCastle.Crypto" publicKeyToken="0e99375e54769942" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.9.0.0" newVersion="1.9.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<system.web>
<membership defaultProvider="ClientAuthenticationMembershipProvider">
<providers>
<add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" />
</providers>
</membership>
<roleManager defaultProvider="ClientRoleProvider" enabled="true">
<providers>
<add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" cacheTimeout="86400" />
</providers>
</roleManager>
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="OPENcontrol" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://192.168.20.2:8080" binding="basicHttpBinding" bindingConfiguration="OPENcontrol" contract="OpenControl.OPENcontrolPortType" name="OPENcontrol" />
</client>
</system.serviceModel>
</configuration>
+1 -1
View File
@@ -72,6 +72,6 @@ CLI_INST=SteamWareSim
;STARTLIST=FP_TR2
;STARTLIST=PING
;STARTLIST=SIM_PIZ03
STARTLIST=PIZ04
STARTLIST=PIZ05
MAXCNC=10
+3 -1
View File
@@ -58,12 +58,14 @@ FORCE_DYN_DATA=TRUE
DELTA_VAL=0.1
; clock base (da 10ms)
timerIntMs=150
timerIntMs=125
; conf parametri memoria READ/WRITE
PARAM_CONF=PIZ04.json
NO_PING=FALSE
; conf blocchi memoria x READ
MEM_BLOCK=PIZ04_MBlock.json
; conf aree allarme
ALARM_CONF=PIZ04_alarm.json
+42 -42
View File
@@ -8,20 +8,20 @@
"index": 489,
"size": 2,
"minVal": -200,
"maxVal": 200,
"unit": "C"
},
"SetHighTempGNC": {
"name": "SetHighTempGNC",
"description": "Set point di avviso per alta temperatura all'uscita del vaporizzatore GNC",
"memAddr": "40491",
"tipoMem": "Real",
"index": 491,
"size": 2,
"minVal": -200,
"maxVal": 200,
"maxVal": 301,
"unit": "C"
},
//"SetHighTempGNC": {
// "name": "SetHighTempGNC",
// "description": "Set point di avviso per alta temperatura all'uscita del vaporizzatore GNC",
// "memAddr": "40491",
// "tipoMem": "Real",
// "index": 491,
// "size": 2,
// "minVal": -200,
// "maxVal": 301,
// "unit": "C"
//},
"SetLowTempAmb": {
"name": "SetLowTempAmb",
"description": "Set point di avviso per bassa temperatura ambiente nell'impianto",
@@ -30,7 +30,7 @@
"index": 421,
"size": 2,
"minVal": -200,
"maxVal": 200,
"maxVal": 301,
"unit": "C"
},
"SetHighTempAmb": {
@@ -41,7 +41,7 @@
"index": 423,
"size": 2,
"minVal": -200,
"maxVal": 200,
"maxVal": 301,
"unit": "C"
}
},
@@ -54,7 +54,7 @@
"index": 1,
"size": 2,
"func": "MEDIAN",
"period": 120,
"period": 90,
"factor": 360,
"minVal": 0,
"maxVal": 100,
@@ -68,7 +68,7 @@
"index": 3,
"size": 2,
"func": "MEDIAN",
"period": 120,
"period": 90,
"factor": 1,
"minVal": 0,
"maxVal": 400,
@@ -82,7 +82,7 @@
"index": 19,
"size": 2,
"func": "MEDIAN",
"period": 120,
"period": 90,
"factor": 1,
"minVal": 0,
"maxVal": 400,
@@ -96,7 +96,7 @@
"index": 21,
"size": 2,
"func": "MEDIAN",
"period": 120,
"period": 90,
"factor": 1,
"minVal": 0,
"maxVal": 400,
@@ -110,10 +110,10 @@
"index": 27,
"size": 2,
"func": "MEDIAN",
"period": 120,
"period": 90,
"factor": 1,
"minVal": -200,
"maxVal": 200,
"maxVal": 301,
"unit": "C"
},
"TempAmb": {
@@ -124,10 +124,10 @@
"index": 11,
"size": 2,
"func": "MEDIAN",
"period": 120,
"period": 90,
"factor": 1,
"minVal": -200,
"maxVal": 200,
"maxVal": 301,
"unit": "C"
},
"SetLowTempGNC": {
@@ -138,26 +138,26 @@
"index": 489,
"size": 2,
"func": "MEDIAN",
"period": 120,
"period": 90,
"factor": 1,
"minVal": -200,
"maxVal": 200,
"unit": "C"
},
"SetHighTempGNC": {
"name": "SetHighTempGNC",
"description": "Set point di avviso per alta temperatura all'uscita del vaporizzatore GNC",
"memAddr": "40491",
"tipoMem": "Real",
"index": 491,
"size": 2,
"func": "MEDIAN",
"period": 120,
"factor": 1,
"minVal": -200,
"maxVal": 200,
"maxVal": 301,
"unit": "C"
},
//"SetHighTempGNC": {
// "name": "SetHighTempGNC",
// "description": "Set point di avviso per alta temperatura all'uscita del vaporizzatore GNC",
// "memAddr": "40491",
// "tipoMem": "Real",
// "index": 491,
// "size": 2,
// "func": "MEDIAN",
// "period": 90,
// "factor": 1,
// "minVal": -200,
// "maxVal": 301,
// "unit": "C"
//},
"SetLowTempAmb": {
"name": "SetLowTempAmb",
"description": "Set point di avviso per bassa temperatura ambiente nell'impianto",
@@ -166,10 +166,10 @@
"index": 421,
"size": 2,
"func": "MEDIAN",
"period": 120,
"period": 90,
"factor": 1,
"minVal": -200,
"maxVal": 200,
"maxVal": 301,
"unit": "C"
},
"SetHighTempAmb": {
@@ -180,10 +180,10 @@
"index": 423,
"size": 2,
"func": "MEDIAN",
"period": 120,
"period": 90,
"factor": 1,
"minVal": -200,
"maxVal": 200,
"maxVal": 301,
"unit": "C"
}
}
+6
View File
@@ -0,0 +1,6 @@
{
"ReadBlocks": {
"40001": 64,
"40421": 72
}
}
+5 -4
View File
@@ -13,8 +13,8 @@ IP=hambaganzola.dyndns.org
PORT=502
[SERVER]
;MPIP=https://localhost:44339
MPIP=https://gwms.egalware.com
MPIP=https://localhost:44339
;MPIP=https://gwms.egalware.com
MPURL=/api
CMDBASE=/IOB/input/
CMDFLOG=/IOB/flog/
@@ -27,7 +27,6 @@ CMDREBO=/IOB/sendReboot?idxMacchina=
ADDR_READ=40001
ADDR_WRITE=40401
SIZE_READ=34
;SIZE_READ=5046
SIZE_WRITE=358
@@ -59,12 +58,14 @@ FORCE_DYN_DATA=TRUE
DELTA_VAL=0.1
; clock base (da 10ms)
timerIntMs=150
timerIntMs=125
; conf parametri memoria READ/WRITE
PARAM_CONF=PIZ05.json
NO_PING=TRUE
; conf blocchi memoria x READ
MEM_BLOCK=PIZ05_MBlock.json
; conf aree allarme
ALARM_CONF=PIZ05_alarm.json
+51 -51
View File
@@ -8,20 +8,20 @@
"index": 489,
"size": 2,
"minVal": -200,
"maxVal": 200,
"unit": "C"
},
"SetHighTempGNC": {
"name": "SetHighTempGNC",
"description": "Set point di avviso per alta temperatura all'uscita del vaporizzatore GNC",
"memAddr": "40491",
"tipoMem": "Real",
"index": 491,
"size": 2,
"minVal": -200,
"maxVal": 200,
"maxVal": 301,
"unit": "C"
},
//"SetHighTempGNC": {
// "name": "SetHighTempGNC",
// "description": "Set point di avviso per alta temperatura all'uscita del vaporizzatore GNC",
// "memAddr": "40491",
// "tipoMem": "Real",
// "index": 491,
// "size": 2,
// "minVal": -200,
// "maxVal": 301,
// "unit": "C"
//},
"SetLowTempAmb": {
"name": "SetLowTempAmb",
"description": "Set point di avviso per bassa temperatura ambiente nell'impianto",
@@ -30,7 +30,7 @@
"index": 421,
"size": 2,
"minVal": -200,
"maxVal": 200,
"maxVal": 301,
"unit": "C"
},
"SetHighTempAmb": {
@@ -41,7 +41,7 @@
"index": 423,
"size": 2,
"minVal": -200,
"maxVal": 200,
"maxVal": 301,
"unit": "C"
}
},
@@ -53,8 +53,8 @@
"tipoMem": "Real",
"index": 1,
"size": 2,
"func": "MAX",
"period": 120,
"func": "MEDIAN",
"period": 90,
"factor": 270,
"minVal": 0,
"maxVal": 100,
@@ -67,8 +67,8 @@
"tipoMem": "Real",
"index": 3,
"size": 2,
"func": "MAX",
"period": 120,
"func": "MEDIAN",
"period": 90,
"factor": 1,
"minVal": 0,
"maxVal": 400,
@@ -81,8 +81,8 @@
"tipoMem": "Real",
"index": 19,
"size": 2,
"func": "MAX",
"period": 120,
"func": "MEDIAN",
"period": 90,
"factor": 1,
"minVal": 0,
"maxVal": 400,
@@ -95,8 +95,8 @@
"tipoMem": "Real",
"index": 21,
"size": 2,
"func": "MAX",
"period": 120,
"func": "MEDIAN",
"period": 90,
"factor": 1,
"minVal": 0,
"maxVal": 400,
@@ -109,11 +109,11 @@
"tipoMem": "Real",
"index": 27,
"size": 2,
"func": "MAX",
"period": 120,
"func": "MEDIAN",
"period": 90,
"factor": 1,
"minVal": -200,
"maxVal": 200,
"maxVal": 301,
"unit": "C"
},
"TempAmb": {
@@ -123,11 +123,11 @@
"tipoMem": "Real",
"index": 11,
"size": 2,
"func": "MAX",
"period": 120,
"func": "MEDIAN",
"period": 90,
"factor": 1,
"minVal": -200,
"maxVal": 200,
"maxVal": 301,
"unit": "C"
},
"SetLowTempGNC": {
@@ -137,27 +137,27 @@
"tipoMem": "Real",
"index": 489,
"size": 2,
"func": "MAX",
"period": 120,
"func": "MEDIAN",
"period": 90,
"factor": 1,
"minVal": -200,
"maxVal": 200,
"unit": "C"
},
"SetHighTempGNC": {
"name": "SetHighTempGNC",
"description": "Set point di avviso per alta temperatura all'uscita del vaporizzatore GNC",
"memAddr": "40491",
"tipoMem": "Real",
"index": 491,
"size": 2,
"func": "MAX",
"period": 120,
"factor": 1,
"minVal": -200,
"maxVal": 200,
"maxVal": 301,
"unit": "C"
},
//"SetHighTempGNC": {
// "name": "SetHighTempGNC",
// "description": "Set point di avviso per alta temperatura all'uscita del vaporizzatore GNC",
// "memAddr": "40491",
// "tipoMem": "Real",
// "index": 491,
// "size": 2,
// "func": "MEDIAN",
// "period": 90,
// "factor": 1,
// "minVal": -200,
// "maxVal": 301,
// "unit": "C"
//},
"SetLowTempAmb": {
"name": "SetLowTempAmb",
"description": "Set point di avviso per bassa temperatura ambiente nell'impianto",
@@ -165,11 +165,11 @@
"tipoMem": "Real",
"index": 421,
"size": 2,
"func": "MAX",
"period": 120,
"func": "MEDIAN",
"period": 90,
"factor": 1,
"minVal": -200,
"maxVal": 200,
"maxVal": 301,
"unit": "C"
},
"SetHighTempAmb": {
@@ -179,11 +179,11 @@
"tipoMem": "Real",
"index": 423,
"size": 2,
"func": "MAX",
"period": 120,
"func": "MEDIAN",
"period": 90,
"factor": 1,
"minVal": -200,
"maxVal": 200,
"maxVal": 301,
"unit": "C"
}
}
+6
View File
@@ -0,0 +1,6 @@
{
"ReadBlocks": {
"40001": 64,
"40421": 72
}
}
+2 -34
View File
@@ -4,7 +4,7 @@
"tipoMem": "DInt",
"memAddr": "40901",
"index": 901,
"size": 4,
"size": 2,
"messages": [
"Basso livello serbatoio",
"Alto livello serbatoio",
@@ -21,22 +21,6 @@
"##",
"Allarme rilevatore gas 3",
"##",
"##",
"##",
"##",
"##",
"##",
"##",
"##",
"##",
"##",
"##",
"##",
"##",
"##",
"##",
"##",
"##",
"##"
]
},
@@ -45,7 +29,7 @@
"tipoMem": "DInt",
"memAddr": "40907",
"index": 907,
"size": 4,
"size": 2,
"messages": [
"##",
"Pulsante di Emergenza Premuto",
@@ -62,22 +46,6 @@
"##",
"##",
"##",
"##",
"##",
"##",
"##",
"##",
"##",
"##",
"##",
"##",
"##",
"##",
"##",
"##",
"##",
"##",
"##",
"##"
]
}
@@ -1,52 +0,0 @@
[
{
"description": "Allarmi Impianto",
"tipoMem": "DInt",
"memAddr": "40901",
"index": 901,
"size": 2,
"messages": [
"Basso livello serbatoio",
"Alto livello serbatoio",
"Errore trasmettitore livello",
"Bassa pressione serbatoio",
"Alta pressione serbatoio",
"##",
"##",
"Allarme rilevatore gas 1",
"##",
"##",
"Allarme rilevatore gas 2",
"##",
"##",
"Allarme rilevatore gas 3",
"##",
"##"
]
},
{
"description": "Emergenza",
"tipoMem": "DInt",
"memAddr": "40907",
"index": 907,
"size": 2,
"messages": [
"##",
"Pulsante di Emergenza Premuto",
"##",
"##",
"##",
"##",
"##",
"##",
"##",
"##",
"##",
"##",
"##",
"##",
"##",
"##"
]
}
]
+6
View File
@@ -391,6 +391,12 @@
<None Include="DATA\CONF\IMI_50.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="DATA\CONF\PIZ04_MBlock.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="DATA\CONF\PIZ05_MBlock.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="DATA\CONF\PIZ05.ini">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
+1 -1
View File
@@ -2964,7 +2964,7 @@ namespace IOB_WIN_NEXT
{
// invio su cloud conf memoria...
string rawData = JsonConvert.SerializeObject(memMap);
utils.callUrlNow($"{urlSaveMemMap}", rawData);
var resp = utils.callUrlNow($"{urlSaveMemMap}", rawData);
// salvo ANCHE come parametri i valori...
objItem currItem = new objItem();
List<objItem> allParam = new List<objItem>();
+176 -56
View File
@@ -5,11 +5,13 @@ using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.NetworkInformation;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace IOB_WIN_NEXT
{
@@ -34,6 +36,11 @@ namespace IOB_WIN_NEXT
protected ModbusClient currPLC;
/// <summary>
/// Copia locale dei valori in Holding Registry, come array chiave (int) valori int[] letti tramite ModBus, da convertire secondo tipo
/// </summary>
protected Dictionary<int, int[]> HoldingRegisterLUT = new Dictionary<int, int[]>();
/// <summary>
/// Ultimo controllo ping x evitare ping flood...
/// </summary>
@@ -49,11 +56,6 @@ namespace IOB_WIN_NEXT
/// </summary>
protected Dictionary<int, int> memSetR = new Dictionary<int, int>();
/// <summary>
/// Setup blocchi memorie write (indirizzo inizio, size)
/// </summary>
protected Dictionary<int, int> memSetW = new Dictionary<int, int>();
/// <summary>
/// parametri di connessione
/// </summary>
@@ -75,7 +77,6 @@ namespace IOB_WIN_NEXT
public IobModbusTCP(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf)
{
lgInfo("NEW IOB ModBus TCP");
setupMemBlocks();
memMap = new plcMemMap();
if (IOBConf != null)
{
@@ -212,7 +213,13 @@ namespace IOB_WIN_NEXT
return valUInt;
}
private Dictionary<string, dataConfTSVC> getDataDictionary(Dictionary<string, dataConfTSVC> memItemList, ref Dictionary<string, string> outVal)
/// <summary>
/// Recupero dati da singole letture
/// </summary>
/// <param name="memItemList">Valori da processare</param>
/// <param name="outVal">Dizionario valori in uscita</param>
/// <returns>Errori di lettura</returns>
private Dictionary<string, dataConfTSVC> getDataDictionary(Dictionary<string, dataConfTSVC> memItemList, bool useLUT, ref Dictionary<string, string> outVal)
{
Dictionary<string, dataConfTSVC> readErrorList = new Dictionary<string, dataConfTSVC>();
// inizializzo i valori
@@ -221,6 +228,11 @@ namespace IOB_WIN_NEXT
// procedo x ogni valore configurato...
foreach (var item in memItemList)
{
// attesa 50 ms prima di procedere x evitare burst dati
if (useLUT)
{
Thread.Sleep(50);
}
double valore = 0;
double valoreScal = 0;
bool dataOk = false;
@@ -246,7 +258,18 @@ namespace IOB_WIN_NEXT
break;
case modBusAddrType.HoldingRegister:
listInt = readHoldReg(item.Value.index - 1, item.Value.size);
if (useLUT)
{
int lutAddress = 40000 + item.Value.index;
if (HoldingRegisterLUT.ContainsKey(lutAddress))
{
listInt = HoldingRegisterLUT[lutAddress];
}
}
else
{
listInt = readHoldReg(item.Value.index - 1, item.Value.size);
}
valore = convertFromReg(listInt, item.Value.size, item.Value.tipoMem);
break;
@@ -303,6 +326,54 @@ namespace IOB_WIN_NEXT
}
}
/// <summary>
/// Effettua lettura blocco memoria indicato e lo salva in copia locale HoldingRegisterLUT
/// </summary>
/// <param name="startAddr">Indirizzo di aprtenza</param>
/// <param name="numReg">NUm registri da leggere (max 120)</param>
private void readBlockHoldingReg(int startAddr, int numReg)
{
// fix massima lunghezza pacchetto
if (numReg > 120)
{
lgError($"Attenzione richiesta lettura blocco troppo grande: numReg {numReg} --> 120");
numReg = 120;
}
// si lavora rispetto all'indirizzo base 40001
int baseAddr = 40001;
int[] rawData = new int[2];
try
{
stopwatch.Restart();
rawData = currPLC.ReadHoldingRegisters(startAddr - baseAddr, numReg);
stopwatch.Stop();
lgInfo($"Lettura in blocco HoldingRegisters| startAddr: {startAddr} | numReg {numReg} | {stopwatch.ElapsedMilliseconds}ms");
// salvo in LUT la versione ESPLOSA 2 byte alla volta...
if (rawData.Length > 0)
{
for (int i = 0; i < rawData.Length / 2; i++)
{
int[] thisSet = new int[2];
Array.Copy(rawData, i * 2, thisSet, 0, 2);
// salvo nel registro...
int currAddr = startAddr + i * 2;
if (HoldingRegisterLUT.ContainsKey(currAddr))
{
HoldingRegisterLUT[currAddr] = thisSet;
}
else
{
HoldingRegisterLUT.Add(currAddr, thisSet);
}
}
}
}
catch (Exception exc)
{
lgError($"Eccezione in readBlockHoldingReg{Environment.NewLine}{exc}");
}
}
#endregion Private Methods
#region Protected Methods
@@ -490,45 +561,11 @@ namespace IOB_WIN_NEXT
{
lgError(exc, "Errore in parse parametri da IOBConf");
}
// ora tento avvio PLC... SE PING OK...
IPStatus esitoPing = testPingMachine;
if (esitoPing == IPStatus.Success)
{
needRefresh = false;
try
{
//Ip-Address and Port of Modbus-TCP-Server
currPLC = new ModbusClient(parametri.ipAdrr, parametri.port);
// disconnetto e connetto...
if (isVerboseLog)
{
lgInfo("ModBus TCP: tryDisconnect");
}
tryDisconnect();
// lo ripeto x evitare che ci sia un loop... e tryConnect richiami la procedura corrente...
needRefresh = false;
lgInfo("ModBus TCP: tryConnect");
tryConnect();
lgInfo("End init Adapter ModBusTCP");
if (isVerboseLog)
{
lgInfo("ModBus TCP CONNESSIONE AVVENUTA");
}
}
catch (Exception exc)
{
lgError(exc, "Errore in INIT ModBusTCP");
}
}
else
{
lgError($"Errore in ping: esito {esitoPing}");
}
parentForm.commPlcActive = false;
// carico conf vettore memoria...
loadMemConf();
// avvio conf blocchi memoria
setupMemBlocks();
// aggiungo DELTA x calcolo min/MAX...
string deltaValStr = getOptPar("DELTA_VAL");
if (!string.IsNullOrEmpty(deltaValStr))
@@ -572,6 +609,44 @@ namespace IOB_WIN_NEXT
lgError(exc, "Errore in contapezzi ModBusTCP");
}
}
// ora tento avvio PLC... SE PING OK...
IPStatus esitoPing = testPingMachine;
if (esitoPing == IPStatus.Success)
{
needRefresh = false;
try
{
//Ip-Address and Port of Modbus-TCP-Server
currPLC = new ModbusClient(parametri.ipAdrr, parametri.port);
// disconnetto e connetto...
if (isVerboseLog)
{
lgInfo("ModBus TCP: tryDisconnect");
}
tryDisconnect();
// lo ripeto x evitare che ci sia un loop... e tryConnect richiami la procedura corrente...
needRefresh = false;
lgInfo("ModBus TCP: tryConnect");
tryConnect();
lgInfo("End init Adapter ModBusTCP");
if (isVerboseLog)
{
lgInfo("ModBus TCP CONNESSIONE AVVENUTA");
}
}
catch (Exception exc)
{
lgError(exc, "Errore in INIT ModBusTCP");
}
}
else
{
lgError($"Errore in ping: esito {esitoPing}");
}
parentForm.commPlcActive = false;
}
else
{
@@ -583,8 +658,33 @@ namespace IOB_WIN_NEXT
/// <summary>
/// effettua il setup dei memblock da gestire (NON leggo intera memoria ma tanti blocchi...)
/// </summary>
protected virtual void setupMemBlocks()
{ }
protected void setupMemBlocks()
{
// se configurato -_> deserializzo
string confFile = getOptPar("MEM_BLOCK");
if (!string.IsNullOrEmpty(confFile))
{
string jsonFileName = $"{Application.StartupPath}/DATA/CONF/{confFile}";
lgInfo($"Apertura file {jsonFileName}");
using (StreamReader reader = new StreamReader(jsonFileName))
{
string jsonData = reader.ReadToEnd();
if (!string.IsNullOrEmpty(jsonData))
{
lgInfo($"File json MemBlock composto da {jsonData.Length} caratteri");
try
{
var currMem = JsonConvert.DeserializeObject<MemBlockConf>(jsonData);
memSetR = currMem.ReadBlocks;
}
catch (Exception exc)
{
lgError($"Errore in setupMemBlock{Environment.NewLine}{exc}");
}
}
}
}
}
/// <summary>
/// Test connessione CNC
@@ -768,26 +868,39 @@ namespace IOB_WIN_NEXT
}
else
{
Dictionary<string, dataConfTSVC> readErrorList = new Dictionary<string, dataConfTSVC>();
Dictionary<string, dataConfTSVC> readErrorListRepeat = new Dictionary<string, dataConfTSVC>();
bool useLUT = memSetR != null && memSetR.Count > 0;
// se configurato leggo IN BLOCCHI da memoria...
if (useLUT)
{
foreach (var item in memSetR)
{
readBlockHoldingReg(item.Key, item.Value);
}
}
// procedo ...
try
{
// processo x ogni valore configurato...
if (memMap.mMapRead.Count > 0)
{
Dictionary<string, dataConfTSVC> readErrorList = new Dictionary<string, dataConfTSVC>();
Dictionary<string, dataConfTSVC> readErrorListRepeat = new Dictionary<string, dataConfTSVC>();
var memItemList = memMap.mMapRead;
readErrorList = getDataDictionary(memItemList, ref outVal);
readErrorList = getDataDictionary(memItemList, useLUT, ref outVal);
// se qualcosa è andato storto riprovo a caricare SOLO gli errori... 1 sola volta
if (readErrorList.Count > 0)
{
lgInfo($"Effettuo rilettura per {readErrorList.Count} variabili");
readErrorListRepeat = getDataDictionary(readErrorList, ref outVal);
lgInfo($"Attesa prima di rilettura | LUT: {useLUT}");
// attendo 3 sec
Thread.Sleep(3000);
lgInfo($"Effettuo rilettura per {readErrorList.Count} variabili | LUT: {useLUT}");
readErrorListRepeat = getDataDictionary(readErrorList, useLUT, ref outVal);
}
// se avessi ancora errori --> disconnetto
if (readErrorListRepeat.Count > 0)
{
lgInfo("Trovati valori non validi al secondo tentativo --> invalido valori letti e resetto adapter con tryDisconnect!");
lgInfo($"Trovati valori non validi al secondo tentativo | LUT: {useLUT} --> invalido valori letti e resetto adapter con tryDisconnect!");
tryDisconnect();
// invalido output
outVal = new Dictionary<string, string>();
@@ -800,12 +913,12 @@ namespace IOB_WIN_NEXT
}
else
{
lgInfo($"getDynData: {memMap.mMapRead.Count} record in mMapRead");
lgInfo($"getDynData: {memMap.mMapRead.Count} record in mMapRead | LUT: {useLUT}");
}
}
catch (Exception exc)
{
lgError(exc, "Errore in getDynData x ModBus TCP PLC --> ciclo disconnect/reconnect");
lgError(exc, "Errore in getDynData x ModBus TCP PLC --> ciclo disconnect/reconnect | LUT: {useLUT}");
tryDisconnect();
outVal = new Dictionary<string, string>();
tryConnect();
@@ -880,9 +993,16 @@ namespace IOB_WIN_NEXT
public int[] readInputReg(int startAddr, int qty)
{
int[] answ = new int[2];
if (currPLC.Connected)
try
{
answ = currPLC.ReadInputRegisters(startAddr, qty);
if (currPLC.Connected)
{
answ = currPLC.ReadInputRegisters(startAddr, qty);
}
}
catch (Exception exc)
{
lgError($"Errore in readInputReg{Environment.NewLine}{exc}");
}
return answ;
}
+27 -23
View File
@@ -34,6 +34,7 @@ namespace IOB_WIN_NEXT
public IobModbusTCPHam(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf)
{
lgInfo("NEW IOB ModBus TCP HAM");
// provo lettura una prima volta i dati DYN
if (currPLC != null && currPLC.Connected)
{
@@ -102,6 +103,30 @@ namespace IOB_WIN_NEXT
#region Private Methods
private void testBlockRead(int baseAddr, int numByte)
{
int baseHold = 40001;
int[] readTestFull = new int[2];
lgInfo($"-------------------- Inizio test lettura {baseAddr} --------------------");
try
{
stopwatch.Restart();
readTestFull = currPLC.ReadHoldingRegisters(baseAddr - baseHold, numByte);
stopwatch.Stop();
lgInfo($"Stats lettura | {readTestFull.Length} val | {stopwatch.ElapsedMilliseconds}ms");
}
catch
{ }
for (int i = 0; i < readTestFull.Length / 2; i++)
{
int[] thisSet = new int[2];
Array.Copy(readTestFull, i * 2, thisSet, 0, 2);
lgInfo($"{baseAddr + i * 2:000} | HoldingRegisters: {thisSet[0]} / {thisSet[1]} | Val Real: {ModbusClient.ConvertRegistersToFloat(thisSet):N6}");
}
lgInfo("-------------------- Completato test lettura {baseAddr} --------------------");
}
private void testRead()
{
//Ip-Address and Port of Modbus-TCP-Server
@@ -111,22 +136,10 @@ namespace IOB_WIN_NEXT
//modbusClient.WriteMultipleCoils(4, new bool[] { true, true, true, true, true, true, true, true, true, true }); //Write Coils starting with Address 5
//bool[] readCoils = modbusClient.ReadCoils(9, 10); //Read 10 Coils from Server, starting with address 10
//int[] readHoldingRegisters = currPLC.ReadHoldingRegisters(0, 34); //Read 10 Holding Registers from Server, starting with Address 1
int[] readHR1000 = currPLC.ReadHoldingRegisters(0, 100); //Read 10 Holding Registers from Server, starting with Address 1
//// Console Output
//for (int i = 0; i < readCoils.Length; i++)
// Console.WriteLine("Value of Coil " + (9 + i + 1) + " " + readCoils[i].ToString());
for (int i = 0; i < readHR1000.Length / 2; i++)
foreach (var item in memSetR)
{
Console.WriteLine($"Value of HoldingRegister {(i)} | {readHR1000[i]} / {readHR1000[i + 1]}");
int[] thisSet = new int[2];
Array.Copy(readHR1000, i, thisSet, 0, 2);
Console.WriteLine($"Convert val HoldingRegister {(i)} | {ModbusClient.ConvertRegistersToFloat(thisSet)}");
testBlockRead(item.Key, item.Value);
}
//Console.Write("Press any key to continue . . . ");
//Console.ReadKey(true);
}
#endregion Private Methods
@@ -174,15 +187,6 @@ namespace IOB_WIN_NEXT
B_input = byteSignals;
}
/// <summary>
/// effettua il setup dei memblock da gestire (NON leggo intera memoria ma tanti blocchi...)
/// </summary>
protected override void setupMemBlocks()
{
// da calcolare... ora setup cablato...
memSetR.Add(1, 34);
}
#endregion Protected Methods
#region Public Methods