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

@ssalonen, I have added the parameter timeBetweenTransactionsMillis=0 and the reponsetime for writing a change from the sitemap is now as low as I was used to with V1, more or less immediate.

My bridge now looks like this:
Bridge modbus:tcp:SH2WEB [ host=“192.168.1.198”, port=502, id=1, timeBetweenTransactionsMillis=0, reconnectAfterMillis=60000]

I have 133 things using this bridge.

CPU-info as follows (in “idle”-mode). I don’t know if it is good or bad?
top - 15:51:28 up 73 days, 20:45, 1 user, load average: 1.40, 1.43, 1.45

2 Likes

Good that the original issue in this thread was solved. Consider marking your own reply as the answer.

Cpu load will be pretty high when each poll of data updates the channels of 100+ things . For this reason, there is the experimental version above, updating the channels less regularly.

I will do this, if it is solved…today no rules are executing and I see this as the last loginfo:

2019-01-06 14:31:03.198 [WARN ] [mmon.WrappedScheduledExecutorService] - Scheduled runnable ended with an exception: 

java.lang.InternalError: BMH.reinvoke=Lambda(a0:L/SpeciesData<LLLI>,a1:L)=>{

t2:L=MethodHandleImpl.array(a1:L);

t3:I=BoundMethodHandle$Species_L3I.argI3(a0:L);

t4:L=BoundMethodHandle$Species_L3I.argL2(a0:L);

t5:L=BoundMethodHandle$Species_L3I.argL1(a0:L);

t6:L=BoundMethodHandle$Species_L3I.argL0(a0:L);

t7:L=MethodHandle.invokeBasic(t6:L,t5:L,t4:L,t3:I,t2:L);t7:L}

at java.lang.invoke.MethodHandleStatics.newInternalError(MethodHandleStatics.java:127) ~[?:?]

at java.lang.invoke.LambdaForm.compileToBytecode(LambdaForm.java:660) ~[?:?]

at java.lang.invoke.LambdaForm.prepare(LambdaForm.java:635) ~[?:?]

at java.lang.invoke.MethodHandle.<init>(MethodHandle.java:461) ~[?:?]

at java.lang.invoke.BoundMethodHandle.<init>(BoundMethodHandle.java:58) ~[?:?]

at java.lang.invoke.BoundMethodHandle$Species_L3I.<init>(Species_L3I) ~[?:?]

at java.lang.invoke.BoundMethodHandle$Species_L3I.copyWith(Species_L3I) ~[?:?]

at java.lang.invoke.MethodHandle.asCollector(MethodHandle.java:1002) ~[?:?]

at jdk.internal.dynalink.DynamicLinker.createRelinkAndInvokeMethod(DynamicLinker.java:228) ~[?:?]

at jdk.internal.dynalink.DynamicLinker.link(DynamicLinker.java:201) ~[?:?]

at jdk.nashorn.internal.runtime.linker.Bootstrap.bootstrap(Bootstrap.java:208) ~[?:?]

at jdk.nashorn.internal.runtime.linker.Bootstrap.createDynamicInvoker(Bootstrap.java:371) ~[?:?]

at jdk.nashorn.internal.runtime.linker.Bootstrap.createDynamicInvoker(Bootstrap.java:345) ~[?:?]

at jdk.nashorn.internal.runtime.linker.InvokeByName.<init>(InvokeByName.java:86) ~[?:?]

at jdk.nashorn.internal.runtime.linker.InvokeByName.<init>(InvokeByName.java:73) ~[?:?]

at jdk.nashorn.internal.objects.Global.<init>(Global.java:96) ~[?:?]

at jdk.nashorn.internal.runtime.Context.newGlobal(Context.java:1111) ~[?:?]

at jdk.nashorn.api.scripting.NashornScriptEngine$2.run(NashornScriptEngine.java:350) ~[?:?]

at jdk.nashorn.api.scripting.NashornScriptEngine$2.run(NashornScriptEngine.java:346) ~[?:?]

at java.security.AccessController.doPrivileged(Native Method) ~[?:?]

at jdk.nashorn.api.scripting.NashornScriptEngine.createNashornGlobal(NashornScriptEngine.java:346) ~[?:?]

at jdk.nashorn.api.scripting.NashornScriptEngine.<init>(NashornScriptEngine.java:143) ~[?:?]

