Home Assistant (afgekort: HA) wordt steeds intuïtiever in gebruik. De nieuwe ontwikkeling om op meer natuurlijke wijze automatiseringen op te stellen is veelbelovend, hoewel ik het zelf nog niet gebruik. Voor ik in detail treedt over mijn ervaringen met triggers, geef ik voor de geïnteresseerden een korte intro / uitleg over het gebruik van HA; via het internet is veel meer goed leesbare informatie beschikbaar, dus beschouw dit als een uitnodiging om verder te kijken.
In Home Assistant definieer je sensoren en bedieningselementen voor door HA ondersteunde hardware. Een slimme stekker kun je aan of uit schakelen, terwijl die stand plus eventueel het vermogen van het aangesloten apparaat uitgelezen kan worden. Toegang tot zo’n apparaat krijg je door de bedieningselementen en sensoren op te nemen in een dashboard: simpelweg een grafische interface op je mobiele telefoon, tablet of PC. Naast rechtstreekse bediening kun je ook automatiseringen programmeren. Daarmee bedien je het apparaat automatisch op basis van sensorwaarden (“als het vermogen groter is dan…”) of toestanden (“als de schakelaar aan of uit staat”). Dit noemt men “triggers”. Je kunt bovendien voorwaarden (“condities”) opgeven waaraan voldaan moet zijn om de gewenste acties uit te voeren (“zet schakelaar om”, “stuur bericht”, “dim een lamp”, et cetera). Zulke acties kunnen gebundeld zijn in een script, en binnen zo’n script kun je met logische bouwstenen weer voorwaarden opnemen, keuzes maken enzovoorts. Soms is het handig om een “scene” te definiëren: een set van bij elkaar horende toestanden van apparaten, zoals bijvoorbeeld de lampen in je woonkamer. De scene legt dan vast welke lampen aan staan, en met welke kleur en/of intensiteit (als een lamp dat kan). Maar het kan natuurlijk ook zoiets zijn als een heleboel schakelaars die tegelijk in de juiste stand moeten staan, of rolluikposities, of combinaties van al deze voorbeelden. Op deze wijze kunnen heel complexe automatiseringen worden opgebouwd. Het komt de leesbaarheid ten goede dat elke stap hernoemd kan worden tot een begrijpelijke tekst. Het geheel is dan meteen de beschrijving van de automatisering. Deze blijft zo erg overzichtelijk, ook later, als je alweer vergeten bent welke puzzel je hebt opgelost. Samenvattend:
Ik gebruik meestal de triggers zoals het programma mij die presenteert. Maar soms is dat niet voldoende. Laat ik als voorbeeld nemen wanneer een laadapparaat ingeschakeld moet zijn als de zonnepanelen meer dan 1000W leveren.
Deze trigger wordt actief als het vermogen van 999 naar 1001 gaat. Eenmaal boven 1000W zal de trigger nooit meer actief worden. Ook niet als de lader uitgeschakeld wordt, bijvoorbeeld omdat de waterkoker even veel stroom vraagt. Pas als het vermogen onder de 1000W zakt, en daarna weer stijgt, zal de trigger de automatisering starten.
Gelukkig kent Home Assistant zoiets als templates, simpel gezegd: berekeningen op basis van toestanden en sensorwaarden, die uiteindelijk weer een toestand of waarde opleveren. Ik heb bijvoorbeeld aan de zuid- en westzijde van het huis 2 sensoren voor lichtsterkte om in te schatten hoe sterk de zon schijnt. De gemiddelde waarde daarvan bereken ik met:
{{ 0.5 * (states('sensor.zuidzon_luminance')|float(0) + states('sensor.westzon_luminance')|float(0)) }}Zo’n template kijkt continu naar de onderliggende elementen, en werkt bij elke wijziging de template uitkomst bij.
“float(x)” betekent niet meer dan dat de sensorwaarde vervangen wordt door “x” als deze om de een of andere reden niet beschikbaar is. Die waarde kies je zodanig dat de template zich naar wens gedraagt als zo’n fout optreedt (wanneer bijvoorbeeld WiFi wegvalt, een batterij leeg is, of de stekker uit het stopcontact ligt, enzovoorts).
Op deze wijze definieer je zelf nieuwe sensoren op basis van bestaande sensoren (“helpers” genaamd). Het heeft mij even moeite gekost om de syntax van templates te doorgronden, maar toen dat gelukt was (mensen met een software achtergrond zullen hier geen probleem mee hebben) ging er een nieuwe wereld voor me open. Zo kun je een sensor definiëren die de afgeleide is van bijvoorbeeld het genoemde vermogen. Een afgeleide geeft aan in welke richting en hoe sterk een waarde verandert: negatief is dalend, positief is stijgend. Je kunt zelfs de stapgrootte ingeven, of het tijdsinterval waarover gemeten moet worden. Mijn voorbeeld:
- Het vermogen van de zonnepanelen: sensor.dakpanelen_productievermogen
- De afgeleide van deze sensor: sensor.dakpanelen_zon_verandering
Ik definieerde de volgende zogenaamde template trigger:
{{ states('sensor.dakpanelen_zon_verandering')|float(0) > 1 and states('sensor.dakpanelen_productievermogen')|float(0) > 1000 }}Dit template levert een logische toestand TRUE of FALSE, afhankelijk van de waarden van de sensoren. Hier staat dus, in simpele bewoording:
“Als de zonneopbrengst hoger is als 1000W EN die waarde stijgt met meer als 1W/seconde, dan is de waarde: TRUE”.
De automatisering wordt nu bij elke redelijke stijging geactiveerd zolang het vermogen boven de 1000W ligt, onafhankelijk van een daling tot onder 1000W (zoals voorheen). Je kunt ook de volgende template gebruiken:
{{ states('sensor.dakpanelen_zon_verandering')|float(0) != 0 and states('sensor.dakpanelen_productievermogen')|float(0) > 1000 }}Nu wordt bij elke stijging of daling de automatisering gestart, als tenminste het vermogen groter dan 1000W is. Een afgeleide is normaal gesproken “0” (nul), tenzij er een waardeverandering is. Om minder triggers te genereren kun je een drempelwaarde voor de stijging aangeven:
{{ (states('sensor.dakpanelen_zon_verandering')|float(0) > 1 or states('sensor.dakpanelen_zon_verandering')|float(0) < -1) and states('sensor.dakpanelen_productievermogen')|float(0) > 1000 }}De drempelwaarde voor de verandering kan willekeurig gekozen worden (ook verschillend voor stijging of daling), maar het is goed om te weten dat grote stappen, gemiddeld over een seconde, zelden voorkomen. Op veel plekken in mijn automatiseringen heb ik gewoon “0” ingevuld, hetgeen betekent dat elke stijging of daling meegenomen wordt. Je kunt ook de bepaling van de afgeleide laten middelen over een langer tijdsinterval. Dan reageert het systeem trager, maar worden korte piekjes niet meegenomen.
Overigens zijn zulke templates praktisch overal in een automatisering te gebruiken: in voorwaarden, scripts, nieuwe helpers en ga zo maar door. Het levert een veelvoud van mogelijkheden op, zodat eigenlijk elk probleem wel oplosbaar is. Een andere toepassing is als je meerdere triggers gebruikt, en voor elke trigger andere voorwaarden hebt. Een op de standaard manier toegevoegde conditie wordt bij alle triggers gebruikt. Bij meerdere triggers voor een automatisering kies je via een bouwsteen per trigger de juiste set acties of het passende script. Je template trigger combineert nu de trigger met de voorwaarde. Bijkomend voordeel is dat de evaluatie van de voorwaarde niet pas begint nadat de trigger heeft plaatsgevonden. Door combinatie in een template is er überhaupt geen trigger als niet aan de voorwaarde voldaan is. Voorbeeld:
{{ is_state('switch.zb_i15', "off") and states('sensor.hw_battery_33e7c0_laadpercentage') | float(0) < 10 and states('sensor.grasbaan_vermogen') | float(0) > 150 }}Dit template (gebruikt als trigger voor een automatisering) levert een logisch TRUE als aan drie voorwaarden wordt voldaan: een bepaalde schakelaar staat uit, een batterij is bijna ontladen (<10%) en er wordt op een bepaald punt meer dan 150W vermogen gemeten. In elke andere situatie is de uitkomst FALSE, en start de automatisering niet. Dit geeft je de mogelijkheid om de trigger te blokkeren als hij niet meer nodig is. Om naar het eerdere voorbeeld van de lader te gaan: als de lader al aanstaat, hoef je niets te doen:
{{ (states('sensor.dakpanelen_zon_verandering')|float(0) > 1 or states('sensor.dakpanelen_zon_verandering')|float(0) < -1) and states('sensor.dakpanelen_productievermogen')|float(0) > 1000 and is_state('switch.lader', "off") }}Deze trigger is alleen actief als de lader uit staat (en het vermogen groter is dan 1000W en een stapje verandert).

