[SOLVED] Many(+100) modbus pollers, is it slowing down the binding?

With the old binding i was polling at 1mS for 6 pollers because i could not disabel the 4 coil pollers and i had no increase of cpu use.

This is my old config.

poll=1

modbus:serial.slave1.connection=/dev/ttyUSB0:38400:8:none:1:rtu:1
modbus:serial.slave1.id=1
modbus:serial.slave1.type=coil
modbus:serial.slave1.start=0
modbus:serial.slave1.length=8

modbus:serial.slave2.connection=/dev/ttyUSB0:38400:8:none:1:rtu:1
modbus:serial.slave2.id=2
modbus:serial.slave2.type=coil
modbus:serial.slave2.start=0
modbus:serial.slave2.length=8

modbus:serial.slave3.connection=/dev/ttyUSB0:38400:8:none:1:rtu:1
modbus:serial.slave3.id=3
modbus:serial.slave3.type=coil
modbus:serial.slave3.start=0
modbus:serial.slave3.length=8

modbus:serial.slave4.connection=/dev/ttyUSB0:38400:8:none:1:rtu:1
modbus:serial.slave4.id=4
modbus:serial.slave4.type=coil
modbus:serial.slave4.start=0
modbus:serial.slave4.length=8


modbus:serial.slave10.connection=/dev/ttyUSB2:38400:8:none:1:rtu:1
modbus:serial.slave10.id=10
modbus:serial.slave10.type=discrete
modbus:serial.slave10.start=0
modbus:serial.slave10.length=16

modbus:serial.slave11.connection=/dev/ttyUSB2:38400:8:none:1:rtu:1
modbus:serial.slave11.id=11
modbus:serial.slave11.type=discrete
modbus:serial.slave11.start=0
modbus:serial.slave11.length=16

Here is my item’s config

Group Verlichting <verlichting>

 
Switch keuken1 "keuken1" ["Lighting"] {modbus="slave1:0"} 
Switch keuken2 "keuken2" ["Lighting"] {modbus="slave1:1"} 
Switch keuken3 "keuken3" ["Lighting"] {modbus="slave1:2"} 
Switch living1 "living1" ["Lighting"] {modbus="slave1:3"}
Switch living2 "living2" ["Lighting"] {modbus="slave1:4"}
Switch eetkamer1 "eetkamer1" ["Lighting"] {modbus="slave1:5"}
Switch eetkamer2 "eetkamer2" ["Lighting"] {modbus="slave1:6"}
Switch livingwand "livingwand" ["Lighting"] {modbus="slave1:7"}

Switch bureau "bureau" ["Lighting"] {modbus="slave2:0"}
Switch inkomhal "inkomhal" ["Lighting"] {modbus="slave3:6"}
Switch wasplaats "wasplaats" ["Lighting"] {modbus="slave2:2"}
Switch voordeur "voordeur" ["Lighting"] {modbus="slave2:3"}
Switch garage "garage" ["Lighting"] {modbus="slave2:4"}
Switch douche "douche" ["Lighting"] {modbus="slave2:5"}
Switch kelder "kelder" ["Lighting"] {modbus="slave2:6"}
Switch voor "voor" ["Lighting"] {modbus="slave2:7"}

Switch zijkant "zijkant" ["Lighting"] {modbus="slave3:0"}
Switch achter "achter" ["Lighting"] {modbus="slave3:1"}
Switch hal "hal"  ["Lighting"]{modbus="slave3:2"}
Switch orientatie "orientatie" ["Lighting"] {modbus="slave3:3"}
Switch masterbedroom "masterbedroom" ["Lighting"] {modbus="slave3:4"}
Switch badkamer "badkamer" ["Lighting"] {modbus="slave3:5"}
Switch open1 "open1" {modbus="slave3:6"}
Switch open2 "open2" {modbus="slave3:7"}

Switch open3 "open3" {modbus="slave4:0"}
Switch open4 "open4" {modbus="slave4:1"}
Switch open5 "open5" {modbus="slave4:2"}
Switch open6 "open6" {modbus="slave4:3"}
Switch open7 "open7" {modbus="slave4:4"}
Switch open8 "open8" {modbus="slave4:5"}
Switch open9 "open9" {modbus="slave4:6"}
Switch open10 "open10" {modbus="slave4:7"}

