Modbus openHAB2 binding available for alpha testing

Hi!

Check out the documentation, and let me know if it unclear.

All the parameters are documented there and this one is not any different. Let me know if there is something to improve in the docs.

Please also note that yuu can use Paper UI for configuration, avoiding the textual configuration. I personally find the textual configuration is convenient and a way of documenting the setup.

Sami

1 Like

everything worked out. Thank you. I use text settings.

1 Like

Can you please provide me the error message?

You can also paste the configuration here, I can check it.

Regarding the encoding, yes, I have read that UTF-8 BOM is the problemā€¦ unrelated to this binding as you mentioned also.

Best,
Sami

Hi ssalonen,
I have done some more testing and the binding seems to be stable (at least in my simple test setup). When I find the time, I will do some more performance testing within my productive setup.

However, there is still a practical problem with some devices that I may have mentioned earlier (canā€™t find the corresponding post anymoreā€¦):

I have some devices that take measurements on request but also provide some more I/Os. The measurement process takes time (~2 seconds) during which the device is not reachable. If the measurement function was the only thing the device is doing, I could simply omit automatic polling and use a rule to start the measurement (write to a certain holding register), wait 2 seconds and then request a refresh of the item corresponding to the input register containing the measured value (and therefore never use automatic polling).

However there are also the I/Osā€¦ of course I want these (coils/inputs) to be polled as often as possible. If I use a poller-thing for that, I get time out errors whenever the measurement-rule is triggering (every 5 minutes). I could write another rule that would have to be executed more than once per second (ideally every couple hundred milliseconds), request updates for the I/O-items manually and pause when the measurement is taking place - but that is not a nice solution and produces a lot of overhead and CPU load considering weā€™re talking 10+ devices hereā€¦

It would be a lot nicer to use the poller thing instead and be able to disable polling from a rule. For example we could make the refresh parameter of the poller thing available as a channel and bind a number item to it.

What do you think about that? It would not be that big a deal and make the binding a lot more flexible.

Best,
Max

1 Like

Hi, great to hear from you!

I wonder if you can follow the advice from here to reconfigure pollers : Thing configuration from rules

I have not tested that personally and not sure if there are some issues in case the things are defined using the text fileā€¦

This would be ideal, I think. I am a bit hesitant to introduce configuration options as channels, havenā€™t seen that with other bindings.

Best
Sami

1 Like

Hi Sami,
even if that works with textually configured things itā€™s still just a hack (or work around). I could also change the configuration files using a shell script and maybe create a ramdisk and mount it to the things folder to avoid harddisk writing.

Both solutions donā€™t sound very appealing to me.

How is this handled in other bindings? What about the thing-status (thing.getStatus())? Can one set the status of a thing to ā€œofflineā€ in, for example, the TCP or HTTP binding and therefore stop polling?

And while were at it: How does the HTTP-Binding or the TCP-Binding handle a loss of connection to its endpoint? Is the corresponding thingā€™s status set to offline? The latter is sth. I would expect to be the behaviour of the Modbus-Binding too.

Kind regards,
Max

Please help
I am allways get error:

Could not get port identifier, maybe insufficient permissions. gnu.io.NoSuchPortException: null

