Setting attributes from dynamic JSON/Rest?

How can I bring this JSON data from an API into an entity? The datetime in the JSON array is dynamic/relative. (Last 7 days of rainfall history). I know I can reference the first value by value_json[‘days’][0], but how can I wildcard this?

I’m fine with all these dumped into a attributes of a state. Ideally, with the attribute name the date, and the attribute value the amount.

Example JSON Response:

{
  "queryCost": 8,
  "latitude": 41.886456,
  "longitude": -87.62325,
  "resolvedAddress": "60601, USA",
  "address": "60601",
  "timezone": "America/Chicago",
  "tzoffset": -5,
  "days": [
    {
      "datetime": "2024-03-30",
      "precip": 0.447
    },
    {
      "datetime": "2024-03-31",
      "precip": 0.179
    },
    {
      "datetime": "2024-04-01",
      "precip": 0.553
    },
    {
      "datetime": "2024-04-02",
      "precip": 0.259
    },
    {
      "datetime": "2024-04-03",
      "precip": 0.248
    },
    {
      "datetime": "2024-04-04",
      "precip": 0.059
    },
    {
      "datetime": "2024-04-05",
      "precip": 0
    },
    {
      "datetime": "2024-04-06",
      "precip": 0
    }
  ]
}

I’ve been playing around with this, obviously doesn’t work.

  - platform: rest
    name: VisualCrossingPrecipHistory
    device_class: precipitation
    unique_id: 'VisualCrossingPrecipHistory'
    scan_interval:
      minutes: 360
    resource_template: "https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/XXXXX/last7days?unitGroup=us&elements=datetime%2Cprecip&include=days&key=XXXXXXXXXXXX&contentType=json"
    value_template: "{{ value_json }}"
    json_attributes_path: "$.['days']"
    json_attributes:
        - datetime
        - precip

You’ll need to make a template sensor from that. If you update the rest sensor to pull in days:

  - platform: rest
    name: VisualCrossingPrecipHistory
    device_class: precipitation
    unique_id: 'VisualCrossingPrecipHistory'
    scan_interval:
      minutes: 360
    resource_template: "https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/XXXXX/last7days?unitGroup=us&elements=datetime%2Cprecip&include=days&key=XXXXXXXXXXXX&contentType=json"
    value_template: "{{ value_json }}"
    json_attributes_path: "$"
    json_attributes:
        - days

Then create a template sensor like this:

template:
  - sensor:
      - name: "Precipitation history"
        state: "{{ now() }}"
        attributes:
          forecast: >
            {% set ns = namespace(out={}) %}
            {% for i in state_attr('sensor.visualcrossingpreciphistory','days') %}
              {% set ns.out = dict(ns.out, **{i['datetime']:i['precip']}) %}
            {% endfor %}
            {{ ns.out }}

If you wanted to try it out first in Developer Tools / Template:

{% set value_json = {"queryCost":8,"latitude":41.886456,"longitude":-87.62325,"resolvedAddress":"60601, USA","address":"60601","timezone":"America/Chicago","tzoffset":-5,"days":[{"datetime":"2024-03-30","precip":0.447},{"datetime":"2024-03-31","precip":0.179},{"datetime":"2024-04-01","precip":0.553},{"datetime":"2024-04-02","precip":0.259},{"datetime":"2024-04-03","precip":0.248},{"datetime":"2024-04-04","precip":0.059},{"datetime":"2024-04-05","precip":0},{"datetime":"2024-04-06","precip":0}]} %}
{% set ns = namespace(out={}) %}
{% for i in value_json['days'] %}
  {% set ns.out = dict(ns.out, **{i['datetime']:i['precip']}) %}
{% endfor %}
{{ ns.out }}

WOW, this is excellent info! I would have never been able to able to come up with this (And I’ve been in IT for 20 years).
THANK YOU!

So, we’re close, but no cigar. DM me if you want the real API URL with the functioning API key.

