Modbus Things

Hi,

I’m really new to OH after trying to setup Home Assistant but gave up mainly due to issues when trying to set up a Modbus TCP controller.

I have managed to add a programmable controller with Modbus TCP interface as a Thing. Basically I want to do 3 different things with this controller in OH:

  1. poll temperature from a single register (64, 1 bit)
  2. add a off/on switch by writing first 1 to register 130 and then after a short delay write 0 or 1 to register 132
  3. change setpoint by writing first 2 to register 130 and then after a short delay write new setpoint to register 132

I am right now struggling with the Things. I have added the controller as a Modbus slave and this is online. After this I added a 2nd Thing as a Regular poll. This is bridged to the first Thing. Finally, I have a 3rd Thing as a Modbus data and bridget with the Regular poll Thing.

I can see these three Things in the Things list. Now when I try to create a new Item and add this Modbus data Thing as a link I can’t see any temperature value in the Items list. This Regular poll Thing is online so I think it reads correctly the temperature data from register 64. All my other items (e.g. TP-Link KP115 smart plug) show their values.

So, what I’m missing?

Once I have managed to solve issue 1 I’ll continue with the other two issues. With these I struggled in HA and finally gave up.

EDIT: I realised one thing. Now when I have tcp Thing, poller Thing and data Thing for reading, do I need to add another data Thing for writing (e.g. to register 64 to poll temperature value). If this is needed how do I bridge it?

Remember, we cannot see anything that you have done. If you are using the GUI to configure things, you can use [code] tab and copy/paste results here to show accurately.

Let’s concentrate on that.
To configure this, you will need to know the Modbus register type.
(64, 1 bit) - Not sure what that means. Integer, float, signed, 64-bit, ordered?

That’s an awkward way to use Modbus, but if that’s what you are stuck with then we can work with it.
It’ll probably be easiest with some indirection, i.e. some Items linked to real Modbus channels activated by a rule that in turn is controlled by virtual Items.

Thanks for your reply. First comments on you questions. When polling MB register 64, the bit is an integer. Yes, I agree that this 2 step MB writing is very annoying but we have to live with it. I am still using Homeseer and in my VB scripts I can handle the situation quite well. I guess, I could do same thing in OH, i.e. make a script.

And now the codes. tcp Thing:

ID: modbus:tcp:292b702683
label: Ouman AT
thingTypeUID: modbus:tcp
configuration:
  rtuEncoded: false
  timeBetweenTransactionsMillis: 60
  connectMaxTries: 1
  reconnectAfterMillis: 0
  port: 502
  timeBetweenReconnectMillis: 0
  host: 192.168.1.60
  connectTimeoutMillis: 10000
  id: 1
  enableDiscovery: false
location: Autotalli

poller Thing:

UID: modbus:poller:292b702683:46c8583af6
label: Autotalli lämpötila
thingTypeUID: modbus:poller
configuration:
  start: 64
  length: 1
  refresh: 500
  maxTries: 3
  cacheMillis: 50
  type: holding
bridgeUID: modbus:tcp:292b702683
location: Autotalli

data Thing:

UID: modbus:data:46c8583af6:da0e27c28d
label: Autotalli T luku
thingTypeUID: modbus:data
configuration:
  readValueType: bit
  writeTransform: default
  writeMultipleEvenWithSingleRegisterOrCoil: false
  readStart: "64.1"
  writeMaxTries: 3
  updateUnchangedValuesEveryMillis: 1000
bridgeUID: modbus:poller:292b702683:46c8583af6
location: Autotalli

As I said all these Things are online but I can’t see the temp value so I’m missing something. Your help would be really appreciated because the Modbus TCP is main part of my home automation system. I tried with HA and I could create very easily the Dashboard. I could read the temp value but I couldn’t create the on/off button because I really don’t understand how to link configuration.yaml file with a scripts.yaml file. This business with configuration and scripts is really messy in HA. I think I’m not going to continue with HA.

And finally, I was going to run HA under Debian 11 on a NUC10i7 but I can’t install Debian. Tried with different USB sticks which were supposed to be bootable but no luck.

The only integers you can get out of 1 bit is 0 or 1, which wouldn’t be much use as a temperature reading.
I think you have misunderstood what your device offers.

Yes, you are quite right. I had a look at the MB manual for the controller and the it should be 32 bit.

I used Modbus Master program to read register 64. Write command is: 00 77 00 00 00 06 01 03 00 40 00 01 and reply is: 00 77 00 00 00 05 01 03 02 09 6e

