How to check items status before sending command

Hi everyone,

I use OH3.2 on Raspberry Pi which is connected to my PLC by modbus binding and everything works well, but… Recently I wanted to get rid of one problems I’ve had from the begining with Google Home.

The way that PLC works is that it changes state on rasing or falling a signal (when 0 is becoming 1, and 1 is becoming 0). To marriage my OH installation I used a very simple transformation file one.js

(function(inputData) {
    return "1" ;
})(input)

So when I send a command ON, transformation makes the job and sends 1 to PLC over modbus binding, a similary when commands is OFF it send also 1 to PLC.

All works but when I started playing with Google Home I noticed that when I ask Google Assistant to switch ON light which was previously turned on my transformation sends “1” to plc, reversing it states. Aparently Google always sends commands without checking for current state of the device.

So when I have light turned on and ask to turn it on, it will switch off. It’s not a huge problem until we have a few lights in one room, and they have different states. Asking Google to switch all lights will switch off turned on lights, but turned on the one that were off before.

I need to check state before sending command to PLC so when the item is on and gets ON command it should do nothing, and when is off and gets command OFF also do nothing. I thought I would do it via transformation, but it looks like it is not possible on that “level”. Can any one help me to figure out how to make this check with simple rule for all lights item in my system?

I guess, that this is slight off the way openHAB works. The items follow a model that hold a state. State changes are not an important part in this model. You change them by sending them commands and the state reflects the commands sent to them. Think of it like a wall switch. It is either on or off and will stay in this state until someone flips the switch. Once again not the change is important but the resulting state. So it might be best if you can adapt your PLC logic to show the same behavior.

You can use change event handlers though on items. So you will be noticed if the item state changes. Your handler will be called for every change and gives you the old and the new state of the item. If you want to stay with this approach, you can use that.

The problem will arise from the question, if you can get the current state from your PLC and act upon it. With current state I mean an api that can be called from the event handler. Please keep in mind, that openHAB works with an event bus. So command handling and state changes are asynchronous. That means you will have to think about eventual consistency.

I hope my two cents will get you a push into the right direction.

Hi,

Using modbus binding I send two coils registars one to detect switch (I think it is “write”) and one to detect state from PLC (which is “read” one). OH see the state of the device from PLC. Is there a way to solve this problem?

Can you explain the MODBUS side first, what do you mean by a rising and falling signal in this context? Rising/falling signals don’t really correspond to MODBUS function codes.

Are you not writing a value to a particular MODBUS coil or register?

I know, but the system works this way: when I want to trun on light I will send “1” to modbus coil and when PLC get this it is in the next step set to 0. Items know the state of the light from different coil. When I switched off the light modbus coil is again set to “1” and “zeroed” by PLC.

That makes more sense, 1 coil address is purely a trigger register, while another address is the actual light state.

Maybe a dumb question, but since coils are by MODBUS definition both read and write, does it not allow you to simply set the light to a defined state using that state coil address rather than toggling? I’m very surprised it wouldn’t implement a way of setting the light to a defined state.

If not, it should still be possible to implement in OH, thought it might be a bit clunky. I think I would use a secondary item (number) to temporarily hold the state coil value. You’d need to consider “threading” in OH, meaning any command to turn on a light would need to read the existing state first using a MODBUS transaction, then another trigger based off the response. You could compare your intended state with the actual state.

So off the top of my head as an idea, you may use a switch item and a number item.

  • When switch receives command, trigger a script which will initiate a MODBUS read, which then updates the state of the number item
  • When the number item receives an update, trigger a script which compares the state of the number to the switch, translating on > 1, off > 0, or vice versa.
  • If they differ then send a toggle bit

Although I run a pretty complicated MODBUS setup, I actually use an external Python script running as a systemd unit to handle my MODBUS communication and translate them to MQTT messages. Then it’s trivial to communicate with OH.

Another thought too: it sounds like you have more than 1 home automation system controlling the lights? Ie both OH and google home? If so I can imagine keeping both systems synced would pose some issues, which would be another benefit to running a python script to be the sole way of controlling the PLC, then any number of systems could interface via MQTT and remain in sync.

You can use MQTT as the center of your HA system then sync to that like you said.

As OH controls Modbus through an Item you can share that item with google and it will auto sync.

You should also be able to follow another item as a profile.

Hi. Thanks for your input. I’m not “fluent” in programming. I set it up few years ago. Using one coil is not possible cause PLC reads it all the time so if it is on, I would not be able to switch the light off for example from my wall switch.

 Thing data SwiatloGabinet [ readStart="1", readValueType="bit", writeStart="0", writeValueType="bit", writeType="coil", writeTransform="JS(one.js)" ]

