Template variable error: 'value_json' is undefined - mqtt

Now I got:

2023-02-14 14:48:58.831 ERROR (MainThread) [homeassistant.util.logging] Exception in message_received when handling msg on 'neo2/dht22': '{"humidity":26.5,"temperature":21.23}'
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/mqtt/debug_info.py", line 44, in wrapper
    msg_callback(msg)
  File "/usr/src/homeassistant/homeassistant/components/mqtt/sensor.py", line 307, in message_received    _update_state(msg)
  File "/usr/src/homeassistant/homeassistant/components/mqtt/sensor.py", line 267, in _update_state
    payload = self._template(msg.payload, PayloadSentinel.DEFAULT)
  File "/usr/src/homeassistant/homeassistant/components/mqtt/models.py", line 249, in async_render_with_possible_json_value
    rendered_payload = self._value_template.async_render_with_possible_json_value(
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 624, in async_render_with_possible_json_value
    return _render_with_context(self.template, compiled, **variables).strip()
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 1984, in _render_with_context
    return template.render(**kwargs)
  File "/usr/local/lib/python3.10/site-packages/jinja2/environment.py", line 1301, in render
    self.environment.handle_exception()
  File "/usr/local/lib/python3.10/site-packages/jinja2/environment.py", line 936, in handle_exception
    raise rewrite_traceback_stack(source=source)
  File "<template>", line 1, in top-level template code
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 1889, in from_json
    return json_loads(value)
orjson.JSONDecodeError: unexpected content after document: line 1 column 38 (char 37)

So it really miss something in that json string, but I don’t see something wrong.

Bizarre. And that’s using value not value_json as per my prior post?

Yep

mqtt:
  sensor:
    - name: "DHT22 Temperature"
      state_topic: "neo2/dht22"
      unit_of_measurement: "°C"
      value_template: "{{ (value|from_json)['temperature'] }}"

You’re sending a character that you shouldn’t be sending at the end of your response. That’s 37 characters long, your error is indicating it’s failing at the 38th character. The encoding that you’re sending is most likely off, make sure you use ascii or utf-8 or utf-16 and strip all whitespace before dropping it in the topic.

1 Like

Yes, you are right. Now made a minimal test-case from the cpp code to a python mqtt client, that failed in a similar way. Problem was this cpp code, that I made from borrowed code on std::string to char. And that extra byte should apparently NOT be there - weird.

                const auto s = j.dump(); // serialize to std::string
                char msgToPublish[s.length() + 1];
                strcpy(msgToPublish, s.c_str());
                printf("%s", msgToPublish);
                pubmsg.payload = msgToPublish;

But now it works with:

                const auto s = j.dump(); // serialize to std::string
                char msgToPublish[s.length()];
                strcpy(msgToPublish, s.c_str());
                printf("%s", msgToPublish);
                pubmsg.payload = msgToPublish;
2 Likes

This code is very very dangerous. Don’t do that.

char msgToPublish[s.length()]; // <= This is on stack
...
pubmsg.payload = msgToPublish; // <= You are setting the payload pointer to a stack variable that'll be cleared when leaving the function, thus payload will be a dangling pointer  

The former code was better since you need to account for the zero byte in the end, but you need to initialize it. A correct code should have read:

const auto s = j.dump(); // serialize to std::string
pubmsg.payload = strdup(s.c_str()); // Make a copy on heap, including the zero byte end

// Don't forget to free the payload after publishing to avoid memory leak:
free(pubmsg.payload);