Again struggle with templates

Tags: #<Tag:0x00007f78075fe070>

I have two sensors:

The first results in:
{ "timestamp": "2020-03-24T17:00:00+01:00", "value": 369.0, "trend": -1, "stateMnwMhw": "normal", "stateNswHsw": "normal" }
and to extract the value, I use this template sensor:

  - platform: template
    sensors:
      rheinpegel:
        value_template: >
          {% set state = states('sensor.rheinpegel_object') | from_json %}
          {{ state.get('value', 'unknown') | multiply(0.01) }}

The second one results in:
{‘cases’: 32879, ‘deaths’: 140, ‘recovered’: 830, ‘tested’: ‘unknown’}

But with template below that does not work and throws:
Error rendering template: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

What’s different?

  - platform: template
    sensors:
      cases:
        value_template: >
          {% set state = states("sensor.berliner_morgenpost") | from_json %}
          {{ state.get("cases", "nix")  }}

The second dataset is not json. Json requires the values to be in double quotes, not single quotes.

Okay, but is it still possible to get the cases value? How?

AND: When I just open that link, the result is:

{
  "current_totals": {
    "cases": 33416,
    "deaths": 143,
    "recovered": 837,
    "tested": "unknown"
  },
  "meta": {
    "source": "ZEIT ONLINE (aggregated data from individual Landkreise in Germany)",
    "info": "https://github.com/jgehrcke/covid-19-germany-gae",
    "contact": "Dr. Jan-Philip Gehrcke, [email protected]",
    "time_source_last_updated_iso8601": "2020-03-24T18:06:05+01:00",
    "time_source_last_consulted_iso8601": "2020-03-24T19:26:00+01:00"
  }
}

I call that sensor with:

  - platform: rest
    name: Berliner-Morgenpost
    value_template: '{{ value_json.current_totals }}'
    resource: https://covid19-germany.appspot.com/now

Why is the result in HA with single quotes?

It’s single quotes because it’s not json. If you want it as json, add this to your rest template

value_template: '{{ value_json.current_totals | to_json }}'

https://ansible-docs.readthedocs.io/zh/stable-2.0/rst/playbooks_filters.html#filters-for-formatting-data

Or just leave it as is and skip the whole conversions all together.

  - platform: template
    sensors:
      cases:
        value_template: '{{ states("sensor.berrliner_morgenpost").get("cases", "nix") }}'
1 Like

Are you wanting to extract more than just the value of cases? If not, then why not just do this:

  - platform: rest
    name: Berliner-Morgenpost
    value_template: '{{ value_json.current_totals.cases }}'
    resource: https://covid19-germany.appspot.com/now

If you do want to extract more, then:

  - platform: rest
    name: Berliner-Morgenpost
    value_template: '{{ value_json.current_totals.cases }}'
    json_attributes: current_totals
    resource: https://covid19-germany.appspot.com/now

Then:

  - platform: template
    sensors:
      berliner_deaths:
        value_template: "{{ state_attr('sensor.berliner_morgenpost', 'current_totals').deaths }}"
      berliner_recovered:
        value_template: "{{ state_attr('sensor.berliner_morgenpost', 'current_totals').recovered }}"
1 Like

Thanks to @jocnnor and @pnbruckner.
I assume, the second solution is a bit easier, because it does no reformatting with to_json and from_json. And therefore faster .

But when I look at the history, it seems to be not a number?
image

Even not when I pipe it to int:
value_template: "{{ state_attr('sensor.berliner_morgenpost_cases3', 'current_totals').recovered | int }}"

it’s most likely because your sensor lacks unit_of_measurement - check out the description.

2 Likes

