]> git.basschouten.com Git - openhab-addons.git/commitdiff
[modbus] Added support for RTU encoding over TCP (#9435)
authorAndrew Fiddian-Green <software@whitebear.ch>
Mon, 28 Dec 2020 05:53:53 +0000 (05:53 +0000)
committerGitHub <noreply@github.com>
Mon, 28 Dec 2020 05:53:53 +0000 (21:53 -0800)
* [modbus] add support for rtu encoded over tcp
* [modbus] move classes to openhab/jamod
* [modbus] spotless
* [modbus] revert EndpointPoolConfiguration
* [modbus] remove virtual serial
* [modbus] resolve dependencies
* [modbus.studer] add support for RTU over TCP bridge

Signed-off-by: Andrew Fiddian-Green <software@whitebear.ch>
bundles/org.openhab.binding.modbus.studer/README.md
bundles/org.openhab.binding.modbus.studer/src/main/resources/OH-INF/thing/thing-types.xml
bundles/org.openhab.binding.modbus/README.md
bundles/org.openhab.binding.modbus/src/main/java/org/openhab/binding/modbus/internal/config/ModbusTcpConfiguration.java
bundles/org.openhab.binding.modbus/src/main/java/org/openhab/binding/modbus/internal/handler/ModbusTcpThingHandler.java
bundles/org.openhab.binding.modbus/src/main/resources/OH-INF/thing/bridge-tcp.xml
itests/org.openhab.binding.modbus.tests/src/main/java/org/openhab/binding/modbus/tests/ModbusDataHandlerTest.java
itests/org.openhab.binding.modbus.tests/src/main/java/org/openhab/binding/modbus/tests/ModbusPollerThingHandlerTest.java
itests/org.openhab.binding.modbus.tests/src/main/java/org/openhab/binding/modbus/tests/ModbusTcpThingHandlerTest.java

index 4520f35f4d066b0ac7c350c1cca476886b8f2330..f03eca6bdddb5ae6aa726b9aaaabbf739da8af73 100644 (file)
@@ -114,6 +114,11 @@ All channels read for a VarioString device
 
 ```
 Bridge modbus:serial:bridge [port="/dev/ttyUSB0",baud=9600,dataBits=8,parity="even",stopBits="1.0",encoding="rtu"]
+..or..
+Bridge modbus:tcp:bridge [host="192.168.178.56", port=502, rtuEncoded=true]
+
+...
+
 Thing modbus:xtender:bridge:xtenderdevice "Xtender" (modbus:serial:modbusbridge) [ slaveAddress=10, refresh=5 ]
 ```
 
index 8c0d9ea38330ed59a4f3270777e470ed44020a35..b690db6750fe40f47cdf5fc7226e39d7d930cfb5 100644 (file)
@@ -7,6 +7,7 @@
        <thing-type id="bsp">
                <supported-bridge-type-refs>
                        <bridge-type-ref id="serial"/>
+                       <bridge-type-ref id="tcp"/>
                </supported-bridge-type-refs>
                <label>BSP Studer</label>
                <description>Thing for Studer BSP Device</description>
index bec9f8b36453e0eb7e9385ccbdad894ee4fa75f5..2471568ace98ead578b949d50b38704de59d343c 100644 (file)
@@ -37,8 +37,8 @@ The binding can also *write* data to Modbus slaves using FC05 (Write single coil
 
 Please note the following caveats or limitations
 
-* the binding does *not* act as Modbus slave (e.g. as Modbus TCP server).
-* the binding does *not* support Modbus RTU over Modbus TCP, also known as "Modbus over TCP/IP" or "Modbus over TCP" or "Modbus RTU/IP", although normal "Modbus TCP" is supported. However, there is a workaround: you can use a Virtual Serial Port Server, to emulate a COM Port and Bind it with openHAB using Modbus Serial.
+* The binding does *not* act as Modbus slave (e.g. as Modbus TCP server).
+* The binding *does* support Modbus RTU over Modbus TCP, (also known as "Modbus over TCP/IP" or "Modbus over TCP" or "Modbus RTU/IP"), as well as normal "Modbus TCP".
 
 
 ## Background Material
@@ -108,11 +108,12 @@ When optional parameters are not specified, they default to the values shown in
 
 Basic parameters
 
-| Parameter | Type    | Required | Default if omitted | Description                                                 |
-| --------- | ------- | -------- | ------------------ | ----------------------------------------------------------- |
-| `host`    | text    |          | `"localhost"`      | IP Address or hostname                                      |
-| `port`    | integer |          | `502`              | Port number                                                 |
-| `id`      | integer |          | `1`                | Slave id. Also known as station address or unit identifier. |
+| Parameter    | Type    | Required | Default if omitted | Description                                                 |
+| ------------ | ------- | -------- | ------------------ | ----------------------------------------------------------- |
+| `host`       | text    |          | `"localhost"`      | IP Address or hostname                                      |
+| `port`       | integer |          | `502`              | Port number                                                 |
+| `id`         | integer |          | `1`                | Slave id. Also known as station address or unit identifier. |
+| `rtuEncoded` | boolean |          | `false`            | Use RTU encoding instead of regular TCP encoding.           |
 
 Advanced parameters
 
index b4314f45e7aa54d46155e5cd7f8525749cf17cda..832e5418705773a4909030d3abf8f1ca0e1a5c55 100644 (file)
@@ -32,6 +32,11 @@ public class ModbusTcpConfiguration {
     private int reconnectAfterMillis;
     private int connectTimeoutMillis;
     private boolean enableDiscovery;
+    private boolean rtuEncoded;
+
+    public boolean getRtuEncoded() {
+        return rtuEncoded;
+    }
 
     public @Nullable String getHost() {
         return host;
index 87fbc4864fdea3699a4f70439e433d6d6db3ab2f..8d90b766683c3a06c85be258b620b6e4aca25602 100644 (file)
@@ -51,7 +51,7 @@ public class ModbusTcpThingHandler
         }
 
         this.config = config;
-        endpoint = new ModbusTCPSlaveEndpoint(host, config.getPort());
+        endpoint = new ModbusTCPSlaveEndpoint(host, config.getPort(), config.getRtuEncoded());
 
         EndpointPoolConfiguration poolConfiguration = new EndpointPoolConfiguration();
         this.poolConfiguration = poolConfiguration;
index b1e48f945f60837c225d6e8f4e80bba7fab9b662..3d40067485e1ae23829b47973ad91c95c9dbe5f2 100644 (file)
                                <default>false</default>
                        </parameter>
 
+                       <parameter name="rtuEncoded" type="boolean">
+                               <label>RTU Encoding</label>
+                               <description>Use RTU Encoding over IP</description>
+                               <default>false</default>
+                       </parameter>
+
                        <!-- connection handling -->
                        <parameter name="timeBetweenTransactionsMillis" type="integer" min="0" unit="ms">
                                <label>Time Between Transactions</label>
index 77fa7c3da1e07b0b9991abbc65ca3032e1bdbb10..16c11ee64ba33efc53120d793dc745c5474e62e4 100644 (file)
@@ -20,8 +20,13 @@ import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.*;
 import static org.openhab.binding.modbus.internal.ModbusBindingConstantsInternal.*;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Objects;
 import java.util.concurrent.ScheduledFuture;
 import java.util.function.Consumer;
 import java.util.function.Function;
@@ -151,7 +156,7 @@ public class ModbusDataHandlerTest extends AbstractModbusOSGiTest {
     }
 
     private Bridge createTcpMock() {
-        ModbusSlaveEndpoint endpoint = new ModbusTCPSlaveEndpoint("thisishost", 502);
+        ModbusSlaveEndpoint endpoint = new ModbusTCPSlaveEndpoint("thisishost", 502, false);
         Bridge tcpBridge = ModbusPollerThingHandlerTest.createTcpThingBuilder("tcp1").build();
         ModbusTcpThingHandler tcpThingHandler = Mockito.mock(ModbusTcpThingHandler.class);
         tcpBridge.setStatusInfo(new ThingStatusInfo(ThingStatus.ONLINE, ThingStatusDetail.NONE, ""));
@@ -257,7 +262,7 @@ public class ModbusDataHandlerTest extends AbstractModbusOSGiTest {
     private void testOutOfBoundsGeneric(int pollStart, int pollLength, String start,
             ModbusReadFunctionCode functionCode, ValueType valueType, ThingStatus expectedStatus,
             BundleContext context) {
-        ModbusSlaveEndpoint endpoint = new ModbusTCPSlaveEndpoint("thisishost", 502);
+        ModbusSlaveEndpoint endpoint = new ModbusTCPSlaveEndpoint("thisishost", 502, false);
 
         // Minimally mocked request
         ModbusReadRequestBlueprint request = Mockito.mock(ModbusReadRequestBlueprint.class);
@@ -409,7 +414,7 @@ public class ModbusDataHandlerTest extends AbstractModbusOSGiTest {
     private ModbusDataThingHandler testReadHandlingGeneric(ModbusReadFunctionCode functionCode, String start,
             String transform, ValueType valueType, BitArray bits, ModbusRegisterArray registers, Exception error,
             BundleContext context, boolean autoCreateItemsAndLinkToChannels) {
-        ModbusSlaveEndpoint endpoint = new ModbusTCPSlaveEndpoint("thisishost", 502);
+        ModbusSlaveEndpoint endpoint = new ModbusTCPSlaveEndpoint("thisishost", 502, false);
 
         int pollLength = 3;
 
@@ -461,7 +466,7 @@ public class ModbusDataHandlerTest extends AbstractModbusOSGiTest {
     private ModbusDataThingHandler testWriteHandlingGeneric(String start, String transform, ValueType valueType,
             String writeType, ModbusWriteFunctionCode successFC, String channel, Command command, Exception error,
             BundleContext context) {
-        ModbusSlaveEndpoint endpoint = new ModbusTCPSlaveEndpoint("thisishost", 502);
+        ModbusSlaveEndpoint endpoint = new ModbusTCPSlaveEndpoint("thisishost", 502, false);
 
         // Minimally mocked request
         ModbusReadRequestBlueprint request = Mockito.mock(ModbusReadRequestBlueprint.class);
@@ -716,7 +721,7 @@ public class ModbusDataHandlerTest extends AbstractModbusOSGiTest {
 
     private void testValueTypeGeneric(ModbusReadFunctionCode functionCode, ValueType valueType,
             ThingStatus expectedStatus) {
-        ModbusSlaveEndpoint endpoint = new ModbusTCPSlaveEndpoint("thisishost", 502);
+        ModbusSlaveEndpoint endpoint = new ModbusTCPSlaveEndpoint("thisishost", 502, false);
 
         // Minimally mocked request
         ModbusReadRequestBlueprint request = Mockito.mock(ModbusReadRequestBlueprint.class);
@@ -764,7 +769,7 @@ public class ModbusDataHandlerTest extends AbstractModbusOSGiTest {
     public void testRefreshOnData() throws InterruptedException {
         ModbusReadFunctionCode functionCode = ModbusReadFunctionCode.READ_COILS;
 
-        ModbusSlaveEndpoint endpoint = new ModbusTCPSlaveEndpoint("thisishost", 502);
+        ModbusSlaveEndpoint endpoint = new ModbusTCPSlaveEndpoint("thisishost", 502, false);
 
         int pollLength = 3;
 
@@ -817,7 +822,7 @@ public class ModbusDataHandlerTest extends AbstractModbusOSGiTest {
             ThingHandler foo = parent.getHandler();
             addThing(parent);
         } else {
-            ModbusSlaveEndpoint endpoint = new ModbusTCPSlaveEndpoint("thisishost", 502);
+            ModbusSlaveEndpoint endpoint = new ModbusTCPSlaveEndpoint("thisishost", 502, false);
 
             // Minimally mocked request
             ModbusReadRequestBlueprint request = Mockito.mock(ModbusReadRequestBlueprint.class);
index 26693da1093efd4cd4249e154969c818454798c1..e09d071588aeed2565f3c020738932221d52155d 100644 (file)
@@ -276,7 +276,7 @@ public class ModbusPollerThingHandlerTest extends AbstractModbusOSGiTest {
 
     @SuppressWarnings("null")
     private boolean checkEndpoint(ModbusSlaveEndpoint endpointParam) {
-        return endpointParam.equals(new ModbusTCPSlaveEndpoint(HOST, PORT));
+        return endpointParam.equals(new ModbusTCPSlaveEndpoint(HOST, PORT, false));
     }
 
     private boolean checkRequest(ModbusReadRequestBlueprint request, ModbusReadFunctionCode functionCode) {
index 5e18fe8e074baabdbe1d8ad6240d964fedb2c671..4e7769e11c60d2f0ef66c2cde35849bec16fd240 100644 (file)
@@ -70,7 +70,7 @@ public class ModbusTcpThingHandlerTest extends AbstractModbusOSGiTest {
         ModbusTcpThingHandler thingHandler = (ModbusTcpThingHandler) thing.getHandler();
         assertNotNull(thingHandler);
         ModbusSlaveEndpoint slaveEndpoint = thingHandler.getEndpoint();
-        assertThat(slaveEndpoint, is(equalTo(new ModbusTCPSlaveEndpoint("thisishost", 44))));
+        assertThat(slaveEndpoint, is(equalTo(new ModbusTCPSlaveEndpoint("thisishost", 44, false))));
         assertThat(thingHandler.getSlaveId(), is(9));
 
         InOrder orderedVerify = Mockito.inOrder(mockedModbusManager);