Group Verlichtinginputs <verlichting>


Contact verlichting1 "verlichting1[MAP(en.map):%s]"  {modbus="slave10:0"}
Contact verlichting2 "verlichting2[MAP(en.map):%s]"  {modbus="slave10:1"}
Contact verlichting3 "verlichting3[MAP(en.map):%s]"  {modbus="slave10:2"}
Contact verlichting4 "verlichting4[MAP(en.map):%s]"  {modbus="slave10:3"}
Contact verlichting5 "verlichting5[MAP(en.map):%s]"  {modbus="slave10:4"}
Contact verlichting6 "verlichting6[MAP(en.map):%s]"  {modbus="slave10:7"}
Contact verlichting7 "verlichting7[MAP(en.map):%s]"  {modbus="slave10:5"}
Contact verlichting8 "verlichting8[MAP(en.map):%s]"  {modbus="slave10:6"}
Contact verlichting9  "verlichting9[MAP(en.map):%s]"  {modbus="slave10:8"}
Contact verlichting10 "verlichting10[MAP(en.map):%s]"  {modbus="slave10:9"}
Contact verlichting11 "verlichting11[MAP(en.map):%s]"  {modbus="slave10:10"}
Contact verlichting12 "verlichting12[MAP(en.map):%s]"  {modbus="slave10:11"}
Contact verlichting13 "verlichting13[MAP(en.map):%s]"  {modbus="slave10:12"}
Contact verlichting14 "verlichting14[MAP(en.map):%s]"  {modbus="slave10:13"}
Contact verlichting15 "verlichting15[MAP(en.map):%s]"  {modbus="slave10:14"}
Contact verlichting16 "verlichting16[MAP(en.map):%s]"  {modbus="slave10:15"}

Contact verlichting17 "verlichting17[MAP(en.map):%s]"  {modbus="slave11:0"}
Contact verlichting18 "verlichting18[MAP(en.map):%s]"  {modbus="slave11:1"}
Contact verlichting19 "verlichting19[MAP(en.map):%s]"  {modbus="slave11:2"}
Contact verlichting20 "verlichting20[MAP(en.map):%s]"  {modbus="slave11:3"}
Contact verlichting21 "verlichting21[MAP(en.map):%s]"  {modbus="slave11:4"}
Contact verlichting22 "verlichting22[MAP(en.map):%s]"  {modbus="slave11:5"}
Contact verlichting23 "verlichting23[MAP(en.map):%s]"  {modbus="slave11:6"}
Contact verlichting24 "verlichting24[MAP(en.map):%s]"  {modbus="slave11:7"}
Contact verlichting25 "verlichting25[MAP(en.map):%s]"  {modbus="slave11:8"}
Contact verlichting26 "verlichting26[MAP(en.map):%s]"  {modbus="slave11:9"}
Contact verlichting27 "verlichting27[MAP(en.map):%s]"  {modbus="slave11:10"}
Contact verlichting28 "verlichting28[MAP(en.map):%s]"  {modbus="slave11:11"}
Contact verlichting29 "verlichting29[MAP(en.map):%s]"  {modbus="slave11:12"}
Contact verlichting30 "verlichting30[MAP(en.map):%s]"  {modbus="slave11:13"}
Contact verlichting31 "verlichting31[MAP(en.map):%s]"  {modbus="slave11:14"}
Contact verlichting32 "verlichting32[MAP(en.map):%s]"  {modbus="slave11:15"}


Switch verlichting1dummy "[%s]"
Switch verlichting2dummy "[%s]"
Switch verlichting3dummy "[%s]"
Switch verlichting4dummy "[%s]"
Switch verlichting5dummy "[%s]"
Switch verlichting6dummy "[%s]"
Switch verlichting7dummy "[%s]"
Switch verlichting8dummy "[%s]"
Switch verlichting9dummy "[%s]"
Switch verlichting10dummy "[%s]"
Switch verlichting11dummy "[%s]"
Switch verlichting12dummy "[%s]"
Switch verlichting13dummy "[%s]"
Switch verlichting14dummy "[%s]"
Switch verlichting15dummy "[%s]"
Switch verlichting16dummy "[%s]"