If someone is interested. Here is it all together:

  # COVID-19
  # https://github.com/jgehrcke/covid-19-germany-gae/
  # Holen der Fallzahlen von Berliner MOrgenpost und Zeit online.
  - platform: rest
    name: Berliner-Morgenpost-Cases
    scan_interval: 600
    value_template: '{{ value_json.current_totals.cases }}'
    unit_of_measurement: "people"
    json_attributes: current_totals
    resource: https://covid19-germany.appspot.com/now
  - platform: template
    sensors:
      berliner_morgenpost_deaths:
        value_template: "{{ state_attr('sensor.berliner_morgenpost_cases', 'current_totals').deaths }}"
        unit_of_measurement: "people"
      berliner_morgenpost_recovered:
        value_template: "{{ state_attr('sensor.berliner_morgenpost_cases', 'current_totals').recovered }}"
        unit_of_measurement: "people"
      berliner_morgenpost_current:
        value_template: "{{ states('sensor.berliner_morgenpost_cases') | int  -  states('sensor.berliner_morgenpost_recovered')$
        unit_of_measurement: "people"
      berliner_morgenpost_sterberate:
        value_template: "{{ (100 * states('sensor.berliner_morgenpost_deaths') | int / states('sensor.berliner_morgenpost_cases$
        unit_of_measurement: '%'

And here a Lovelace View combining this data with the COVID-19 integration data:

  - panel: true
    path: corona
    theme: ios-light-mode-orange
    title: Corona
    badges: []
    cards:
      - cards:
          - cards:
              - animate: true
                decimals: 0
                entities:
                  - color: green
                    entity: sensor.germany_coronavirus_confirmed
                    name: Bestätigt
                  - color: blue
                    entity: sensor.germany_coronavirus_current
                    name: Aktuell
                  - color: pink
                    entity: sensor.germany_coronavirus_recovered
                    name: Geheilt
                  - color: red
                    entity: sensor.germany_coronavirus_deaths
                    name: Verstorben
                extrema: true
                font_size: 150
                font_size_header: 20
                height: 350
                hour24: true
                hours_to_show: 168
                icon: 'mdi:allergy'
                line_color: '#E53935'
                line_width: 2
                name: Corona Deutschland
                points_per_hour: 0.5
                show:
                  fill: fade
                type: 'custom:mini-graph-card'
              - cards:
                  - type: horizontal-stack
                    cards:
                      - content: '### Johns Hopkins Universität'
                        style: |
                          ha-card {
                            background: rgba(0,250,0,0.5);
                            border-radius: 15px;
                            height: 50px
                            }
                        type: markdown
                      - content: '### Berliner Morgenpost & Zeit online'
                        style: |
                          ha-card {
                            background: rgba(0,250,0,0.5);
                            border-radius: 15px;
                            height: 50px
                            }
                        type: markdown
                  - type: horizontal-stack
                    cards:
                      - entity: sensor.germany_coronavirus_confirmed
                        style: |
                          ha-card {
                            border-radius: 10px;
                            height: 40px
                          }
                        scale: 25px
                        title: Bestätigt
                        type: 'custom:bignumber-card'
                      - entity: sensor.berliner_morgenpost_cases
                        style: |
                          ha-card {
                            border-radius: 10px;
                            height: 40px
                          }
                        scale: 25px
                        title: Bestätigt
                        type: 'custom:bignumber-card'
                  - type: horizontal-stack
                    cards:
                      - entity: sensor.germany_coronavirus_current
                        style: |
                          ha-card {
                            border-radius: 10px;
                            height: 40px
                          }
                        scale: 25px
                        title: Aktuell
                        type: 'custom:bignumber-card'
                      - entity: sensor.berliner_morgenpost_current
                        style: |
                          ha-card {
                            border-radius: 10px;
                            height: 40px
                          }
                        scale: 25px
                        title: Aktuell
                        type: 'custom:bignumber-card'
                  - type: horizontal-stack
                    cards:
                      - entity: sensor.germany_coronavirus_recovered
                        style: |
                          ha-card {
                            border-radius: 10px;
                            height: 40px
                          }
                        scale: 25px
                        title: Geheilt
                        type: 'custom:bignumber-card'
                      - entity: sensor.berliner_morgenpost_recovered
                        style: |
                          ha-card {
                            border-radius: 10px;
                            height: 40px
                          }
                        scale: 25px
                        title: Geheilt
                        type: 'custom:bignumber-card'
                  - type: horizontal-stack
                    cards:
                      - entity: sensor.germany_coronavirus_deaths
                        style: |
                          ha-card {
                            border-radius: 10px;
                            height: 40px
                          }
                        scale: 25px
                        title: Verstorben
                        type: 'custom:bignumber-card'
                      - entity: sensor.berliner_morgenpost_deaths
                        style: |
                          ha-card {
                            border-radius: 10px;
                            height: 40px
                          }
                        scale: 25px
                        title: Verstorben
                        type: 'custom:bignumber-card'
                  - decimals: 3
                    entities:
                      - entity: sensor.sterberate
                        name: JHU
                      - entity: sensor.berliner_morgenpost_sterberate
                        name: MoPo & Zeit online
                    height: 200
                    hour24: true
                    hours_to_show: 168
                    icon: 'mdi:allergy'
                    points_per_hour: 0.5
                    type: 'custom:mini-graph-card'
                type: vertical-stack
            type: horizontal-stack
        type: vertical-stack
