Templates — Wanneer gewone regels niet meer genoeg zijn
In het vorige hoofdstuk heb je kennisgemaakt met helpers. Daarmee kun je informatie bewaren die niet rechtstreeks van een apparaat hoeft te komen.
In het vorige hoofdstuk heb je kennisgemaakt met helpers. Daarmee kun je informatie bewaren die niet rechtstreeks van een apparaat hoeft te komen.
Je kunt bijvoorbeeld een helper gebruiken voor:
- de gewenste temperatuur in De Werkplaats;
- een grenswaarde voor de hoeveelheid licht;
- de keuze tussen automatisch en handmatig gebruik;
- een tijdstip waarop een bepaalde actie mag plaatsvinden.
Dat maakt een automatisering al een stuk flexibeler.
Maar er komt een moment waarop alleen een opgeslagen waarde niet meer voldoende is.
Stel dat je in De Werkplaats een temperatuursensor hebt en een helper waarin je de gewenste temperatuur instelt. Je wilt vervolgens niet simpelweg zeggen:
Als de temperatuur lager is dan 18 °C, doe dan iets.
Je wilt eigenlijk zeggen:
Als de gemeten temperatuur lager is dan de temperatuur die ik zelf heb ingesteld, doe dan iets.
Die grenswaarde staat nu dus niet meer vast.
Home Assistant moet een waarde opzoeken, twee waarden met elkaar vergelijken en daaruit een resultaat berekenen.
Daar komen templates van pas.
Een template is een klein stukje logica waarmee Home Assistant tijdens het uitvoeren van een automatisering zelf een waarde kan samenstellen of berekenen. Templates kunnen bijvoorbeeld de toestand van een entiteit uitlezen, getallen vergelijken, tekst samenstellen en afhankelijk van een situatie een andere uitkomst geven. Home Assistant gebruikt hiervoor de template-taal Jinja.
Dat klinkt misschien alsof we nu ineens moeten gaan programmeren.
Dat valt mee.
We beginnen met een paar heel kleine voorbeelden en veranderen steeds maar één ding tegelijk.
Eerst het probleem zonder template
We nemen opnieuw De Werkplaats als voorbeeld.
Daar hebben we:
- een temperatuursensor;
- een elektrische verwarming;
- een helper waarin de gewenste temperatuur staat.
Stel dat de entiteiten als volgt heten:
sensor.werkplaats_temperatuur
input_number.werkplaats_gewenste_temperatuur
switch.werkplaats_verwarming
Zonder helper zou je een vaste regel kunnen maken:
Als de temperatuur onder 18 °C komt, zet de verwarming aan.
Dat werkt.
Maar wanneer je later besluit dat 19 °C prettiger is, moet je de automatisering aanpassen.
Met een helper kun je de gewenste temperatuur buiten de automatisering instellen.
Bijvoorbeeld:
19
Nu hebben we echter een nieuw probleem.
De automatisering moet niet meer controleren:
temperatuur < 18
maar:
temperatuur < ingestelde temperatuur
En beide waarden kunnen veranderen.
Dat is precies het soort probleem waarvoor een template handig is.
Een template geeft een resultaat terug
Het belangrijkste om te begrijpen is dat een template uiteindelijk gewoon een resultaat oplevert.
Dat kan bijvoorbeeld zijn:
true
of:
false
maar ook:
18.7
of:
De temperatuur in De Werkplaats is 18,7 graden.
Welke uitkomst je nodig hebt, hangt af van waar je de template gebruikt.
Bij een voorwaarde wil je meestal weten:
Is iets waar of niet waar?
Bij een melding wil je misschien tekst maken.
En bij een actie wil je soms eerst een getal berekenen.
Templates worden daardoor vooral interessant wanneer een waarde tijdens het uitvoeren van de automatisering moet worden bepaald.
Je eerste template
Laten we beginnen met iets wat nog helemaal niets automatiseert.
Open in Home Assistant:
Instellingen → Ontwikkelaarstools → Template
De template-editor is juist bedoeld om templates eerst afzonderlijk uit te proberen. Dat is veel prettiger dan iedere verandering direct in een echte automatisering te testen. De officiële Home Assistant-documentatie raadt deze editor ook aan bij het testen en oplossen van problemen met templates.
Voer in:
{{ 2 + 3 }}
Voorspel eerst
Wat verwacht je dat Home Assistant teruggeeft?
Waarschijnlijk:
5
Probeer het.
Je hebt nu je eerste template uitgevoerd.
De twee accolades:
{{ }}
betekenen ongeveer:
Bereken wat hier tussen staat en geef het resultaat terug.
Je hoeft die precieze technische definitie niet te onthouden.
Voorlopig is dit voldoende:
{{ iets }}
betekent:
Geef mij de uitkomst van iets.
De toestand van een entiteit opvragen
Rekenen met 2 + 3 is natuurlijk niet waarvoor we Home Assistant gebruiken.
Interessanter is de temperatuur in De Werkplaats.
Een entiteit in Home Assistant heeft een state, oftewel een huidige toestand of waarde. In de Ontwikkelaarstools kun je bekijken welke entiteiten Home Assistant kent en welke state en attributen daarbij horen.
Een veilige en veelgebruikte manier om zo'n state in een template op te vragen is:
{{ states('sensor.werkplaats_temperatuur') }}
Vervang de naam uiteraard door de echte entiteit uit jouw Home Assistant-installatie.
Je zou bijvoorbeeld als resultaat kunnen krijgen:
18.7
We kunnen hetzelfde doen met onze helper:
{{ states('input_number.werkplaats_gewenste_temperatuur') }}
Bijvoorbeeld:
19.0
We hebben nu dus beide waarden beschikbaar.
Maar we vergelijken ze nog niet.
Een getal moet ook echt een getal worden
Hier zit een belangrijk detail.
De functie:
states('sensor.werkplaats_temperatuur')
levert de state in een vorm op die je in eerste instantie het beste als tekst kunt beschouwen.
Wij willen ermee rekenen.
Daarom zetten we de waarde om naar een getal.
Dat kan met:
| float
Bijvoorbeeld:
{{ states('sensor.werkplaats_temperatuur') | float }}
float betekent hier dat we de waarde omzetten naar een getal waarin ook decimalen mogen voorkomen.
Bijvoorbeeld:
18.7
Je zult het teken | vaak in templates tegenkomen.
Je kunt het voorlopig lezen als:
Neem de waarde links en verwerk die met wat rechts staat.
Dus:
{{ states('sensor.werkplaats_temperatuur') | float }}
kun je lezen als:
Lees de temperatuur uit en maak er een getal van.
Dat is minder geheimzinnig dan het er op het eerste gezicht uitziet.
Twee waarden vergelijken
Nu kunnen we de gemeten en gewenste temperatuur vergelijken.
{{ states('sensor.werkplaats_temperatuur') | float
< states('input_number.werkplaats_gewenste_temperatuur') | float }}
Lees dit eens van links naar rechts.
Er staat eigenlijk:
Is de temperatuur in De Werkplaats lager dan de gewenste temperatuur?
Stel:
Gemeten temperatuur: 18,7 °C
Gewenste temperatuur: 19,0 °C
Voorspel
Wat verwacht je als resultaat?
Omdat 18,7 kleiner is dan 19,0:
true
Verander daarna tijdelijk de gewenste temperatuur naar bijvoorbeeld 18 °C.
Dezelfde template geeft dan:
false
Dit is een belangrijk moment.
De regel zelf is niet veranderd.
Alleen de informatie waarop de regel werkt, is veranderd.
Daarmee heb je een automatisering losgekoppeld van een vaste grenswaarde.
Een template als voorwaarde
Zo'n vergelijking kan in een automatisering worden gebruikt als templatevoorwaarde.
Het principe is:
{{ states('sensor.werkplaats_temperatuur') | float
< states('input_number.werkplaats_gewenste_temperatuur') | float }}
De automatisering mag verder wanneer de uitkomst waar is.
Dus:
true → doorgaan
false → stoppen
Daarmee kunnen we bijvoorbeeld deze regel bouwen:
Wanneer beweging in De Werkplaats wordt gedetecteerd, controleer dan of de temperatuur lager is dan de ingestelde gewenste temperatuur. Alleen dan mag de verwarming worden ingeschakeld.
Let op wat hier gebeurt.
De trigger kan nog steeds heel eenvoudig zijn:
Er wordt beweging gedetecteerd.
De template zit alleen in de voorwaarde.
Dat is vaak een goede manier om templates te gebruiken: niet overal ingewikkelde logica toevoegen, maar alleen op de plaats waar een gewone regel niet meer voldoende is.
Templates en helpers vullen elkaar aan
Je kunt nu ook beter zien waarom helpers en templates zo goed bij elkaar passen.
Een helper bewaart bijvoorbeeld:
Gewenste temperatuur = 19 °C
De template gebruikt die informatie:
Werkelijke temperatuur < Gewenste temperatuur?
De automatisering reageert op het resultaat.
Je kunt dat zien als drie afzonderlijke taken:
Helper
↓
onthoudt de instelling
Template
↓
rekent of vergelijkt
Automatisering
↓
voert de actie uit
Dat is meestal beter dan alles in één grote automatisering vastleggen.
Stel dat je later van 19 °C naar 17 °C wilt gaan.
Dan hoef je niets aan de automatisering te veranderen.
Je verandert alleen de helper.
Templates kunnen ook tekst maken
Templates zijn niet alleen bedoeld voor getallen en voorwaarden.
Ze zijn bijzonder handig voor meldingen.
Stel dat je een melding naar je telefoon wilt sturen wanneer het in De Werkplaats te koud wordt.
Je zou als vaste tekst kunnen gebruiken:
Het is te koud in De Werkplaats.
Maar Home Assistant weet ook hoe koud het werkelijk is.
Waarom zou je die informatie niet meteen meesturen?
Bijvoorbeeld:
De temperatuur in De Werkplaats is
{{ states('sensor.werkplaats_temperatuur') }} °C.
Home Assistant kan daar bijvoorbeeld van maken:
De temperatuur in De Werkplaats is 17.8 °C.
Templates kunnen binnen automatiseringen onder andere worden gebruikt om dynamische berichten samen te stellen en waarden aan acties door te geven.
Dat maakt een melding meteen bruikbaarder.
Je weet niet alleen dát er iets aan de hand is, maar ook wat Home Assistant heeft waargenomen.
Een vriendelijkere melding maken
We kunnen nog een stap verder gaan.
Stel dat je afhankelijk van de temperatuur een andere tekst wilt maken.
Bijvoorbeeld:
{% if states('sensor.werkplaats_temperatuur') | float < 15 %}
Het is behoorlijk koud in De Werkplaats.
{% else %}
De temperatuur in De Werkplaats is iets te laag.
{% endif %}
Hier zien we een tweede soort markering:
{% %}
Waar:
{{ }}
een waarde teruggeeft, wordt:
{% %}
voor logica gebruikt.
In dit voorbeeld:
{% if ... %}
betekent:
Als dit waar is…
else betekent:
Anders…
En:
{% endif %}
sluit de beslissing af.
Dat is in wezen dezelfde keuze die je eerder met Choose hebt gemaakt.
Het verschil is vooral waar je de beslissing gebruikt.
Gebruik Choose wanneer verschillende acties moeten worden uitgevoerd.
Gebruik een template bijvoorbeeld wanneer je binnen één waarde of tekst iets dynamisch wilt bepalen.
Kies niet automatisch voor een template
Templates zijn krachtig.
En precies daarom is het verleidelijk om ze overal voor te gebruiken.
Dat is meestal geen goed idee.
Als Home Assistant een gewone voorwaarde aanbiedt waarmee je hetzelfde duidelijk kunt oplossen, gebruik die dan.
Bijvoorbeeld:
Alleen doorgaan tussen 08:00 en 22:00.
Daar heb je waarschijnlijk geen template voor nodig.
Hetzelfde geldt voor:
Alleen doorgaan wanneer de lamp uit staat.
Ook daarvoor bestaat een normale toestandvoorwaarde.
Een template zoals:
{{ is_state('light.werkplaats', 'off') }}
kan prima werken.
Maar wanneer de gewone gebruikersinterface dezelfde controle duidelijker kan weergeven, heeft die meestal de voorkeur.
Een goede vuistregel is:
Gebruik eerst de gewone bouwstenen van Home Assistant. Gebruik een template wanneer je iets moet berekenen, combineren of dynamisch samenstellen wat met die bouwstenen niet prettig lukt.
Daarmee houd je automatiseringen leesbaar.
Dat wordt vooral belangrijk wanneer je er over een half jaar weer naar kijkt.
is_state() gebruiken
Toch is er één functie die handig is om te herkennen:
is_state()
Daarmee kun je controleren of een entiteit een bepaalde toestand heeft.
Bijvoorbeeld:
{{ is_state('binary_sensor.werkplaats_beweging', 'on') }}
Dit betekent:
Staat de bewegingssensor op on?
De uitkomst is:
true
of:
false
Je zou ook kunnen schrijven:
{{ states('binary_sensor.werkplaats_beweging') == 'on' }}
maar is_state() maakt duidelijker wat je probeert te controleren.
Ook hier geldt echter: als je alleen een gewone toestandvoorwaarde nodig hebt, is de standaardvoorwaarde in de automatiseringseditor vaak makkelijker te begrijpen.
Je hoeft een template niet te gebruiken alleen omdat het kan.
Let op unknown en unavailable
Er is nog een reden waarom we voorzichtig omgaan met sensorwaarden.
Een temperatuursensor geeft niet altijd netjes een getal terug.
Wanneer een sensor bijvoorbeeld tijdelijk niet bereikbaar is, kan de state zijn:
unavailable
of:
unknown
Dat is geen temperatuur.
Een template waarin je zonder nadenken met zo'n waarde gaat rekenen, kan daardoor een onverwacht resultaat geven.
Daarom zul je bij numerieke waarden vaak een standaardwaarde zien:
{{ states('sensor.werkplaats_temperatuur') | float(0) }}
Als de waarde niet in een bruikbaar getal kan worden omgezet, wordt in dit voorbeeld 0 gebruikt.
Maar let op.
Dat betekent niet automatisch dat 0 een goede standaardwaarde is.
Stel dat een defecte temperatuursensor hierdoor ineens wordt geïnterpreteerd als:
0 °C
Dan zou Home Assistant kunnen denken:
Het is heel koud, dus de verwarming moet aan.
Technisch werkt de template dan precies zoals je hem hebt geschreven.
Maar de automatisering doet niet wat je werkelijk bedoelde.
Dit is een goed voorbeeld van een fout die nuttige informatie geeft.
Het probleem zit dan niet in Home Assistant.
Het probleem zit in onze aanname:
Er zal altijd een geldige temperatuur zijn.
Bij belangrijke automatiseringen is het daarom verstandig om ook na te denken over de vraag:
Wat moet er gebeuren wanneer een sensor géén geldige waarde heeft?
Controleer eerst je gegevens
Voordat je een template maakt, is het verstandig eerst te bekijken wat Home Assistant werkelijk weet.
Ga naar:
Instellingen → Ontwikkelaarstools → Statussen
Zoek daar de gewenste entiteit op.
Controleer bijvoorbeeld:
- de exacte entiteits-ID;
- de huidige state;
- welke attributen aanwezig zijn;
- hoe een apparaat aan en uit weergeeft;
- of een sensor een getal of tekst oplevert.
De Home Assistant-documentatie adviseert juist deze stap voordat je templates met states gaat bouwen.
Ga niet uit van wat je denkt dat een entiteit bevat.
Kijk wat er werkelijk staat.
Dat voorkomt veel zoekwerk.
Eerst testen, daarna automatiseren
Laten we van onze temperatuurregel een klein experiment maken.
We willen uiteindelijk controleren:
Werkplaatstemperatuur < Gewenste temperatuur
Maar bouw nog geen complete automatisering.
Stap 1 — Controleer de gemeten waarde
In de template-editor:
{{ states('sensor.werkplaats_temperatuur') }}
Controleer of je de verwachte temperatuur ziet.
Stap 2 — Controleer de helper
{{ states('input_number.werkplaats_gewenste_temperatuur') }}
Controleer opnieuw de uitkomst.
Stap 3 — Zet beide om naar getallen
{{ states('sensor.werkplaats_temperatuur') | float }}
en:
{{ states('input_number.werkplaats_gewenste_temperatuur') | float }}
Stap 4 — Vergelijk ze
Pas daarna:
{{ states('sensor.werkplaats_temperatuur') | float
< states('input_number.werkplaats_gewenste_temperatuur') | float }}
Stap 5 — Verander één waarde
Pas de helper aan.
Bijvoorbeeld van:
19 °C
naar:
17 °C
Voorspel vóór je kijkt wat de uitkomst van de template zal zijn.
Controleer daarna of je voorspelling klopt.
Je hebt nu ieder afzonderlijk onderdeel getest.
Pas als dat werkt, zet je dezelfde logica in de automatisering.
Dit lijkt omslachtiger dan alles in één keer bouwen.
In de praktijk bespaart het tijd.
Wanneer de automatisering later niet werkt, weet je namelijk al dat de losse vergelijking correct functioneert.
Van meting naar betekenis
Templates worden pas echt interessant wanneer je meerdere stukjes informatie combineert.
Stel dat we in De Werkplaats hebben:
sensor.werkplaats_temperatuur
sensor.werkplaats_licht
binary_sensor.werkplaats_beweging
input_boolean.werkplaats_automatisch
Je zou dan willen bepalen:
Moet het werklicht aan?
De regel zou kunnen zijn:
- automatische bediening staat aan;
- er is beweging;
- er is minder dan 300 lux.
In gewone taal is dat:
Automatisch aan
EN
beweging aanwezig
EN
lichtniveau lager dan 300 lux
In een template zou dat bijvoorbeeld kunnen worden:
{{
is_state('input_boolean.werkplaats_automatisch', 'on')
and is_state('binary_sensor.werkplaats_beweging', 'on')
and states('sensor.werkplaats_licht') | float < 300
}}
Nu begint een template meerdere gegevens samen te brengen tot één antwoord:
true
of:
false
Je kunt dit zien als een klein stukje beslislogica.
Maar stel jezelf meteen een tweede vraag:
Wordt dit hierdoor duidelijker?
Je zou dezelfde drie controles waarschijnlijk ook als drie gewone voorwaarden onder elkaar kunnen zetten.
Voor een beginner is dat vaak gemakkelijker te lezen.
Een template wordt vooral waardevol wanneer gewone voorwaarden de bedoeling niet meer duidelijk kunnen uitdrukken.
Maak templates niet slimmer dan nodig
Een automatisering die werkt is prettig.
Een automatisering die je begrijpt is beter.
Je kunt met templates behoorlijk ingewikkelde constructies maken. Je kunt lijsten doorzoeken, tijden berekenen, attributen combineren, teksten opbouwen en allerlei filters toepassen. Home Assistant bevat daarvoor een groot aantal templatefuncties, filters en tests.
Maar ingewikkelder betekent niet automatisch beter.
Stel dat je na een jaar deze template tegenkomt:
{{ is_state('input_boolean.werkplaats_automatisch','on')
and states('sensor.werkplaats_licht')|float(0)<states('input_number.werkplaats_lichtgrens')|float(300)
and is_state('binary_sensor.werkplaats_beweging','on') }}
Technisch kan daar niets mis mee zijn.
Maar dit leest waarschijnlijk prettiger:
{{
is_state('input_boolean.werkplaats_automatisch', 'on')
and
states('sensor.werkplaats_licht') | float(0)
< states('input_number.werkplaats_lichtgrens') | float(300)
and
is_state('binary_sensor.werkplaats_beweging', 'on')
}}
De computer maakt het niets uit.
Voor jou wel.
En jij bent degene die over een half jaar moet begrijpen waarom het licht niet aangaat.
Een template is geen geheugen
Na het vorige hoofdstuk is er nog een onderscheid dat belangrijk is.
Een template onthoudt normaal gesproken niets.
Een template kijkt naar de informatie die op dat moment beschikbaar is en berekent daar een resultaat uit.
Bijvoorbeeld:
Temperatuur = 18,2 °C
Gewenste temperatuur = 19 °C
De template berekent:
18,2 < 19
en geeft:
true
Verander je de helper naar 18 °C, dan wordt dezelfde berekening:
18,2 < 18
en dus:
false
De helper bewaart de instelling.
De template gebruikt de instelling.
Dat verschil is belangrijk:
Helpers bewaren informatie. Templates verwerken informatie.
Samen vormen ze een krachtige combinatie.
Templates kunnen ook nieuwe sensoren vormen
Tot nu toe gebruiken we templates binnen een automatisering.
Home Assistant heeft daarnaast een Template-integratie waarmee je entiteiten kunt maken waarvan de waarde uit andere gegevens wordt afgeleid.
Je zou bijvoorbeeld van verschillende gegevens één nieuwe sensor kunnen maken.
Denk aan:
Comfort in De Werkplaats
waarvan de toestand afhankelijk is van temperatuur en luchtvochtigheid.
Bijvoorbeeld:
Comfortabel
Te koud
Te warm
Te vochtig
Dat kan handig zijn wanneer dezelfde berekening op meerdere plaatsen nodig is.
Maar daarmee gaan we een stap verder dan nodig is om automatiseringen te leren begrijpen.
Voorlopig gebruiken we templates vooral daar waar we ze direct kunnen zien en testen:
- in voorwaarden;
- in acties;
- voor berekende waarden;
- voor dynamische meldingen.
Een praktische template voor De Werkplaats
Laten we afsluiten met een voorbeeld dat helpers en templates combineert.
We hebben:
sensor.werkplaats_temperatuur
input_number.werkplaats_minimumtemperatuur
De helper staat bijvoorbeeld op:
16 °C
Wanneer de temperatuur daaronder komt, willen we een waarschuwing.
De controle kan zijn:
{{
states('sensor.werkplaats_temperatuur') | float
<
states('input_number.werkplaats_minimumtemperatuur') | float
}}
En de melding:
Waarschuwing: het is in De Werkplaats
{{ states('sensor.werkplaats_temperatuur') }} °C.
De ingestelde ondergrens is
{{ states('input_number.werkplaats_minimumtemperatuur') }} °C.
Bij een temperatuur van 14,8 °C en een ingestelde grens van 16 °C krijgt je melding bijvoorbeeld de betekenis:
Waarschuwing: het is in De Werkplaats 14,8 °C.
De ingestelde ondergrens is 16 °C.
Dat is veel bruikbaarder dan:
Temperatuur te laag.
De automatisering vertelt nu niet alleen wat hij heeft besloten.
Hij laat ook zien waarom.
Dat maakt controleren en foutzoeken een stuk eenvoudiger.
Wat je uit dit hoofdstuk moet meenemen
Je hoeft Jinja na dit hoofdstuk niet uit je hoofd te kennen.
Dat is ook niet het doel.
Belangrijker is dat je herkent wanneer een template nuttig kan zijn.
Een gewone regel zegt bijvoorbeeld:
Als temperatuur < 18 °C
Een helper maakt de grens instelbaar:
Gewenste temperatuur = 19 °C
Een template kan vervolgens zeggen:
Als werkelijke temperatuur < gewenste temperatuur
Daarmee verschuif je langzaam van vaste automatiseringen naar regels die zich aanpassen aan de informatie in Home Assistant.
Onthoud vooral deze vier punten:
- Gebruik gewone voorwaarden wanneer die voldoende zijn.
- Gebruik helpers om instellingen of toestanden te bewaren.
- Gebruik templates om waarden te berekenen, vergelijken of samen te stellen.
- Test een template eerst afzonderlijk voordat je hem onderdeel maakt van een grotere automatisering.
En misschien wel de belangrijkste:
Een ingewikkelde template is niet automatisch een slimme automatisering.
De beste oplossing is meestal degene waarvan je later nog kunt begrijpen waarom Home Assistant een bepaalde beslissing neemt.
Tot nu toe hebben we onze automatiseringen zelf opgebouwd. We hebben triggers, voorwaarden, acties, keuzes, wachttijden, scripts, helpers en nu ook templates gebruikt.
Maar Home Assistant biedt nog een andere mogelijkheid.
Je kunt complete automatiseringspatronen hergebruiken die door iemand anders zijn voorbereid.
Die heten blueprints.
Dat klinkt aantrekkelijk: importeren, een paar apparaten selecteren en klaar.
Maar juist daar is het belangrijk dat je blijft begrijpen wat je Home Assistant laat doen.
In het volgende hoofdstuk kijken we daarom naar:
Blueprints — Handig gereedschap, geen zwarte doos.