Switch verlichting17dummy "[%s]"
Switch verlichting18dummy "[%s]"
Switch verlichting19dummy "[%s]"
Switch verlichting20dummy "[%s]"
Switch verlichting21dummy "[%s]"
Switch verlichting22dummy "[%s]"
Switch verlichting23dummy "[%s]"
Switch verlichting24dummy "[%s]"
Switch verlichting25dummy "[%s]"
Switch verlichting26dummy "[%s]"
Switch verlichting27dummy "[%s]"
Switch verlichting28dummy "[%s]"
Switch verlichting29dummy "[%s]"
Switch verlichting30dummy "[%s]"
Switch verlichting31dummy "[%s]"
Switch verlichting32dummy "[%s]"

I created a dropbox acount here is the link https://www.dropbox.com/s/cur1xfblf8wqm0q/Modbus%20logs.txt?dl=0

Do you have some other file sharing service?

Btw, having poll=1 with the old binding does not mean it is polling with that high frequency. In practice it is polling as fast as possible. Not saying that there isn’t room to improve in the new binding

@Pe_Man, the logs say that reconnectAfterMillis is 10000 not 60000? I guess that works too… Are you sure you changed the config and recorded correct logs?

After thinking this for a while, I think the “scheduling logic” of the polling needs improvement… Writing down my notes here.

Currently, a fixed size thread pool (5 threads) is used for all polling. However, all but one of this threads are waiting since in your configuration everything polls the same slave. We have limited to have at most one connection to the slave at a time.

This means that processing of commands gets delayed. Furthermore, poll tasks with high poll frequency do not get fair share of time.

I will try to replicate this with my own setup and see if there’s a quick workaround for you.

That’s not unreasonable, given the Modbus underlying philosophy or model of everything queuing for one serial bus.

I think you have already implemented the queue shortening idea of discarding new polls where already one in the queue? i.e. only one request per poller thing. Wouldn’t make anything work faster, just reduce queue length.

Looking at your earlier time analysis, I note that post-comms callback processing is not insignificant. What we can’t see is what workload we are throwing on to the rest of the system e.g. putting updates on the OH event bus.
I wonder if we may yet revisit the OH1 option of not updating if no change. I know this is not general policy, but fast polling is not something OH will ever handle well.

@Pe_Man, reanalyzing your logs, (see this post)

You can see that modbus transactions are completed every 100 ms. Note that by default the binding waits timeBetweenTransactionsMillis, 60 ms for tcp things. Since actual modbus I/O takes ~20 ms, and callback handling takes ~15 ms, it’s basically working all the time!

Please also note that the poll period of 1 second is infeasible considering the default timeBetweenTransactionsMillis – 100 pollers would take at least 6 seconds to complete just due to wait time between transactions.

As adviced in tcp thing configuration docs, you do have option to reduce timeBetweenReconnectMillis to lower value. For example, with your config and timeBetweenTransactionsMillis=0 reconnectAfterMillis=60000 I can reach ~92 transactions/second against a local modbus slave (diagslave).

I advice to lower timeBetweenTransactionsMillis as low as possible (provided you are not getting any errors), and report back.

@Rado1 I’m not sure I have solid advice regarding CPU usage. It might be because of the new binding doing more work (updating at every poll). Alternatively the new binding has to go through longer code path with channels and things etc. that were not present with old binding.

To work on this hypothesis: If you have the energy, would appreciate if you can compare CPU load with these two setups

  1. openHAB 2.4.0 release with modbus1 binding. Use your old configuration but set updateunchangeditems to true for all “slaves”. Old docs: https://github.com/openhab/openhab1-addons/wiki/Modbus-Binding
  2. openHAB 2.4.0 release with modbus2 binding. Configure interTransactionDelayMillis=1 to all tcp things to match the old configuration better.

Provide verbose logs from each setup.

