Modbus openHAB2 binding available for alpha testing

Yes… At first I was reading holding registers, as I was experienced this issue.
Then I tested it with the status register that was a input.

I have now gone back to what I used to do with this device:

			    
Bridge poller Smartlight [ start=4738, length=2, refresh=1000, type="holding" ] {
	    
	         Thing data Smartlight [ readStart="4738", readValueType="uint32_swap", writeStart="4738", writeValueType="uint32_swap", writeType="holding" ]

}

When I read it with my modbus tool, I read it as a holding register and there I can see the value changes between 0-100

Ok Thanks

It’s quite weird indeed.

From verbose logs we should be able to see what data the binding is polling exactly.

Would be interesting to see verbose logs for this sequence of events…

One thing to check out is any warnings regarding queue size in the log. With verbose logs you can find out the binding queue size, it should stay small.

Ill turn on verbose logging and grab some data

Here is a sequence with Debug turned on

13:55:09.014 [DEBUG] [.handler.ModbusPollerThingHandlerImpl] - Thing modbus:poller:endpointSmarthouse:Smartlight received registers RegisterArrayWrappingInputRegister(00 45 00 00) for request ModbusPollerThingHandlerImpl.ModbusPollerReadRequest@47eb7870[slaveId=1,functionCode=READ_MULTIPLE_REGISTERS,start=4738,length=2,maxTries=3]
13:55:09.015 [DEBUG] [modbus.handler.ModbusDataThingHandler] - Thing modbus:data:endpointSmarthouse:Smartlight:Smartlight channels updated: {modbus:data:endpointSmarthouse:Smartlight:Smartlight:dimmer=ON, modbus:data:endpointSmarthouse:Smartlight:Smartlight:lastReadSuccess=2018-09-09T13:55:09.015+0200}. readValueType=uint32_swap, readIndex=Optional[4738], readSubIndex(or 0)=0, extractIndex=0 -> numeric value 69 and boolValue=true. Registers RegisterArrayWrappingInputRegister(00 45 00 00) for request ModbusPollerThingHandlerImpl.ModbusPollerReadRequest@47eb7870[slaveId=1,functionCode=READ_MULTIPLE_REGISTERS,start=4738,length=2,maxTries=3]
13:55:09.029 [DEBUG] [modbus.handler.ModbusDataThingHandler] - Successful write, matching request ModbusWriteRegisterRequestBlueprintImpl@71075449[slaveId=20,reference=0,functionCode=WRITE_SINGLE_REGISTER,registers=ModbusRegisterArrayImpl(38 10),maxTries=3]

It’s not clear what you mean here. The value reverts to 100 after 20 seconds?

As your OH config is for a uint32 type, you should read two holding registers with modbus tool, just in case there is something going on in the “other half”.

What i’m trying to explain :slight_smile:

If I set the Holding register to eg. 60, the light changes to 60 and stays on that level.

However OH revert the reading that should have been 60 to 100. This is delayed between 5-20 sec.

If I read the holding register (two words) with my modbus tool I see the value 60 and nothing in the other half

Have a look in events log for the “mystery” Item value change, then you’ll know where to look in the debug log. There should be many successful read polls before that?

1 Like

I think I made a working solution, but it really gives no sense ?

I’m reading values between 0-100, i’m also seeing that value in my modbus tool.

If I use readtransform and divide the result by 1 it works :roll_eyes:

// Wrap everything in a function
(function(i) {
    return parseFloat(i) / 1;
})(input)
// input variable contains data passed by openhab
1 Like

Brilliant fix! So, you’ve now got a working Dimmer Item with two different Modbus channels? Ah no, wait, this is just one holding register pair now isn’t it?

The transform may be circumventing some issue with number/string formatting or parsing into percentage. Might tie in with reported different Number/Dimmer behaviour?

Yes it is working 100% :slight_smile:

// #Smartlight Function
			    
Bridge poller Smartlight [ start=4700, length=42, refresh=1000, type="input" ] {
	    
	         Thing data Smartlight [ readStart="4702", readValueType="uint16", readTransform="JS(divide1.js)", writeStart="4738", writeValueType="uint32_swap", writeType="holding" ]

}

Combined Input and Holding register

Would you mind sharing the item definition still? Is it DimmerItem bound to channel named dimmer?

Do you mind sharing the logs without the transformation in place? I am curious to find out if there is a bug that would need fixing…

Hi (@ssalonen)

Thanks a lot for the Modbus binding.

I was able to connect our Ökofen heater to OH with the binding.

Best regards

Raphael

1 Like

Hi… I shared the log approx 1-2 days ago, it the log sufficient ?

My Item definition is:

Dimmer Light_GF_Sove_Seng	 	"LED Seng [%d %%]"	 	                 (GF_Sove, Lights)                 { channel="modbus:data:endpointSmarthouse:Smartlight:Smartlight:dimmer" }
1 Like

The two lines of log? No… I would need more to really dig into this. Ideally would be the whole sequence of events, starting from command from openHAB, value changing, and then value reverting back start (e.g. your case mentioned here).

