In the end, you could use Present as the timer so long as ON keeps getting sent to it while you are present every <n minutes where n is the timer length.
I did just that. My presence detection is based on the Fritz!Box (router) TR065 binding. The binding updates presence items (MAC addresses of iPhones) once per minute. So there is my âevery x minutesâ trigger to keep the timers running.
The Fritz!Box presence detection is generally very reliable. However, there are two catches: Sometimes a MAC will be falsely reported as being absent for a short period of time. Especially at night, when the phones are on standby. I have learned from experience that this generally happens within a timeframe of less than five minutes. Secondly, the moment a MAC becomes (really) absent, it sometimes gets reported as being present again directly after the absence and then (finally) absent again within seconds. It then stays absent reliably.
The solution is what you proposed, and it is beautifully elegant. I cannot use the presence Items controlled by the binding directly for the reasons mentioned above. So they serve as the triggers for the ârealâ presence items I then use in other rules. The ârealâ presence items expire after 5 minutes if not updated. In other words, presence is detected immediately and absence is detected with a 5min delay. (Actually, just for completenessâ sake: Absence is detected with a 20mind delay because the Fritz!Box reports absence with a delay of 15min. This seems to be built into the firmware and cannot be helped.)
Note that I also use âarrivalâ items. I have defined a timeframe of 5min in which someone is in the state of arriving. E.g. the front door light would be switched on during that time (if it is dark, etc.). Those are just âsugarâ items that are not really necessary. The advantage being that the arrival timeframe can be defined in the items definition file as well.
Items:
// Fritz!Box presence items
// iPhone A
Switch PresenceFritzA "A (Fritz) [MAP(presence.map):%d]" <present> {fritzboxtr064="maconline:xx-xx-xx-xx-xx-xx"}
// iPhone B
Switch PresenceFritzB "B (Fritz) [MAP(presence.map):%d]" <present> {fritzboxtr064="maconline:xx-xx-xx-xx-xx-xx"}
// if at least one person is present (ON), the group is present (ON), else absent (OFF)
Group:Switch:OR(ON, OFF) PresenceAnyone "Anyone [MAP(presence.map):%d]" <present>
// be present immediately but be absent after (not receiving presence update for) five minutes
Switch PresenceA "A [MAP(presence.map):%d]" <present> (PresenceAnyone) {expire="5m,command=OFF"}
Switch PresenceB "B [MAP(presence.map):%d]" <present> (PresenceAnyone) {expire="5m,command=OFF"}
// if at least one person is arriving (ON), anyone is arriving (ON) else not (OFF)
Group:Switch:OR(ON, OFF) ArrivalAnyone "Anyone [MAP(arrival.map):%d]"
// status "arriving" is kept for five minutes
Switch ArrivalA "A [MAP(arrival.map):%d]" (ArrivalAnyone) {expire="5m,command=OFF"}
Switch ArrivalB "B [MAP(arrival.map):%d]" (ArrivalAnyone) {expire="5m,command=OFF"}
// There is no XOR for groups so we need to use an Item and a rule
Switch ArrivalFirst "First [MAP(arrival.map):%d]" {expire="5m,command=OFF"}
Rules:
rule "A (Fritz) present or absent"
when
Item PresenceFritzA received update ON
then
PresenceA.sendCommand(ON);
end
rule "B (Fritz) present or absent"
when
Item PresenceFritzB received update ON
then
PresenceB.sendCommand(ON);
end
rule "A arriving"
when
Item PresenceA changed to ON
then
ArrivalA.sendCommand(ON)
end
rule "B arriving"
when
Item PresenceB changed to ON
then
ArrivalB.sendCommand(ON)
end
rule "First arrival"
when
Item PresenceAnyone changed to ON
then
ArrivalFirst.sendCommand(ON)
end
Thank you very much for that elegant solution. It helped me do away with tons of lines of cumbersome timer code as well.