Hey there! If you want to do more advanced things in Home Assistant, you’ll need to use YAML and Jinja. Within YAML, you can utilize Jinja code to apply various logic and calculations to your data in Home Assistant. In this series, I’ll be telling you how to create templates and how to program using Jinja. Today, we’ll start with the basics covering expressions, statements, comments, variables, and filters. I aim to publish a new part every week so that you can gradually learn more about Jinja and eventually build your templates.
โญโญโญ NOTE: โญโญโญ
This article accompanies a YouTube video. I wrote it for people who would rather read than watch a video. To keep doing this, I want to ask you to check out the video, leave a comment under the video, give the video a thumbs up, and subscribe to my YouTube channel. This means that the video is offered more often to new visitors so that they also stay informed of the latest Home Assistant tutorials.
Thank you for your support!
Ed
Introduction
First of all, some guys on the Home Assitant forums know a lot about Jinja and templating. I want to thank Petro and TheFes for letting me know that a series about Jinja would be very valuable. So, here it is, the start of my Jinja and Yaml course.
A Jinja template is simply a text file. Jinja can generate any text-based format and in the case of Home Assistant, we want to create YAML. YAML is a human-readable data serialization language that is often used for writing configuration files. Depending on whom you ask, YAML stands for yet another markup language and is a popular formatting language because it is designed to be easy to read and understand.
You can use YAML and Jinja in various places in Home Assistant. You can use it, for example, in automations, on dashboards, or to create custom sensors yourself. Throughout this series on Jinja, I’ll show you all of that, but, as I mentioned earlier, let’s start with the basics.
How the template editor works
For now, we’ll mainly get started in the developer tools to play around with Jinja a bit.
Go to the developer tools and click on the Template tab. Click on Reset to demo template to be sure that the demo template code is shown.
As you can see, on the left side, you have access to the template editor. On the right side, you can see the results generated by your created templates.
Let’s clear the template editor by clicking on “clear” for a moment.
Expressions
You can use expressions to, for example, retrieve a value from a sensor or a variable. Expressions are placed within double braces:
{{ ... }}
If I want to display the status of my home zone, I can do it as follows:
{{ states('zone.home') }}
You can see that on the right side, the value is 1. This is the state of my Home zone, where currently 1 person is present. I’ll explain later how to retrieve the values of sensors. For now, it’s just about the notation.
Statements
In addition to expressions, you can also use statements. With statements, you can perform logical operations on your data, such as creating an if then statement. Within a statement, you can also use expressions again.
Statements are enclosed within curly braces and percent signs:
{% ... %}
For example, if I want to check if someone is at home, I can use the following statement:
{% if states('zone.home') != '0' %}
Someone is present
{% else %}
Nobody is present
{% endif %}
You’ll see the result on the right side. Let’s not focus on the statement code for now either. I’ll explain that later. What matters here is that you put the statement code between curly braces and percent signs. Note the indentation of the lines “Someone is present” and “Nobody is present”. It’s good practice to indent lines between your statements to make the code more readable. In this example, the indentation results in two spaces before each line, so in this case, using no indentation would give a better output result.
Comments
To keep your code readable, it’s occasionally useful to add some comments to your code. This comment won’t be displayed in the template output. Comments are placed between curly braces and hashtags:
{# ... #}
So if I want to add comments to the code I showed earlier, it can be done like this, for example:
{# show if someone is present or not #}
As you can see, the comment is not displayed on the right side.
Templates are indicated by lines that start and end with curly braces and percent signs or double braces. Everything else is YAML. The language contained inside curly braces and percent signs or double braces is Jinja. It is not YAML.
I need your help!
You will be doing me a huge favor if you subscribe to my channel if you haven’t already. And, you will help me a lot if you also give this video a thumbs up and leave a comment. This way, YouTube will present this video to new people, making the channel grow! In the video description, you will also find information about how you can sponsor me so that I can continue to make these tutorials for you.
Thank you!
Variables
Now that you know how to use Statements and Expressions, you can use them to define and retrieve variables.
When creating a custom sensor, you might find yourself using an existing sensor value multiple times in your code. In such cases, it’s best to store that value in a variable and then continue working with the value stored in that variable. This makes the code easier to read and maintain. If you ever need to replace the previously used sensor with a new one, you only need to replace it in one place: where you declared the variable.
Creating a variable is very simple. See this example:
{% set myvariable = "My variable value" %}
I have used a statement here that defines the variable “myvariable” with the value “My variable value”.
If I now want to retrieve that variable, I use the following expression:
{{ myvariable }}
You can see that the value “My variable value” is displayed on the right side.
Let’s go back to the code that shows if someone is present or not and rewrite it to use a variable.
{# show if someone is present or not #}
{% set presentstatus = states('zone.home') %}
The present status is {{ presentstatus }}
{% if presentstatus != '0' %}
Someone is present
{% else %}
Nobody is present
{% endif %}
As you can see, I have defined a variable named “presentstatus”. Then, I display the contents of that variable in an expression and also use that variable in my if-then statement. So, I only need to retrieve the value of zone.home once and can then use it multiple times. If I now want to check if someone is present at my workplace, I just need to replace zone.home with my zone.work and the rest of the code will continue to work as usual.
Introduction to Filters
As the final part of this episode, let’s briefly discuss filters. With the help of a filter, you can easily perform operations on the values of your sensors or variables. When you retrieve the value of a sensor in Home Assistant, it’s always returned as a string. So, if you request a numeric value, you’ll get it back as a string and you’ll need to convert it to a number first. That’s where a filter comes in handy. There’s a list of built-in filters in Jinja that you can use. You can find the link to this list in the description of this video. When you want to use a filter, you need to place a pipe symbol between the value and the filter. Let me show you a few examples.
Let’s retrieve the status of the home zone again and this time check if it has the value 0 without putting double quotes around it:
{# show if someone is present or not #}
{% if states('zone.home') != 0 %}
Someone is present
{% else %}
Nobody is present
{% endif %}
The status of Zone.home is 1, and you can see the result now indicating that someone is present. The code seems to be working, but it’s not actually correct. The status is a string, so 1 is between double quotes. We’re checking if the status is not equal to 0, which is true because it’s the string “1”. Now, if I check for the value 1, I would expect to see that someone is present, but as you can see, it’s showing that no one is present:
{# show if someone is present or not #}
{% if states('zone.home') == 1 %}
Someone is present
{% else %}
Nobody is present
{% endif %}
This is because the value is returned as a string and not as a number. If we now filter the value and convert it to an integer, the string will be translated into a real number, and you will see that the code works:
{# show if someone is present or not #}
{% if states('zone.home') | int >= 1 %}
Someone is present
{% else %}
Nobody is present
{% endif %}
To give another example, I’m going to convert the value of my variable to uppercase. See this example:
{% set myvariable = "My variable value" %}
{{ myvariable | upper }}
Because of the filter upper, the result is shown in uppercase.
You can also chain filters together so that they affect each other. See this example:
{% set myvariable = "My variable value" %}
{{ myvariable | reverse | upper }}
In this case, the value of my variable is reversed first, and after that, it is converted to uppercase. What all filters do is shown on this page. Throughout this series, I will use various filters and explain what each specific filter does.
So, this was the first episode of the Jinja course. I hope you found it helpful. In the next episode, we’ll continue with this so that you can call yourself a Jinja professional in no time! Make sure to subscribe so you do not miss the next episodes.
Thanks for watching. If my videos save you time, consider becoming one of my sponsors, just like these people are. Without your help, I can’t continue this channel. This channel is my job, and unfortunately, YouTube earnings alone are not enough to live on. Thank you. And don’t forget to give this video a thumbs up and subscribe to my channel if you haven’t already. I also appreciate it if you leave a comment under this video. That way, YouTube will show the video to more people. See you soon in my next video.
Bye Bye.