[SOLVED] How to use json_attributes? (e.g. MQTT Sensor)

Hey all,

I am hoping to get a sonoff switch mqtt ‘state’ payload into a sensor that can be used.
This page should be the reference I need: https://home-assistant.io/components/sensor.mqtt/

But for those of us wishing to retrieve a number of attributes from the payload, all we get is this non-useful descrtiption:

  • json_attributes
    (list | string)A list of keys to extract values from a JSON dictionary payload and then set as sensor attributes.

I have failed to find a single example of how to use this - and my trial and error has been 100 % error :slight_smile: These features really need examples somewhere, don’t they? Is there another documentation resource that I am unaware of?

Anyway, the specifics - can anyone please explain how this should look?

Payload:
{"Time":"2018-01-26T03:05:54","Uptime":1,"Vcc":3.461,"POWER":"OFF","Wifi":{"AP":1,"SSId":"Geogaddi","RSSI":100,"APMac":"00:11:32:45:90:1F"}}

Attempt 1:

  - platform: mqtt
    name: "Bedroom Light"
    state_topic: "tele/sonoff/STATE"
    value_template: '{{ value_json.POWER }}'
    json_attributes: 
      - Time
      - Uptime
      - POWER
      - Vcc

Attempt 2:

  - platform: mqtt
    name: "Bedroom Light"
    state_topic: "tele/sonoff/STATE"
    value_template: '{{ value.POWER }}'
    json_attributes: 
      time: '{{ value.Time }}'
      uptime: '{{ value.Uptime }}'
      Power: '{{ value.POWER }}'
      vcc: '{{ value.Vcc }}'

See if this helps:
https://community.home-assistant.io/t/sonoff-pow/40672/17

1 Like

Thanks mate - yeah I think I will give up on getting the ‘json _attributes’ thing working for now…

A light doesn’t have those options, try making a sensor out of it. The post above really have everything very detailed

Thanks Sthope - yes it is all I need in this specific case, to operate a light, and the link is useful.

But the Tasmota firmware does put out the payload I added, with the extra detail. In this case it would be useful to see if the VCC value started creeping - I bought and flashed a number of Sonoff devices from Aliexpress; these things are very cheap and (for all I know) a potential fire risk, if quality control wasn’t highest priority.

I would also greatly benefit from a sensor that collects all MQTT variables in other use-cases as well - but I cannot get the ‘json_attributes’ feature to work… hence the post.

Have you tried the first example with {{ value_json }} instead?

Hi - I gave up on the json_attributes feature.

This worked fine for grabbing the whole payload, so I just used this:

  - platform: mqtt
    name: "mqttjsontest"
    state_topic: "tele/bedlight/STATE"
    value_template: '{{ value_json }}'

I’m having the exact same issue with a MQTT sensor. I’ve attempted all of the permutations of ways to list the attributes within the json_attributes list, but the component will not parse them. My yaml for the component looks like:

- platform: mqtt
  name: playroom motion
  state_topic: 'home/downstairs/playroom/sensor/motion'
  value_template: '{{ value_json.status }}'
  payload_on: "MOTION"
  payload_off: "NO MOTION"
  device_class: motion
  json_attributes:
    noise
    event_id
    height
    width
    x
    y
    pixels
    status

with a typical json payload of

{"status": "MOTION", "noise": "21", "event_id": "149", "height": "752", "width": "876", "x": "402", "y": "376", "cam_id": "1", "pixels": "8862"}

The value_template is parsing the json just fine, so I’m confident it is formatted correctly…it just seems to totally ignore json_attributes aspect. Unfortunately I can’t just dump the entire structure into the value_template

Hey there - maybe I can help, with what I eventually found worked - to my surprise it did not require a “state” variable:

sensor:
  - platform: mqtt
    name: "mqttjsontest"
    state_topic: "tele/bedlight/STATE"
    value_template: '{{ value_json }}'

…and this is how it looks, within the ‘states’ view of HASS (a Tasmota switch):

sensor.mqttjsontest
{'Time': '2018-02-11T04:51:01', 'Uptime': 12, 'Vcc': 3.46, 'POWER': 'OFF', 'Wifi': {'AP': 1, 'SSId': 'Geogaddi', 'RSSI': 82, 'APMac': '00:11:32:45:90:1F'}}
friendly_name: mqttjsontest

Okay…it looks like part of my issue is that I’m using a binary sensor instead of a sensor (which makes sense).

I just did it your way and now the status of the sensor is the json string, instead of it being parsed out as attributes. Not exactly what I was trying to acheive

Yes but I assumed (not fully tested yet) that any automation trigger or condition etc. could simply consist of a template that extracts the variable you wish to use. I’ll have a go soon and test that assumption.

OK I think JSON is handled a bit differently in templating.
entering {{ states.sensor.mqttjsontest }} yields:
<template state sensor.mqttjsontest={'Time': '2018-02-11T07:41:02', 'Uptime': 15, 'Vcc': 3.463, 'POWER': 'ON', 'Wifi': {'AP': 1, 'SSId': 'Geogaddi', 'RSSI': 84, 'APMac': '00:11:32:45:90:1F'}}; friendly_name=mqttjsontest @ 2018-02-11T19:41:02.459049+13:00>

I am trying to find the way to properly treat the sensor output as JSON.

