Setup an item linked to modbus

Hello all,

I have been an long time OH user starting a new house and moving from OH1 to OH3… quite a big step :slight_smile:

I am stuck setting up my config. I have a PLC (Phoenix Contact) controlling my lights, in order to connect to OH I am using Modbus. Every light has 1 bit to control (ON/OFF) and 1 bit for the status (ON/OFF). The PLC takes the control request and reports the light status.

In OH1 this was connected via
Switch GF_BTN1 “Light1” {modbus=">[slave2:1],<[slave1:1]", autoupdate=false""}

In OH3 I am not succeeding in getting this done. I have tried a lot of different items, the closest I got is via the following options

  1. Define an equipment group with 2 points (status and control) linked to the corresponding modus data item. As in MB lamp 1 in the image below. This gives me a switch which sends the modbus command and controls the light and gives me a status update “open or closed” via the modbus. But it doesn’t combine the items together.

  2. Define and equipment as lamp and add the two channels. This looks like it should, controls the PLC successfully but doesn’t update its status with the PLC status update channel.

image

image

It seems I am missing some basic understanding of the new way of working with OH3 :frowning: . I look forward of getting through this learning curve, I am very impressed with the new changes and want to be as close as possible to the new intended use (stay away from sitemaps and coding)

Thank you for taking the time to respond! I apologize already if I could have figured this out myself and am wasting your time.
-Daan

runtimeInfo:
version: 3.2.0
buildString: Release Build
locale: en-US
systemInfo:
configFolder: /etc/openhab
userdataFolder: /var/lib/openhab
logFolder: /var/log/openhab
javaVersion: 11.0.13
javaVendor: Azul Systems, Inc.
javaVendorVersion: Zulu11.52+13-CA
osName: Linux
osVersion: 5.10.63-v7l+
osArchitecture: arm
availableProcessors: 4
freeMemory: 81326440
totalMemory: 194772992
bindings:

  • chromecast
  • dsmr
  • modbus
  • mqtt
  • tplinksmarthome

Hello Daan,

I have a similar setup, controlling my light by plc and connecting openhab to plc over modbus. I have one switch item that both reflects the status AND controls the light.

Most of them are either automatically controlled with an override in Openhab or with a dimmer setting. I’ll take an easy example. This is in my plc:

The %MX2.10 is the set bit that comes from Openhab. For this light I have 3 physical buttons that control the light (SB_2_21L etc). R_M20 is the PLC output line and that one is read by Openhab.

There are two modbus things in openhab, one that reads the R_M20 address and one that writes to the %MX2.10 address to toggle the light (note: the %MX2.10 only controls the light status by toggling it).

There is only one item in my UI/sitemap that both serves to display the status and controls the light. The item is directedly linked to the modbus thing that reads the status. And then there is a rule that catches commands send to the item and forwards the event to the proper (item linked to the) modbus thing that is able to write to %MX2.10. That rule looks like this:

configuration: {}
triggers:
  - id: "0"
    configuration:
      itemName: Light_L2_Attic
    type: core.ItemCommandTrigger
conditions: []
actions:
  - inputs: {}
    id: script
    configuration:
      type: application/vnd.openhab.dsl.rule
      script: >
        if(Light_L2_Attic.state != receivedCommand)
        Toggle_Light_L2_Attic.sendCommand(ON)
    type: script.ScriptAction

Here Toggle_Light_L2_Attic is linked to %MX2.10 and Light_L2_Attic is the actual item that I put in my UI.

Now if you don’t have a toggle box in the plc program that sets the status of the light, like this:
image
then things get easier. You can then just have one thing that both reads from R_M20 and writes to %MX2.10. That’s supported by the modbus binding.

I hope this explanation helps?

1 Like

It would be really helpful to show us your Modbus Thing/channels as well.

As @MathiasVDA suggests, you also need to identify if your PLC is emulating a simple on/off function, or a pulsed toggle type.

1 Like

I was trying to avoid writing a rule for this, but I might have to give it a try
My PLC is emulating a pulsed toggle switch. I have push buttons in the walls and relais (or dimmers (next task to program :slight_smile: )) to control the lights. I use a phoenix contact PLC (ILC131ETH) and the modbus implementation of the PLC doesn’t give updates on an input. For this reason I have to go the separated bit route, on for input and one for out. I have created a functional block in the PLC which contains the impuls relais and controls the relais. Additionally it transfers the relais status to OpenHAB via Modbus (MBout) and gets a input from Modbus (MBin) with the request from OpenHAB to 1) switch on the light or 0) turn of the light.

