Can I use a for loop template to create sensors?

I have a nice set of templated sensors that use hourly weather information to create per-hour precipitation sensors:

# Weather Hourly
  - platform: template
    sensors:
      rain_hourly_0:
        value_template: "{{ state_attr('weather.home_hourly','forecast')[0].precipitation }}"
        friendly_name: 'Rain Forecast Hour 0'
        unit_of_measurement: 'mm'
        attribute_templates:
          time_of_day: "{{ as_timestamp(state_attr('weather.home_hourly','forecast')[0].datetime,0) | timestamp_custom('%-I %p',True,None) }}"
        icon_template: >-
          {% if state_attr('weather.home_hourly','forecast')[0].precipitation|float(default=0) >= 2.0 %}mdi:water
          {% elif state_attr('weather.home_hourly','forecast')[0].precipitation|float(default=0) >= 0.2 %}mdi:water-outline
          {% else %}mdi:water-remove-outline
          {% endif %}
      rain_hourly_1:
        value_template: "{{ state_attr('weather.home_hourly','forecast')[1].precipitation }}"
        friendly_name: 'Rain Forecast Hour 1'
        unit_of_measurement: 'mm'
        attribute_templates:
          time_of_day: "{{ as_timestamp(state_attr('weather.home_hourly','forecast')[1].datetime,0) | timestamp_custom('%-I %p',True,None) }}"
        icon_template: >-
          {% if state_attr('weather.home_hourly','forecast')[1].precipitation|float(default=0) >= 2.0 %}mdi:water
          {% elif state_attr('weather.home_hourly','forecast')[1].precipitation|float(default=0) >= 0.2 %}mdi:water-outline
          {% else %}mdi:water-remove-outline
          {% endif %}

Works fine, except thereā€™s 24 of them obviouslyā€¦ Is there a way to use a loop to create the same sensors? I have working code that produces exactly what I want in the Developer Template:

{% for i in state_attr('weather.home_hourly','forecast') -%}
rain_hourly_{{ loop.index0 }}:
  value_template: {{ i.precipitation|float(default=0) }}
  friendly_name: "Rain Forecast Hour {{ loop.index0 }}"
  unit_of_measurement: 'mm'
  attribute_templates:
    time_of_day: "{{ as_timestamp(i.datetime,default="unknown") | timestamp_custom('%-I %p',True,None) }}"
  icon_template: >-
    {% if i.precipitation|float(default=0) >= 2.0 %}mdi:water
    {% elif i.precipitation|float(default=0) >= 0.2 %}mdi:water-outline
    {% else %}mdi:water-remove-outline
    {% endif %}
{% endfor %}

Iā€™m just stumped as to how I would integrate that into my sensors.yaml file.
I tried inserting it as a block of code but, as expected, the yaml parser in the File Editor doesnā€™t like it:

missed comma between flow collection entries (194:10)

 191 | # Weather Hourly
 192 |   - platform: template
 193 |     sensors:
 194 |         {% for i in state_attr('weather. ...
----------------^
 195 |         rain_hourly_{{ loop.index0 }}:
 196 |           value_template: {{ i.precipita ...

And the Developer YAML ā€œCheck Configurationā€ thing hates it too:

Configuration invalid!
Error loading /config/configuration.yaml: while scanning for the next token
found character '%' that cannot start any token
in "/config/sensors.yaml", line 194, column 8

Is there another way to load such a templated set of sensors?

No.

What you have is a Jinja2 template that generates YAML. The generated YAML can be copy-pasted into your sensors.yaml file, not the Jinja2 template.

Keep in mind that Home Assistant processes all YAML first then processes Jinja2 second. Based on that order of processing, you canā€™t do what you have been attempting, namely make it process the Jinja2 first in order to generate YAML that will be processed second (thatā€™s simply not the correct order of processing).

But I formatted my post so nicely! :smiley:

That explanation makes sense, thanks.

1 Like

The following post may be of interest to you, possibly for use in a future application. It employs a YAML feature called ā€˜anchors and aliasesā€™ as well as the Jinja2 this variable.