1 Like

And one more :wink:
For this data:

[{"deceased":0,"extraction_date":"Wed, 25 Mar 2020 00:00:00 GMT","infected":285,"province":"SK K\u00f6ln"}]

Here I get an array.
If I go analog to the above, with

    value_template: '{{ value_json.0.infected }}'
    unit_of_measurement: "people"
    json_attributes: 0

I see only the value 285.
In the case above without the array, I get the number as state and all values as attributes. And with this the option to extract further values with template sensors. How would I do this with the array?

You should be able to put in your rest sensor:

json_attributes: value_json.0
or
json_attributes: value_json[0]

These are the same…whichever makes more sense for you. I personally like the array syntax to make it clear I’m extracting array value 0…but that’s probably because I’m not used to using json that much.

Tried already…

value_template: '{{ value_json.0 | to_json }}'

“| to_json” to get the result with "…

{"deceased": 149, "extraction_date": "Wed, 25 Mar 2020 00:00:00 GMT", "infected": 31555}

But than, the other attributes still do not work and results in unknown.

value_template: "{{ state_attr('sensor.rki_cases', 0).deceased }}"

You need to update the json_attributes field in the restful sensor. This tells the sensor “add ALL json values in the following template as attributes”

In your current sensor, json_attributes is returning nothing. It will be empty.

    value_template: '{{ value_json.0.infected }}'
    unit_of_measurement: "people"
    json_attributes: 0 # <---- this is returning nothing

Instead make it this:

  - platform: rest
    name: infected
    scan_interval: 600
    # This sensor extracts just the infected value. The rest will be attributes. 
    value_template: '{{ value_json.0.infected}}'
    unit_of_measurement: "people"
    # Put ALL json values in this field as attributes
    json_attributes: "{{ value_json.0 }}"

Now to get the attributes, use them as normal.

state_attr('sensor.infected', 'deceased')
state_attr('sensor.infected', 'extraction_date')

etc

The json_attributes parameter can specify either “root level” properties, or properties of the zeroth-element of a root level array. So you could do this:

json_attributes: deceased, infected, province

Then:

{{ state_attr('sensor.xyz', 'deceased') }}
1 Like

Did not get the attributes following @jocnnor idea…
But with the hints of @pnbruckner it got what I was looking for.

Thanks a lot to both!

And here is my code:

  # Zahlen des RKI aggregiert aus deren Dashboard
  # https://github.com/maxisses/Covid-19API
  - platform: rest
    name: RKI-Cases
    scan_interval: 3600
    resource: https://covid19-germany-api.eu-de.mybluemix.net/get_totals
    value_template: '{{ value_json.0.infected }}'
    unit_of_measurement: "p"
    json_attributes: deceased, infected
  - platform: template
    sensors:
      rki_deaths:
        value_template: "{{ state_attr('sensor.rki_cases', 'deceased') }}"
        unit_of_measurement: "p"
      rki_sterberate:
        value_template: "{{ (100 * states('sensor.rki_deaths') | int / states('sensor.rki_cases') | int) | round(3)}}"
        unit_of_measurement: '%'
1 Like

Yep, I learned something too!

When was 0th added? Or has it always been here?

I don’t understand your question…


Meanwhile the resulting json has changed its format and is no more an array…

I wasn’t asking you, I was asking @pnbruckner

No, it hasn’t always been there. Looks like it was added in PR #28835 and made the 0.103 release.

1 Like