at jdk.nashorn.api.scripting.NashornScriptEngineFactory.getScriptEngine(NashornScriptEngineFactory.java:148) ~[?:?]

at javax.script.ScriptEngineManager.getEngineByName(ScriptEngineManager.java:238) ~[?:?]

at org.eclipse.smarthome.transform.javascript.internal.JavaScriptTransformationService.transform(JavaScriptTransformationService.java:77) ~[?:?]

at org.openhab.binding.modbus.internal.Transformation.transform(Transformation.java:140) ~[?:?]

at org.openhab.binding.modbus.internal.Transformation.transformState(Transformation.java:186) ~[?:?]

at org.openhab.binding.modbus.internal.handler.ModbusDataThingHandler.lambda$9(ModbusDataThingHandler.java:819) ~[?:?]

at java.util.HashMap$KeySpliterator.forEachRemaining(HashMap.java:1553) ~[?:?]

at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580) ~[?:?]

at org.openhab.binding.modbus.internal.handler.ModbusDataThingHandler.processUpdatedValue(ModbusDataThingHandler.java:787) ~[?:?]

at org.openhab.binding.modbus.internal.handler.ModbusDataThingHandler.onRegisters(ModbusDataThingHandler.java:667) ~[?:?]

at org.openhab.binding.modbus.internal.handler.ModbusPollerThingHandlerImpl$ReadCallbackDelegator.lambda$0(ModbusPollerThingHandlerImpl.java:91) ~[?:?]

at java.util.concurrent.CopyOnWriteArrayList.forEach(CopyOnWriteArrayList.java:891) ~[?:?]

at org.openhab.binding.modbus.internal.handler.ModbusPollerThingHandlerImpl$ReadCallbackDelegator.onRegisters(ModbusPollerThingHandlerImpl.java:91) ~[?:?]

at org.openhab.io.transport.modbus.internal.ModbusLibraryWrapper.invokeCallbackWithResponse(ModbusLibraryWrapper.java:279) ~[?:?]

at org.openhab.io.transport.modbus.internal.ModbusManagerImpl$PollOperation.lambda$1(ModbusManagerImpl.java:163) ~[?:?]

at org.openhab.io.transport.modbus.internal.SimpleStopWatch.timeRunnable(SimpleStopWatch.java:148) ~[?:?]

at org.openhab.io.transport.modbus.internal.ModbusManagerImpl$PollOperation.accept(ModbusManagerImpl.java:162) ~[?:?]

at org.openhab.io.transport.modbus.internal.ModbusManagerImpl$PollOperation.accept(ModbusManagerImpl.java:1) ~[?:?]

at org.openhab.io.transport.modbus.internal.ModbusManagerImpl.executeOperation(ModbusManagerImpl.java:571) ~[?:?]

at org.openhab.io.transport.modbus.internal.ModbusManagerImpl.lambda$15(ModbusManagerImpl.java:719) ~[?:?]

at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[?:?]

at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) ~[?:?]

at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) ~[?:?]

at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) ~[?:?]

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:?]

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:?]

at java.lang.Thread.run(Thread.java:748) [?:?]

 Caused by: java.lang.OutOfMemoryError: Java heap space

I don’t understand what this means or the cause. Is it because the modbus-binding or something else?

No idea, looks like very low level java issue when it is doing the transformation… this is outside the scope of the binding.

Perhaps open new thread regarding this? Can you get the issue all the time?

I believe (could be very wrong) that Modbus binding being the one to discover there is no memory does not make it the guilty party - could be anyone.

If you’ve still got all the tracing turned on that be making some extra load on loggers etc.

ok. I restarted openhab service and it runs as usual now.
If/when it happen again I posta a new thread about it.

Thanks again @ssalonen for your wokr!

Best,
Per

1 Like

As I understood, this parameter configures if and if yes how ofter MODBUS Thing will get an update if the status is not changed?

Thing data do08 [ readStart="0", readValueType="bit", writeStart="0", writeValueType="bit", writeType="coil",updateUnchangedValuesEveryMillis="500000" ]

This parameter is not in the documentation. Is it only available on 2.5 snapshot or in 2.4 stable binding too?

