[Solved] Template sensor to read dynamically nested attribute information

I want to read i.e. precipitation_probability from todays date (or always first set after forecast) fromt the following sensor:

temperature: 30
humidity: 36
pressure: 1019.1
wind_bearing: 224
wind_speed: 9.3
visibility: 42.9
attribution: Data provided by Deutscher Wetterdienst (DWD)
forecast: 
- datetime: '2020-09-15'
  condition: sunny
  temperature: 30.3
  templow: 17
  precipitation: 0
  precipitation_probability: 2

I have some troubles finding the right code for a template sensor to read the probabilty and precipitation from the foreast and can find any documentation for HAss to read from a nested sensor with a dynamic date as the identifier to match. Can someone point me in the right direction? Thanks!

Is the lates forecast always the first entry in the forecast: section?

Then it should work like this:

state_attr('sensor.xyz', 'forecast')[0]['precipitation_probability']

If it is not always the first entry, I donā€™t know of any easy way (I know how to do it in python with AppDaemon) to do this.

1 Like

This should always match todays date (if it exists)

{% set date = now().stftime('%Y-%m-%d') %}
{% set item = state_attr('sensor.xyz', 'forecast') | selectattr('datetime','eq', date) | first %}
{{ item.precipitation_probability if item else 'unknown' }}
1 Like

Cool, whenever I see your solutions, I say to myself ā€œmaybe you should start doing more things with HA than AppDaemonā€.

Iā€™ve been thinking about moving back but Iā€™d need to make some new integrations. Appdaemon is great but I donā€™t know if itā€™s needed anymore. It really depends on the automation I guess.

What do you mean with this? Sorry, I donā€™t understand.

Currently Iā€™m still doing all automations in AppDaemon, however with all the new features (like global variables) that will get introduced in 0.115, I need to rethink this as some of these currently missing features were the reason to use AppDaemon in the first place. However, one of the main uses for AppDaemon for me is to learn Python, in the hope to contribute some code to HA one day.

I have a few appdeamon apps that could be replaced with a built in integration. Iā€™ve just been too lazy to make them. Iā€™ve got one on my list thatā€™s a pretty high up WTH, so I might be doing this pretty soon.

You could probably add stuff now. Itā€™s not that hard and you donā€™t need to know the core that well. The hardest part is knowing how to use the API. If you can learn appdeamon, you can build an integration.

Thanks for the feedback - as it is always the first item on the list this seems easier to me.

Now I have a formatting problem. This code shows the correct value in the Template Editor in Dev Tools:

{{ state_attr('weather.xyz, 'forecast')[0]['temperature'] }}

If I try to use it as a template sensor it does not:

- platform: template
  sensors: 
    DWD_today_max_temp:
      friendly_name: 'DWD Today Max Temp'
      device_class: temperature
      unit_of_measurement: 'Ā°C'
      icon_template: 'mdi:thermometer-high'
      value_template: '{{ state_attr('weather.xyz', 'forecast')[0]['temperature'] }}'

Error Message of HAss File Editor:

can not read an implicit mapping pair; a colon is missed at line 115, column 99:
ā€¦ forecastā€™)[0][ā€˜temperatureā€™] }}ā€™
^

Any ideas why the value_template needs different code than the template editor?

You need double quotes outside the curly brackets, like this:

"{{ state_attr('weather.xyz', 'forecast')[0]['temperature'] }}"
1 Like

Otherwise this happens:

Ahh, thanks to both of you for explaining, works!

I am trying to do something similar but seem to be missing something with the last part. I am trying to make a template sensor with just the ā€œscoreā€ of my image_processing, and numbers only even when no value/attribute is defined so it is a chartable valueā€¦ I cannot figure out how to get just the numeric value.
This is the raw attribute:

{
  "matches": {
    "person": [
      {
        "score": 95.44724,
        "box": [
          0.19603582,
          0.408492,
          0.4463838,
          0.46571591
        ]
      }
    ]
  },
  "summary": {
    "person": 1
  },
  "total_matches": 1,
  "process_time": 0.42949440190568566,
  "friendly_name": "Doods side_yard"
}

I have tried a few variations of this which gets me close but I cannot get it to pull the numeric value for score. I tried [0], [ā€˜scoreā€™] and a few others I found in some similar posts. I am not sure why it doesnā€™t like it, the extra curly braces? :

{{ state_attr('image_processing.doods_side_yard', 'score') }}

which gets me to this:

[{'score': 95.44724, 'box': [0.19603582, 0.408492, 0.4463838, 0.46571591]}]

If anyone has any suggestions it would be appreciatedā€¦

To pull the 95.4 value out of that structure, youā€™d need:

{{ WHATEVER_THAT_JSON_IS_FROM['matches']['person'][0]['score'] }}

You say ā€œthis is the raw attributeā€, but if that is {{ state_attr('image_processing.doods_side_yard', 'score') }} I donā€™t see how youā€™d get the result you pasted.

Sorry That is the result of getting just the attribute with no .matches or .person


{{ states('image_processing.doods_side_yard.attributes ')}}

I see now I left that out as that was one of the multiple variations I triedā€¦ :sweat_smile: it was way past my bedtime

Right. In that case, try:

{{ state_attr('image_processing.doods_side_yard', 'matches')['person'][0]['score'] }}

Note the warning box in this section ā€” always safer to follow its adviceā€¦

Iā€™m also not clear on what you mean by:

Are you saying that the match might be for something other than a person? Itā€™s still solvable if that is the case, but will be a bit more involved. Try this in the template editor, and you can change person for anything else:

{% set j = { "matches": {"person": [
      {
        "score": 95.44724,
        "box": [0.19603582, 0.408492, 0.4463838, 0.46571591]
      }
    ]
  },
  "summary": {
    "person": 1
  },
  "total_matches": 1,
  "process_time": 0.42949440190568566,
  "friendly_name": "Doods side_yard"
}
%}

{% for thing in j['matches'] %}
  {% if 'score' in j['matches'][thing][0] %}
    {{ thing }}: {{ j['matches'][thing][0]['score'] }}
  {% else %}
    0
  {% endif %}
{% endfor %}

If no person is detected the count goes back to zero and this is what I get for that same

{{  states(' image_processing.doods_side_yard.attributes ')}}
unknown

That template wonā€™t ever work. What does this show in the template editor when there is no detection?

{{ state_attr('image_processing.doods_side_yard', 'matches') }}

my apologies i am mixing these up because i was trying to post while getting ready for work and was on mobileā€¦
the result of:

{{ state_attr('image_processing.doods_side_yard', 'matches') }}

with no current person detected is:

{}

Excellent. So this template sensor should give 0 if thereā€™s no detection, or the first non-zero score of however many scores exist:

template:
  - sensor:
      - name: Detection score
        state: >-
          {% set x = state_attr('image_processing.doods_side_yard', 'matches') %}
          {% if not x %}
            0
          {% else %}
            {% set ns = namespace(s=0) %}
            {% for thing in x %}
              {% if 'score' in x[thing][0] and ns.s == 0 %}
                {% set ns.s = x[thing][0]['score'] %}
              {% endif %}
            {% endfor %}
            {{ ns.s }}
          {% endif %}

EDIT: updated in line with @petroā€™s suggestion, which will also then give zero if the sensor doesnā€™t even have a matches attribute.

1 Like

You can just use if x and itā€™ll resolve false if the dictionary is empty, none, zero, etc.

1 Like