Modbus openHAB2 binding available for alpha testing

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.

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