You can record CPU usage of openHAB with this one-liner in bash (I am assuming you are on linux):

FILENAME=ps.log ;        echo > $FILENAME; while true; do (echo "%CPU %MEM ARGS $(date)" && ps -o pcpu,pmem,args -p `pgrep -f openhab` | cut -d" " -f1- ) | tee -a $FILENAME; sleep 0.5; done

@rossko57

I think you have already implemented the queue shortening idea of discarding new polls where already one in the queue? i.e. only one request per poller thing. Wouldn’t make anything work faster, just reduce queue length.

Yeah queue is not accumulating anymore and there is at most one item in the queue per poller. Actually previously there were two queue and if the polling was fast (faster than updating channels), the other one would grow without limit…

Looking at your earlier time analysis, I note that post-comms callback processing is not insignificant. What we can’t see is what workload we are throwing on to the rest of the system e.g. putting updates on the OH event bus.

I wonder if we may yet revisit the OH1 option of not updating if no change. I know this is not general policy, but fast polling is not something OH will ever handle well.

This is certainly true. I am seeing a lot more time spent with low-end PCs such as Raspberry Pi 3 B (400 ms!). Tried to profile where the time goes but it really looks like it just does so much work serializing/deserializing the updates to internal event bus openHAB uses.

There might be a point what you are saying. In case we would introduce “update-channels-only-on-value-change” I would like to tune it such that it would be “update-channels-only-on-value-change-or-every-X-ms” to support cases where you would like to have “heartbeat” updates (e.g. with expire binding).

Need to try this out when I have the time.

UPDATE: @Rado1 Try with this version. It updates channels “lazily” (every x seconds) unless the value changes. org.openhab.binding.modbus-2.5.0-lazy-updates-SNAPSHOT.jar.pdf (61.9 KB) . Rename the pdf as jar.

Best,
Sami

1 Like

Yes, i changed to 10000 afterwards to see if there was a difference(but it was not).

I probably captured the logs with the latter settings.

Med vänlig hälsning,
Per

I will try this when I’m back home in a couple of days.

Meanwhile, just throwing an idea out here while I’m thinking about it.

Is it possible to prioritise the polls depending on usage, like things used in rules or items on a current homepage etc need faster response time. While things not used by any process could wait?

I don’t know if it is possible , but I think an HMI driver works like this, just poll the items on the current page making modbus requests quite fast.

Med vänlig hälsning,
Per

Is it possible to prioritise the polls depending on usage, like things used in rules or items on a current homepage etc need faster response time. While things not used by any process could wait?

No I don’t think that is possible.

The SNAPSHOT binding does not show up in the binding inbox?I named it like this “org.openhab.binding.modbus-2.5.0-lazy-updates-SNAPSHOT.jar” and put it in the openhab2-addons file.And i uninstalled the 2.4 modbus binding restart openhab and nothing show’s up?Am i doing something wrong?I am using the jablotron SNAPSHOT binding the same way and that one is showing up in the binding inbox?

Hmm, I haven’t used PaperUI for this so I’m not sure how it works out
bundle:list|grep -i modbus list all modbus bundles.
bundle:update XX where XX is the ID of the modbus binding as listed by bundle:list. Updates the binding from addons folder.

What do you mean by openhab2-addons file?

The file smb://openhabian-server.local/openhab2-share/openhab2-addons
When i drop the jar file there i should install te binding.
And it did

openhab> bundle:list|grep -i modbus
289 │ Installed │  80 │ 2.5.0.201812281754     │ Modbus Binding

But i have this warning

2018-12-28 20:37:07.859 [WARN ] [org.apache.felix.fileinstall        ] - Error while starting bundle: file:/usr/share/openhab2/addons/org.openhab.binding.modbus-2.5.0-lazy-updates-SNAPSHOT.jar

