Should be var Number counter1 = 0
Otherwise, you will get an error when you try to counter1 = counter1 + 1.
Was that your error?
Let’s step back a second because your code is WAY more complex than it needs to be. This is why I keep suggesting the Expire binding. If I understand the code correctly you want an alert when your iPhone is away for 3 minutes or more and another alert when the iPhone comes back. And you have more than one iPhone you are tracking.
So let’s drop all the timers, and all the counters and add apply my Generic Presence Detection example.
So if I expand that example to include a way to detect when individuals leave or arrive rather than just generic someone is home:
Switch Present "Someone is Present" <present> // master presence switch
Group:Switch:AND(OFF,ON) gPresent <present> // all presence sensors belong to this group
Switch Present_Timer { expire="3m,command=OFF" }
Group:Switch:AND(OFF,ON) gHamPresent <present>
Switch Ham_Present <present> // master Ham present switch
Switch Ham_Present_Timer { expire="3m,command=OFF" }
Group:Switch:AND(OFF,ON) gPerson2Present <present>
Switch Person2_Present <present> // master Person2 present switch
Switch Person2_Present_Timer { expire="3m,command=OFF" }
Switch Ham_iphone (gPresent, gHamPresent)
Switch Ham_otherSensor (gPresent, gHamPresent)
...
Switch Sensor1Person2 (gPresent, gPerson2Present)
Switch Sensor2Person2 (gPresent, gPerson2Present)
...
Rules:
import org.eclipse.xtext.xbase.lib.Functions
val Functions$Function3 <GroupItem, SwitchItem, SwitchItem, Boolean> processPresence = [grp, sw, timer |
// came home
if(grp.state == ON && sw.state != ON) {
timer.postUpdate(OFF) // cancel the timer if necessary
sw.sendCommand(ON)
sendBroadcastNotification(sw.label + " returned home")
}
// not home
else if(grp.state == OFF and sw.state != OFF){
timer.sendCommand(ON) // start the timer
}
true
]
val Functions$Function1 <SwitchItem, Boolean> processTimer = [sw |
sw.sendCommand(OFF)
sendBroadcastNotification(sw.label + " has left home")
true
]
rule "System started"
when
System started
then
// assume no one is home on startup
Present.sendCommand(OFF)
Ham_Present.sendCommand(OFF)
Person2_Present.sendCommand(OFF)
end
rule "gPresent updated, at least one sensor changed state"
when
Item gPresent received update
then
processPresence.apply(gPresent, Present, Present_Timer )
end
rule "gHamPresent updated, at least one sensor changed state"
when
Item gHamPresent received update
then
processPresence.apply(gHamPresent, Ham_Present, Ham_Present_Timer )
end
rule "gPerson2Present updated, at least one sensor changed state"
when
Item gPerson2Present received update
then
processPresence.apply(gPerson2Present, Person2_Present, Person2_Present_Timer )
end
rule "Present_Timer expired"
when
Item Present_Timer received command OFF
then
processTimer.apply(Present)
end
rule "Ham_Present_Timer expired"
when
Item Ham_Present_Timer received command OFF
then
processTimer.apply(Ham_Present)
end
rule "Person2_Present_Timer expired"
when
Item Person2_Present_Timer received command OFF
then
processTimer.apply(Person2_Present)
end
I’m certain there are ways to combine some of this code but this is already a lot simpler logic. By moving the Timer logic to the Timer Items and the Expire binding we no longer have to do any bookkeeping at all. All the issues with casting, keeping track of timers or counters disappears and you just have a few simple rules which I’ve combined the logic for using lambdas. No longer are there global vars, nested if else statements, etc.
And this logic allows you to easily add more sensors for presence detection without ever needing to change your rules again. You just need to add the sensors to the right groups.