I found that within a template string you can do this: {% set value_json=states(‘sensor.mqttjsontest’) %}. After that, value_json looks like a proper json object. But I cannot figure out how to use that object.

This is much much harder than it needs to be!

Yea… it seems like the json parsing in this component is legitimately broken and needs to be patched

A worked example would be great, showing how to use “json_attributes”.
The code is here: https://github.com/home-assistant/home-assistant/pull/11439/files
But I can’t make sense of it.

Here’s an example …

in sensors.yaml (it’s not a binary sensor really :stuck_out_tongue: )
My xiaomi Cube’s data for a rotate event is sent via statestream from my pi to my pc
this is the statestream mqtt topic
#homeassistant/binary_sensor/cube_158d000117d706/event
This is the data that comes with it

#{“event_type”:“rotate”, “value”:"-23.5"}
So this is how I extract said data

- platform: mqtt
  name: hassio_cube_158d000117d706_event
  state_topic: 'homeassistant/binary_sensor/cube_158d000117d706/event'
  qos: 1
  json_attributes: 
    - event_type
    - value

This is the output in the dev tool state table

To extract them …

{{ states.sensor.hassio_cube_158d000117d706_event.attributes.event_type }}
{{ states.sensor.hassio_cube_158d000117d706_event.attributes.value | float }}
3 Likes

Very nice, I understand now the benefit, by being able to combine many attribute variables to one sensor, then pull then out as needed.

Do you know if attribute states change can be used to drive events?

You would have to ask a Dev about that :slight_smile:

I am sure they could, using a template in the automation trigger. In Keith’s example, the template to use would be like {{ states.sensor.hassio_cube_158d000117d706_event.attributes.value | float }}

Below is an example from https://home-assistant.io/docs/automation/trigger/

automation:
  trigger:
    platform: numeric_state
    entity_id: sensor.temperature
    # Optional
    value_template: '{{ state.attributes.battery }}'
    # At least one of the following required
    above: 17
    below: 25

Why not just create multiple MQTT template sensors? I’m doing something like this (from a package definition). Sorry for the YAML anchor stuff which might make this a little obfuscated, but I think you’ll get the idea.

Simply, I define a bunch of different sensors. Each happens to subscribe to the same topic, and each selects a different part of the JSON payload. One advantage of this is that you don’t need to worry about attribute changes kicking off a state-change or not. Since each sensor is unique with only a single value, you can reliably use it in an automation based on the state being updated.

################################################################
## Package / ws1400 weather sensors
################################################################

################################################
## Customize
################################################

homeassistant:
  customize:
    ################################################
    ## Node Anchors
    ################################################

    package.node_anchors:
      customize: &customize
        package: 'ws1400'

      ################################################
      ## ws1400 MQTT sensor customization
      ################################################
      ws1400cfg: &ws1400cfg
        platform: mqtt
        state_topic: 19916/dev/ws1400-0


################################################
## sensor
################################################

# MQTT messages from WS1400IP weather station shim look like this:
#
# {"AbsPress": 28.99, "CurrTime": "01:51 05/05/2017", "IndoorID": "0x40", "Outdoor1ID": "0x5d", "RelPress": 30.07, "avgwind": 0.0, "gustspeed": 0.0, "inBattSta": "Normal", "inHumi": 44.0, "inTemp": 72.7, "outBattSta1": "Normal", "outHumi": 99.0, "outTemp": 50.2, "rainofdaily": 0.0, "rainofhourly": 0.0, "rainofmonthly": 0.0, "rainofweekly": 0.0, "rainofyearly": 0.87, "solarrad": 0.0, "time": "2017-05-05 05:51:18", "timestamp": 1493963478.24681, "windir": 214.0}]

sensor:
  - name: 'WX Pressure'
    value_template: '{{ value_json.RelPress }}'
    unit_of_measurement: 'in'
    <<: *ws1400cfg

  - name: 'WX Indoor Humidity'
    value_template: '{{ value_json.inHumi }}'
    unit_of_measurement: '%'
    <<: *ws1400cfg

  - name: 'WX Indoor Temp'
    value_template: '{{ value_json.inTemp }}'
    unit_of_measurement: 'F'
    <<: *ws1400cfg

  - name: 'WX Outdoor Humidity'
    value_template: '{{ value_json.outHumi }}'
    unit_of_measurement: '%'
    <<: *ws1400cfg

  - name: 'WX Outdoor Temp'
    value_template: '{{ value_json.outTemp }}'
    unit_of_measurement: 'F'
    <<: *ws1400cfg

  - name: 'WX Solar Radiation'
    value_template: '{{ value_json.solarrad }}'
    <<: *ws1400cfg

  - name: 'WX Indoor Battery'
    value_template: '{{ value_json.inBattSta }}'
    <<: *ws1400cfg

  - name: 'WX Outdoor Battery'
    value_template: '{{ value_json.outBattSta1 }}'
    <<: *ws1400cfg

Well - initially I couldn’t get much sense from the sensor at all - even now, I suspect the format is bung (the JSON is hidden within a string). I gave up on it for now to be honest.

But also; if you could define a single sensor for each object, instead of 5 or 6 - then I think things would be a lot tidier. It’s fine if you only have several such devices, but I intend to have up to 15 of these things. In that scenario, 75 sensors might be excessive :slight_smile: