Two-Code Door Sensor

Use a template sensor.

Also input_boolean will restore its state in a HA restart

Exactly, which was part of the question.

Ok, so I create this as a boolean_input:

testdoorswitch:
  name: TestDoorSwitch
  initial: on
  icon: mdi:door-closed

Now how do I process the MQTT to turn this on/off?

I picture creating MQTT sensors like this:

- platform: mqtt
  name: "TestDoorSwitchOPEN"
  state_topic: "rflink/SelectPlus-065afa"
  value_template: '{{ value_json["SWITCH02"] }}'
  icon: mdi:door-open
- platform: mqtt
  name: "TestDoorSwitchCLOSED"
  state_topic: "rflink/SelectPlus-065af8"
  value_template: '{{ value_json["SWITCH02"] }}'
  icon: mdi:door-closed

I can create an automation based on these sensors that would flip the boolean_input.

But what I don’t understand is that once the sensor gets the “ON”, there is nothing to turn it off. I feel like I would still need to add something to set the OPEN sensor to “OFF” when the CLOSED sensor gets an “ON” message?

Does that make sense?

I made this change to my sensors (adding the expire_after value) and will see how this works:

- platform: mqtt
  name: "TestDoorSwitchOPEN"
  state_topic: "rflink/SelectPlus-065afa"
  value_template: '{{ value_json["SWITCH02"] }}'
  expire_after: 2
  icon: mdi:door-open
- platform: mqtt
  name: "TestDoorSwitchCLOSED"
  state_topic: "rflink/SelectPlus-065af8"
  value_template: '{{ value_json["SWITCH02"] }}'
  expire_after: 2
  icon: mdi:door-closed

I created these automations to process the data and make the boolean change:

- id: testdoorswitchopened
  alias: testdoorswitch-opened
  description: TestDoorSwitch Opened
  trigger:
    platform: state
    entity_id: sensor.testdoorswitchopen
    to: 'ON'
  action:
    - service: input_boolean.turn_on
      data:
        entity_id: input_boolean.testdoorswitch
- id: testdoorswitchclosed
  alias: testdoorswitch-closed
  description: TestDoorSwitch Closed
  trigger:
    platform: state
    entity_id: sensor.testdoorswitchclosed
    to: 'ON'
  action:
    - service: input_boolean.turn_off
      data:
        entity_id: input_boolean.testdoorswitch

I want to point out that your code won’t capture the door’s state when HA is not running (reboot etc).

If you don’t mind having yet another MQTT topic, it is possible to do the following:

  • create an automation with MQTT triggers that will publish the received state (ON/OFF) to a dedicated topic like house/ground_floor/door with retain: true
  • create a normal MQTT binary sensor for that topic - it will be your door sensor’s state

That way you’ll know the door’s last reported state even if you restart/shutdown your HA for a while (provided your MQTT broker is up and running).

Like this?

- id: testdoorswitchopened
  alias: testdoorswitch-opened
  description: TestDoorSwitch Opened
  trigger:
    platform: state
    entity_id: sensor.testdoorswitchopen
    to: 'ON'
  action:
    - service: input_boolean.turn_on
      data:
        entity_id: input_boolean.testdoorswitch
    - service: mqtt.publish
      data:
        topic: doorswitches/testdoorswitch
        payload: on
        retain: true
      
- id: testdoorswitchclosed
  alias: testdoorswitch-closed
  description: TestDoorSwitch Closed
  trigger:
    platform: state
    entity_id: sensor.testdoorswitchclosed
    to: 'ON'
  action:
    - service: input_boolean.turn_off
      data:
        entity_id: input_boolean.testdoorswitch
    - service: mqtt.publish
      data:
        topic: doorswitches/testdoorswitch
        payload: off
        retain: true

With binary_sensor:

- platform: mqtt
  name: bs_testdoorswitch
  state_topic: "doorswitches/testdoorswitch"
  device_class: door

Do I still need the input_boolean?

you don’t need sensor.testdoorswitchopen, only bs_testdoorswitch.
you don’t need input_boolean as the data will be stored by MQTT broker.
you do need automations that trigger on state MQTT messages and publish ON/OFF and on “doorswitches/testdoorswitch” with retain: true

That’s why I need sensor.testdoorswitchopen - it reads the MQTT publish for opening since the switch itself sends one topic for open and a different topic for close.

Then I have those automations to do the publish commands for either the open or the close.

In my previous post I linked a MQTT trigger - don’t you think it’ll help you instead of MQTT sensor?

Oh, I see now. You mean this: MQTT TRIGGER

It did not show up as a hyperlink in your original message.

I dropped the sensors and changed the automations to:

- id: testdoorswitchopened
  alias: testdoorswitch-opened
  description: TestDoorSwitch Opened
  trigger:
    platform: mqtt
    topic: "rflink/SelectPlus-065afa"
  action:
    - service: mqtt.publish
      data:
        topic: doorswitches/testdoorswitch
        payload: on
        retain: true
      
- id: testdoorswitchclosed
  alias: testdoorswitch-closed
  description: TestDoorSwitch Closed
  trigger:
    platform: mqtt
    topic: "rflink/SelectPlus-065af8"
  action:
    - service: mqtt.publish
      data:
        topic: doorswitches/testdoorswitch
        payload: off
        retain: true

I will test with the actual door switch and will see how it works.

Thank you!

I’ve tested the following suggested solution and it works.

Step 1 - Create a binary_sensor to represent your door

Define a simple binary_sensor that subscribes to a “middleman” topic:

  - platform: mqtt
    name: 'Front Door'
    state_topic: tmp/front_door
    device_class: door

