Hi, this is episode 3 of the YAML & Jinja Templating course. Today we’re going to talk about If-Then statements and For-loops. Let’s get started!
โญโญโญ 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
In episode 1 and 2, we covered the basics of YAML & Jinja. If you haven’t seen these yet, go to the YAML & Jinja Course playlist to watch them first. I received feedback from some people that they think I could talk a little slower. For those people who can’t keep up with the speed, I want to give you the tip that you can play this video slower. You can do that by going to the settings of this video and turning down the playback speed there. And, of course, you can also use the pause button every now and then. So, now that we’ve had the housekeeping announcements, let’s get down to business.
If-Then Statements
I have already used If-Then statements a few times in episode 1 and 2, but there I did not explain how they actually work. An If-Then statement allows you to perform an action based on certain conditions. So, for example, if no one is home, show a text that everyone has left the house. You do that in the following way:
- First, go to the Developer Tools again and open the Template Tab.
- Now use the following code:
{% if states('zone.home') | int == 0 %}
Nobody is present
{% endif %}
Now what do we see here? You always start an if statement with a check for some value. In this case, we are checking how many people are in the Home zone. We check if there are 0 persons present. You do that using a double is-equal sign. So, in this rule, we check if 0 people are present in the zone Home. If there are, then the text “Nobody is present” is displayed. Then, we close the if statement with an “endif” line.
In this case we check that the value is exactly equal to 0. But you can also use other comparison operators. A comparison operator returns the value true or false and can be used in If Then statements.
The most common comparison operators you can use are:
- > Greater Than
- < Less Than
- >= Greater Than or Equal To
- <= Less Than or Equal To
- == Equal To
- != Not Equal To
In addition, you can also combine multiple comparisons by using And and OR statements.
Here, for example, I have defined two variables and check that both variables are true:
{% set x = "blue" %}
{% set y = 0 %}
{% if x == "blue" and y == 0 %}
Yes, it's true!
{% endif %}
I defined the variable x that contains the value “blue”. I also defined the variabele y that contains the value 0. Here I check whether x equals blue and y equals 0. Both conditions are true, so I show the text “Yes, it’s true!”
But, I can also check if one of the variables is true:
{% set x = blue %}
{% set y = 0 %}
{% if x == "red" or y == 0 %}
Yes, it's true!
{% endif %}
Here I check whether the variable x is equal to “Red” or whether the variable y is equal to 0. Now only one of the two conditions needs to be true to show the text “Yes, it’s true!”. So since y is equal to 0, this text is indeed shown. Now if I were to check that y equals 1, you will see that the text disappears. If I then replace the Equal To with Not Equal To, you see that the text reappears. What I’m trying to tell you here is that using comparison operators in combination with And and Or statements can be very powerful, but also frustrating. I recommend that you always build these more complex comparisons slowly. Start with one equation first and then slowly expand it.
Else Statement
But there is more you can do with the If-Then statement. In addition to If-Then, you can also use the else statement. For example, in this example, I’m checking whether or not someone is home:
{% if states('zone.home') | int == 0 %}
Nobody is present
{% else %}
Someone is present
{% endif %}
You can see that I first check that the number of people in the Home zone is equal to 0. If it is, then the text “Nobody is present” is displayed. But, if people are home, then I want to show a different text. I can do that by using the “Else” statement. After the else statement, I then put the text or code I want to use. In this case, it is the text “Someone is present”. And we close again neatly with an “Endif” line. Since I’m home now, you can see that the text “Someone is present” is displayed.
Elif statement
But what if I want to check multiple values? For example, whether there are 0, 1 or multiple people in the house? Well, you can do that by using the elif statement. Take a look at this code:
{% if states('zone.home') | int == 0 %}
Nobody is present
{% elif states('zone.home') | int == 1 %}
There's one person present
{% else %}
More than one person is present
{% endif %}
Again, you see that I first check whether the number of people in the Home zone is equal to 0. If that is the case, the text “Nobody is present” is displayed. Then I check whether exactly one person is present by using the “elif” statement. If so, the text “There’s one person present” is displayed. And if both checks are not met, the “else” statement catches it and displays the text “More than one person is present”. You can use the elif statement as many times as you want.
You can easily test this yourself by changing the state of zone.home in the states tab. I first set the state to 0 and then you will see that the text “Nobody is present” is displayed. Then I set the state to 1. Now you see that the text “There’s one person present” is shown. And finally, I set the state to 2. Now you see that the text “More than one person is present” is shown.
For loops
If you are creating a template, sometimes you want to check if a certain value is in a list. Or, you want to repeat a certain function a number of times. For that, you can use For-loops.
Let’s start with a simple example so you understand a little bit about how for loops work. In this code, I use a variable i that I run over 8 times. Each time I run over it, the value of i is printed:
{% for i in range(8) -%}
{{ 'The value of i is: ' + i | string }}
{% endfor %}
In the first line, I specify that I want to loop over the value of i 8 times. I do that by specifying a range of 8. You can see that the first value is 0. It’s important to realize that when you declare a range, it always starts with the value 0. Next, the text “The value of i is: ” is printed with the value of i converted to a string. You can see that in this case the value of i is incremented by 1 with each loop.
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!
This is a simple example where I am looping through a range. But I can also loop through a list, for example. Let’s create an example where I use a list and loop through it.
{% set names = ['Ed', 'Smart Home Junkie', 'Joe', 'Jane'] %}
{% for name in names -%}
{{ 'The name is: ' + name }}
{% endfor %}
As you can see, I first defined a list containing several names. That list is called “names”. Then, I iterate through that list using the for statement. Now, you can see that the variable “name” takes on the value of each name in the list during each iteration. In the line following the for statement, that value is printed out each time.
Now, you could combine the for loop with an if statement so that you can, for example, check if a certain name is in the list. In this example, I’m checking if the name “Smart Home Junkie” is in the list, and if it is, I display a message:
{% set names = ['Ed', 'Smart Home Junkie', 'Joe', 'Jane'] %}
{% for name in names -%}
{% if name == "Smart Home Junkie" %}
Please subscribe to my channel!
{% endif %}
{% endfor %}
You can now see that the text “Please subscribe to my channel!” is printed because the name “Smart Home Junkie” is present in the list. If I were to check for a name that is not in the list, nothing is printed as you can see:
{% set names = ['Ed', 'Smart Home Junkie', 'Joe', 'Jane'] %}
{% for name in names -%}
{% if name == "Bearded Tinker" %}
Please subscribe to my channel!
{% endif %}
{% endfor %}
However, as is often the case in software programming, you can write some code even shorter. After more than 30 years of programming experience, I always prefer to keep my code as readable as possible, but that’s my personal preference. Nevertheless, I want to show you how you can also quickly check if a value is in a list.
{% set names = ['Ed', 'Smart Home Junkie', 'Joe', 'Jane'] %}
{% if "Smart Home Junkie" in names %}
Please subscribe to my channel!
{% endif %}
As you can see, I no longer use a for-loop now, but check directly in the list whether a given value exists. So more often than not, there are multiple ways that lead to Rome!
Well, let’s convert this example to determine if a particular person is home.
We start with a loop that shows which persons are home:
{% set people = state_attr('zone.home','persons') %}
{% for person in people -%}
{{ person }}
{% endfor %}
In the first line, I define a variable “people” which is filled with the values found in the “persons” attribute of the zone. Don’t worry too much about the “state_attr” function for now. For now, you just need to know that this function can retrieve attributes of a specific sensor. Then, I display the people who are in the zone “home”. In this case, my son and I are at home. You can see that “person.daan” and “person.ed” are printed.
Now, we’re going to check if my son is at home. If so, I’ll print a welcome message:
{% set people = state_attr('zone.home','persons') %}
{% for person in people -%}
{% if person == "person.daan" %}
Welcome home Daan!
{% endif %}
{% endfor %}
You can see that here I’m using an if statement to check if my son is at home. And since this is the case, a text saying “Welcome home Daan!” is printed.
Within a for-loop, you can use various functions as you can see on this page. For instance, you can determine if an item in the loop is the first or the last item:
{% for i in range(8) -%}
{{ 'The value of i is: ' + i | string }}
{%- if loop.first -%}
{{ ' (This is the first item in the loop)' }}
{%- endif -%}
{%- if loop.last -%}
{{ ' (This is the last item in the loop)' }}
{%- endif %}
{% endfor %}
In this example, for each item in the loop, I check whether it is the first item by using the variable loop.first. If it is, then the line “(This is the first item in the loop)” is printed. In addition, I check whether the item is the last item in the loop. If it is, then the line “(This is the last item in the loop)” is printed. This is a simple example, but experiment with all the variables in this list and let me know in the comments what uses you can think of for them.
This is just the beginning of what you can do with If-Then statements and For-loops. In the coming episodes I will use these more often and you will see how powerful If-Then statements and For-loops can be.
And that brings us to the end of this episode. Thanks for watching and, if you appreciate my work, please consider sponsoring me monthly with a small amount, just like these wonderful people do. They make sure that you can continue to watch my tutorials. Making these tutorials is my daily work and unfortunately the income from YouTube alone is too little to live on. Without your help I cannot continue this channel. Thanks for that! The link to Patreon, Ko-Fi and how to join my channel can be found in the description of the video. And, don’t forget to give this video a thumbs up and subscribe to my channel if you haven’t already. It also helps tremendously if you take a moment to post a comment below the video. That way this video will be shown to more people on YouTube.
See you soon in my next video!
Bye Bye.