Modbus openHAB2 binding available for alpha testing

Info only - Thing status can now be used to trigger rules, which for Modbus users allows for creating error management rules.

1 Like

I’m trying to post up first version of the binding to the IOT marketplace. I have tested it very superficially but would like to start gathering first feedback already.

At this stage only TCP connections are supported, will implement serial support later.

UPDATE : the binding is now in the eclipse market place :

Both the transport and binding should be installed for a working installation

Best,
Sami

The binding follows the thing hierachy described in here (Alternative proposal (better?) version).

So you have to define the following things

  1. Connection, e.g. 192.168.1.100 port 502.
  • you can define parameters specific to endpoint, such as the the time between transactions etc. (previously in the old binding these were in the connection string)
  1. Poll definition (use connection as bridge)
  • what to poll (holding register, input register, coils, discrete inputs)
  • how often to poll (use zero to disable polling!)
  • how many items to poll, starting from what index
  1. readwrite definition (use poller as bridge): gathers different “read rules” and “write rules”, similar to item config string in the old binding
  • no configuration
  1. read definition, optional, use readwrite as bridge
  • specify the index (relative to polled items) from which to read, how to read it (valuetype), trigger and transform a bit similarly as with old binding
  • TODO: need to document this more carefully and improve the help text in UI
  1. write definition, optional, use readwrite as bridge
  • now should support non-16bit writing, e.g. writing float32
  • what modbus item to write: coil or holding register
  • address to write, not relative to polled data
  • how to write: value type
  • transform and trigger as with old binding
  • TODO: need to document this more carefully and improve the help text in UI

It’s most convenient to use readwrite channels to read the data; values from all read are aggregated from all the read things. This is similar how old binding item state reflected all the “read definitions” in the config string.

Please comment!

Best,
Sami

Serial slaves should be now supported as well, jenkins is building so tonight there should be a test version available in the IOT store.

Any feedback or testing would be much appreciated!

could you post an example configuration (.things + .items) for serial devices?

Sure!

Here’s some examples

modbus.things

Reads from from a serial device, configures serial parameters. Holding registers are polled every 500ms. Values are extracted from the holding registers to things read1 and read2. Furthermore, write1 thing is defined in order to tell how commands to readwriteCollector should be handled. In this case the are written as int16 register (first register)

Bridge modbus:serial:endpoint [ port="/dev/ttyS0", baud=9600, id=1, stopBits="1.0", parity="none",dataBits=8, echo=false, encoding="rtu", flowControlIn="none", flowControlOut="none", receiveTimeoutMillis=1500 ] {
    Bridge poller poller1 [ start=0, length=3, refresh=500, type="holding" ] {
        Bridge readwrite readwriteCollector { 
            Thing read read1 [ start=0, transform="default", trigger="*", valueType="int16" ]
            Thing read read2 [ start=1, transform="default", trigger="*", valueType="int16" ]
            Thing write write1 [ start=0, transform="default", trigger="*", valueType="int16", type="holding" ]
        }
    }   
}

modbus.items

Number NumberItemTest            "Number readwrite [%f]"    { channel="modbus:readwrite:endpoint:poller1:readwriteCollector:number" }

modbus.sitemap

sitemap modbus label="Modbus"
{
    Frame {
        Text item=NumberItemTest
    }
}

###To install the modbus binding

  1. Install serial transport: feature:install openhab-transport-serial
  2. install modbus transport bundle (copy it to addons folder, see this thread if you are unsure)
  3. install modbus binding bundle (same way as the transport bundle)
  4. List modbus bundles bundle:list | grep -i modbus . If necessary, start them with bundle:start BUNDLENUMER

The bundles are not visible via Eclipse IOT openhab addon (reason unknown, discussed here). However, you can download the jar files manually for installation.

Best,
Sami

UPDATE: corrected NumberItemTest channel reference.

Thx Sami.

I’ve tried your example configuration.

First off, the value of the Item NumberItemTest is always NULL - it never changes. There are no error message in the log:
https://pastebin.com/raw/UpemGDib

Just for fun I’ve changed the value of “refresh” in the .things file to a lower value WHILE openhab was running. It seems to work (activity leds are blinking faster now) but in the log I got these errors: https://pastebin.com/raw/VQc2WpEZ

Best,
Max

Thanks @mbs38!

I think I had the wrong item configuration (channel id was incomplete). I have now updated the above configuration, please check if it works for you now.

The ERRORs you got – I need to check those more carefully, might be a bug which shows up when poller parameters are changed.

UPDATE: Figured out likely reason for the ERRORs, actually it was something on my backlog already :slight_smile: Jenkins is now building fixed version. Should be out latest tomorrow!

