Okay, suppose I write template sensors in my configuration.yaml
in the template:
section. How would I put my macro definition there so that I can use it inside a template sensor definition?
Is it inside the template:
section? After some keyword? Indented? Is there any documentation available regarding this use case?
I recently showed you a template for converting the current day’s name from English to German. Instead of using it to create a macro, use it to create a Template Sensor.
Wherever you need the current day’s name in German, simply reference the Template Sensor’s value.
But then I have to write this long code 31 times, for each of the 31 date sensors!
That’s exactly what functions in programming languages are for.
There has to be a better way, hopefully!
You’ll need to clarify your intended application(s) otherwise you’ll continue to get suggestions that don’t meet your requirements. So far, all we know is that you created a macro and you wanted to use it in a card (which isn’t possible with the standard set of cards because they don’t support templates).
Okay, I’ll ask another question then: should we not use the macro feature of Jinja at all then in Home Assistant?
Well, it works, but the idea of a function is to be able to use it anywhere.
Several Mushroom cards allow the use of templates but unfortunately, there’s no entities (plural) card in the Mushroom collection.
So I use a default lovelace entities card together with the secondary-entity-row add-on which allows for templates in the secondary information of an entity in an entities card.
My use case is: I want to list ~30 (German) holiday dates. I use the Calendarific integration to create the sensors. They contain the number of days until the holiday. In the entities card I additionally want to display the exact date of that sensor, which is an attribute of the sensor. This works fine, in English:
The yaml code for the entities in the entities card looks like this for the first 3 of ~30 entities:
- entity: sensor.cal_valentine_s_day
type: custom:secondaryinfo-entity-row
secondary_info: >-
{{ as_timestamp(state_attr('sensor.cal_valentine_s_day', 'date')) |
timestamp_custom('%A, %d.%m.%Y') }}
- entity: sensor.cal_rosenmontag
type: custom:secondaryinfo-entity-row
secondary_info: >-
{{ as_timestamp(state_attr('sensor.cal_rosenmontag', 'date')) |
timestamp_custom('%A, %d.%m.%Y') }}
- entity: sensor.cal_st_patrick_s_day
type: custom:secondaryinfo-entity-row
secondary_info: >-
{{ as_timestamp(state_attr('sensor.cal_st_patrick_s_day', 'date')) |
timestamp_custom('%A, %d.%m.%Y') }}
If I want the weekday names in German I can use the tip you, @123, gave me. But because I don’t want to repeat that weekday names array and the additional code ~30 times for each date sensor entity in its secondary_info (it would look like this for every row:
{{ ['Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag', 'Sonntag'][as_datetime(state_attr('sensor.cal_karfreitag', 'date')).weekday()] }}, {{ as_datetime(state_attr('sensor.cal_karfreitag', 'date')).strftime('%d.%m.%Y') }}
), I thought I’d define this macro once …
{% macro formatted_date(datesensorname) -%}
{% set thedate = as_datetime(state_attr(datesensorname, 'date')) %}
{{
['Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag', 'Sonntag'][thedate.weekday()]
}}, {{ thedate.strftime('%d.%m.%Y') }}
{%- endmacro %}
… and have the individual lines of the entities card look like this then:
- entity: sensor.cal_valentine_s_day
type: custom:secondaryinfo-entity-row
secondary_info: {{ formatted_date('sensor.cal_valentine_s_day') }}
Much shorter.
I don’t have a problem defining template sensors inside my configuration.yaml
in the template:
section. But as long as I can’t use that macro there, neither, I have nothing gained because I still have to write that long definition with the weekday names ~30 times, for each template sensor. Which is … quite … annoying … and … dumb.
So, there’s my specific use case. Eager to know what I can do about it.
Macros cannot be used across your system. They are only available in your single template.
You can approach this differently to remove the macro as well, with a template sensor, and yaml anchor.
template:
- trigger:
- platform: time
at: "00:00"
variables: &date_variables
entities:
- sensor.cal_karfreitag
- sensor.cal_valentine_s_day
dates: >
{% set ns = namespace(items=[]) %}
{% for entity in entities %}
{% set dt = state_attr(entity, 'date') | as_datetime %}
{% set day = ['Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag', 'Sonntag'][dt.weekday()] %}
{% set day = day ~ ', ' ~ dt .strftime('%d.%m.%Y') %}
{% set ns.items = ns.items + [ (entity, day) ] %}
{% endfor %}
{{ dict.from_keys(ns.items) }}
- platform: homeassistant
event: start
variables: *date_variables
sensor:
- name: Holidays
unique_id: holidays
state: "{{ dates | count }}"
attributes:
dates: "{{ dates }}"
Your template in the card would be (it wouldn’t change for any of them).
- entity: sensor.cal_valentine_s_day
type: custom:secondaryinfo-entity-row
secondary_info: "{{ state_attr('sensor.holidays', 'dates')[entity] }}"
EDIT: I’m just going to delete option 1.
WOW! That’s beyond my skills, currently. But I’ll study it for sure! Always eager to learn something new and thus widen my horizon!
Thanks so much for your effort & help! Very much appreciated!
Almost works!
I see the new sensor sensor.holidays
with its dates
attribute value that contains all the single sensor.cal_*
names and their exact dates in form of a JSON dictionary.
As we can see, accessing a single item’s date string (like we want it in the secondary info) works, too, for the example of sensor.cal_karfreitag
in the screenshot.
However, that sensor’s entity name has to be put in (single) quotes, it has to be a string, when used as the index to that dictionary.
When we look at the template code in the lovelace entities card,
- entity: sensor.cal_valentine_s_day
type: custom:secondaryinfo-entity-row
secondary_info: "{{ state_attr('sensor.holidays', 'dates')[entity] }}"
… we see that the index in [ ] is not a string. And indeed, it doesn’t work:
However, my template coding knowledge is not (yet) sufficient to fix this. Putting single quotes around entity
– ['entity']
– doesn’t work, of course. We need the quote characters and entity
replaced with its value.
How can this be achieved?
Probably needs to be enitity.entity_id without quotes
Exactly. Write it once, create a shell script that blasts it out 31 times. Most of the time the shell script is just replacing an entity name. This way you can also change it later in one place and regenerate the other 31 instances.
Unfortunately not.
Sorry, it’s just what the card uses and that’s an old card lacking proper documentation about the variables that are supplied to the namespace. I’m taking guesses as to what is available. So try entity_id
without quotes.
EDIT: Looking at the code, I don’t see how entity
would fail. It assigns this._config.entity
to the entity variable. So that should work, or entity.entity_id
.
For testing, just make it
- entity: sensor.cal_valentine_s_day
type: custom:secondaryinfo-entity-row
secondary_info: "{{ entity }}"
and post the results here
well, when all else fails, just default to writing the entity_id twice.
- entity: sensor.cal_valentine_s_day
type: custom:secondaryinfo-entity-row
secondary_info: "{{ state_attr('sensor.holidays', 'dates')['sensor.cal_valentine_s_day'] }}"
yeah, well I was trying to avoid that. But oh well. Not too much of a hassle. That custom card needs some love. I haven’t seen that dev in a about a year.
EDIT: Whelp, he’s still managing his cards, so maybe he doesn’t know about this issue.
Err, isn’t the “Entities Card” a core/official HA lovelace card? I thought so …
(But we’re getting off-topic. )
You’re using custom:secondary info row, that’s what I’m referring to
Ahhh, I see! Sorry!