Errors in logs:
ValueError: could not convert string to float: “{‘queryCost’: 8, ‘latitude’: 44.902414, ‘longitude’: -93.29012, ‘resolvedAddress’: ‘60601, USA’, ‘address’: ‘60601’, ‘timezone’: ‘America/Chicago’, ‘tzoffset’: -5.0, ‘days’: [{‘datetime’: ‘2024-03-31’, ‘precip’: 0.0}, {‘datetime’: ‘2024-04-01’, ‘precip’: 0.0}, {‘datetime’: ‘2024-04-02’, ‘precip’: 0.064}, {‘datetime’: ‘2024-04-03’, ‘precip’: 0.01}, {‘datetime’: ‘2024-04-04’, ‘precip’: 0.0}, {‘datetime’: ‘2024-04-05’, ‘precip’: 0.0}, {‘datetime’: ‘2024-04-06’, ‘precip’: 0.0}, {‘datetime’: ‘2024-04-07’, ‘precip’: 0.442}]}”

ValueError: Sensor sensor.visual_crossing_precip_history has device class ‘precipitation’, state class ‘None’ unit ‘None’ and suggested precision ‘None’ thus indicating it has a numeric value; however, it has the non-numeric value: ‘{‘queryCost’: 8, ‘latitude’: 44.902414, ‘longitude’: -93.29012, ‘resolvedAddress’: ‘60601, USA’, ‘address’: ‘60601’, ‘timezone’: ‘America/Chicago’, ‘tzoffset’: -5.0, ‘days’: [{‘datetime’: ‘2024-03-31’, ‘precip’: 0.0}, {‘datetime’: ‘2024-04-01’, ‘precip’: 0.0}, {‘datetime’: ‘2024-04-02’, ‘precip’: 0.064}, {‘datetime’: ‘2024-04-03’, ‘precip’: 0.01}, {‘datetime’: ‘2024-04-04’, ‘precip’: 0.0}, {‘datetime’: ‘2024-04-05’, ‘precip’: 0.0}, {‘datetime’: ‘2024-04-06’, ‘precip’: 0.0}, {‘datetime’: ‘2024-04-07’, ‘precip’: 0.442}]}’ (<class ‘str’>)

Ah yes. Remove the device_class line from the rest sensor and change its value_template to the same as the template sensor’s state.

Even closer… I’m now getting values in the sensor, but kind of gibberish.
I’m putting my real API key in the URL if you, or anyone else wishes to test.
I’ll just change the key later.

  - platform: rest
    name: "visualcrossingpreciphistory"
    unique_id: 'visualcrossingpreciphistory'
    scan_interval:
      minutes: 360
    resource_template: "https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/55419/last7days?unitGroup=us&elements=datetime%2Cprecip&include=days&key=95KUJDA7MGDA3X99CQKRM2DD8&contentType=json"
    value_template: "{{ now() }}"
    json_attributes_path: "$"
    json_attributes:
        - days
template:
  - sensor:
      - name: "Precipitation history"
        value_template: "{{ now() }}"
        attributes:
          forecast: >
            {% set ns = namespace(out={}) %}
            {% for i in state_attr('sensor.visualcrossingpreciphistory','days') %}
              {% set ns.out = dict(ns.out, **{i['datetime']:i['precip']}) %}
            {% endfor %}
            {{ ns.out }}

(Ignore the ‘b’ at the end of the sensorName in the screenshot. I’ve been testing a few different options, to no avail)

EDIT: Just noticed this in the logs:
Invalid config for ‘template’ at configuration.yaml, line 163: required key ‘state’ not provided Invalid config for ‘template’ at configuration.yaml, line 164: ‘value_template’ is an invalid option for ‘template’, check: sensor->0->value_template

Here is line 163 and 164:

161: template:
162: - sensor:
163: - name: “Precipitation history”
164: value_template: “{{ now() }}”

Sorry, my mistake above. Modern-format template sensors use state not value_template. I’ve corrected my prior posts.

It should remain as value_template in the rest sensor, though — that is correct.