This rule will always say the rear door is Closed, even if its OPEN

Hi All,

This rule will always say its closed, even if its open, despite the state of the contact being correct.

I’ve traced it to this piece, which when if changed to state == “OPEN” , as opposed to without “”, it works just fine.

Some doors in the home, will show OPEN, some will show ON, so I convert them with transform maps.

Here is the rule

import org.openhab.core.types.State

rule "Keep track of the last time a door was opened or closed"
when
  Member of gDoorSensors changed
then
  if(previousState == NULL) return;

  val name = triggeringItem.name
  val state = triggeringItem.state
  // Update the time stamp
  postUpdate(name+"_LastUpdate", now.toString)

  // Set the timer if the door is open, cancel if it is closed
  if(state == OPEN || state == ON) sendCommand(name+"_Timer", "ON")
  else postUpdate(name+"_Timer", "OFF")

  // Set the message
  val msg = new StringBuilder
  msg.append(transform("MAP", "en.map", name) + " was ")
  msg.append(if(state == OPEN) "opened" else "closed")    <----- THIS IS THE PROBLEM AREA!

So basically, if I change OPEN to “OPEN” the front door will message alert correctly, but the rear door says its closed when its open. If I change it to OPEN, without “”, the rear gate works fine, but the front door wont work!

How bizzare. Can anyone see what I’m doing wrong?

Cheers

Don’t do that, that’s probably copied from OH1 rules.

You’ll already know Items can have states like OPEN or ON which are dedicated Item type states, and are very much not the same as string types like “OPEN” or “banana”. They’re not even the same type, so they can’t be the same.

In a rule, OPEN does not equal “OPEN”. Type mismatch, before we even get to contents. So types are important.

We’d like to know the types of the Items here; from this description could be Switch, Contact, or String, or any mix of those.

We don’t know the states of any of those Items.

For
if(state == OPEN) "opened" else "closed"
A Contact with state OPEN will return “opened”
A Contact with state CLOSED will return “closed”
A Switch with state ON will return “closed”
A Switch with state OFF will return “closed”
A String with any state will return “closed”
Any type Item with state NULL will return “closed”

Thanks for the reply rossko

The Sonoff relay gets an ON/OFF from a magnetic read sensor.

The item definition is for the rear gate is:

String  Gate_status    "Sliding Gate"         (Group_HabPanel_Dashboard,gDoorSensors)  [ "Switchable" ] { mqtt="<[broker:cmnd/SENSOR/POWER8:state:MAP(gate.map)]", autoupdate="false" }

and the Front door is a Contact

Contact FrontDoor_status              "Front Door [MAP(door.map)]"      (Group_HabPanel_Dashboard,gDoorSensors,gLock)           { mqtt="<[broker:/house/out/FrontDoor_status/state:state:default], >[broker:/house/in/FrontDoor_status/command:command:*:default]", alexa="ContactSensor.detectionState" }

the map

ON=CLOSED
OFF=OPEN

I thought with a transform map, it didnt matter the item type - it would translate the ON/OFF to OPEN/CLOSED. I tried using a Switch item and still had issues - maybe I was doing something wrong (likely)

This Item is a String type. It can never have state CLOSED, but can have “CLOSED”.

This Item is a Contact type. It can never have state “CLOSED” but can have state CLOSED.

So, back to the rule …
For
if(state == OPEN) "opened" else "closed"
A Contact with state OPEN will return “opened”
A Contact with state CLOSED will return “closed”
A String with any state will return “closed”
For
if(state == "OPEN") "opened" else "closed"
A Contact with any state will return “closed”
A String with state “OPEN” will return “opened”
A String with any other state will return “closed”

Make sense?

You can either consider the different cases (as you do earlier in the same rule) with ‘OR’ function

For
if(state == OPEN || state == "OPEN") "opened" else "closed"
A Contact with state OPEN will return “opened”
A String with state “OPEN” will return “opened”
Any Item with any other state will return “closed”