Restart Home Assistant to load the new binary_sensor.

Step 2 - Create an automation to manage the binary_sensor’s state

Create an automation that subscribes to both of the rflink’s topics. Depending on which topic triggers the automation, it will publish the appropriate state to the “middleman” topic.

- alias: 'Door Binary Sensor'
  trigger:
  - platform: mqtt
    topic: rflink/SelectPlus-065afa
  - platform: mqtt
    topic: rflink/SelectPlus-065af8
  action:
    service: mqtt.publish
    data_template:
      topic: tmp/front_door
      payload: "{{ 'ON' if trigger.topic[-1] == 'a' else 'OFF' }}"
      retain: true

After creating the automation, be sure to click Configuration > Server Controls > Reload Automations

Proceed to test and confirm it works properly.


NOTE
The automation disregards the received payload. All it cares about is which of the two topics triggered it.

  • If the topic’s name ends with the letter 'a' then that’s the topic (SelectPlus-065afa) responsible for indicating when the door is open so the automation publishes ON.
  • If the triggering topic’s name doesn’t end with 'a' (meaning it was triggered by SelectPlus-065af8) then it publishes OFF.

If you know the topic’s payload should NOT be ignored (perhaps because it not only reports CMD: ON but also CMD: OFF) then let me know and we can adjust the automation.


EDIT
Simplified the suggested solution; it no longer relies on a python_script.

well, it does not seem to keep the last state after HA reboot, does it?
and as the mqtt sensor is subscribed to a dummy topic, maybe it can be replaced with a template sensor or something more basic?
actually, going this route we arrive to the beginning of this story - it’s easier to use input_boolean + mqtt automation, no need for python_script.set_state and the last state will survive HA restart. If needed, input_boolean can be wrapped with binary template sensor.

or I missed something?

No, you were right, the binary_sensor failed to maintain its state after a restart. Thanks for bringing that to my attention because, after reviewing my entire approach with fresh eyes, I was not only able to fix the deficiency, I simplified the solution.

It no longer relies on a python_script. The automation simply publishes the appropriate state to the binary_sensor’s topic (as a retained message). Easy-peasy.

I presume that all sensors don’t do that by design as they are not containers.

I don’t know about “by design” but what I overlooked to take into account (in the first version I had posted) was that on startup the binary_sensor would look to its state_topic to determine its current state. The topic has no message so Home Assistant sets the binary_sensor’s state to off by default.

In the revised version, the automation no longer uses python_script.set_state and opts for publishing a retained message to the binary_sensor’s state_topic. This effectively stores the binary_sensor’s value. On startup the binary_sensor acquires this retained message and so its state is restored to whatever it was prior to restart.

I have a bunch of MQTT Sensors and MQTT Binary_Sensors configured like this and yet I managed to forget all about it when I created the original suggestion! :man_facepalming:

The code worked for me but I had to make a change to the binary_sensor to add the payload values.

- platform: mqtt
  name: "TestDoorSwitch State"
  state_topic: "doorswitches/testdoorswitch"
  device_class: door
  payload_on: on
  payload_off: off
  payload_available: "online"
  payload_not_available: "offline"

Prior to this change, I was getting these errors in the log and it was not changing the state when I moved the switch back and forth.

2020-03-17 18:14:51 INFO (MainThread) [homeassistant.components.automation] Executing testdoorswitch-opened
2020-03-17 18:14:54 INFO (MainThread) [homeassistant.helpers.script] Script testdoorswitch-opened: Running script
2020-03-17 18:14:54 INFO (MainThread) [homeassistant.helpers.script] Script testdoorswitch-opened: Executing step call service
2020-03-17 18:14:55 WARNING (MainThread) [homeassistant.components.mqtt.binary_sensor] No matching payload found for entity: TestDoorSwitch State with state topic: doorswitches/testdoorswitch. Payload: True, with value template None

After I added the payload items then it worked just fine. However, I did not try restarting HA to see if it retained the messages. I will have to give that a try and report back.

Thanks!

I recommend you try the example I posted above. The binary_sensor’s configuration is far simpler (uses default values) and it requires only one automation.

Ok, as I had the code I would open the switch and restart HA or even reboot and when it came back up the binary_sensor was still showing open.

I changed my binary_sensor to match yours:

- platform: mqtt
  name: "TestDoorSwitch State"
  state_topic: "doorswitches/testdoorswitch"
  device_class: door

And I changed my automation down to a single one to match yours as well:

- id: testdoorswitchopenedclosed
  alias: testdoorswitch-openedclosed
  description: TestDoorSwitch Action
  trigger:
  - platform: mqtt
    topic: rflink/SelectPlus-065afa
  - platform: mqtt
    topic: rflink/SelectPlus-065af8
  action:
    service: mqtt.publish
    data_template:
      topic: doorswitches/testdoorswitch
      payload: "{{ 'ON' if trigger.topic[-1] == 'a' else 'OFF' }}"
      retain: true      

It works and it keeps the last setting after restart or reboot.

However, if HA is down and I change the state of the switch it is not picked up when HA comes back online.

I think that makes sense since RFLink & espRFLinkMQTT are still capturing the events from the physical device and publishing the MQTT to the broker but HA is missing that message while it is offline. I’m not sure how to address that. Does espRFLinkMQTT need to publish those with retain as well or would that mess something else up?

Thank you all for your help. This works now. This last issue isn’t the end of the world but if there is a way to address it, it would be nice.

-TimG

1 Like

mate, that’s what I already warned you about above

you need a message with retain: true for the state to be preserved. and a running broker.