MqTT problems with empty json value

I see similar topics have been discussed earlier, but I can’t solve this with that info.

I have a mqtt topic that reset to no info when the value is not calculated by the sender. Then my template throws errors for each update.

I’ve tried various parameters, but with same result.

Error received:

ValueError: Template error: round got invalid input 'None' when rendering template '{% if value_json.value == undefined %}

Template:

      value_template: >
        {% if value_json.value == undefined %}
          ∞
        {% else %}

        {% set seconds = value_json.value | round(0) | int %}
        {% set days = (seconds / 86400) | round(0, 'floor') | int %}
        {% set hours = ((seconds - days * 86400) / 3600) | round(0, 'floor') | int %}
        {% set minutes = ((seconds - hours * 3600) / 60) | round(0, 'floor') | int %}

        {% if 2 > days >= 1 %}
          {{days}} Dag
        {% elif days >= 2 %}
          {{days}} Dager
        {% elif hours > 0 %}
          {{hours}} Timer
        {% elif minutes > 0 %}
          {{minutes}} Minutter
        {% else %}
          ∞
        {% endif %}
        {% endif %}

Any good suggestions?

      value_template: >
        {% if value_json.value is not defined or value_json.value is none %}
          ∞
        {% else %}
           ... etc ...
1 Like

Thanks for the suggestion. It looks promising. I can’t get the broker to publish an empty topic to test it, but I’ll see tomorrow when it again goes empty if my logfile explodes again or not :grin:

Copy-paste the following template into the Template Editor and experiment with it to see how it behaves with different values.

Test 1
{% set value_json = none -%}
{% if value_json.value is not defined or value_json.value is none -%}
  ∞
{% else -%}
  {{ value_json.value }}
{% endif -%}
Test 2
{% set value_json = {'value': none} -%}
{% if value_json.value is not defined or value_json.value is none -%}
  ∞
{% else -%}
  {{ value_json.value }}
{% endif -%}
Test 3
{% set value_json = {'value': 123} -%}
{% if value_json.value is not defined or value_json.value is none -%}
  ∞
{% else -%}
  {{ value_json.value }}
{% endif -%}
1 Like

Nice. Your knowledge is valued.

I tried some similar variants earlier to see if I could get the errors.
Now also with your three. The only way I can get an error is if I completly empty the value field, like this:

{% set value_json =  -%}

Receiving the

TemplateSyntaxError: Expected an expression, got ‘end of statement block’

If i put ’ ’ single marks with empty content, it goes as wanted with no error. Can it be that the topic is completly removed from the sender side when null, and that throws the error? Allthough, I see the topic in mqtt-explorer when it goes blank.

That’s an incomplete expression and is the reason why you got the error message.

This mean an empty string. ''
This means a null object. none

Entering nothing at all to the right of = is invalid.

Which one of the two is best for your application depends on what is being received.

Your original template was invalid because it compared the value of the variable value_json to the value of the (non-existent) variable undefined.

{% if value_json.value == undefined %}

Please post a screenshot of what is displayed in MQTT Explorer.

Exactly. It looks like there is not valid json published when there is no value for that topic.

It’s equal to these. This is not in use, but still published. Looks like mye seconds that is only published when there is no production. This is a off-grid solar from Victron.
Clipboard_03-04-2025_01
It shows as null in mqtt-explorer. But I suspect that is a fix applied there?

The value null seen in that screenshot corresponds to none in a Jinja2 template.

The second test example handles none.

Test 2
{% set value_json = {'value': none} -%}
{% if value_json.value is not defined or value_json.value is none -%}
 ∞
{% else -%}
 {{ value_json.value }}
{% endif -%}

If you’re interested, here’s another version you can test in the Template Editor. Change the value of value_json to see how it behaves.

{% set value_json = {'value': 6178} %}

{% set t = time_since(now() - timedelta(seconds=value_json.value), 2) %}
{{ t.replace('days', 'Dager').replace('day', 'Dag')
  | regex_replace('(hours|hour)', 'Timer')
  | regex_replace('(minutes|minute)', 'Minutter')  }}

It uses the time_since() function. The number 2 you see represents the function’s precision.

From the documentation:

  • time_since(datetime, precision) converts a datetime object into its human-readable time string. The time string can be in seconds, minutes, hours, days, months, and years. precision takes an integer (full number) and indicates the number of units returned. The last unit is rounded. For example: precision = 1 could return “2 years” while precision = 2 could return “1 year 11 months”. This function can also be used as a filter. If the datetime is in the future, returns 0 seconds. A precision of 0 returns all available units, default is 1.
1 Like

Very nice of you. I have no more time today, but will have time to test this tomorrow in real time when the value will disappear again :slight_smile:

Thanks for your help, this solved it. No error today! enjoy the coffee :smiley:

Now I see that I have to exclude it from recorder, it sends very varying and frequent updates when the sun intensity change. Wish that the mqtt sensor could have the same as we have in esphome, update_interval.

1 Like