And can I set it to false, which means I get only changed Things trigger and no update trigger?
Which means my item only get changed events? This will reduce the load on OH? Because MODBUS will update my items every sec. and I have 100 of them.

Check out above posts for all the answers, linked here for your convenience.

experimental version (not just a typical snapshot, you have to download it here)

Please read the following messages for the installation instructions and issues you might encounter

Docs which explains the behavior as well Many(+100) modbus pollers, is it slowing down the binding?

Note that “false” is not valid configuration value, it is not a number.

Thanks for the hint, I missed this. Can I ask one more question about this parameter

updateUnchangedValuesEveryMillis=
Normally values are not updated unless their value change. In milliseconds.

Does this mean, if I do not configure the parameter the binding only acts on thing change and will update the item?
In an earlier version of the binding I run into a problem with my persistance. I had a config to persist on every update. This slows down OH a lot. I changed persist on every change and it works again. This is why I thought that the modbus-binding sends an update to the thing/item at every poll interval. But this seams not the case. I will try it.

As you found, this can be a problem for any polling binding. It’s frequent polling that is the issue, not modbus as such.

It did. The 2.5 version now gives you an option not to do that for Items. (I believe the data thing is still updated e.g. with lastReadSuccess and so on)

1 Like

Correct Rossko57

With the expiremental version, the channel is updated when

  • new state (so the value after read transformation etc) is different from last poll, OR
  • more than X milliseconds have passed since the last update with this channel where X is the new configuration parameter, default for X is 1000 ms

All channels are treated the same way, e.g. since lastReadSuccess channel value changes on every poll (at least with the default transformation), it would be updated on every poll.

I tried this version, works perfect, great work.

1 Like

@HomeAutomation @pe_man @wolfgan1966 could you please try with this version:

org.openhab.binding.modbus-2.5.0-pr4655-SNAPSHOT.jar.pdf (61.6 KB) (this was broken version)

Should be the same as before, this time matching upcoming PR https://github.com/openhab/openhab2-addons/pull/4655

One question. Is this feature included in the new snapshot pr4655? I use this feature and see no cpu high consumption any more. very stable.

Yes, the PR 4655 is about introducing the feature to main development branch / upcoming release.

Would like you test it out one final time and confirm that it is still working as expected before pushing it forward.

Best
Sami

I updated to the pr4655 version.

This parameter is not working:
updateUnchangedValuesEveryMillis=“1000000”

It updates every poll interval. Went back to lazy version which is working perfect. Is the syntax/spelling of the parameter changed?

Thanks for testing.

Not intentionally, so something wrong. Will look into it

UPDATE: I’m not sure what I did – it was completely wrong piece of code. Now the fix is available here: https://github.com/openhab/openhab2-addons/pull/4701

No code changes to test this time, but here’s the latest version in any case:

org.openhab.binding.modbus-2.5.0-pr-4701-lazy-updates-SNAPSHOT.jar.pdf (61.7 KB)

@HomeAutomation, would appreciate if you test it one more time please.

I want to request a little change.

If “updateUnchangedValuesEveryMillis” is set to 0 updateUnchangedValues is disabled, Should I open a PR?

In my use cases I need updates only if something is changed. See no need of getting the same value every time. Does this make sense? Or should I set updateUnchangedValuesEveryMillis to one week?

1 Like

I have been running this version without any problems

openhab> bundle:list -s | grep modbus
214 x Active   x  80 x 2.5.0.201901041623     x org.openhab.binding.modbus

Just for test, I replaced the binding to the latest snapshot:

openhab> bundle:list -s | grep modbus
230 x Active   x  80 x 2.5.0.201901250552     x org.openhab.binding.modbus

Immediatly I do not notice any difference in performance (reactiontimes for rules)

/per

1 Like

If “updateUnchangedValuesEveryMillis” is set to 0 updateUnchangedValues is disabled, Should I open a PR?
In my use cases I need updates only if something is changed. See no need of getting the same value every time. Does this make sense? Or should I set updateUnchangedValuesEveryMillis to one week?

You can get what you want by using arbitrarily big number. However, please note that with autoupdate=true, the item state might not anymore reflect the true status in case there is e.g. modbus errors happening.

To me at least it makes sense that updateUnchangedValuesEveryMillis=0 updates on every poll takes more than zero millis.

Best,
Sami