Really would appreciate all the help!

Best,
Sami

EDIT:

I think I know what might be the reason, with a similar setup (reading & writing to holding register, using dimmer, no transformation), I have the following in the verbose logs

xxxx will be updated to 'ON' (type OnOffType). Input data: number value 60 (value type 'uint16' taken into account) and bool value t

So numeric value of 60 is converted to ON. Logic is explained more thoroughly here: Modbus - Bindings | openHAB (Transform On Read section)

The default is to convert non-zero numbers to ON / OPEN , and zero numbers to OFF / CLOSED , respectively. If the item linked to the data channel does not accept these states, the number is converted to best-effort-basis to the states accepted by the item. For example, the extracted number is passed as-is for Number items, while ON / OFF would be used with DimmerItem.

The behaviour is meant to be smart with Switch etc items (converting numeric values to “boolean” values) but obviously a bit unexpected with DimmerItem. Since Dimmer items accept ON/OFF, the same piece of logic applies to it as well (a bit unexpectedly, I admit).

Best,
Sami

1 Like

Humm, bit debatable whether automatically converting a number read from a Modbus register to a Dimmer Item would be a good idea.
Given the variety of manufacturers devices (although dimmers are rare!) I would not think that numeric100 representing 100% is guaranteed. 255 seems just as likely.
Not to consider we’re (usually) dealing with 16-bit values … or as in this case, 32-bit.
We’ve already had this conversation, I bet?

Requiring a transform to scale a register to a Dimmer Item doesn’t seem unreasonable. Even for the odd time it is effectively a no-op transform.

It would be a good idea to make this clear in the docs, an example would be helpful.

Out of interest, is it just chance that the write side works here? I imagine that would often need scaling/transform as well.

1 Like

Heh, indeed it is a bit deja vu. I think we have had this discussion before.

Good question regarding write… On write, the binding accepts DecimalType, OPEN/CLOSED and ON/OFF.

Since PercentType used by dimmer items is inherited from DecimalType, it should work with writes when the command is a number.

But, when command is ON/OFF, it would be converted to 1 and 0 when writing, probably not something you would want… Cc @Nanna_Agesen

Definitely needs a proper example in docs.

We try to convert transformation output to number ( DecimalType ), OPEN / CLOSED ( OpenClosedType ), and ON / OFF ( OnOffType ); in this order.

Draft example (fictional simple device) - please review @ssalonen @Nanna_Agesen
Completely untested !

OpenHAB Dimmer type Items are not a straightforward match to Modbus registers, as they feature a numeric value which is limited to 0-100 Percent, as well as handling ON/OFF commands.
Transforms can be used to match and scale both reading and writing.

Example for a dimmer device where 255 register value = 100% for fully ON :
Thing definition

Bridge modbus:tcp:remoteTCP [ host="192.168.0.10", port=502 ]  {
   Bridge poller MBDimmer [ start=4700, length=2, refresh=1000, type="holding" ]  {
	         Thing data DimmerReg [ readStart="4700", readValueType="uint16", readTransform="JS(dimread255.js)", writeStart="4700", writeValueType="uint16", writeType="holding", writeTransform="JS(dimwrite255.js)" ]

Dimmer transforms
dimread255.js

// Wrap everything in a function (no global variable pollution)
// variable "input" contains data string passed by binding
(function(inputData) {
    // here set the 100% equivalent register value
    var MAX_SCALE = 255;
    // convert to percent
    return Math.round( parseFloat(inputData) * 100 / MAX_SCALE );
})(input)

dimwrite255.js

// variable "input" contains command string passed by openhab
(function(inputData) {
    // here set the 100% equivalent register value
    var MAX_SCALE = 255;
    var out = 0
    if (inputData == 'ON') {
          // set max
         out = MAX_SCALE
    } else if (inputData == 'OFF') {
         out = 0
    } else {
         // scale from percent
         out = Math.round( parseFloat(inputData) * MAX_SCALE / 100 )
    }
    return out
})(input)

Item

Dimmer myLight "My Dimmer"   { channel="modbus:data:remoteTCP:MBDimmer:DimmerReg:dimmer" }

This is excellent!

The example looks good! I just noticed one small thing, the writeValueType should be int16, there’s no such thing as uint16 when writing. Second thing was missing braces (}) in the things snippet.

Would @Nanna_Agesen like to try this out?

Woah, is that so? Seems a little asymmetric. I haven’t tried it, does it fail ? Or are we just talking about the logic - because an OH Number covers the range of both uint16 and int16 without worry.

Is there an implication that to write hex FFEE to a register, you’d need an OH Number of -18 for int16, rather than 65518 for uint16? Or do both varieties just give the same result automagically? (65518 technically “won’t fit” into int16 but I’m sure the binding can just do it anyway on a write) Just a bit worried about truncation of numbers over 32767, the theoretical max for int16.

I take it for granted int32 works similar !

@ssalonen @rossko57

Interesting example, Ill give it a test this weekend :slight_smile: