Setting up stateless RF Motion Sensors as `binary_sensors` in Home Assistant

This post explains how to set up binary_sensors in Home Assistant that track the state of RF motion sensors. Our RF gateway converts radio messages to MQTT messages with the RF code in its payload and sent on its own topic. (e.g. /rf/<code>) We can set up binary_sensors in our Home Assistant configuration that track the state of RF devices and get updated according to RF codes sent on the relevant MQTT topic.

We can use the binary_sensor.mqtt component for this task as it supports a few properties and behaviours that come in handy.

Types of RF Devices

First of all, we need to distinguish between two different kinds of RF devices:

  • those that send RF signals for both the “on” and “off” state (“garage door open” and “garage door close”)
  • those that only send “trigger” signals, that are not followed by an “off” signal (such as “motion detected”)

The following sections explain how to configure them in Home Assistant.

On/Off Type RF devices

The first kind we can handle as shown in the door_sensor example below.

  1. The RF device sends a signal indicating the door has been opened.
  2. Our RF gateway converts this to a MQTT message containing the 10179082 payload and a message send on /rf/10179082.
  3. This is picked up by the binary_sensor component in Home Assistant and;
  4. Our sensors state is changed to "on".

Similarly, when the door is shut, the device emits a radio signal that is converted to a MQTT message containing the payload_off code. Again, this results in the binary_sensor component updating the state of the sensor inside Home Assistants state machine. This is easy enough becuase the RF device emits signals for both its on and off state, i.e. it is completely stateful. The following YAML shows how to ste up this type of RF device as a binary_sensor.

- platform: mqtt
  name: "door_sensor"
  device_class: 'door'
  state_topic: "/rf/all"
  payload_on: '10179082'
  payload_off: '10179086'

Trigger type RF devices

The second kind of RF device does not send off signals because it is either not supported or it doesn’t make sense to send such a signal.

This poses a problem because our binary_sensor gets stuck in the on position indefinitely. Any subsequent signals sent out are therefore not registered in Home Assistant because they do not trigger a state change in the binary sensor component (on -> on does not represent a change in state).

- platform: mqtt
  name: "living_room_motion"
  device_class: 'motion'
  state_topic: "/rf/10179082"
  off_delay: 5 # make sure you update HA to v0.81 for this feature

Note that the binary_sensor.mqtt component does not support the expire_after property as used in other types of sensors. This property would come in very handy and I hope they add this functionality soon. (They have!!!)

Since v0.81, Home Assistant does support the off_delay parameter, which we can use here to turn off the MQTT binary sensor automatically after some delay. This means that the rest of this post is obsolete as the functionality has been added into Home Assistant.

How do we set the binary_sensor state back to off? (Obsolete)

There is currently no way to set the state of sensors directly in Home Assistant. The only way is to fake an MQTT sensor update by sending an MQTT message on the sensor topic which HA will interpret as a message originating from the MQTT sensor.

To achieve this we can create an automation that resets the binary_sensor to off after some time (say 5 seconds). Consider the living_room_motion sensor above. It’s payload_off RF code is set to 0. This is not a real RF code1. It’s a fake code we are going to use to reset its state back to off using the following automation.

- alias: Motion Sensor Reset Off
  hide_entity: yes
  trigger:
    platform: state
    entity_id: binary_sensor.living_room_motion
    to: 'on'
    for:
      seconds: 5 # Trigger once the sensor has been in the to state for 5sec
  action:
    - service: mqtt.publish ## Why MQTT? See notice below
      data:
        topic: '/rf/all'
        payload: '0'

I will use the '0' payload in all trigger-type RF devices. However, this means that different RF devices can interfere with each other when the intent was to reset a particular device. Instead all devices with payload_off: '0' are switched off. The reason I did this is to avoid defining unique fake codes for each RF device. It’s not perfect. Keep in mind that this is only really a problem if your reset window is much longer than 5 seconds. Any device that is reset prematurely (because of another device triggering the automation) would have gotten reset a few seconds later anyway by its own reset trigger.

Conclusion

We have successfully configured Home Assistant to maintain the state of our motion sensor and door sensor. This means that Home Assistant now contains an accurate representation of the true states of these RF devices. The next step is to create motion based automations