MQTT sensor: How to access non json payload in value_template?

Hi,

I tried to parse a battery state from the payload, which is NOT json:

from mosquitto_sub verbose output:
robonect/mower/battery/charge 99 %

Like this:

sensor:
  - platform: mqtt
    name: "mymower charge"
    state_topic: "robonect/mower/battery/charge"
    value_template: "{{ value_json | regex_findall_index('\\d+') | int }}"
    unit_of_measurement: "%"

But then the entity value is null and the logs say:

WARNING (MainThread) [homeassistant.helpers.template] Template variable warning: 'value_json' is undefined when rendering '{{ value_json | regex_findall_index('\d+') | int }}'

If I just remove the value_template then the sensor entity shows up with the correct value but as a string and a trailing percent sign.

I tried this in the template editor and it works:

{% set value_json = "99 %" %}
{{ value_json | regex_findall_index('\\d+') | int }}

The documentation does not give any hint about how to access non json payloads.
Or did I miss something?

Thank you!

I found the answer on another forum post:
https://community.home-assistant.io/t/mqtt-value-template/126059

I just had to use value instead of value_json. I couldn’t find it in any home assistant docs though.

If you think the documentation needs updating, there are links at the bottom of each page for giving feedback.

I believe Troon’s link disproves that claim; it’s clearly documented.

BTW, here’s another way to get the value. It uses the space character in the data to serve as a means of splitting it into items of a list. The desired item is the second one in the list (99) which is identified by an index value of 1 because lists are zero-based.

    value_template: "{{ value.split()[1] | int }}"

NOTE
The assumption it makes is that the received format is consistent and the desired value is always the second item in the list. However, if the received data’s format is inconsistent then the technique you used is better.

I think that’s the output from mosquitto including the topic for information, and the actual received data is "99 %", so {{ value.split()[0]|int }} would be needed.

I’m glad, I was wrong! :wink:
Thanks for pointing me in the right direction. I already had the feeling that I had missed something obvious.

The split is nice, too!

Thank you!

If that’s the situation then, yes, your version with an index value of 0, is the way to go.

Using regex_findall_index also works but it doesn’t fail gracefully in the event it doesn’t find a matching value.