The last two bytes give the temperature (9*256+110=2414, 6e=110). So, how do I need to setup the data Thing then? In HA conversion from the hex code to integer was more or less automatic (I had to use scale 0.01, though).

Okay, let’s guess at signed integer too.

But two bytes is not 32-bit, there is still confusion here.

Alright, read one holding register from ID 1, starting at address 64

Your TCP Thing has ID=1, tick.

Your poller Thing -

looks good.

Your data Thing -

is bad.
You’ve only read one register, so you only have 16 bits. Let’s guess its signed, for a temperature. Try

  readValueType: int16
  readStart: "64"

Link this to a Number type Item, use default profile.
Get that working and then we’ll worry about the scaling.

This will be useful

I changed the parameters as you suggested but the bridge to make link is not quite clear to me. One more thing, I have data Thing for reading register 64 but do I need to create a new data Thing to write register 64?

This is basic openHAB familiarisation, you might want toreview OH concepts.
Items are the key stuff internal to openHAB, that we interact with using the GUI and rules etc.
Items can be linked to the channels of Things, this is the device specific stuff.
So you need to create an Item, and can then link it to the channel of a Thing.

Modbus data Things offer many channels, each a different way to interpret associated Modbus data. Here you’ll be interested in the number channel.

Why do you want to write to a temperature sensor? Let’s make it read first.
To write to modbus, you can set up any arbitrary write register on any data Thing, then you must send a linked Item a command.

OK, I understand that I don’t want to write to reg 64. It was just somewhat unclear to me if I need to poll separately but it’s the poller Thing which takes care of this.

I have created an Item “Garage temperature” which has the data Thing (Value as Number) as a Channel link. This Item still shows NULL in the Items list so I’m still missing something.

It seems that my learning curve is rather steep and this Modbus thing is a key issue so I need to get it working.

Modbus is difficult, non-intuitive, and unforgiving if you do not know exactly what you want. That’s the nature of Modbus, as you’ve discovered it’s not going to help hopping around different automation systems to work with it.

If you have now got your heirarchy of Things and an Item as you think they should be, I would first reboot. In-flight editing of polled device parameters is not always reliable.
Then if it still does not work,look in your openhab.log for clues.

rossko57
Rebooting did the trick, now I can see the temp value. I applied gain 0.01 and now I have the actual temp. This is really a big step forward.

Next step is to create on/off button and input box/slider for the temp setpoint. In HA this turned out to be too difficult for me. I tried to create a script but I don’t understand how to pass a variable from configuration to script.yaml. Another thing is that I don’t understand the scripting in HA at all, i.e. where a script ends if you have several different sequences in it. I also tried splitting but didn’t succeed. Really messy. I was hoping that I could create a script in OH which would write 1 to register 130 and after that 0 or 1 to register 132. But let’s see how it goes. I need to look at the documentation in more detail. Thanks a lot for your help (most likely I’ll need your help again).

EDIT: I fully agree with you about the Modbus. I have spent countless hours in trying to understand the hex codes and I still struggle with some hex messages from one of my electricity meters (ABB).

Sure.
Suggestion -

I’m assuming you have no need to read these registers, whatever type they are. You do need to know precisely what they are though, your device will probably require you to write exactly 1 or 16 or 32 bit or whatever. You’ll have to find out if you are supposed to scale this as well, etc.

Make data Things with write parameters for reg 130 and reg 132. You can add these to your existing poller -it doesn’t have to include them in its read-poll, if they are write-only.

Link a Number Item to each of your regNN channels. These are for “internal use” by openHAB, not for use in GUI etc.

Now make an Item representing whatever-it-is - the setpoint? This doesn’t need linking to anything.
From the UI, you can command this “virtual” Item. Nothing much happens - yet.

Now make a rule that triggers from commands to your virtual Item. This rule can command the ‘real’ Item for reg 130 then set up a timer to command reg 132 a little later.

Great, thanks. I’ll continue tomorrow, it’s bed time now here.

One quick question. Do I need to create a page where I have e.g. the on/off button, because you discussed about UI? This is perhaps a dumb question because I’m not quite sure whether I fully understood your suggestion.

All Items have some kind of default presentation in MainUI.
For prettified user facing pages with selected Items, you would build pages yes.

@ rossko57

I’m assuming you have no need to read these registers,

Well, in principle I don’t need to read these registers as long as OH keeps track of the value written into these registers. Hopefully OH “remembers” the previous settings after reboot.

