Can a MQTT Binary Sensor retain it's status or do I need an Input_Boolean?

I utilise NodeRED extensively for this purpose, taking an existing topic structure and republishing it either as different topic(s) or value, with retention if appropriate. You likely have to handle the reverse case too… In this case splitting a compound topic value into the individual topics and value. I don’t regard it as a kludge, just a transformation.

NodeRED is really good at this and also needn’t load HA in implementation, if on a separate cpu. It’s a great translator between automations.

I also don’t think using Node-Red to pre-process or transform values is a kluge. What I do think are kluges are the roundabout techniques people employ to solve a basic requirement, namely restoring entity states after a restart.

Call it ‘persistence’, or something else, but it’s missing in HA. A few entities, like input_boolean and others, are restored on startup using the values stored by Recorder. However, that’s a fraction of all entities so people use one bandaid solution or another to restore entity states.

As a benchmark, openHAB offers the ability to restore states and so does the HA system I’ve used for ten years (and it was invented in 1998). This feature is long overdue for Home Assistant. Having said that, I have seen a PR where the new JSON storage is being used to store an entitiy’s state.

Which broker are you using? I seem to remember that the embedded broker does not respect the retain flag, which may be why that solution did not work for you.

Thanks for the reply guys. I am using Mosquitto a my MQTT Broker.

I will stick to using an input_boolean in the back ground to keep it simpler than going back and forth with MQTT messages.

I will look at setting up a binary sensor for the front end to save having to use add on packages.

I will put a couple of feature requests in.

One to have more than two states for a device class.
To be able to use device classes on input_booleans.
For binary sensors to be persistent and survive a restart.

One to have more than two states for a device class.

For sensors, device_classes represent the magnitude of a given property like temperature, humidity, battery, etc.

For binary sensors, device_classes represent its two possible states. It can’t have three or more states because then it’s not a binary sensor.

To be able to use device classes on input_booleans.

If an input_boolean could be assigned a device_class of fan it could allow the UI to show icons of a moving or stopped fan (based on the state). That’s marginally better than what’s possible now (use customize to show a fan icon).

BTW, if you’re using an input_boolean to represent the state of something you cannot control (like a motion or contact sensor) then you’re using the wrong entity for the job. The UI will render a toggle switch which is misleading; the toggle switch suggests the end-user can control the state of the contact/motion sensor.

For binary sensors to be persistent and survive a restart.

This capability shouldn’t be limited to binary sensors. A persistence feature should be capable of storing the current value of all entities. You should have control over it so you can indicate which entities are included/excluded from the persistence feature. This sounds a lot like the existing Recorder component except it was never fully used for persistence (i.e. to restore states after a restart).

I got there in the end.
Still very long winded but it works.

This is setup as a package security.yaml

input_boolean:
  master_bedroom_window:
  master_bedroom_window_alarm:

automation:
##########
# Start of Master Bedroom Window
##########
- alias: master_bedroom_window_open
  trigger:
    platform: mqtt
    topic: tele/sonoffBridge/RESULT
  condition:
    condition: template
    value_template: '{{ trigger.payload_json.RfReceived.Data == "1234EE" }}'
  action:
    service: homeassistant.turn_on
    entity_id: input_boolean.master_bedroom_window

- alias: master_bedroom_window_close
  trigger:
    platform: mqtt
    topic: tele/sonoffBridge/RESULT
  condition:
    condition: template
    value_template: '{{ trigger.payload_json.RfReceived.Data == "1234E7" }}'
  action:
    service: homeassistant.turn_off
    entity_id: input_boolean.master_bedroom_window

- alias: master_bedroom_window_alarm
  trigger:
    platform: mqtt
    topic: tele/sonoffBridge/RESULT
  condition:
    condition: template
    value_template: '{{ trigger.payload_json.RfReceived.Data == "1234EB" }}'
  action:
    service: homeassistant.turn_on
    entity_id: input_boolean.master_bedroom_window_alarm


binary_sensor:
  - platform: template
    sensors:
      master_bedroom_window:
        friendly_name: "Master Bedroom Window"
        device_class: window
        value_template: >-
          {{ is_state('input_boolean.master_bedroom_window', 'on') }}

      master_bedroom_window_alarm:
        friendly_name: "Master Bedroom Window Alarm"
        device_class: problem
        value_template: >-
          {{ is_state('input_boolean.master_bedroom_window_alarm', 'on') }}

The Yellow Window Open and Problem symbol are the two binary_sensor’s

Thanks wills106!
This worked like magic for me.
The only problem is that after updating HA to 0.87.0, the sensor wouldn’t change state no matter what I try.