Or you can force things to be the same type
For
val state = triggeringItem.state.toString
if(state == "OPEN") "opened" else "closed"
A Contact with state OPEN or a String with state “OPEN” will return “opened”
Any Item with any other state will return “closed”

MAP doesn’t care, MAP always returns a string.
But depending where you use it, the openHAB framework may do further stuff with the string.
For example, if you use it in a channel configuration then the framework will try it’s best to parse the string into something suitable for whatever Item type you have linked it to.
For example,
returns “CLOSED” is simply a straight transfer to a String type.
returns “CLOSED” is parsed into CLOSED for a Contact type.
returns “CLOSED” blows up if you link to a Switch type, it cannot be parsed into an ON/OFF type state.

This should work

Contact  Gate_status    "Sliding Gate"         (Group_HabPanel_Dashboard,gDoorSensors)  [ "Switchable" ] { mqtt="<[broker:cmnd/SENSOR/POWER8:state:MAP(gate.map)]", autoupdate="false" }

though you might get all sorts of knock-on effects with rules, persistence, sitemaps, Group aggregations etc. if you change any Item type.

3 Likes

thanks rossko for the huge and informative reply, I know understand and see the issue ! I’ve left the item as a string item and modified the rule accordingly.

This information is far better written than the help docs! people should keep this is a reference - I know I will

hi rossko57, further to this topic. I’ve begun to convert all my MQTT 1.x devices over to MQTT2

All the switches, temps and humidity sensors work fine, however the Contact/String items for doors being open/closed do not.

First example is using a Contact item, which worked fine on MQTT 1.x.


Does this appear correct for my MQTT topic being ‘doorsensor’, my map is correct (was used successfully previously.)

This log snippet shows the door closed from the Sonoff Tasmota device:

08:27:46 MQT: tele/doorsensor/STATE = {“Time”:“2021-07-20T08:27:46”,“Uptime”:“0T00:00:15”,“Vcc”:3.478,“SleepMode”:“Dynamic”,“Sleep”:50,“LoadAvg”:19,“POWER”:“ON”,“Wifi”:{“AP”:1,“SSId”:“Tard”,“BSSId”:“FC:EC:DA:D1:6D:D7”,“Channel”:1,“RSSI”:100}}
08:27:46 MQT: tele/doorsensor/SENSOR = {“Time”:“2021-07-20T08:27:46”,“Switch2”:“OFF”}
08:28:00 MQT: stat/doorsensor/RESULT = {“POWER”:“OFF”}
08:28:00 MQT: stat/doorsensor/POWER = OFF

Cheers

No.
Why use a channel profile? The binding provides more sophisticated ways
to transform at the channel, including for output (unlike the profile) although you don’t need that for this particular Item.

Okay, so the problem is that you have selected a channel of type contact.
Channels of type contact will, like their Item equivalents, deal in states OPEN and CLOSED.
If an on-topic message {blahblah} comes along, the channel will do its best to make that fit OPEN/CLOSED, and if it doesn’t fit, discard the message.

Whatever it is your gate.map does, it will never get fed any data by this configuration because none of the MQTT messages shown fit into the only allowed contact channel output OPEN/CLOSED.
Normally of course, we’d use transformations to select and massage message that we will make fit.

So, which of these messages are you interested in? Each channel can only listen to one incoming topic.

You can make several channels to listen to different topics, transform in different ways, and link more than one channel to the same Item.
You might do that with

08:28:00 MQT: stat/doorsensor/RESULT = {“POWER”:“OFF”}
08:28:00 MQT: stat/doorsensor/POWER = OFF

for example, if that represents the same information presented different ways, like Tasmota does.

But is this the door information you are after?

08:27:46 MQT: tele/doorsensor/SENSOR = {“Time”:“2021-07-20T08:27:46”,“Switch2”:“OFF”}

I think you’ll need the full topic to get any further, this looks a bit shorter than what you were using in binding v1.

I tried using this:

stat/doorsensor/POWER

