This topic is part of the community-driven cookbook where you can find other topics you might be interested in or might like to contribute to.
When you ask around for a solution to a problem in Home Assistant, then 9 out of 10 times you’ll get a response using a Jinja2 template that you can put in a YAML file. These templates look like delimiter salad when you first see them.
While you can simply copy paste those templates in your configuration, things get way more fun if you can read them. It is also helpful understand why templates might fail if you change a seemingly little thing. And who knows, at some point you’ll be able to write your own templates.
Below is a common example template. It is used to get the brightness from one light and use it for another light. This example and breakdown is borrowed from a question here:
brightness: "{{ state_attr(trigger.entity_id, 'brightness') | int(0) }}"
Breaking down the template to character level:
-
Putting things inside
{{ }}
is the sign that we are switching from YAML to Jijna2 templates. Whenever you need to do something besides just entering a value, Jinja templates are your friend. Jinja is very related to Python. In Jinja this is a block that outputs something. Jinja also uses{% %}
blocks that are not outputting something. They are mostly used for control blocks or setting Jinja variables. More on Jinja delimiters here. -
Unfortunately,
{ }
means something different in YAML when it is not in a string or multiline text block. When a template is on the same line as the tag then it must be inside quotes to avoid the confusion. That is why the" "
are around it. If you enter a template in the GUI, do not use the outer quotes because then they will be put around the result. -
When you need to use a quote inside
" "
you cannot simply use another"
without ending the string. You either need to escape it, or switch to'
single quotes. Jinja and Python do not mind which one you use as long as they match. The first quote starts a string, the second one of the same kind ends it. So strings used for names use single quotes here. One really important thing: don’t use the fancy curly quotes! IOS keyboards can change them automatically, but they have no meaning to Python an Jinja and the difference will lead to errors. -
Notice how
'brightness'
has quotes buttrigger.entity
has none? Brightness is a literal name of an attribute, and trigger is a variable that holds an entity_id (That is also a variable inside the trigger object, the.
delimiter in between selects it from the trigger object).
This example was lifted from an automation. Automations provide all kinds of information on what triggered the automation via the trigger variable. So in this case, the entity_id that triggered the automation is used. If you wanted to explicitly name the entity_id yourself, you’d use something like'light.myentity'
. More on trigger variables here. -
Now that we’re almost done with the delimiter salad, we can start doing stuff. But this is a good time to discuss indenting: YAML dislikes delimiters (some irony intended) and instead relies on indenting to decide what goes with what. Indenting identifies nested groups. Things with the same indent belong together on the same level, and when you indent deeper it means there is a deeper level of things inside that. The spaces on the beginning of a line are crucial information. More on YAML and indenting here.
-
To show what that all means: If you create a multiline text block in YAML using the
>
or the|
symbol then you no longer need the outer quotes, because you are already in a string. But you do need an extra indent to show what belongs to the multiline block. You can add newlines for readability, as long as all lines are indented sufficiently. You could use double quotes for names if you wanted to (just a demo, normally I would not change it to keep things consistent). More on multiline strings here:
brightness: >
{{
state_attr(trigger.entity_id, "brightness") | int(0)
}}
-
Soooo. Back to actually doing things in Jinja.
state_attr()
is a Python function from Home Assistant that you can use in Jinja to get the attribute of an entity. It is the preferred way because it has some error handling. What we need is the value of the ‘brightness’ attribute of the light entity that triggered the automation. -
States of entities in Home Assistant are always strings. Attributes can be any type of value, but it is often hard to tell what it is exactly. The symbol
|
is called a pipe, it means use some filter to transform the value on the left. The filter used isint
which converts the input to an integer value. It is advised to useint(0)
which means, use 0 as a default if the input is not a number. When a light is off or unavailable, then the brightness attribute is not there. The 0 default will prevent errors.
Simple, right?
The power of HA comes from the combination of many powerful languages, but at the price of complexity. Python and YAML like to keep things short, so there’s a lot of information in each character.
There are crazy number of things that templates can do using calculations, variables, functions and filters. A lot of it is regular Python or Jinja. Many Home Assistant specific things are listed in the template documentation.
This topic is part of the community-driven cookbook where you can find other topics you might be interested in or might like to contribute to.