MQTT payload parsing error

I’ve a door lock that is able to publish its state to a local MQTT broker and the payload on MQTT shows the correct state of the lock (i.e. “locked”):

{"deviceId":"123456","deviceType":"Smart Lock","lockState":"locked","battery":95}

In the configuration file, I added a binary sensor as follows:

mqtt:
  binary_sensor:
    - name: "Front Door Lock"
      state_topic: "switchbot/123456/status/both"
      device_class: lock
      value_template: >-
        {{ value_json.lockState }}

But this sensor is always shown as “unknown” so I decided to check it in the template editor with following:

{% set value_json={"deviceId":"123456","deviceType":"Smart Lock","lockState":"locked","battery":95} %}
{{  value_json.lockState }}

And the template shows the correct output as “locked”.

So I’m not really sure this code is working in the template editor but not in the configuration file.

Please see if anyone can spot any error or point me in the right direction.
Thanks.

Hi @PanMat,

You are defining a binary sensor so the states available are either ON or OFF.

It should be something like:

mqtt:
  binary_sensor:
    - name: "Front Door Lock"
      state_topic: "switchbot/123456/status/both"
      device_class: lock
      value_template: >-
        {% if value_json.lockState == "locked" %}ON{% else %}OFF{% endif %}

Thanks @mak-dev for your input.

I modified the code to include the if-else block and restarted the HA just to make sure there are no glitches with the reload and still seeing the same state.

From the Developer tools, I also called the service for MQTT: Export to dump the payload for the topic just in case the data was not making its way to this template.

The mqtt:Export service dumped a file “mqtt.dump.txt” in the config folder which shows that correct data is being received by HA.

TL;DR: MQTT sensors are a little different.

And you locked/unlocked the door to trigger a new event, just to be sure? Maybe also check your QoS on that topic and whether state is retained.

Lastly, the template can be reduced to this (binary sensors not only accept on/off, but also true/false):

{{ value_json.lockState == "locked" }}

The sensor is on if the template evaluates as True , yes , on , enable or a positive number. Any other value will render it as off . The actual appearance in the frontend (Open /Closed , Detected /Clear etc) depends on the sensor’s device_class value.

Template - Home Assistant

I toggled the door lock to “open” position and within few seconds the value for “lockState” changed to “unlocked” on the MQTT broker.

Looking at MQTT Explorer, this topic has QoS=0, but cannot ascertain if the messages are set to retained or not.

Here is the set up details just in case it helps:

  1. HA running in supervised mode on a Debian machine
  2. Mosquitto broker installed on HA as add-on
  3. Installed Switchbot lock, keypad and a mini Hub. The hub connects to WiFi and provide access to the lock via mobile app or any online interface.
  4. SwitchBot-Mqtt installed as HA add-on that is polling (cloud) the Switchbot API to get the states of lock, keypad and the mini Hub to HA.

Do you have anything else using MQTT, just to confirm your base is working?

Yes, I have few tasmota devices and a zigbee bridge that is using the MQTT broker. There are couple of light automations using these devices which are working fine.

@PanMat,

I use your exact same payload and have been able to make it work on my side.
I used this, as I think it is even better than if-else:

binary_sensor:
  - name: "Front Door Lock"
    state_topic: "switchbot/123456/status/both"
    device_class: lock
    payload_on: "unlocked"
    payload_off: "locked"
    value_template: "{{ value_json.lockState }}"

So I think it should be OK and if not, there should be something wrong in your setup.

Make sure to send the payload again after reloading the configuration of your MQTT binary sensor.
Otherwise, it will still be “unknown” if the payload is not sent with the retain flag.

@parautenbach,

You are referring to template binary sensors.
I think this doesn’t work with binary_sensor.mqtt as it expects either ON or OFF by default.

2 Likes

Yeah, you’re right. I remembered (wrongly) that without payload_on and payload_off you just need to output a truish/falsy value.

I think your last post gives the best answer. It’s the cleanest.

Thanks for confirming! Now some good news, I created another sensor for battery level that has information in the same payload and it is working correctly. That eliminates few doubts and seems like MQTT is working correctly.

Another question - is there any way to create a text sensor from MQTT playload? I just want to see the raw value that binary sensor might be getting from the MQTT broker.

@parautenbach
:wink: :+1:

@PanMat,
You can simply use an mqtt sensor then:

sensor:
  - name: "Front Door Lock"
    state_topic: "switchbot/123456/status/both"
    value_template: "{{ value_json.lockState }}"

This is the minimal configuration, you will find more options such as defining icon on sensor.mqtt