What I did:

  1. Install OH2(2.3.0) on my Synology DS418
  2. Make all installation steps for serial connection(https://github.com/openhab/openhab-syno-spk). Create group, set permission on device, modify udev rules, change owner of lock dir. Also add -Dgnu.io.rxtx.SerialPorts=/dev/ttyUSB1 to karaf script
  3. Install serial transport
  4. Install Modbus Binding
  5. Install openHAB MODBUS Transport Bundle
  6. set log TRACE ā€¦
  7. Create Thing : slave serial, /dev/ttyUSB1
  8. Create Poller for slave: holding register

But connection always could not created:

2018-06-20 22:04:46.106 [TRACE] [ing.ModbusSlaveConnectionFactoryImpl] - Created connection SerialConnection@7a70950e[portName=/dev/ttyUSB1,port=<null>] for endpoint ModbusSerialSlaveEndpoint@73a395c7[portName=/dev/ttyUSB1]
2018-06-20 22:04:46.108 [ERROR] [et.wimpi.modbus.net.SerialConnection] - Could not get port identifier, maybe insufficient permissions. gnu.io.NoSuchPortException: null
2018-06-20 22:04:46.110 [ERROR] [ing.ModbusSlaveConnectionFactoryImpl] - connect try 1/1 error: Could not get port identifier, maybe insufficient permissions. null. Connection SerialConnection@7a70950e[portName=/dev/ttyUSB1,port=<null>]. Endpoint ModbusSerialSlaveEndpoint@73a395c7[portName=/dev/ttyUSB1]
2018-06-20 22:04:46.111 [ERROR] [ing.ModbusSlaveConnectionFactoryImpl] - re-connect reached max tries 1, throwing last error: Could not get port identifier, maybe insufficient permissions. null. Connection SerialConnection@7a70950e[portName=/dev/ttyUSB1,port=<null>]. Endpoint ModbusSerialSlaveEndpoint@73a395c7[portName=/dev/ttyUSB1]
2018-06-20 22:04:46.112 [ERROR] [ing.ModbusSlaveConnectionFactoryImpl] - Error connecting connection SerialConnection@7a70950e[portName=/dev/ttyUSB1,port=<null>] for endpoint ModbusSerialSlaveEndpoint@73a395c7[portName=/dev/ttyUSB1]: Could not get port identifier, maybe insufficient permissions. null

java version:

java version "1.8.0_172"
Java(TM) SE Runtime Environment (build 1.8.0_172-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.172-b11, mixed mode)

DS418
Realtek RTD1296 SoC
DSM 6.1.7-15284

Hi Max!

I can see that my suggestion feels like a hack/workaroundā€¦

Regarding the thing status: as far as I know, binding controls the thing status, and thus not possible to ā€œsetā€ it from outside. Even if it would be possible, the binding is updating the status all the time, thus overwriting any possible changes.

TCP and HTTP are version 1 bindings, and have no concept of OFFLINE or OFFLINE so I think we should not compare to those.

knx binding was rewritten for openHAB2 and does have regular polling (readInterval) as well. The implementation is similar to modbus binding ā€“ I canā€™t see any way to disable polling ā€œduring runtimeā€.

Another example is the Atlona binding (polling).

In case of read/write errors, the modbus binding is setting the data and poller things OFFLINE. The status is reseted to ONLINE whenever operation is successful.

Does this help at all?

Best,
Sami

Hi Sami,

Sure. I assumed those bindings had already made it to version 2. Sry for the bad research.

The KNX spec specifies how KNX devices communicate on a low level (bus communication, addressing) and on a higher level in order to allow for interoperability. That is not the case with Modbus. Modbus only specifies the low level communication and thatā€™s it. The rest is vendor specific. Since things are a lot clearer in KNX, the need to disable polling for a specific device during runtime may never have arisenā€¦

Nice! I like that :slight_smile:

I will try the hacky workarounds although Iā€™d love to see a cleaner solution.

Thx for the good work! I hope this binding will soon be merged.

Best,
Max

I found some details on the SMA inverter I was trying to communicate with.

Iā€™m trying to read the Input registers (Uint32 and Int32), normally read length of 2.

This is not working with SMA, if I set the length to 4 it works perfectly - but why?

It seems to be problem/bug with the device, see discussion here https://github.com/openhab/openhab1-addons/issues/4931

Best
Sami

Thanks Sami, good to know that I havenā€™t ā€œlostā€ it.

Hi Sami,
seems like that doesnā€™t work with textually configured things:

2018-06-22 23:38:57.718 [INFO ] [st.core.internal.thing.ThingResource] - Received HTTP PUT request for update configuration at 'things/modbus:poller:wc101:coils/config' for an unmanaged thing 'modbus:poller:wc101:coils'.

Best,
Max

@andrey I believe you messaged me privately as well?

Unfortunately I canā€™t help you with the Synology, sounds like something special needs to be done with this device.

The README of https://github.com/openhab/openhab-syno-spk says that

For Z-Wave and Devices that use dev/ttyACM0 or dev/ttyACM1 will at install a script copy to /usr/local/etc/rc.d that will execute install or on Boot. This exec on the PortĀ“s chmod 777. And load some USB Kernelmodules. To make these itĀ“s necessary to enter on Installation the Admin Password from DSM.

By looking into pacakge.tgz, you can find openHAB-zwave.sh:

sudo insmod /lib/modules/usbserial.ko
sudo insmod /lib/modules/ftdi_sio.ko
sudo insmod /lib/modules/cdc-acm.ko

sudo chmod 777 /lib/modules/usbserial.ko
sudo chmod 777 /lib/modules/ftdi_sio.ko
sudo chmod 777 /lib/modules/cdc-acm.ko

sudo chmod 777 /dev/ttyACM0
sudo chmod 777 /dev/ttyACM0

Perhaps something similar is needed for your serial port? You might consider opening a new thread regarding serial port configuration with Synology.

Best,
Sami

@zacofunny, can you please try out with the latest version?

We now have caching in place (used only with REFRESH commands) to avoid spamming the modbus, see cacheMillis parameter of poller in docs.

Default cache is now 50 ms which probably cuts out the majority of REFRESH calls.

@mbs38 Thanks for trying it out! I will try to figure something out for you .

Will first get the PR merged, and then introduce additional improvement to tackle thisā€¦

All, I noticed that the Marketplace was pointing to 2.3.0-SNAPSHOT allthough 2.4.0-SNAPSHOT is the latest.

Please try out with this new version! All feedback is now highly appreciated since the code is about to be merged to main openHAB code base.

Hi! I will try it asap! Thanks for your hard work!

You are welcome Sami. Thx for tackling this issue.

Btw: Iā€™m really looking forward to the merge. Iā€™ve got a friend who has another huge Modbus-Installation (~50 devices spread over multiple serial ports, >1500 I/Os). I am excited to see how the new binding is going to perform there :smiley:

Hi, Iā€™m back :slight_smile:

The situation is:

  1. I have set up new instance of openhab (stable 2.3) and put latest snapshot of the binding
  2. I have set up logging to TRACE
  3. I have currently set 102 things (colis). Note: This is only part of the system
    Current configuration (full config contains 799 markers(coils) as stated below):
Bridge modbus:serial:fatekplcusb0  "FatekPLC_USB0" [ baud=115200, timeBetweenTransactionsMillis=60, cacheMillis=500, connectMaxTries=1, stopBits="1.0", parity="none", receiveTimeoutMillis=1500, dataBits=8, echo=false, encoding="rtu", flowControlIn="none", port="/dev/ttyUSB0", flowControlOut="none", connectTimeoutMillis=10000, id=1 ] {

    Bridge poller coils_Y0_to_Y255 "FatekPLC_Poller_Y0_to_Y255" [ start=0, length=256, refresh=1000, type="coil" ] {
        // Note the zero based indexing: first coil is index 0.
        Thing data FatekPLC_Modbus_Y0 "FatekPLC_Modbus_Y0" @ "Modbus" [ readStart="0", readValueType="bit", writeStart="0", writeValueType="bit", writeType="coil" ]
        Thing data FatekPLC_Modbus_Y1 "FatekPLC_Modbus_Y1" @ "Modbus" [ readStart="1", readValueType="bit", writeStart="1", writeValueType="bit", writeType="coil" ]
    }
//M0 to M799
    Bridge poller markers_M0_to_M799 "FatekPLC_Poller_M0_to_M199" [ start=2000, length=800, refresh=2000, type="coil" ] {
        // Note the zero based indexing: first coil is index 0.
        Thing data FatekPLC_Modbus_M0 "FatekPLC_Modbus_M0000" @ "Modbus" [ readStart="2000", readValueType="bit", writeStart="2000", writeValueType="bit", writeType="coil" ]
        Thing data FatekPLC_Modbus_M1 "FatekPLC_Modbus_M0001" @ "Modbus" [ readStart="2001", readValueType="bit", writeStart="2001", writeValueType="bit", writeType="coil" ]
        //Thing data FatekPLC_Modbus_M2 "FatekPLC_Modbus_M0002" @ "Modbus" [ readStart="2002", readValueType="bit", writeStart="2002", writeValueType="bit", writeType="coil" ]
        //Thing data FatekPLC_Modbus_M3 "FatekPLC_Modbus_M0003" @ "Modbus" [ readStart="2003", readValueType="bit", writeStart="2003", writeValueType="bit", writeType="coil" ]
        //Thing data FatekPLC_Modbus_M4 "FatekPLC_Modbus_M0004" @ "Modbus" [ readStart="2004", readValueType="bit", writeStart="2004", writeValueType="bit", writeType="coil" ]
        //Thing data FatekPLC_Modbus_M5 "FatekPLC_Modbus_M0005" @ "Modbus" [ readStart="2005", readValueType="bit", writeStart="2005", writeValueType="bit", writeType="coil" ]
        //Thing data FatekPLC_Modbus_M6 "FatekPLC_Modbus_M0006" @ "Modbus" [ readStart="2006", readValueType="bit", writeStart="2006", writeValueType="bit", writeType="coil" ]
        //Thing data FatekPLC_Modbus_M7 "FatekPLC_Modbus_M0007" @ "Modbus" [ readStart="2007", readValueType="bit", writeStart="2007", writeValueType="bit", writeType="coil" ]
        Thing data FatekPLC_Modbus_M8 "FatekPLC_Modbus_M0008" @ "Modbus" [ readStart="2008", readValueType="bit", writeStart="2008", writeValueType="bit", writeType="coil" ]
        Thing data FatekPLC_Modbus_M9 "FatekPLC_Modbus_M0009" @ "Modbus" [ readStart="2009", readValueType="bit", writeStart="2009", writeValueType="bit", writeType="coil" ]
        //Thing data FatekPLC_Modbus_M10 "FatekPLC_Modbus_M0010" @ "Modbus" [ readStart="2010", readValueType="bit", writeStart="2010", writeValueType="bit", writeType="coil" ]
        Thing data FatekPLC_Modbus_M11 "FatekPLC_Modbus_M0011" @ "Modbus" [ readStart="2011", readValueType="bit", writeStart="2011", writeValueType="bit", writeType="coil" ]
        Thing data FatekPLC_Modbus_M12 "FatekPLC_Modbus_M0012" @ "Modbus" [ readStart="2012", readValueType="bit", writeStart="2012", writeValueType="bit", writeType="coil" ]
        Thing data FatekPLC_Modbus_M13 "FatekPLC_Modbus_M0013" @ "Modbus" [ readStart="2013", readValueType="bit", writeStart="2013", writeValueType="bit", writeType="coil" ]
        //Thing data FatekPLC_Modbus_M14 "FatekPLC_Modbus_M0014" @ "Modbus" [ readStart="2014", readValueType="bit", writeStart="2014", writeValueType="bit", writeType="coil" ]
        //Thing data FatekPLC_Modbus_M15 "FatekPLC_Modbus_M0015" @ "Modbus" [ readStart="2015", readValueType="bit", writeStart="2015", writeValueType="bit", writeType="coil" ]
        Thing data FatekPLC_Modbus_M16 "FatekPLC_Modbus_M0016" @ "Modbus" [ readStart="2016", readValueType="bit", writeStart="2016", writeValueType="bit", writeType="coil" ]
        Thing data FatekPLC_Modbus_M17 "FatekPLC_Modbus_M0017" @ "Modbus" [ readStart="2017", readValueType="bit", writeStart="2017", writeValueType="bit", writeType="coil" ]
        //Thing data FatekPLC_Modbus_M18 "FatekPLC_Modbus_M0018" @ "Modbus" [ readStart="2018", readValueType="bit", writeStart="2018", writeValueType="bit", writeType="coil" ]
        Thing data FatekPLC_Modbus_M19 "FatekPLC_Modbus_M0019" @ "Modbus" [ readStart="2019", readValueType="bit", writeStart="2019", writeValueType="bit", writeType="coil" ]
        Thing data FatekPLC_Modbus_M20 "FatekPLC_Modbus_M0020" @ "Modbus" [ readStart="2020", readValueType="bit", writeStart="2020", writeValueType="bit", writeType="coil" ]
        //Thing data FatekPLC_Modbus_M21 "FatekPLC_Modbus_M0021" @ "Modbus" [ readStart="2021", readValueType="bit", writeStart="2021", writeValueType="bit", writeType="coil" ]
        //Thing data FatekPLC_Modbus_M22 "FatekPLC_Modbus_M0022" @ "Modbus" [ readStart="2022", readValueType="bit", writeStart="2022", writeValueType="bit", writeType="coil" ]
        //Thing data FatekPLC_Modbus_M23 "FatekPLC_Modbus_M0023" @ "Modbus" [ readStart="2023", readValueType="bit", writeStart="2023", writeValueType="bit", writeType="coil" ]
        //Thing data FatekPLC_Modbus_M24 "FatekPLC_Modbus_M0024" @ "Modbus" [ readStart="2024", readValueType="bit", writeStart="2024", writeValueType="bit", writeType="coil" ]
        Thing data FatekPLC_Modbus_M25 "FatekPLC_Modbus_M0025" @ "Modbus" [ readStart="2025", readValueType="bit", writeStart="2025", writeValueType="bit", writeType="coil" ]
        Thing data FatekPLC_Modbus_M26 "FatekPLC_Modbus_M0026" @ "Modbus" [ readStart="2026", readValueType="bit", writeStart="2026", writeValueType="bit", writeType="coil" ]
        Thing data FatekPLC_Modbus_M27 "FatekPLC_Modbus_M0027" @ "Modbus" [ readStart="2027", readValueType="bit", writeStart="2027", writeValueType="bit", writeType="coil" ]
        Thing data FatekPLC_Modbus_M28 "FatekPLC_Modbus_M0028" @ "Modbus" [ readStart="2028", readValueType="bit", writeStart="2028", writeValueType="bit", writeType="coil" ]
        Thing data FatekPLC_Modbus_M29 "FatekPLC_Modbus_M0029" @ "Modbus" [ readStart="2029", readValueType="bit", writeStart="2029", writeValueType="bit", writeType="coil" ]
        //Thing data FatekPLC_Modbus_M30 "FatekPLC_Modbus_M0030" @ "Modbus" [ readStart="2030", readValueType="bit", writeStart="2030", writeValueType="bit", writeType="coil" ]

This is my current Fatek config:
image

With this configuration it works without issues thaat I have had before, however Iā€™m not satisfied since i observe the following behavior when I turn on/off switch:

2018-07-03 23:05:05.815 [ome.event.ItemCommandEvent] - Item 'Kitchen_Bar_Table_Light' received command ON
2018-07-03 23:05:05.865 [vent.ItemStateChangedEvent] - Kitchen_Bar_Table_Light changed from OFF to ON
2018-07-03 23:05:07.430 [vent.ItemStateChangedEvent] - Kitchen_Bar_Table_Light changed from ON to OFF
2018-07-03 23:05:09.590 [vent.ItemStateChangedEvent] - Kitchen_Bar_Table_Light changed from OFF to ON
2018-07-03 23:05:09.604 [vent.ItemStateChangedEvent] - Kitchen_Bar_Table_Light_GH changed from OFF to ON
2018-07-03 23:05:19.819 [ome.event.ItemCommandEvent] - Item 'Kitchen_Bar_Table_Light' received command OFF
2018-07-03 23:05:19.850 [vent.ItemStateChangedEvent] - Kitchen_Bar_Table_Light changed from ON to OFF
2018-07-03 23:05:21.715 [vent.ItemStateChangedEvent] - Kitchen_Bar_Table_Light changed from OFF to ON
2018-07-03 23:05:23.718 [vent.ItemStateChangedEvent] - Kitchen_Bar_Table_Light changed from ON to OFF
2018-07-03 23:05:23.729 [vent.ItemStateChangedEvent] - Kitchen_Bar_Table_Light_GH changed from ON to OFF
2018-07-03 23:05:51.028 [ome.event.ItemCommandEvent] - Item 'Kitchen_Bar_Table_Light' received command ON
2018-07-03 23:05:51.043 [vent.ItemStateChangedEvent] - Kitchen_Bar_Table_Light changed from OFF to ON
2018-07-03 23:05:51.731 [vent.ItemStateChangedEvent] - Kitchen_Bar_Table_Light changed from ON to OFF
2018-07-03 23:05:53.808 [vent.ItemStateChangedEvent] - Kitchen_Bar_Table_Light changed from OFF to ON
2018-07-03 23:05:53.813 [vent.ItemStateChangedEvent] - Kitchen_Bar_Table_Light_GH changed from OFF to ON
2018-07-03 23:06:00.017 [ome.event.ItemCommandEvent] - Item 'Kitchen_Bar_Table_Light' received command OFF
2018-07-03 23:06:00.042 [vent.ItemStateChangedEvent] - Kitchen_Bar_Table_Light changed from ON to OFF
2018-07-03 23:06:00.272 [vent.ItemStateChangedEvent] - Kitchen_Bar_Table_Light changed from OFF to ON
2018-07-03 23:06:04.150 [vent.ItemStateChangedEvent] - Kitchen_Bar_Table_Light changed from ON to OFF
2018-07-03 23:06:04.163 [vent.ItemStateChangedEvent] - Kitchen_Bar_Table_Light_GH changed from ON to OFF

So when I switch light on, it turns on correctly however the status bar in habdroid turns on, then off then on again. The above log shows it as I described. Same behavior I see in Basic UI.
A least it sets the correct state in the end, however only if I wait for the full cycle. If I do it too quickly the state sets often to wrong value.