Modbus openHAB2 binding available for alpha testing

Dear Sami

Coming back to my post 8 days ago: Most of the things I could get running (was an issue on USR IOT side). I have only one problem left. Reading registers is not a problem, but when trying to write into a register, that does not work. E.g. When trying to do it via paper UI:
modbus

I type in a different value, e.g. 210 however number goes always back to 230 (even when typing (maybe it has something to do wish refreshing?)

the things file looks like that:

Bridge modbus:tcp:Pool [ host="192.168.178.30", port=502, id=1 ] {
     Bridge poller holding_high [ start=128, length=45, refresh=500, type="holding"]{
        Thing data holding134 [ readStart="134", readValueType="uint16", writeStart="134", writeValueType="uint16", writeType="holding" ]
     }
}

The item file like that:

Number Pumpenspannung "Sollspannung [%.0f V]" {channel="modbus:data:Pool:holding_high:holding134:number"}

When trying to adjust the number via sitemap also this does not work:

Setpoint	item=Sollspannung 			minValue=0 maxValue=230 step=10 icon=temperature

It would be great to get a hint on this issue

Thank you in advance and best regards
Rolf

Because Modbus is a polling protocol, I would not expect you to have any luck writing a register from PaperUI. By the time you have finished typing a new value, modbus will read the old value from your device and update your Item to overwrite what you typed.

You could make the Item write-only. But that often won’t be useful.

You can update the Item from a rule, where the value to be written is not affected by any read poll.
If you need to type something in for testing, use an intermediate Item that you can update from UI, and a rule that triggers on that Item being updated and writes that new value to the ‘real’ register Item.

1 Like

Dear rossko57

Thank you very much for the quick reply. I suspected that this is the problem. What about using e.g. setpoint in a sitemap? Do you expect the same problems? I already tried that but could not do anything meaningful with it.

Thank you very much in advance for a hint.

Best regards
Rolf

Dear roosko57

I understand better, why there seems to be an issue with setpoint: I’m using a Transformationservice for the data thing:

Thing data holding1 [ readStart="1", readValueType="int16" , readTransform="JS(divide10.js)",writeStart="1", writeValueType="int16", writeTransform="JS(multiply10.js)", writeType="holding" ]

with item

Number Pumpenfrequenz "Pumpenfrequenz" {channel="modbus:data:Pool:holding_low:holding1:number"}

and with setpoint

Setpoint	item=Pumpenfrequenz 		minValue=0 maxValue=50 step=5 icon=temperature

somehow the values are messed up by dividing too many times by 10, when trying to change the value. When I take out the scaling the setpoint is working perfectly.

Any ideas would be highly appreciated.

Best regards
Rolf

I’m not at all familiar with the interaction of transforms and setpoints, sorry.

Ok, found it by myself. I now use a different modbus lib on the arduino. It seems to work fine now

So long

Sven

1 Like

Dear Sami or anybody else

Somebody else an idea. For your information, When looking into the log file there is an error:

21:20:08.102 [ERROR] [inding.modbus.internal.Transformation] - transformation throws exception [transformation=JS(multiply10.js), response=3.6]
org.eclipse.smarthome.core.transform.TransformationException: An error occurred while executing script.
        at org.eclipse.smarthome.transform.javascript.internal.JavaScriptTransformationService.transform(JavaScriptTransformationService.java:84) [224:org.eclipse.smarthome.transform.javascript:0.10.0.b1]
        at org.openhab.binding.modbus.internal.Transformation.transform(Transformation.java:150) [222:org.openhab.binding.modbus:2.3.0.201804290926]
        at org.openhab.binding.modbus.handler.ModbusDataThingHandler.handleCommand(ModbusDataThingHandler.java:163) [222:org.openhab.binding.modbus:2.3.0.201804290926]
        at sun.reflect.GeneratedMethodAccessor142.invoke(Unknown Source) ~[?:?]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[?:?]
        at org.eclipse.smarthome.core.internal.common.AbstractInvocationHandler.invokeDirect(AbstractInvocationHandler.java:153) [111:org.eclipse.smarthome.core:0.10.0.b1]
        at org.eclipse.smarthome.core.internal.common.InvocationHandlerSync.invoke(InvocationHandlerSync.java:59) [111:org.eclipse.smarthome.core:0.10.0.b1]
        at com.sun.proxy.$Proxy136.handleCommand(Unknown Source) [222:org.openhab.binding.modbus:2.3.0.201804290926]
        at org.eclipse.smarthome.core.thing.internal.profiles.ProfileCallbackImpl.handleCommand(ProfileCallbackImpl.java:72) [118:org.eclipse.smarthome.core.thing:0.10.0.b1]
        at org.eclipse.smarthome.core.thing.internal.profiles.SystemDefaultProfile.onCommandFromItem(SystemDefaultProfile.java:49) [118:org.eclipse.smarthome.core.thing:0.10.0.b1]
        at sun.reflect.GeneratedMethodAccessor141.invoke(Unknown Source) ~[?:?]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[?:?]
        at org.eclipse.smarthome.core.internal.common.AbstractInvocationHandler.invokeDirect(AbstractInvocationHandler.java:153) [111:org.eclipse.smarthome.core:0.10.0.b1]
        at org.eclipse.smarthome.core.internal.common.Invocation.call(Invocation.java:53) [111:org.eclipse.smarthome.core:0.10.0.b1]
        at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:?]
        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: javax.script.ScriptException: <eval>:1:0 Expected an operand but found /