image

In OH I have configures the Modbus PLC and 2 pollers since my PLC gives an error when the wrong MODBUS FC is used on the wrong register. Hence one poller for the read registers and one poller for the write registers. After that I have created 2 things per light using modbusdata, 1 for status and 1 for control.

All independent channels update as they should and the PLC is reacting how I intended it to react… The remaining problem I still have is combining this in one item… our start over and try another strategy :wink:

Thanks you for your input already
-Daan

Don’t. You’ve got two functions - send a pulse to do something, and report a steady state.
openHAB doesn’t natively support pulsey toggle stuff, so we have to simulate the action. To get the pulse out on Modbus, we have to command an Item on and off. Meantime, we want to command an Item ON to turn stuff on, and expect to stay on.
So two Items.
One Item represents the light state, we use that on the UI (or rule) to send ON and OFF commands. Link that to the Modbus state reporting register.
The other Item represents the pulse. Not interested in this for the UI at all. We set up a rule that listens for commands to the steady-state Item, and - only if required - sends a ‘go’ pulse to the pulsey Item and so onwards to the Modbus action register. Followed shortly by a ‘stop’ pulse.

Examples

It’s file based but easily amended for GUI use.

1 Like

@rossko57 sorry for not being clear. I do not use the pulse, I translate that in the PLC. I write a 1 to turn the light on and 0 to turn it off. The PLC report a 1 when the light is on and 0 when the light is off. My issue is that the switch doesn’t update when the contact state changes and that one items used 2 entries in the UI.

I will go through the examples you shared and see if I can implement them.

@rossko57 and @MathiasVDA thank you for the support both examples, links and some more digging gave me a solution to what I wanted.

  • Decoupled the 2 items advised, linked the “control item” to the light (still have to investigate if I have to disable autoupdate)
  • Created a new Item from the “status channel” and made this part of group together will all other status channels
  • Made sure both corresponding Items have the same number at the end
  • Created a rule to trigger on a change in the status group and write an update to the correct control item!

and it worked! The item now updates according the PLC status and can be controlled via PLC and OH… and my PLC is happy

Thank you for the input, hope my example might help others in the future!

configuration: {}
triggers:
  - id: "1"
    configuration:
      groupName: MB_status_lamp
    type: core.GroupStateChangeTrigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    configuration:
      type: application/vnd.openhab.dsl.rule
      script: >-
        var String filename = "modbus.rules" 

        //logInfo (filename,triggeringItem.name)

        var Light_Num = triggeringItem.name.split("_").get(3) // get the 01 part from the triggering item

        var Item = "MBlamp" + Light_Num // build the name of the item to update

        //logInfo (filename,"received command: "+ triggeringItem.state) // find the state of item that triggered

          if (triggeringItem.state == OPEN) {
            sendCommand (Item, "ON")
           //logInfo (filename, "Update to ON")
           } else if (triggeringItem.state == CLOSED) { // by testing both, we will ignore REFRESH commands etc.
               sendCommand (Item, "OFF")
               //logInfo (filename, "Update to OFF")
            }
    type: script.ScriptAction
1 Like

Then one Item with no rules will do.
Again, please show us your Modbus Things and channels.

I also agree with this. I am pretty sure it should work without an additional rule.

As far as I understood you only need a modbus thing with write type coil to write your control bit to the plc.
Then next you need a modbus thing with read type bit to read your status bit in the plc.
Both things are linked to one switch item, with parameter autoupdate=false.

So please show us how you configured your modbus things.

@rossko57 and @Tuny I was under the impression I had already posted exactly that in a previous post. What is missing?

this part

This is exactly what I started with (or at least tried), but when I link the 2 modbus things as a channel to that singe switch item the switch doesnt follow the status posted by the contact channel…
I was trying to implement this as shown in the posts above and the repeating the specific screenshot again below. I might be making a mistake using the new UI.

image

Summarizing the setup that I think is meant the work with a single item without rules. I have also created it again to ensure I wasn’t making a mistake setting it up and have encountered some behavior I didn’t expect (aka learning :slight_smile: )