After few trials and errors, I realized that the mqtt topic had to be in double quotes for the automation to work again:

platform: mqtt
topic: "tele/sonoffBridge/RESULT"

Hi there ! Just a little update to refresh things up syntax-wise on this super helpful topic. On Hassio 0.94.3.

In configuration.yaml I have :

# Input Booleans
input_boolean:
  cave_door:
  garage_door:

# Binary Sensors
  - platform: template
    sensors:
      cave_door:
        friendly_name: "Cave Door"
        device_class: door
        value_template: >-
          {{ is_state('input_boolean.cave_door', 'on') }}

  - platform: template
    sensors:
      garage_door:
        friendly_name: "Garage Door"
        device_class: garage_door
        value_template: >-
          {{ is_state('input_boolean.garage_door', 'on') }}

Then in automations.yaml (as I have automation: !include automations.yaml entry in my configuration.yaml)

  - alias: cave_door_open
    trigger:
      platform: mqtt
      topic: rfbridge/tele/RESULT
    condition:
      condition: template
      value_template: '{{ trigger.payload_json.RfReceived.Data == "31D20A" }}'
    action:
      service: homeassistant.turn_on
      entity_id: input_boolean.cave_door

  - alias: cave_door_close
    trigger:
      platform: mqtt
      topic: rfbridge/tele/RESULT
    condition:
      condition: template
      value_template: '{{ trigger.payload_json.RfReceived.Data == "31D20E" }}'
    action:
      service: homeassistant.turn_off
      entity_id: input_boolean.cave_door

  - alias: garage_door_open
    trigger:
      platform: mqtt
      topic: rfbridge/tele/RESULT
    condition:
      condition: template
      value_template: '{{ trigger.payload_json.RfReceived.Data == "32BB0A" }}'
    action:
      service: homeassistant.turn_on
      entity_id: input_boolean.garage_door

  - alias: garage_door_close
    trigger:
      platform: mqtt
      topic: rfbridge/tele/RESULT
    condition:
      condition: template
      value_template: '{{ trigger.payload_json.RfReceived.Data == "32BB0E" }}'
    action:
      service: homeassistant.turn_off
      entity_id: input_boolean.garage_door

It is working absolutely great ! Thanks guys ! I am sure this have helped tons of RF Bridge users.

Although the solution I offered many months ago does work, I would now suggest a completely different one. It’s simpler to implement, easier to manage, and doesn’t require the use of input_booleans.

I recommend Strategy #2 in this post: Sonoff RF Bridge. Strategies for receiving data. It uses the concept of demultiplexing (demux).

The solution consists of:

  • One simple automation
  • One simple python_script

The configuration of each MQTT Binary Sensor is greatly simplified. It doesn’t even need a value_template.

For example, this is how simple they become when using Strategy #2:

  - platform: mqtt
    name: 'Cave Door'
    state_topic: 'home/sensor1'
    device_class: door

  - platform: mqtt
    name: 'Garage Door'
    state_topic: 'home/sensor2'
    device_class: garage_door

The only work you have to perform is configuring the JSON dictionary within the python_script (see the linked post for complete instructions).

For example, this is how it would be defined for @Lefuneste’s two binary_sensors:

d = { '31D20A':['sensor1','ON','true'],
      '31D20E':['sensor1','OFF','true'],
      '32BB0A':['sensor2','ON','true'],
      '32BB0E':['sensor2','OFF','true']
    }

The true you see there means the payload (ON or OFF) is published as a retained message. That means the binary_sensor’s state is stored by the MQTT broker so when Home Assistant restarts, it acquires the sensor’s latest state from the broker.

Adding another binary_sensor becomes child’s play:

Step 1: Define it.

  - platform: mqtt
    name: 'Kitchen Window'
    state_topic: 'home/sensor3'
    device_class: window

Step 2: Append its RF codes to the JSON dictionary in the python_script.

d = { '31D20A':['sensor1','ON','true'],
      '31D20E':['sensor1','OFF','true'],
      '32BB0A':['sensor2','ON','true'],
      '32BB0E':['sensor2','OFF','true'],
      '36DE0A':['sensor3','ON','true'],
      '36DE0E':['sensor3','OFF','true']
    }

Step 3: Restart Home Assistant.

Thanks @123 I will have a look into this method when I get chance. As I have quite a few new RF devices to setup.
Should help to clean it up alot!

Yeah Many thanks for the update. I’ll check it too !

Ok I have implemented this scripted solution and it seems to work just fine as well.