Above I have modbus thing file code. As I remmeber read bit is state of the device and write is command to change state of the device.

And here is coresponding item file code:

Switch   FF_Office_Light        "Światło Gabinet"     <light>         (FF_Office, gLight)          ["Lighting", "Switchable"]   {channel="modbus:data:wagoMB:coils:SwiatloGabinet:switch", autoupdate="false", ga="Light"}

Maybe this will help a bit more to understand what I want to achive. OH correctly see state of the device. It is only a problem of Google Home integration.

I use mqtt to communicate my heater device. All works good, but I don’t want rewrite all the code I have already written :slight_smile:

It looks like the state bit is coil address 1, and the toggle bit is address 0, however you are trying to use a single data thing to handle both MODBUS transactions?

I would suggest making the data thing as read only for the state coil, by leaving writeStart and writeType as empty. Then create a second data thing as write only to send values to the toggle coil address.

In terms of linking the channels to items, I would probably have a switch that acts as the main user control item / GUI item, but I would have at least another number item to link to the state coil data. I would suggest becoming familiar with the Javascript addon for creating scripts, as that will probably be the easiest and most flexible way to handle the logic in line with my previous post.

So if you send a command to your GUI switch item:

  • Trigger a script, inline or separate, which then sends a command REFRESH to the linked data/state item. The thing might need to be a poller thing rather than data thing to accept a REFRESH command, I’m not sure.
  • Trigger another script based off the updated state item, then do the comparison between the state item and switch. You could then send a command to the write only item which sends the toggle bit. You may also be able to call a thing action directly from the script in order to trigger the coil write.

It also sounds like you have manual way of controlling the lights, which adds some complexity. So you may set the poller thing to periodically read the state, but then distinguishing when the switch was manually controlled from OH will take some more thought.

For example, if your switch is off in OH, manually controlling the light from somewhere else would probably result in OH checking the state coil against the switch, then turning the light off again.

In terms of Python scripting, all the heavy lifting is done by the paho mqtt and pymodbus library. From what you’re describing, I would think it’s the easiest way but I suppose that’s because I’ve already done it. Then OH can easily send mqtt command topics or receive state topic updates and your switch will be in sync regardless of whether you control the lights from OH or a manual switch.

Another thought on the external switch vs controlling via OH:

You could distinguish between the 2 by utilising the public cache in JS scripts. Essentially they are like global variables where any script can read/write the value based on the key (or “variable” name)

So when you send a command to the switch item (like a GUI interaction), in the triggered script, you could set a command flag by placing a key in the public cache, eg, "light1_command’ = 1

Then when the coil state item is updated and the second script is triggered, you could do a check on that public cache key. If the flag is 0, don’t send a toggle bit to MODBUS, instead just update the GUI item (not command). If the command flag is 1, then send a toggle bit via MODBUS, then also reset the command flag to 0.

About 6 months ago I did a complete re-write of my Python script, which amounted to a couple of thousand lines of code. Sometimes a completely new approach is the best thing, especially since you said you set up these lights years ago. Even if it’s completely within OH.

When I decided for home automation system I know that I want to do it around PLC. When I did it, my friend told me about OpenHab then in version 1.2. I decided that I would use it as an GUI for my system. Now it is a bit more then GUI, cause it is so simple to add another devices such as hvac, security, etc. OH still runs on Rasbbery PI, a little toy. I could install it on proper server, but it works. If I wanted to do PLC as a support to my OH and Raspbbery then I don’t know how I would be able to connect at least 300 cables to it :slight_smile: My whole system is not wireless, so I don’t have to bother myself to change baterries all the time. After more then five years of using it I am super happy. PLC worked even when my ethernet router broke down and I did not have access to OH for a while. Now I just want to check state of the device and take an action to swtich state or do nothing. I thinik one way as You metioned is to do another modus item as number, but I am not sure doubling items is a good idea.

Items aren’t duplicates in this case. Items are like objects, with properties and methods.

In this instance you have a desired light state, and an actual light state, and need to process different variables in a specific order. They also need to interact with bindings, and items are the way of doing that.

One item would be in the semantic model as a user interactive item, while the the other is a hidden back-end item. It also makes sense to keep them separate since they are acting on different MODBUS coil addresses.

What kind of solution were you hoping for…? Do you have a lot of codebase in OH3.2 that you don’t want to move to a more recent version?