Så vissa av er har erfarenhet av GEA. Normalt körs GEA's regler var 30:e sekund (går att ställa om) eller så reagerar de på direkt på triggers (-1).
En GEA regel som ska göra något om en dörr stått öppen i 5min, kollar regeln var 30:e sekund och efter 10*30s då villkoret varit sant så kör den höger-sidan av regeln.
ER är annorlunda här och det kan vara bra att förstå. 'for' är konstruktionen för att se om ett villkor varit sant en viss tid.
Code: Select all
rule("for(<tid>,<villkor>) => <commandon>")
Vad ER gör är att när regeln definieras så inspekteras <villkor> för att se vilka "potentiella" triggers som det innehåller. Om det är en test av en fibaro global, eller status på en device eller ngt annat. Ex.
Code: Select all
rule("for(00:05,77:isOn & $Home=='away' & 10:00..11:00) => log('Hupp")")
Regeln ovan anropas när deviceID 77 ändrar status, fibaro global 'Home' ändrar status, när kl. blir 10:00, och när kl. blir 11:00:01.
Vid varje anrop så kommer 'for' att beräkna villkoret (77:isOn & $Home=='away' & 10:00..11:00) och om det är sant starta en timer för 5min. Om det är falskt så stoppas timern. Om en timer är redan startad, men det har inte gått 5min än så görs inget.
Det viktiga här är att regeln reagerar på triggers, inte testas med jämna intervall som i GEA. Oftast gör det ingen skillnad. Notera dock att man måste definiera 77, och 'Home' i scen headern annars får vi ingen trigger. I GEA behövs det inte eftersom de hämtar värdena själv var 30:e sekund.
Fördelen med ER är att om 77 och Home inte ändrar värden så behöver regeln inte köras (förutom kl. 10.00 och 11.00.01).
En annan skillnad är att man bör tänka på vad som ska hända när en ER scen startar upp. Regler körs inte automatiskt vid startup utan när de får en trigger (interval och tidsregler @ och @@, körs men de får 'tids-triggers' av ER)
I det tidigare exemplet när en push notis skulle sändas om ett kylskåp varit öppet i 3min, 'for' regeln triggas när kylskåpet öppnas.
Code: Select all
rule("for(00:03,kok.kylen:breached) => telefon.daniel:msg='Kylen har stått öppen i 3min' ; log('Notis skickad!')")
men vi har ett potentiellt problem. Om kylskåpsdörren redan är öppen när vi startar ER scenen, så får regeln ingen trigger (inget nytt händer).
Vi skulle egentligen vilja att regler kördes en gång vid startup. Tyvärr orsakar det andra problem i det generella fallet (jag kan återkomma varför i en annan post), men vi skulle behöva ngt sätt att sparka på vissa regler när scenen startas upp.
För de flesta regler kan vi göra det (i en ny version av EventRunner som jag just laddade upp till GitHub)
Code: Select all
rule("for(00:03,kok.kylen:breached) => telefon.daniel:msg='Kylen har stått öppen i 3min' ; log('Notis skickad!')").start()
rule(<regel>) returnerar ett Lua objekt som representerar regeln. Det objektet har 3 metoder; enable(), disable(), och start().
Den sistnämnda, 'start()', kör regeln direkt utan att vänta på en trigger, och är vad vi behöver här. Om kylskåpsdörren är stängd händer inget, och om den är öppen så startas timern.
Ett annat exempel är om vi ska göra ngt beroende på en fibaro global
Code: Select all
rule("$HomeStatus=='away' & alarm:isOff => alarm:on").start()
den här regeln vill vi förmodligen också köra när scenen startar upp, och vi testar att larmet är av så vi inte startar det 2 ggr på varandra.
Inget av det här är ett problem när scenen väl kör men vid startup bör vi tänka igenom vad som ska hända. För tidsregler finns också 'catch' flaggan som kör en regel vid startup även om tiden har passerat.