home-assistant / core

:house_with_garden: Open source home automation that puts local control and privacy first.
https://www.home-assistant.io
Apache License 2.0
72.41k stars 30.3k forks source link

Problem with MQTT sensor JSON parsing in transition from 'json_attributes:' to 'json_attributes_template' : WARNING (MainThread) [homeassistant.components.mqtt] JSON result was not a dictionary #35402

Closed deepcoder closed 4 years ago

deepcoder commented 4 years ago

Problem with MQTT sensor JSON parsing in transition from 'json_attributes:' to 'json_attributes_template'

Not able to get 'json_attributes_template:' to extract subset of attributes in JSON string referenced by 'json_attributes_topic:'

Throws this warning and no attributes are added to the MQTT sensor:

'WARNING (MainThread) [homeassistant.components.mqtt] JSON result was not a dictionary'

JSON string that is being parsed:

b'{"timestamp":"20200509001056", "mac-address":"3F:46:0D:90:F0:14","rssi":-81, "temperature":90.4, "humidity":47.5, "battery":100, "sensor-name":"Govee_H5052_F014"}'

see example yaml from sensor section of configuration below.

0.109.6 in docker container running on raspberry pi 3 example_mqtt_sensors

Problem-relevant configuration.yaml

# problem syntax, throws above warning and does not produce any attribute for sensor
  - platform: mqtt
    name: 'Backyard Govee Humidity'
    state_topic: 'homeassistant/sensor/govee/3F:46:0D:90:F0:14'
    value_template: '{{ value_json.humidity }}'
    unit_of_measurement: '%'
    json_attributes_topic: 'homeassistant/sensor/govee/3F:46:0D:90:F0:14'
    json_attributes_template: '{{ value_json.battery }}'

# works fine, if you do not specify 'json_attributes_template:', but returns all members of the mqtt dictionary shown above

  - platform: mqtt
    name: "Backyard Govee Temperature"
    state_topic: "homeassistant/sensor/govee/3F:46:0D:90:F0:14"
    value_template: "{{ value_json.temperature }}"
    unit_of_measurement: "°F"
    json_attributes_topic: "homeassistant/sensor/govee/3F:46:0D:90:F0:14"

In the example for 'JSON ATTRIBUTES TEMPLATE CONFIGURATION' in 'MQTT Sensor' documentation, you show only an example with dictionary in a dictionary

https://www.home-assistant.io/integrations/sensor.mqtt/#json-attributes-template-configuration

In the documentation/example referenced by 'json_attributes_template:' documentation,
https://www.home-assistant.io/docs/configuration/templating/#processing-incoming-data

it is shown that a simple single level, non-nested JSON string should parse correctly with the 'value_json.<attribute>' syntax

Traceback/Error logs

 (MainThread) [homeassistant.components.mqtt] Received message on homeassistant/sensor/govee/3F:46:0D:90:F0:14: b'{"timestamp":"20200509001056", "mac-address":"3F:46:0D:90:F0:14","rssi":-81, "temperature":90.4, "humidity":47.5, "battery":100, "sensor-name":"Govee_H5052_F014"}'

WARNING (MainThread) [homeassistant.components.mqtt] JSON result was not a dictionary

Additional information

probot-home-assistant[bot] commented 4 years ago

Hey there @home-assistant/core, @emontnemery, mind taking a look at this issue as its been labeled with a integration (mqtt) you are listed as a codeowner for? Thanks! (message by CodeOwnersMention)

emontnemery commented 4 years ago

As explained in the docs, https://www.home-assistant.io/integrations/sensor.mqtt/#json_attributes_topic, the attributes must be a valid json dictionary.

If you want to extract only battery level as an attribute, use a template like this: json_attributes_template: '{{ {"battery": value_json.battery } | tojson }}'

deepcoder commented 4 years ago

Thank you very much for the correct syntax example! The syntax examples cited in the documentation did not work for me, for example : "{{ value_json.batt }}" of the 'GET BATTERY LEVEL' example at https://www.home-assistant.io/integrations/sensor.mqtt/#json_attributes_topic . The format of the mqtt message in this example was very similar to my message, with no multi level hierarchy.

The Jinja syntax seems to be an ART and science!!

Again thank you very much for your answer and work!!!!

emontnemery commented 4 years ago

The documentation is maybe confusing, the "GET BATTERY LEVEL" example is about using the battery level as the sensor state, not as an attribute. Maybe that chapter should instead be called "Using JSON dict key as sensor state" or something like that?

Please help by reviewing this update of the configuration: home-assistant/home-assistant.io/pull/13382