MQTT Binary Sensor Can't get state to change

So I am attempting to integrate my home’s built in window/door reed switches to HA.

The device I’m using broadcasts a json package like the following (Z01 to Z48) with each ZXX representing a window or door sensor.

{
  "Z01": 0,
  "Z02": 0,
  "Z03": 0,
  "Z04": 1,
  "Z05": 1,
  "Z06": 1,
  "Z07": 1,
.....
  "Z44": 1,
  "Z45": 1,
  "Z46": 1,
  "Z47": 1,
  "Z48": 1
}

Now if I just use the basic “sensor” entries in configuration.yaml, i get the state changes ok. And it’s all good. But I’d like to use the “device_class” setting and can’t use that with basic sensor.

sensor:
  - platform: mqtt
    unique_id: 1022
    name: "ALARM_Front_Entry_Window"
    state_topic: "HOME/SECURITY/ALARM/inputs"
    json_attributes_topic: "HOME/SECURITY/ALARM/inputs"
    value_template: >
      {% if value_json.Z03 %} Closed {% else %} Open {% endif %}

I can use the device_class attribute with binary_sensor, but the same text in the configuration file does not work.
I’ve been pulling my hair out trying to get the thing to work as I understand this will help automate icon changes for things like windows/doors.

  - platform: mqtt
    unique_id: 102455_binary
    name: "ALARM_Powder_Room_Window"
    state_topic: "HOME/SECURITY/ALARM/inputs"
    device_class: 'window'
    value_template: >
      {% if value_json.Z05 %} "ON" {% else %} "OFF" {% endif %}

I have tried various terms like “Open”/“Closed” and “ON”/“OFF” but can’t seem to make it work.
what am i missing?

You should compare your value_json.Zxx to “0” or “1”.
The way you did it, any value will result in a ON

How do you mean? I tried like this with no luck.

      {% if value_json.Z05=="0" %} "ON" {% else %} "OFF" {% endif %}

0 is on? Unusual…
If it doesn’t work with quotes, try without.

Yeah it’s a fail-safe type thing. if a wire breaks it’ll go low at the input and show a 0. I just left the logic that way through the HA.

I’ve tried with and without quotes and no change. I’ve got to be missing something simple.

It failed because this "0" means string zero, not integer zero. By putting the zero between double quotes you have represented it as a string and not a numeric value. Based on your example, the received JSON data contains numeric values.

Assuming 0 represents on, try this template:

value_template: "{{ 'ON' if value_json.Z03 == 0 else 'OFF' }}"
1 Like

Thank you! That did it.

I had tried without the quotes, as i was thinking the same thing (integer vs string) but didn’t work either way.

I hadn’t tried encapsulating the ON and OFF in single quotes tho. Is that all I was actually missing?

1 Like

FWIW, if the received data looked like this:

{
  "Z01": "0",
  "Z02": "0",
  "Z03": "0",
  "Z04": "1",
 etc

then you probably would have nailed the template on your own.

Yes, you need to delimit 'ON' within that template because without the quotes the Jinja2 template interpreter will handle it as the name of a variable.

Example employing variables:

{% set cat = 'this' %}
{% set hat = 'that' %}
{{ cat if value_json.whatever == 1 else hat }}

The template will report this if the value is 1.

1 Like

Ok well really big thanks for helping me out on this one. YAML is kicking my butt on this templating stuff.

But this definitely keeps me moving forward so much appreciated!