Defining my goal
I have a conversation intent_script that identifies areas with open windows and produces a response like “Windows are open in Kitchen and Living Room.”
I would like to make this sound more natural by using appropriate articles: “Windows are open in the Kitchen and the Living Room.” However, not all of my area names take the definite article “the”, since I have areas named things like “Jason’s Room”.
I don’t want to add “the” to my area names directly in Home Assistant, since I prefer my areas to be named “Kitchen” instead of “the Kitchen”.
I also would like to do this in a piece of reusable code for the sake of simplicity and efficiency.
Current effort
I am attempting to solve this by creating a custom Jinja macro at custom_templates/add_articles_areas.jinja
. Here’s what it currently holds:
{%- macro add_article(room) -%}
{%- set rooms_with_the = [
'Basement',
'Basement Bathroom',
'Utility Room',
'Kitchen',
'Living Room',
'Main Bedroom',
'Upstairs Bathroom',
'Upstairs Hallway',
'Outdoors'
] -%}
{%- if room in rooms_with_the -%}
the {{ room }}
{% else %}
{{ room }}
{%- endif -%}
{%- endmacro -%}
This is the relevant section of my configuration.yaml
:
intent_script:
getWindowState:
speech:
text: >
{% from 'add_articles_areas.jinja' import add_article %}
{% set open_areas = state_attr('binary_sensor.exterior_windows', 'entity_id') | select("is_state", "on") | map('area_name') | unique | list %}
{% if is_state("binary_sensor.exterior_windows", "off") %}
{{ [
"All the windows I know about seem to be closed.",
"As far as I can tell, all windows are closed.",
"Sensors report no open windows.",
"They all look closed to me."
] | random }}
{% elif open_areas | length == 1 %}
There are windows open in {{ add_article(open_areas[0]) }}.
{% elif open_areas %}
{% set formatted_areas = open_areas | map("add_article") | list %}
There are windows open in {{ formatted_areas[:-1] | join(', ') }} and {{ formatted_areas[-1] }}.
{% endif %}
I’ll admit this is cobbled together, and I don’t fully understand every step of what I’m doing. For reference, this is a working version of the template without any of the attempts I’ve made to programmatically add “the”.
{% set open_areas = state_attr('binary_sensor.exterior_windows', 'entity_id') | select("is_state", "on") | map('area_name') | unique | list %}
{% if is_state("binary_sensor.exterior_windows", "off") %}
{{ [
"All the windows I know about seem to be closed.",
"As far as I can tell, all windows are closed.",
"Sensors report no open windows.",
"They all look closed to me."
] | random }}
{% elif open_areas | length == 1 %}
There are windows open in {{ open_areas[0] }}.
{% elif open_areas %}
There are windows open in {{ open_areas[:-1] | join(', ') }} and {{ open_areas[-1] }}.
{% endif %}
Issue
Presently, this doesn’t work. When I ask Assist one of the trigger phrases, “Are any windows open?”, Assist responds “An unexpected error occurred”.
When I test the intent_script
template in the Template Designer, I get the issue:
TemplateRuntimeError: No filter named ‘add_article’.
What am I missing here? Is it possible to do what I want, or am I barking up the wrong tree?