Having problems correctly parsing MQTT with a template

Hello,

I am trying to make a switch or entity in Home Assistant go on whenever a doorbell button is pressed. The doorbell button emits a RF signal which gets caught by my Sonoff RF Bridge, running Tasmota.

Whenever the doorbell button is pressed, I will get this in my Tasmota log (I redacted the string):

13:17:20.993 MQT: tele/deurbel/RESULT = {"Time":"2024-06-23T13:17:20","RfRaw":{"Data":"AA AA AA 0000 0000 0000 12341234123412341234123412341234123412341234123412 55"}}

configuration.yaml:

mqtt:
  sensor:
    - name: "Deurbel"
      state_topic: "tele/deurbel/RESULT"
      availability_topic: "tele/deurbel/RESULT"
      availability_template: "{% if value_json.RfRaw.Data.split(' ')[6] == '12341234123412341234123412341234123412341234123412' %}true{% else %}false{%endif %}"
      payload_available: "true"
      payload_not_available: "false"

The entity pops up in Home Assistant but stays offline. What am I doing wrong?

Kind of crazy trying to do it that way.
I use the 2nd strategy listed here:
Sonoff RF Bridge. Strategies for receiving data, (Thanks @123 :orange_heart:)
After that you can look at my config and see how I do it.
Copy anything you like. My config link is in my message footer.

1 Like

Thank you, that’s useful.

1 Like

I suggest you consider using an MQTT Event to model the operation of a doorbell. A doorbell’s state is neither on or off but momentarily pressed.

mqtt:
  - event:
      name: "Door Bell"
      state_topic: "tele/deurbel/RESULT"
      event_types:
        - press
      device_class: "button"
      unique_id: "abc123xyz456"
      value_template: |
        {
          {% if '1234123412341234' in value_json.RfRaw.Data %}
            "event_type": "press"
          {% endif %}
        }

It will produce an event entity whose state value will initially be unknown.

When the doorbell button is pressed, the state value of event.door_bell will change to the date and time when it was pressed.

This makes it very easy for an automation to detect whenever the doorbell button is pressed. All it needs is a State Trigger to detect when the state value changes.

alias: example
trigger:
  - platform: state
    entity_id: event.door_bell
    to:
condition: []
action:
  ... etc ...
2 Likes

Thank you for the detailed write-up, I have incorporated this now.

@123 One problem I’ve found is that on one button press, the doorbell will send a salvo of three signals, and all of them get detected. Is there a way to disregard the second and third signal, so that I don’t get three entries in my log?

Is the value of Data identical in all three payloads?

{
    "Time": "2024-06-23T13:17:20",
    "RfRaw": {
        "Data": "AA AA AA 0000 0000 0000 12341234123412341234123412341234123412341234123412 55"
    }
}

What is the time interval between each of the three received payloads? More than second apart or less than?

If it’s less than a second apart, I suggest you consider using a Tasmota command called ButtonDebounce. EDIT I just realized you’re using a Sonoff RF Bridge so you probably have no ability to debounce the RF doorbell.

image


EDIT

Here’s a simple way to make your automation ignore any triggers that occur faster than three seconds apart. Use a Template Condition to check if the last time the automation was triggered is more than 3 seconds ago. If it was less than three seconds then the trigger is ignored.

alias: example
trigger:
  - platform: state
    entity_id: event.door_bell
    to:
condition:
  - condition: template
    value_template: "{{ now() - this.attributes.last_triggered > timedelta(seconds=3) }}"
action:
  ... etc ...

Is the value of Data identical in all three payloads?

Often, but sometimes it isn’t.

What is the time interval between each of the three received payloads? More than second apart or less than?

Less than a second.

Here’s a simple way to make your automation ignore any triggers that occur faster than three seconds apart.

This is nice, thanks. Another way to do this would be to add a delay at the end of the automation and set the automation mode to Single.

However, the (MQTT) event still pops up three times in my log for one button press. Is there a way to suppress subsequent entries, perhaps by editing the MQTT in one way or another?

I tried to create a Tasmota rule that gets triggered by RfRaw to have it emit a different MQTT message when it detects a doorbell press, but AFAIK there’s no way to parse the payload in Tasmota with Rules. So probably the best way to do this would be to create some sort of different event in Tasmota that gets fired only once.

If you don’t like seeing the three instances of the event recorded in Logbook, then I suggest modeling your door bell as an MQTT Binary Sensor. It’s the more traditional way and was used before MQTT Event was introduced.

We will use an MQTT Binary Sensor’s off_delay option and set its value to 3 (seconds).

mqtt:
  - binary_sensor:
      name: "Door Bell"
      state_topic: "tele/deurbel/RESULT"
      unique_id: "abc123xyz456"
      value_template: "{{ iif('1234123412341234' in value_json.RfRaw.Data, 'ON', 'OFF') }}"
      off_delay: 3

After the MQTT Binary Sensor is created, its initial state will be unknown. It will change to on when it receives a payload containing the appropriate string. It will automatically change to off after 3 seconds.

During the 3 second period, any other payloads received will not change the binary sensor’s state so no additional state-changes will be recorded within that period.

The automation should use a State Trigger to detect the binary_sensor’s state-change from off to on. It doesn’t need a condition.

alias: example_2
trigger:
  - platform: state
    entity_id: binary_sensor.door_bell
    from: 'off'
    to: 'on'
condition: []
action:
  ... etc ...

Ohh~~ Neat! I learned something new today.

Which one of my two suggestions did you ultimately choose? MQTT Event or MQTT Binary Sensor?

For the last month, I have been using the MQTT Event, it’s been working great!

Glad to hear it has been working well for you.

Please consider marking my post above with the Solution tag.

It will automatically place a check-mark next to the topic’s title which indicates to others that the topic has been solved. It helps users find answers to similar questions.

1 Like