I'm trying to use self-referencing templates in Home Assistant, because I want to make a reusable way to add an AQI calculation to every air sensor I have in my house (which have recently multiplied since IKEA made one that integrates really well with HA).
All I really want is to allow code reuse (really, just define a function to which I can pass a single variable), but self-referencing plus merge keys are the only way I've found to do that. If there's some way better method for doing this, I'm all ears.
I have the following template, but when I enter it in the template editor, it returns UndefinedError: 'this' is undefined
. I've read about the need to guard for startup issues but that doesn't seem to apply.
# AQI Calculation from https://www.airnow.gov/sites/default/files/2020-05/aqi-technical-assistance-document-sept2018.pdf p14
- sensor:
- name: "Nursery AQI"
unique_id: "sensor.nursery_aqi"
attributes:
particulates: "{{ states('sensor.airlink_pm_2_5') | float }}"
<<: &aqi_from_pm25
unit_of_measurement: "aqi"
icon: mdi:blur
state: >
{% set pm = this.attributes.particulates %}
{% if pm <= 12.0 %}
{% set low = 0.0 %}
{% set high = 50.0 %}
{% set lowpm = 0.0 %}
{% set highpm = 12.0 %}
{% elif pm <= 35.4 %}
{% set low = 50.0 %}
{% set high = 100.0 %}
{% set lowpm = 12.1 %}
{% set highpm = 35.4 %}
{% elif pm <= 55.4 %}
{% set low = 101.0 %}
{% set high = 150.0 %}
{% set lowpm = 35.5 %}
{% set highpm = 55.4 %}
{% elif pm <= 150.4 %}
{% set low = 151.0 %}
{% set high = 200.0 %}
{% set lowpm = 55.5 %}
{% set highpm = 150.4 %}
{% elif pm <= 250.4 %}
{% set low = 201.0 %}
{% set high = 300.0 %}
{% set lowpm = 150.5 %}
{% set highpm = 250.4 %}
{% elif pm <= 350.4 %}
{% set low = 301.0 %}
{% set high = 400.0 %}
{% set lowpm = 250.5 %}
{% set highpm = 350.4 %}
{% elif pm <= 500.4 %}
{% set low = 401.0 %}
{% set high = 500.0 %}
{% set lowpm = 350.5 %}
{% set highpm = 500.4 %}
{% else %}
{% set low = 501.0 %}
{% set high = 502.0 %}
{% set lowpm = 500.5 %}
{% set highpm = 15000.0 %}
{% endif %}
{% set i_diff = high-low %}
{% set pm_diff = highpm-lowpm %}
{% set conc = pm-lowpm %}
{{ ((conc * ((i_diff) / pm_diff)) + low) | round(0) }}
- name: "Family Room AQI"
unique_id: "sensor.family_room_aqi"
<<: *aqi_from_pm25
attributes:
particulates: "{{ states('sensor.ikea_of_sweden_vindstyrka_particulate_matter_2') | float }}"
- name: "Living Room AQI"
unique_id: "sensor.living_room_aqi"
<<: *aqi_from_pm25
attributes:
particulates: "{{ states('sensor.ikea_of_sweden_vindstyrka_particulate_matter') | float }}"
- name: "TEST Outdoor AQI"
unique_id: "sensor.test_outdoor_aqi"
<<: *aqi_from_pm25
attributes:
particulates: "{{ states('sensor.airnow_pm2_5') | float }}"
The answer (for anyone looking in the future) was that this was a guard issue. Here's the key line to fix:
{% set pm = ((this.attributes.particulates| default(-1, false)) | float) %}
Adding the guard here made me decide to add the float conversion here as well, so I dropped |float
from the attributes.particulates
line.