MQTT sensor, Filter states to ignore "Null" "None "Unknown"

That would work only for “action” (didn’t know it had its own topic, not documented…)

The other 3 features of interest (action_source-name, action_user and pin_code) do not have a separate topic…

So now back to why I am getting “unknown” states while using

(value_json['action'] is defined

:thinking:

OK lets try this -
as far as I can tell “unknown” happens when something occurs that has not been accounted for, and that is why the state becomes unknown, so let’s do a hacky workaround.

{% set o = states('sensor.doorlock_front_action_z2mtag666') %}
{% if value_json is defined and value_json['action'] is defined and value_json['action'] not in ['','unknown','unavailable','null'] %}
  {{ value_json['action'] }}
{% else %}
  {{ o }}
{% endif %}

I mean I guess it’s worth testing.

Note we are now checking is value_json is defined too, because for template sensors at least, when an error happens trying to render the template, then the state becomes unknown, which makes me wonder if something is being sent that cannot be decoded from JSON and that’s why it’s changing to unknown.

EDIT:
Playing with the template editor again… might have hit on the problem.

{{ json_value['action'] if (value_json['action'] is defined and value_json['action'] is not none and value_json['action'] != "") else states('sensor.doorlock_front_action_z2mtag666') }}

If the JSON is pasted into the template as a dictionary:

{% set j = {"action": null } %}
{{ j.action is defined }} #false
{{ j.action is not none }} #true

{% set j = '{"action": null }'|from_json %}
{{ j.action is defined }} #true
{{ j.action is not none }} #false

So when it is being converted from JSON to a dictionary, that action: null changes from not being defined, to becoming none.

1 Like

damn… “none” still getting through…

image


  - name: "DOORLOCK front action z2mtag1001"  
    unique_id: doorlock_front_action_z2mtag1001
    state_topic: "zigbee2mqtt/DOORLOCK FRONT"  
    value_template: >-
      {% set o = states('sensor.doorlock_front_action_z2mtag1001') %}
      {% if value_json is defined and value_json['action'] is defined and value_json['action'] not in ['','unknown','unavailable','null'] %}
        {{ value_json['action'] }}
      {% else %}
        {{ o }}
      {% endif %}

hold on, just saw your edit… will get back after dinner… thx

1 Like

Bingo.
Thanks! :+1:
This was a tricky one…

Ps: there is a small typo in your template: json_value

1 Like

Urgh I am always doing that!!

So glad that we finally got to the bottom of that!

I’ll edit my post just in case anyone comes across this saga lol

1 Like

Just to improve my skills, why doesn’t my template from post 9 work?

  {% if value_json.action is defined and value_json.action != ""  and value_json.action != "None" and value_json.action != "null" %}
 

In this case, value_json.action would be “null” / undefined so shouldn’t pass the filter?

Or is the null state processed as “something that has not been accounted for” and bypasses the template to become unknown/None.
Therefore needs to be processed as json_value[‘action’] /index, where it is defined (“none”) and can be stripped by filtering “none” state?

Your template tests if:

  1. The action attribute is defined (it is)
  2. If its value is not an empty string (it’s not)
  3. If its value is not a string equal to “None” (it’s not)
  4. If its value is not a string equal to “null” (it’s not)

The action attribute contains no value and that’s represented by null which is not a string.

none is another way to say null so this template checks if the action attribute exists and has a value.

{{ value_json.action is defined and value_json.action is not none }}
1 Like

Does none catch “” too or do we need to test for that.

You would need to test for it because an empty string is not none.

{{ value_json.action is defined and
  value_json.action is not none and
  value_json.action != '' }}
2 Likes

Thanks for the clarifications, so both solutions below tested/working:

  - name: "DOORLOCK front action z2mtag555"  
    unique_id: doorlock_front_action_z2mtag555
    state_topic: "zigbee2mqtt/DOORLOCK FRONT"  
    value_template: >-
      {{ value_json['action'] if (value_json['action'] is defined and value_json['action'] is not none and value_json['action'] != "") else states('sensor.doorlock_front_action_z2mtag555') }}

  - name: "DOORLOCK front action z2mtag333"  
    unique_id: doorlock_front_action_z2mtag333
    state_topic: "zigbee2mqtt/DOORLOCK FRONT"  
    value_template: >-
      {% if value_json.action is defined and value_json.action is not none and value_json.action != ""  %}
        {{ value_json.action }}
      {% else %}
        {{ this.state }}  
      {% endif %}

One takeaway is that “none” state is not a string…

Thanks again for sharing your expertise, much appreciated :+1:

1 Like