Json_attributes with no parent key

I’m trying to set up a REST Sensor where I read the attributes from a JSON page - where there is a parent key name it’s easy - e.g. messages[0].totaldiskspace but I’m stumped with this feed:-

[
{"busService":"4","destinationName":"City, Cornerhouse T7","departureType":"estimated","time":"2018-05-18T12:50:51+01:00","minutes":"3.70","atcoCode":"3390G1","originName":"City, S Sherwood St G1","commonName":"City, S Sherwood St G1"},
{"busService":"4","destinationName":"City, Cornerhouse T7","departureType":"estimated","time":"2018-05-18T12:54:25+01:00","minutes":"7.27","atcoCode":"3390G1","originName":"City, S Sherwood St G1","commonName":"City, S Sherwood St G1"}
]

The YAML below doesn’t get any attributes, and the “obvious” [0].busService is syntactically incorrect so you can’t use that (I’ve tried the Bus Service attributes in all three methods listed below, but one at a time)

sensor bus_stop:
  - platform: rest
    name: Live Bus
    scan_interval: 90
    json_attributes:
      - '{{ value_json[0].busService }}'
      - value_json[0].busService
      - busService
      - destinationName
      - departureType
      - time
    resource: https://example.com/rest.json
    value_template: '{{ value_json[0].minutes }}'
    unit_of_measurement: "Mins"

How does one access array element [0] when there isn’t a parent Key Name?

(The Value Template is working as expected).

That is syntactically correct. That’s aloud. Are you getting an error when you try to extract the data?

When getting items out of a list that contains dictionaries, you have 2 ways of doing that:

If it’s a list of json objects, then both of these methods should work:

value_json[0].busService
value_json[0]['busService']

if it’s a list of dictionaries, then only the following will work

value_json[0]['busService']

Accessing any item in an array is exactly how you listed it above [0]. So in your example, there has to be a top level object. It’s going to be spelled out in the documentation, I would guess value_json or value. So assuming that value_json[0] gets you the list, then value_json[0][0].busService would get you the first item in the list. But… I’ve heard that the REST components that sniff json websites does not support a top level list object. I don’t know if that’s true because I’ve never tried it myself, nor have I debugged into the component. This is just what I’ve read when cruising the forums recently.

Using the template page under Developer tools is normally the easiest way to check these things out. value_json[0].busService certainly seems to work

Imitate available variables:
{% set my_test_json = [
{"busService":"4","destinationName":"City, Cornerhouse T7","departureType":"estimated","time":"2018-05-18T12:50:51+01:00","minutes":"3.70","atcoCode":"3390G1","originName":"City, S Sherwood St G1","commonName":"City, S Sherwood St G1"},
{"busService":"4","destinationName":"City, Cornerhouse T7","departureType":"estimated","time":"2018-05-18T12:54:25+01:00","minutes":"7.27","atcoCode":"3390G1","originName":"City, S Sherwood St G1","commonName":"City, S Sherwood St G1"}
]
 %}

The temperature is {{ my_test_json[0].busService }} 

results in

Imitate available variables:


The temperature is 4

[0].busService as a ````json_attribute``` results in:-

Error loading /home/pi/.homeassistant/configuration.yaml: while parsing a block collection
  in "/home/pi/.homeassistant/configuration.yaml", line 826, column 7
expected <block end>, but found '<scalar>'
  in "/home/pi/.homeassistant/configuration.yaml", line 826, column 12

value_json[0].busService results in no errors but also no attributes (which makes sense as there is no parent key called value_json.

When used as
value_template: '{{ value_json[0].busService}}'
It’s extracted correctly (but then the minutes is lost)

So the issue is the inability to add a prefix, as far as I can see, on the attributes :frowning:

I’ve heard that the REST components that sniff json websites does not support a top level list object.

Seems to work fine for the primary value (e.g. the value_template) just not the attributes.

I understand your problem now. The json_attributes documentation does say

A list of keys to extract values from a JSON dictionary result

So to expect it to handle an array of dictionaries is a step too far.

You probably need to store the result of the call in this sensor, and then define a couple of template sensors to extract the information you actually want.

Sorry, not seen this reply come through for some reason.

That’s exactly what I’m trying to do! Just can’t seem to store it as attributes to allow the template sensors to read it

Changing the value template to be ‘{{ value_json[0] }}’ sets the state to the json string

e.g. {"busService":"4","destinationName":"City, Cornerhouse T7","departureType":"estimated","time":"2018-05-18T12:50:51+01:00","minutes":"3.70","atcoCode":"3390G1","originName":"City, S Sherwood St G1","commonName":"City, S Sherwood St G1"},

But that doesn’t seem readable

{{ states.sensor.live_bus.state }}
returns a the json string
{{ states.sensor.live_bus.state.busService }} returns blank

if {{ states.sensor.live_bus.state }} returns a json object, try {{ states.sensor.live_bus.state[‘busService’] }}

if {{ states.sensor.live_bus.state }} returns a string, you can do a search through the string for bus service and pull out the value until the next comma. Would be a shit implementation but it should work.

Guessing it must be a string as that doesn’t appear to work, the following is shown on the dev-template page

<template state sensor.live_bus={'commonName': 'Bus Stop Name', 'originName': 'Bus Terminus Name', 'time': '2018-06-15T20:43:00+01:00', 'destinationName': 'City', 'departureType': 'estimated', 'busService': '1', 'atcoCode': '3300', 'minutes': '14.32'}; friendly_name=Live Bus, unit_of_measurement=Mins @ 2018-06-15T20:28:42.036925+01:00>

You could toss that state into a mqtt topic and it will convert it to a json object.

Here is how I got it working with json_attributes (one level dictionary only!):

I’m using a command line sensor with curl and then I pipe everything to python and print the first item of the list (watch for the escape quotes in the command)

- platform: command_line
  command: 'curl -sb -H \"https://your_url.com\" | python -c \"import sys, json; print(json.dumps(json.load(sys.stdin)[0]))\"'