org.osgi.framework.BundleException: Could not resolve module: org.openhab.binding.modbus [289]

  Unresolved requirement: Import-Package: org.eclipse.jdt.annotation; resolution:="optional"

  Unresolved requirement: Import-Package: org.openhab.io.transport.modbus

	at org.eclipse.osgi.container.Module.start(Module.java:444) ~[?:?]

	at org.eclipse.osgi.internal.framework.EquinoxBundle.start(EquinoxBundle.java:383) ~[?:?]

	at org.apache.felix.fileinstall.internal.DirectoryWatcher.startBundle(DirectoryWatcher.java:1260) [10:org.apache.felix.fileinstall:3.6.4]

	at org.apache.felix.fileinstall.internal.DirectoryWatcher.startBundles(DirectoryWatcher.java:1233) [10:org.apache.felix.fileinstall:3.6.4]

	at org.apache.felix.fileinstall.internal.DirectoryWatcher.startAllBundles(DirectoryWatcher.java:1221) [10:org.apache.felix.fileinstall:3.6.4]

	at org.apache.felix.fileinstall.internal.DirectoryWatcher.doProcess(DirectoryWatcher.java:515) [10:org.apache.felix.fileinstall:3.6.4]

	at org.apache.felix.fileinstall.internal.DirectoryWatcher.process(DirectoryWatcher.java:365) [10:org.apache.felix.fileinstall:3.6.4]

	at org.apache.felix.fileinstall.internal.DirectoryWatcher.run(DirectoryWatcher.java:316) [10:org.apache.felix.fileinstall:3.6.4]
openhab> bundle:list|grep -i modbus
289 │ Installed │  80 │ 2.5.0.201812281754     │ Modbus Binding
openhab> bundle:update 289
openhab>                                                                      

You are missing the modbus transport (org.openhab.io.transport.modbus). You can install it with feature:install openhab-transport-modbus or something similar (see all available features with feature:list).

It is working cpu level is less but very unstable between 10% and 35% with an average of 13%.
Before without de modbus binding cpu level was around 4%.Your on the right track.I keep testing and report back to you.

1 Like

You can also try adjusting the rate which data things are updated (in case the value is not changing), see the parameter documentation here

Default of 1000 ms that channels are updated every second even though value would be the same.

I would be curious to know how it compares to the old binding.

That sounds like an attractive compromise.

I must get my own ‘live’ system set up so that I can swap test “openhabs” in easily. Happy to trial things, but I have to leave it functional at the end of each day :crazy_face:

1 Like

I have tested some different configurations the updateUnchangedValuesEveryMillis does influence the cpu load.This config is giving me best performance and lowest cpu load.The cpu load is still higher then the modbus1 binding.But it is acceptable.I also set timeBetweenTransactionsMillis=1.and refresh=1.Very fast polling