Best
Sami

Unfortunately it doesn’t work either. -.-

Hmm, something’s wrong. I have to try reproduce using locally…

In the meanwhile, could you enable verbose logging:

log:set TRACE net.wimpi.modbus
log:set TRACE org.openhab.binding.modbus
log:set TRACE org.openhab.io.transport.modbus

and paste here what comes out. Thanks!

https://pastebin.com/raw/2zfMr94P

Best,
Max

Thanks, I will let you know once I know more.

At least there is the NullPointerException, perhaps that causes bad things later on. Know how to fix that – let’s see if there is something else as well.

Thanks for the help!!

OK, I know the reason for not having a value. With this version, you have to link the read thing’s channel to an item

modbus_dummy_bug_workaround.items

Number DummyFix            "Number read1 [%f]"    { channel="modbus:readwrite:endpoint:poller1:read1:number" }
Number DummyFix2            "Number read2 [%f]"    { channel="modbus:readwrite:endpoint:poller1:read2:number" }

update: these dummy items are not needed anymore with the fixed version

The modbus_dummy_bug_workaround.items should not be needed anymore, new version fixes this

I have also fixed the NullPointerException.

Update (July 30): The jenkins seems have some issues which means that the IOT marketplace is not updated yet.

Update (July 31): build issues are now solved and IOT marketplace is updated

Seems to work. However, changing the the poller parameter “refresh” has no effect.

EDIT: There may also be a design issue concerning the thing definitions: If I have understood the idea behind “things” correctly, things should represent an actual physical device - like a Modbus capable sensor for example. We should not confuse users by mixing the concept of things with the concept of objects in object oriented programming…
What do you think about that?

Best,
Max

Cannot reproduce the issue with refresh. At least modifying the *.things file seems to have an effect. It seems that you cannot modify the parameters with paper UI if things file is defined – is this an feature of openhab2?

Updated the binding with some NullPointer fixes when poller has been set to not to poll (refresh=0)

Regarding things and physical objects: indeed, I have the same concern. In fact, it has been discussed quite much in this thread as well. I’m not sure that the analogy of physical object applies really well to modbus, which is basically just bunch of bits and registers – there is no concept of a sensor really.

As commented earlier here, it feels like other low level protocols have not yet received openhab2 translation (KNX, MQTT, HTTP) although some work is ongoing there (e.g. KNX seems to have similar “generic” channels for different item types). I think we could use these as inspiration.

Would love to hear your thoughts on alternative ways to structure the things.

Btw, can’t work on this for the next month due to travels but let me know if there’s something broken there.

Well there are two issues around the refresh parameter:

  • If the refresh parameter in the .things file is changed several times in a short time frame the polling stops / crashes
  • once openhab has been restarted, the default refresh rate (sth. linke 1.5 seconds) is used again and the refresh parameter in the .things file is ignored.
1 Like

Thanks @mbs38!

Can you please try with the latest, version, available here (there are some issues with build once again, and IOT market place is not updated). I think that some crashes might have fixed with the recent changes.

If you find any crashes or weird behaviour, can you please attach the verbose logs and I will have a look once I have the time, thanks!

Sure.

In Modbus we have a physical device (a PLC, IO-Module, sensor… you name it). Of course we do not know what the meaning of a certain coil or register is…
In my imagination openhab should work like this:
One should be able to define a new Modbus capable device (as a thing) with channels that point to certain registers/coils/… Sth like:
Thing mySensor {
connection=/dev/tty…
device address = 1
channel1:someInt [read: holding register 123 refresh = 5, write: holding register 456 refresh = 0]
channel1:someInt2 [read: holding register 124 refresh = 5, write: holding register 457 refresh = 0]
channel3:someBool [coil 5, refresh=10]
channel4:someOtherInt [read: holding register 4522 refresh = 0, write: holding register 6432]
}
In my opinion the binding should then be able to figure out how to poll the registers as efficiently as possible and also consider the limitations (it is not possible to poll holding registers 123 to 4522 in a singe request for example, neither is it efficient), meaning that register 123 and 124 should be polled within a single request and 4522 in a separate request. Of course all parameters, channels etc. should be editable within the Paper UI.
The user should then be able to bind items to the channels and use these items just like any other.

Best,
Max

It cannot do that, due to the vagaries of device implementations.
Some devices allow you read regs 1 to 10 when only regs 1,2,5,8,9 are defined. Some don’t.

There’s no right way to go about this, but the track Sami has taken is based on the experiences of real users trying to work with a range of quirky devices. The needed flexibility comes at the cost of complex manual configuring.