With zero joy, it doesnt update the state when the door opens and closes with the CONTACT channel. I believe the right way is using the STAT right? However the MQTT V1 used the cmnd. This is where im confused - I’m not sure what I’m meant to use. I tried either, same issue.

Full topic??

I have a garage door (uses a contact, did in MQTT V1 and worked) using a Sonoff Basic and the Sliding Gate (which you helped with last week) which uses a Sonoff 4 Channel and uses a String

Maybe we could see that. Contact Items do not handle commands (except REFRESH).

Just go at this logically. Don’t know if/what message arrives on a topic? Find out. Create a temporary string type channel for your topic, no transformations, link to a String type Item, no profiles, and there it is.

When you know what the message is, then you can use transformations on the real channel type of your choice to beat it into shape. You want to use contact type, then you must beat it into OPEN/CLOSED shape only.

I dunno. That’s all up to the Tasmota, the way you’ve wired and configured it. openHAB can’t guess, you need to understand what you’re trying to achieve.

Let’s say you want to connect this with a Contact (not sure why, isn’t it an output relay in Sonoff?).
08:28:00 MQT: stat/doorsensor/POWER = OFF
You would set up your contact channel with stateTopic stat/doorsensor/POWER
Now you’ve got to transform ON/OFF message payload into OPEN/CLOSED for the contact type. You could do that with a MAP, but the binding provides mini-transform features we can use here.
Set Custom On/Open Value to ON, and Off/Closed to OFF
Finally link your channel to a Contact type Item, with no profile involved.

Hundreds of people have been this way already

Note that when editing xxx.things file MQTT channels, the binding is not always clever about applying changes in-flight, and a restart often helps.

Thanks, i think ive done all that correctly. Perhaps im trying to subscribe to the wrong topic. Is there a way for that String type Item to list to everything - ie subscribe to all state changes? so that an open/close of the door will just update the string item

If you want to do that, use a third party tool like mqtt.fx or mqtt explorer.
Editing openHAB Things is about the clumsiest investigatory tool you could think of, because it assumes you know what you are doing when you set it up.

Fair enough. My string doesnt even update, with just basic configuration when the door is open/closed so it must be a topic issue! :confused:

if you look on the console of the tasmota device you will see what is happening.
It will show you if anything happens when the door opens and it will also show you the topics being used.

Indeed

11:52:16 MQT: tele/gate/STATE = {"Time":"2021-07-20T11:52:16","Uptime":"8T05:18:55","Vcc":2.948,"SleepMode":"Dynamic","Sleep":50,"LoadAvg":19,"POWER1":"OFF","POWER2":"OFF","POWER3":"OFF","POWER4":"OFF","Wifi":{"AP":1,"SSId":"Tard","BSSId":"FC:EC:DA:D1:6D:D7","Channel":1,"RSSI":100,"LinkCount":5,"Downtime":"0T00:04:00"}}
11:52:16 MQT: tele/gate/SENSOR = {"Time":"2021-07-20T11:52:16","Switch8":"ON"}

but using stat/gate/SENSOR doesnt update the item

If you type in status 0 in the console it will show you everything.

1 Like

So now we look at that channel (which is not the same one discussed earlier)

