Problem with value_template

I have pyload:
{"TEMP":19.3,"HUM":00,"BAT":"LOW"}
I can’t read temperature using
value_template: "{{ value_json.TEMP }}"
because “HUM”:00. If I manually change HUM!= 00 it’s working correctly. Any Idea how to solve it?

1 Like

Fixing the device that is sending 00 instead of 0 would be the best option.

This device is espRFLinkMQTT Why with “HUM”:0 its working ok, but not with 00? I only need TEMP.

Because 00 is not a number ( 0 is) and needs to be in quotes as it is a string. For valid JSON format strings need to be in quotes. Numbers don’t. Invalid JSON will cause the template with value_json… to not evaluate.

Can you please try:

value_template: "{{ value.TEMP }}"

Not sure if that helps, but if i put this in Dev tools/templates

{% set value = {"TEMP":19.3,"HUM":00,"BAT":"LOW"} %}
{{ value }}

it returns
Auswahl_204

1 Like

It didn’t worked. I will install second container with home assistant for some tests.

But that isn’t a valid test. You’ve just created a dictionary. You didn’t parse the JSON string. @tom_l is correct, that payload is invalid JSON:

>>> json.loads('{"TEMP":19.3,"HUM":00,"BAT":"LOW"}')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.6/json/__init__.py", line 354, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.6/json/decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python3.6/json/decoder.py", line 355, in raw_decode
    obj, end = self.scan_once(s, idx)
json.decoder.JSONDecodeError: Expecting ',' delimiter: line 1 column 21 (char 20)
>>> json.loads('{"TEMP":19.3,"HUM":0,"BAT":"LOW"}')
{'TEMP': 19.3, 'HUM': 0, 'BAT': 'LOW'}

Given that it is considered to be invalid JSON, you can handle it as a string and extract the desired value using a regex pattern.

sensor:
  - platform: mqtt
    name: my_sensor
    state_topic: test/my_sensor
    value_template: '{{ value | regex_findall_index("TEMP\":(-?\d+\.?\d+)") }}'

The regex pattern I’ve used looks for the literal string TEMP: followed by

  • an optional hyphen (indicating a negative value)
  • one or more numbers
  • an optional period (replace it with a comma if that’s what used as a decimal-point indicator for your country)
  • one or more optional numbers (representing the fractional value)
1 Like

Nice! How did you figure out that you can change the output of the regex filter by using parentheses to specify a group? I’ll have to remember that one!!

Thank you for your help. It’s working like a charm.

The parentheses define a ‘capturing group’ which extracts/reports the matching string it finds.

Here’s a screenshot from Regex101.com (a very handy tool for creating, and learning about, regular expressions):

1 Like

Yes, I know regex basics. (Well, at least basic basics. :slight_smile:) I was asking about the regex filter implementation in HA’s Jinja.

EDIT: Ah, interesting. If you specify more than one group the result is a tuple. Very useful to know.

Glad to hear it.

Please mark my post with the Solution tag so other users, facing a similar challenge, can find it easily. Only you, the author of this topic, can mark a post as being the Solution. A checkmark will appear next to the topic’s title (indicating there is a solution) and the solution will automatically appear as a link under your first post.

Sorry, I misunderstood your question. Honestly, I just assumed it was supported (given that it’s a standard part of regular expressions). I checked the history of my posts about it and the first significant one I posted contained a capturing group and an example of how to handle the result if it contains more than one item (i.e. the ‘index’ in regex_findall_index).

1 Like