/ Wrap everything in a function (no global variable pollution)
^ in <eval> at line number 1 at column number 0
        at jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException(NashornScriptEngine.java:470) ~[?:?]
        at jdk.nashorn.api.scripting.NashornScriptEngine.compileImpl(NashornScriptEngine.java:537) ~[?:?]
        at jdk.nashorn.api.scripting.NashornScriptEngine.compileImpl(NashornScriptEngine.java:524) ~[?:?]
        at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:402) ~[?:?]
        at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:150) ~[?:?]
        at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:249) ~[?:?]
        at org.eclipse.smarthome.transform.javascript.internal.JavaScriptTransformationService.transform(JavaScriptTransformationService.java:82) ~[?:?]
        ... 19 more
Caused by: jdk.nashorn.internal.runtime.ParserException: <eval>:1:0 Expected an operand but found /
/ Wrap everything in a function (no global variable pollution)
^
        at jdk.nashorn.internal.parser.AbstractParser.error(AbstractParser.java:294) ~[?:?]
        at jdk.nashorn.internal.parser.AbstractParser.error(AbstractParser.java:279) ~[?:?]
        at jdk.nashorn.internal.parser.Parser.unaryExpression(Parser.java:3182) ~[?:?]
        at jdk.nashorn.internal.parser.Parser.expression(Parser.java:3282) ~[?:?]
        at jdk.nashorn.internal.parser.Parser.expressionStatement(Parser.java:1150) ~[?:?]
        at jdk.nashorn.internal.parser.Parser.statement(Parser.java:967) ~[?:?]
        at jdk.nashorn.internal.parser.Parser.sourceElements(Parser.java:773) ~[?:?]
        at jdk.nashorn.internal.parser.Parser.program(Parser.java:709) ~[?:?]
        at jdk.nashorn.internal.parser.Parser.parse(Parser.java:283) ~[?:?]
        at jdk.nashorn.internal.parser.Parser.parse(Parser.java:249) ~[?:?]
        at jdk.nashorn.internal.runtime.Context.compile(Context.java:1284) ~[?:?]
        at jdk.nashorn.internal.runtime.Context.compileScript(Context.java:1251) ~[?:?]
        at jdk.nashorn.internal.runtime.Context.compileScript(Context.java:627) ~[?:?]
        at jdk.nashorn.api.scripting.NashornScriptEngine.compileImpl(NashornScriptEngine.java:535) ~[?:?]
        at jdk.nashorn.api.scripting.NashornScriptEngine.compileImpl(NashornScriptEngine.java:524) ~[?:?]
        at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:402) ~[?:?]
        at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:150) ~[?:?]
        at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:249) ~[?:?]
        at org.eclipse.smarthome.transform.javascript.internal.JavaScriptTransformationService.transform(JavaScriptTransformationService.java:82) ~[?:?]
        ... 19 more

I used the code as proposed in the readme:

// Wrap everything in a function (no global variable pollution)
// variable "input" contains data passed by openhab
(function(inputData) {
    // on read: the polled number as string
    // on write: i openHAB command as string
    var MULTIPLY_BY = 10;
    return Math.round(parseFloat(inputData, 10) * MULTIPLY_BY);
})(input)

Any help would be highly appreciated.

Best regards
Rolf

I have found the mistake, very silly. was a copy-paste mistake. instead of // I lost the first / at the beginning of the function. Now it is working…

Thank all of you anyhow.

Best regards rolf

1 Like

Have not encountered this kind of behavior unfortunately. Could it be that your device is changing the coil state as well?

UPDATE now saw your reply, never mind

Best
Sami