Things involved:

  • one modbus TCP thing (didn’t make a screenshot since this seems to be working correctly)
  • two modbus pollers (one to read the bits and one to write the bits) → screenshots below
  • two modbus data items (one to read a bit and one to write a bit) → screenshots below

Items involved and how I created it: (screenshot below)

  • one switch item with 2 channels
    • Add equipment to my test location (type: switch, meta data to AutoUpdate=false)
    • Add channel links → the corresponding modbus data read (as Contact) and write bit (as Switch)

The expected behavior: the OH item doesn’t follow the Modbus stat when it is updated/changed by the PLC. I checked via a seperate tool that the modbus is actually updated when I switch the PLC.
The unexpected behavior I see, the Item now only reports the ON state in the logging (screenshot below), not the OFF state and doesn’t update the actual modbus. When I turn on the autoupdate it does update the modbus. This clearly is a lack in my understanding of how OH process this.

Then when I update to the solution written above with the rule all starts to work. I do this without changing any of the Modbus Things, which tells me they are “working”

Sorry if I am repeating myself or am giving to much screenshots… trying to make it clear what I am doing/ trying to achieve and what I am seeing…


image

Please, look at your Modbus data Thngs, use the [code] tab, and copy-paste to the forum, thanks.

So switching from OH to PLC works… So Thing configuration for poller and modbus data for writing should be ok…

For reading I would switch to poller type “holing”. Then when using the Read Value Type “bit” you need to Adress your status bit like “2000.0” I think.
Then for reading you might want to link the modbus data to a different item… to get out some complexity. For your Channel link I would use also “switch” for the status bit and not contact.

Maybe it is better to switch to a textual thing configuration. It makes it easier four you (and maybe for us) to see what your configuration looks like.

Sorry I didn’t share that earlier.
This is the control bit I write:

UID: modbus:data:e265faf031
label: MB control light 1
thingTypeUID: modbus:data
configuration:
  readTransform: default
  writeTransform: default
  writeType: coil
  updateUnchangedValuesEveryMillis: 1000
  writeValueType: bit
  writeMultipleEvenWithSingleRegisterOrCoil: true
  writeMaxTries: 3
  writeStart: "1000"
bridgeUID: modbus:poller:41de4e2124:0a69490ed0

This is the status bit I read:

UID: modbus:data:428a658773:dd4ed84b71
label: MB stat light 1
thingTypeUID: modbus:data
configuration:
  readValueType: bit
  readTransform: default
  writeTransform: default
  readStart: "2000"
  updateUnchangedValuesEveryMillis: 1000
  writeMultipleEvenWithSingleRegisterOrCoil: false
  writeMaxTries: 3
bridgeUID: modbus:poller:41de4e2124:428a658773

@Tuny I will try your suggestions. About the textual thing config, your are correct. I wasn’t aware this was possible…

Okay.
It is non-obvious, but a data Thing may read and write to completely different places.

So,blending your write target with your read status

UID: modbus:data:428a658773:dd4ed84b71
label: MB stat light 1
thingTypeUID: modbus:data
configuration:
  readStart: "2000"
  readValueType: bit
  readTransform: default

  writeStart: "1000"
  writeType: coil
  writeValueType: bit
  writeTransform: default
  writeMultipleEvenWithSingleRegisterOrCoil: true
  writeMaxTries: 3
bridgeUID: modbus:poller:41de4e2124:428a658773

One data Thing, to link to one Item.

1 Like

This works! 1 Thing, 1 Item and no rules needed!

Its indeed counter intuitive because you start the thing creation with selecting the poller you want to refer to. Since I have to use separate ones for the read and write operation, it only works when I link it to the poller with the highest address range.

After that the setup intuitive again and everything works accordingly. The AutoUpdate option of must be left default, when switched of it doesn’t update anymore.

@rossko57 @MathiasVDA @Tuny thank you for your support!

1 Like

There is no poller involved in Modbus write operations at all. That’s why we can tag completely arbitrary write setups onto any data Thing.

To read however, we must set up a poller to read a block of registers. Then we can select registers from that block in associated data Things.

Then you’re not getting updates correctly from your PLC.

I’d suggest sharing your data Thing, channel, and Item as they are now.