13:21:36 MQT: stat/gate/STATUS = {"Status":{"Module":23,"FriendlyName":["GateControl","GateControl2","GateControl3","GateControl4"],"Topic":"gate","ButtonTopic":"0","Power":0,"PowerOnState":0,"LedState":1,"SaveData":1,"SaveState":0,"SwitchTopic":"SENSOR","SwitchMode":[0,0,0,1,0,0,0,2],"ButtonRetain":0,"SwitchRetain":0,"SensorRetain":0,"PowerRetain":0}}
13:21:36 MQT: stat/gate/STATUS1 = {"StatusPRM":{"Baudrate":115200,"GroupTopic":"sonoffs","OtaUrl":"http://domus1:80/api/arduino/GarageController.ino.bin","RestartReason":"Power on","Uptime":"8T06:48:15","StartupUTC":"2021-07-12T05:33:21","Sleep":50,"CfgHolder":4617,"BootCount":44,"SaveCount":55,"SaveAddress":"F7000"}}
13:21:36 MQT: stat/gate/STATUS2 = {"StatusFWR":{"Version":"6.5.0(release-basic)","BuildDateTime":"2019-03-19T12:25:14","Boot":7,"Core":"2_3_0","SDK":"1.5.3(aec24ac9)"}}
13:21:36 MQT: stat/gate/STATUS3 = {"StatusLOG":{"SerialLog":0,"WebLog":4,"SysLog":0,"LogHost":"domus1","LogPort":514,"SSId":["Tard",""],"TelePeriod":300,"Resolution":"558180C0","SetOption":["00000008","280500000100000000000000000000000000","00000001"]}}
13:21:36 MQT: stat/gate/STATUS4 = {"StatusMEM":{"ProgramSize":432,"Free":568,"Heap":17,"ProgramFlashSize":1024,"FlashSize":1024,"FlashChipId":"144051","FlashMode":3,"Features":["00000809","0F082380","000483A0","21021706","000001C0"]}}
13:21:36 MQT: stat/gate/STATUS5 = {"StatusNET":{"Hostname":"gate-8044","IPAddress":"192.168.0.239","Gateway":"192.168.0.254","Subnetmask":"255.255.255.0","DNSServer":"192.168.0.254","Mac":"60:01:94:BF:7F:6C","Webserver":2,"WifiConfig":5}}
13:21:36 MQT: stat/gate/STATUS6 = {"StatusMQT":{"MqttHost":"192.168.0.3","MqttPort":1883,"MqttClientMask":"Gate","MqttClient":"Gate","MqttUser":"mosquitto","MqttCount":7,"MAX_PACKET_SIZE":1000,"KEEPALIVE":15}}
13:21:36 MQT: stat/gate/STATUS7 = {"StatusTIM":{"UTC":"Tue Jul 20 12:21:36 2021","Local":"Tue Jul 20 13:21:36 2021","StartDST":"Sun Mar 28 02:00:00 2021","EndDST":"Sun Oct 31 03:00:00 2021","Timezone":"+01:00","Sunrise":"05:08","Sunset":"20:44"}}
13:21:36 MQT: stat/gate/STATUS10 = {"StatusSNS":{"Time":"2021-07-20T13:21:36","Switch8":"ON"}}
13:21:36 MQT: stat/gate/STATUS11 = {"StatusSTS":{"Time":"2021-07-20T13:21:36","Uptime":"8T06:48:15","Vcc":2.920,"SleepMode":"Dynamic","Sleep":50,"LoadAvg":19,"POWER1":"OFF","POWER2":"OFF","POWER3":"OFF","POWER4":"OFF","Wifi":{"AP":1,"SSId":"Tard","BSSId":"FC:EC:DA:D1:6D:D7","Channel":1,"RSSI":100,"LinkCount":5,"Downtime":"0T00:04:00"}}}
13:21:44 WIF: Checking connection...

I can see a SwitchTopic and a Topic

This is your old setup for "Gate_status"Item, yes?
What that did was listen for topic cmnd/SENSOR/POWER8
So far as I know, Tasmota does not publish cmnd/ type topics. It subscribes to them, and treats incoming messages as instructions.

I think here you are “eavesdropping” on instructions from openHAB or someone else to the Tasmota, and using that as “status”. Is there an RF remote control involved here?
I don’t think you ever used a real contact - how is that connected to your Sonoff?

The unit does have an RF control, but I never use it. And yes, that is the old setup - which worked.

I’ve got a dry contact reed switch into the GND/SNA pins of the Sonoff - this is how it’s setup and i’ve had no issues for years

Well, reproduce it then.
stateTopic cmnd/SENSOR/POWER8
transformationPattern MAP:gate.map

I think you can in fact configure cmnd/ topics - you might use that to trigger some other Sonoff, for example.
But there’s nothing there about ‘gate’, I have doubts about your v1 topic ever working.