Test, if json object exists

Dear community,

I have build a little temperature and humidity sensor with D1mini and Tasmota.
I am using automations and mqtt to set it to deep sleep. This is all working fine.
For more details: Link

I would like to add a sensor, which should indicate, how long the current DeepSleepTime is.

When changing the DeepSleepTime via mqtt, Tasmota sends back a confirmation:

stat/D1mini/Dachzimmer/RESULT -> {"DeepSleepTime":3600}

I can parse this into a sensor with this:

    - name: "Dachzimmer DeepSleepTime"
      unique_id: "mqtt.Dachzimmer.DeepSleepTime"
      state_topic: "stat/D1mini/Dachzimmer/RESULT"
      value_template: '{{value_json.DeepSleepTime | timestamp_custom("%H:%M", False, "unavailable") }}'
      device_class: "duration"

Unfortunately, Tasmota then sends the timestamp of the next wakeup via the same topic:

stat/D1mini/Dachzimmer/RESULT -> {"DeepSleep":{"Time":"2023-01-09T24:00:00","Epoch":1673301600}}

As there is no “DeepSleepTime”-object in the second json, my above sensor throws an error.

I am looking for a way to have something like a trigger-based sensor, which only updates, if the json-object “DeepSleepTime” exists. How do I check this in a template?

There has been something interesting by @petro, but it does not work - or I do not understand it. :man_shrugging:

I just stumbled across regex im HomeAssistant :star_struck: I will try something with this. Update to follow.

    - name: "Dachzimmer DeepSleepTime"
      unique_id: "mqtt.Dachzimmer.DeepSleepTime"
      state_topic: "stat/D1mini/Dachzimmer/RESULT"
      value_template: >
        {{ value_json.DeepSleepTime | timestamp_custom("%H:%M", False, "unavailable") if value_json.DeepSleepTime is defined else this.state }}
      device_class: "duration"
  • If value_json.DeepSleepTime is defined then it displays the received time in the specified format.
  • If value_json.DeepSleepTime is not defined then it displays the sensor’s current value (this.state).

@123
Thank you very much for your quick help. I played around with “is defined”, but got always the error, that the attribute “DeepSleepTime” is not defined, or something like this.

I will test your template tomorrow evening[*] and report back, but I am confident that it will work.

As I do love regex, here the template, I came up with just a minute ago in the dev tools.

{% if ( value_json | regex_search('DeepSleepTime') )  %}
  {{ value_json.DeepSleepTime | timestamp_custom("%H:%M", False, "error in mqtt value")  }}
{% else %}
  {{ states( 'sensor.dachzimmer_deepsleeptime' ) }}
{% endif %}

I could probably change it to this?

    - name: "Dachzimmer DeepSleepTime"
      unique_id: "mqtt.Dachzimmer.DeepSleepTime"
      state_topic: "stat/D1mini/Dachzimmer/RESULT"
      value_template: >
        {% if ( value_json | regex_search('DeepSleepTime') )  %}
          {{ value_json.DeepSleepTime | timestamp_custom("%H:%M", False, "error in mqtt value")  }}
        {% else %}
          {{ this.state }}
        {% endif %}
      device_class: "duration"

[*] I look myself out of the backend via firewall, so that I get to bed before midnight… :innocent:

The example I posted should work. You can test it in the Template Editor using the following example:

{% set value_json = { 'foo': 5000 } %}
{{ value_json.DeepSleepTime is defined }}
{{ value_json | regex_search('DeepSleepTime') }}
---
{% set value_json = { 'DeepSleepTime': 5000 } %}
{{ value_json.DeepSleepTime is defined }}
{{ value_json | regex_search('DeepSleepTime') }}
1 Like

Hi @123,

I just included your template and it works perfectly fine. Thank you very much for your quick help.

Take care,
Chris

1 Like

Hi @123,

I am still struggling with my sensor.
The mqtt provides this:

{"DeepSleepTime":300}
{"DeepSleepTime":900}
{"DeepSleepTime":3600}

I am currently using this template:

    - name: "Wohnzimmer DeepSleepTime"
      unique_id: "mqtt.Wohnzimmer.DeepSleepTime"
      state_topic: "stat/D1mini/Wohnzimmer/RESULT"
      value_template: >
        {{ value_json.DeepSleepTime | timestamp_custom("%H:%M", False, "unavailable") if value_json.DeepSleepTime is defined else this.state }}
      device_class: "duration"
      unit_of_measurement: "h"

As soon, as the DeepSleepTime is 3600s → I get “01:00”. If it is one of the others, I get “0”. This comes probably from the UoM. (I added the UoM because the log was complaining about the missing configuration for the “duration”…)

Could I change the template to show something like this:

5 min
15 min
1 hour (or if easier: 60min)

thanks,
Chris

p.s.: where do I find the documentation for all that time-related stuff? I search on the homeassistant documentation, I search for jinja2, … but I couldn’t find anything helpful…)
ok, I found the “duration”: Sensor - Home Assistant

If you specify the unit of measurement to be “h” then the result produced by value_template must be a float or int (i.e. numeric). You can’t have the template report 00:30 if you are using h as the unit of measurement. In other words, if the value of DeepSleepTime is 1800 then the template should report 0.5 (half an hour).


If you want it to report the time as text that includes “min” and “hour” then I don’t believe you can set the sensor’s device_class to be ‘duration’ or specify a unit of measurement.

If you remove device_class and unit_of_measurement, you can try this and see if it meets your needs:

value_template:
  {{ relative_time(now() - timedelta(seconds = value_json.DeepSleepTime)) }}
1 Like

Hi @123 ,

thank you very much for your help.
This is my new sensor:

    - name: "Wohnzimmer DeepSleepTime"
      unique_id: "mqtt.Wohnzimmer.DeepSleepTime"
      state_topic: "stat/D1mini/Wohnzimmer/RESULT"
      value_template: >
        {% if value_json.DeepSleepTime is defined %}
          {{ relative_time(now() - timedelta(seconds = value_json.DeepSleepTime  )) }}
        {% else %}
          {{ this.state }}
        {% endif %}

with this result in Dashboard:

Chris