Hi, my true config contains about 200 “markers” as I have this amount of coils in my system, I just cut it for this thread purposes as it was very long. Every single marker is configured the same way from 0 to 199. I will do more tests with verbose logging soon however I’m busy right now, sorry. I will back to the issue asap.

1 Like

Hi, I want to read data from 2 modbus RTU slaves. both are connected at MOXA nport230. It is working with one slave. For 2 slaves I modified modbus.things

/poller thing -lenght, type are required
Bridge modbus:serial:endpointMOXA [port="/dev/ttyr01",baud=9600,id=11,dataBits=8,parity=“none”,stopBits=“1”,encoding=“rtu”] {
Bridge poller holdingsREG1[ start=0, length=6, refresh=4000, type=“holding”] {
Thing data temp1 [ readStart=“0”, readValueType=“int16”, readTransform=“JS(divide10.js)” ]
Thing data temp2 [ readStart=“1”, readValueType=“int16”, readTransform=“JS(divide10.js)” ]
Thing data temp3 [ readStart=“2”, readValueType=“int16”, readTransform=“JS(divide10.js)” ]
Thing data temp4 [ readStart=“3”, readValueType=“int16”, readTransform=“JS(divide10.js)” ]
Thing data temp5 [ readStart=“4”, readValueType=“int16”, readTransform=“JS(divide10.js)” ]
Thing data temp6 [ readStart=“5”, readValueType=“int16”, readTransform=“JS(divide10.js)” ]
}

}
Bridge modbus:serial:endpointMOXA2 [port="/dev/ttyr01",baud=9600,id=10,dataBits=8,parity=“none”,stopBits=“1”,encoding=“rtu”] {
Bridge poller holdingsREG2[ start=0, length=8, refresh=4500, type=“holding”] {
Thing data teplota1 [ readStart=“0”, readValueType=“int16”, readTransform=“JS(divide10.js)” ]
Thing data teplota2 [ readStart=“1”, readValueType=“int16”, readTransform=“JS(divide10.js)” ]
Thing data teplota3 [ readStart=“2”, readValueType=“int16”, readTransform=“JS(divide10.js)” ]
Thing data teplota4 [ readStart=“3”, readValueType=“int16”, readTransform=“JS(divide10.js)” ]
Thing data teplota5 [ readStart=“4”, readValueType=“int16”, readTransform=“JS(divide10.js)” ]
Thing data teplota6 [ readStart=“5”, readValueType=“int16”, readTransform=“JS(divide10.js)” ]
}

poller2 is in error
Error with read: org.openhab.io.transport.modbus.internal.ModbusSlaveIOExceptionImpl:
null
Have you any idea? Thanx

I am trying to add new bridge - modbus serial - but with the same result. conflict with reading /dev/ttyr01 my virtual port from MOXA driver. Have you any example of reading from 2 or more slaves?
Thanx Martin

Hi

It’s suggested to check out logs for more information on the error.

It seems you have nonstandard serial port name. Check this section on docs for special steps to make it work https://github.com/ssalonen/openhab2-addons/blob/modbus-openhab2-native-binding/addons/binding/org.openhab.binding.modbus/README.md#serial-port-configuration

Multiple endpoints work without anything special. Just ensure you have unique names for each endpoint.

Is this binding still in alpha testing, or is it getting close to be released to Bindings in Paper UI for Openhab 2.3? Great work so far, I am using Modbus Tcp to communicate with PLC and distrebutet IO in my system, please let me know if you need me to test anything :slight_smile:

It’s getting there, you can follow the pull request for more information. The code is getting reviewed and pending some improvements from me.

It should be fairly stable. There is probably still something to do with the case of many items, see issue described by @zacofunny above.

openhab> bundle:start BUNDLENUMER
Error executing command: No matching bundles

what’s wrong?

Are you actually using a number or the text BUNDLENUMBER? It should be a number.

Can you please print out the list of bundles with :

bundle:list | grep -i modbus

There you can see whether the addon is running or not.

it works. Can I look at examples of use /dev/ttyAMA0??

The examples apply, just modify the port name acordingly.

Please note that /dev/ttyAMA0 is non-standard port name which means you have to do some additional configuration. See this section in docs for more information https://github.com/ssalonen/openhab2-addons/blob/modbus-openhab2-native-binding/addons/binding/org.openhab.binding.modbus/README.md#serial-port-configuration

Best
Sami

my port is working. I use UART - RS485. tell me where to put it “writeMultipleEvenWithSingleRegisterOrCoil” ?
I use devices with the function 06 of 16 in one network.