Make data Things with write parameters for reg 130 and reg 132.

I made these. I think I would need two data Things for reg 132 because I will write either 0 or 100 depending on whether I want to switch Off or On the heating.

Code for dataThing for reg 130:

UID: modbus:data:292b702683:e3d7fd4fc9
label: Autotalli OnOff 130
thingTypeUID: modbus:data
configuration:
  readTransform: default
  writeType: holding
  writeTransform: default
  updateUnchangedValuesEveryMillis: 1000
  writeValueType: int16
  writeMultipleEvenWithSingleRegisterOrCoil: false
  writeMaxTries: 3
  writeStart: "130"
bridgeUID: modbus:poller:292b702683:46c8583af6
location: Autotalli

Similarly two data Things for reg 132.

Link a Number Item to each of your regNN channels.

This is where my problems start from. I created three Items for values 1 (for reg 130), 0 and 100 (Off and On for reg 132). My problem is that I haven’t figured out how to assign these values to the Items. There is no code for these Items so I’ll attach a screen copy:

Now make an Item representing whatever-it-is - the setpoint?

I have created two new items, one for “Off” and one for “On”. Screen copy for “Off”:

Now make a rule that triggers from commands to your virtual Item. This rule can command the ‘real’ Item for reg 130 then set up a timer to command reg 132 a little later.

Here I’m again getting somewhat lost. I created two rules, one for “Off” and one for “on” because these are two states of my heating system so I think you need two rules because you can write only 0 or 100 to reg 132.

Here is the code for “Off” rule:

configuration: {}
triggers:
  - id: "1"
    configuration:
      itemName: Autotalli_Off
    type: core.ItemCommandTrigger
conditions: []
actions: []

I haven’t figured out how to add action. i.e. send write commands to regs 130 and 132.

??
You command the single linked Item with whatever value you want. You wouldn’t create 16,000 things and Items to represent different numerical values.

One data Thing “reg130”
One data Thing “reg132”
One Number Item “MB130”, linked to “reg130”
One Number Item “MB132”, linked to “reg132”
One Switch Item, “myswitch”, linked to nothing.

Your problem is lack of familiarity with openHAB and how it works. You’ve leapt in at the deep end with a technically demanding project, which has some tough wrinkles even if you already had basic OH skills. Happy to help with Modbus, not delivering openHAB basics.

Items are the central "model"of outside world in openHAB. In the normal course of events, their state values are derived from external devices via bindings and channels.
Clicking at the UI sends commands to Items, and in turn commands are passed through binding to real devices.
Rules can interfere in any part of these processes.

What I’m trying to nudge you towards is an indirect arrangement -
“myswitch” Item can be clicked ON/OFF in the GUI.
A rule listens for commands to “myswitch”, and when it sees one it commands “1” to item MB130, and also sets up a timed job to send either “0” or “100” to item MB132.

Note that you, the user, need never set any value to the MBxx items. They’re used behind the scenes.

1 Like

Thanks for clarifications. Of course I’m still very unexperienced with OH and it takes lot of time to learn different features but if I get this problem walked through I will learn how to multiply this procedure to my other controllers. I know this is rather difficult project which is just due to nature of the Modbus interface of my controllers. I have to say it’s not very elegant. I now understand that there is no point to create Things/Items for each numerical value.

I think I picked up now the idea but I still can’t figure out how to assign e.g. value 1 to Number Item “MB130”.

I have made some progress. My rule sends “1” to MB130 which I can see e.g. with Modbus Master when reading reg 130. I can then “manually” send either “0” or “100” to MB132 with my rule and I don’t actually need a timer in between MB130 and MB132. I can also see this with MB Master so reg 132 is either “0” or “100”.

Problem now is that when I toggle my switch it changes its state between ON and OFF but how to set up a command to MB132 then.

Well for the method outlined, we don’t need to do that.
What we want is a rule that includes a directive like
MB130.sendCommand(1)
and then a command is sent to the Item, and in turn passed on the Modbus data Thing, which writes to the bus according to the channel settings.

The state of MB130 does not come into play here, though as it happens openHABs autoupdate feature will probably respond to the command by ‘predicting’ a new state of 1.
It’s important to grasp that commands and states are two different things, “do something” as opposed to “its like this”. Bit more obvious with e.g. a Dimmer where you can command INCREASE but might see a state of 55% changing to 65%.

If you wish to test the process at a low level, the API Explorer tool allows you to send commands directly to Items without faff of UI formats and options etc.