Bridge modbus:serial:slave1 [ port="/dev/ttyUSB0" ,id=1 , baud=38400, stopBits="1", parity="none",timeBetweenTransactionsMillis=1,dataBits=8, encoding="rtu" ]{

Bridge poller slave1coils [ start=0, length=8, refresh=0, type="coil" ]{
    
        Thing data do00 [ readStart="0", readValueType="bit", writeStart="0", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]
        Thing data do01 [ readStart="1", readValueType="bit", writeStart="1", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]
        Thing data do02 [ readStart="2", readValueType="bit", writeStart="2", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]
        Thing data do03 [ readStart="3", readValueType="bit", writeStart="3", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]
        Thing data do04 [ readStart="4", readValueType="bit", writeStart="4", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]
        Thing data do05 [ readStart="5", readValueType="bit", writeStart="5", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]
        Thing data do06 [ readStart="6", readValueType="bit", writeStart="6", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]
        Thing data do07 [ readStart="7", readValueType="bit", writeStart="7", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]

    } 
}     
Bridge modbus:serial:slave2 [ port="/dev/ttyUSB0" ,id=2 , baud=38400, stopBits="1", parity="none",timeBetweenTransactionsMillis=1,dataBits=8, encoding="rtu" ]{

Bridge poller slave2coils [ start=0, length=8, refresh=0, type="coil" ]{
    
        Thing data do08 [ readStart="0", readValueType="bit", writeStart="0", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]
        Thing data do09 [ readStart="1", readValueType="bit", writeStart="1", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]
        Thing data do10 [ readStart="2", readValueType="bit", writeStart="2", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]
        Thing data do11 [ readStart="3", readValueType="bit", writeStart="3", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]
        Thing data do12 [ readStart="4", readValueType="bit", writeStart="4", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]
        Thing data do13 [ readStart="5", readValueType="bit", writeStart="5", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]
        Thing data do14 [ readStart="6", readValueType="bit", writeStart="6", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]
        Thing data do15 [ readStart="7", readValueType="bit", writeStart="7", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]

    } 
} 
Bridge modbus:serial:slave3 [ port="/dev/ttyUSB0" ,id=3 , baud=38400, stopBits="1", parity="none",timeBetweenTransactionsMillis=1,dataBits=8, encoding="rtu" ]{

Bridge poller slave3coils [ start=0, length=8, refresh=0, type="coil" ]{
    
        Thing data do16 [ readStart="0", readValueType="bit", writeStart="0", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]
        Thing data do17 [ readStart="1", readValueType="bit", writeStart="1", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]
        Thing data do18 [ readStart="2", readValueType="bit", writeStart="2", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]
        Thing data do19 [ readStart="3", readValueType="bit", writeStart="3", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]
        Thing data do20 [ readStart="4", readValueType="bit", writeStart="4", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]
        Thing data do21 [ readStart="5", readValueType="bit", writeStart="5", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]
        Thing data do22 [ readStart="6", readValueType="bit", writeStart="6", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]
        Thing data do23 [ readStart="7", readValueType="bit", writeStart="7", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]

    } 
}
Bridge modbus:serial:slave4 [ port="/dev/ttyUSB0" ,id=4 , baud=38400, stopBits="1", parity="none",timeBetweenTransactionsMillis=1,dataBits=8, encoding="rtu" ]{

Bridge poller slave4coils [ start=0, length=8, refresh=0, type="coil" ]{
    
        Thing data do24 [ readStart="0", readValueType="bit", writeStart="0", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]
        Thing data do25 [ readStart="1", readValueType="bit", writeStart="1", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]
        Thing data do26 [ readStart="2", readValueType="bit", writeStart="2", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]
        Thing data do27 [ readStart="3", readValueType="bit", writeStart="3", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]
        Thing data do28 [ readStart="4", readValueType="bit", writeStart="4", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]
        Thing data do29 [ readStart="5", readValueType="bit", writeStart="5", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]
        Thing data do30 [ readStart="6", readValueType="bit", writeStart="6", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]
        Thing data do31 [ readStart="7", readValueType="bit", writeStart="7", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]

    } 
}          
Bridge modbus:serial:slave10 [ port="/dev/ttyUSB0" ,id=10 , baud=38400, stopBits="1", parity="none",timeBetweenTransactionsMillis=1,dataBits=8, encoding="rtu" ]{ 
   
Bridge poller slave10Inputs [ start=0, length=16, refresh=1, type="discrete" ]{ 
    
       Thing data di00 [ readStart="0", readValueType="bit",updateUnchangedValuesEveryMillis="500000" ]
       Thing data di01 [ readStart="1", readValueType="bit",updateUnchangedValuesEveryMillis="500000" ]
       Thing data di02 [ readStart="2", readValueType="bit",updateUnchangedValuesEveryMillis="500000" ]
       Thing data di03 [ readStart="3", readValueType="bit",updateUnchangedValuesEveryMillis="500000" ]
       Thing data di04 [ readStart="4", readValueType="bit",updateUnchangedValuesEveryMillis="500000" ]
       Thing data di05 [ readStart="5", readValueType="bit",updateUnchangedValuesEveryMillis="500000" ]
       Thing data di06 [ readStart="6", readValueType="bit",updateUnchangedValuesEveryMillis="500000" ]
       Thing data di07 [ readStart="7", readValueType="bit",updateUnchangedValuesEveryMillis="500000" ]
       Thing data di08 [ readStart="8", readValueType="bit",updateUnchangedValuesEveryMillis="500000" ]
       Thing data di09 [ readStart="9", readValueType="bit",updateUnchangedValuesEveryMillis="500000" ]
       Thing data di10 [ readStart="10", readValueType="bit",updateUnchangedValuesEveryMillis="500000" ]
       Thing data di11 [ readStart="11", readValueType="bit",updateUnchangedValuesEveryMillis="500000" ]
       Thing data di12 [ readStart="12", readValueType="bit",updateUnchangedValuesEveryMillis="500000" ]
       Thing data di13 [ readStart="13", readValueType="bit",updateUnchangedValuesEveryMillis="500000" ]
       Thing data di14 [ readStart="14", readValueType="bit",updateUnchangedValuesEveryMillis="500000" ]
       Thing data di15 [ readStart="15", readValueType="bit",updateUnchangedValuesEveryMillis="500000" ]
          
    }
}   
Bridge modbus:serial:slave11 [ port="/dev/ttyUSB0" ,id=11 , baud=38400, stopBits="1", parity="none",timeBetweenTransactionsMillis=1,dataBits=8, encoding="rtu" ]{ 
   
Bridge poller slave11Inputs [ start=0, length=16, refresh=1,type="discrete" ]{ 
    
       Thing data di16 [ readStart="0", readValueType="bit",updateUnchangedValuesEveryMillis="500000" ]
       Thing data di17 [ readStart="1", readValueType="bit",updateUnchangedValuesEveryMillis="500000" ]
       Thing data di18 [ readStart="2", readValueType="bit",updateUnchangedValuesEveryMillis="500000" ]
       Thing data di19 [ readStart="3", readValueType="bit",updateUnchangedValuesEveryMillis="500000" ]
       Thing data di20 [ readStart="4", readValueType="bit",updateUnchangedValuesEveryMillis="500000" ]
       Thing data di21 [ readStart="5", readValueType="bit",updateUnchangedValuesEveryMillis="500000" ]
       Thing data di22 [ readStart="6", readValueType="bit",updateUnchangedValuesEveryMillis="500000" ]
       Thing data di23 [ readStart="7", readValueType="bit",updateUnchangedValuesEveryMillis="500000" ]
       Thing data di24 [ readStart="8", readValueType="bit",updateUnchangedValuesEveryMillis="500000" ]
       Thing data di25 [ readStart="9", readValueType="bit",updateUnchangedValuesEveryMillis="500000" ]
       Thing data di26 [ readStart="10", readValueType="bit",updateUnchangedValuesEveryMillis="500000" ]
       Thing data di27 [ readStart="11", readValueType="bit",updateUnchangedValuesEveryMillis="500000" ]
       Thing data di28 [ readStart="12", readValueType="bit",updateUnchangedValuesEveryMillis="500000" ]
       Thing data di29 [ readStart="13", readValueType="bit",updateUnchangedValuesEveryMillis="500000" ]
       Thing data di30 [ readStart="14", readValueType="bit",updateUnchangedValuesEveryMillis="500000" ]
       Thing data di31 [ readStart="15", readValueType="bit",updateUnchangedValuesEveryMillis="500000" ]
          
    }
}    



This is with de SNAPSHOT binding.

@Rado1 do you have any figures how much higher cpu usage you are seeing?

I made a few loggings with various config’s
First old modbus1 binding with my old config

Second old modbus1 binding with updateunchangeditems =true

And last modbus2 SNAPSHOT with config from previous post

1 Like

Dear @ssalonen, dear @Rado1

I updated to OH 2.4 and modbus binding V2 today. With Modbus Binding V1 I used

updateunchangeitems=false

for all my modbus slaves, as I have 235 modbus items in my setup (smart home :slight_smile: ). CPU load on my odroid XU4 was between 20% and 30% usually.

After updating the modbus binding CPU load increased to 200% + (2 CPU cores constantly occupied). By changing the poll cycles from 500ms to 2000ms I was able to reduce the CPU load to about 80%. Now with the 2.5.0 snapshot version I was able to configure 500ms again with a cpu load of 30% in average. For all data points I use

updateUnchangedValuesEveryMillis="1000000"

now.

Thanks, @ssalonen for all the work you put into the modbus binding for the last years!

Yours

Wolfgang

2 Likes