Generic Presence Detection

“Misbehave” is only going to happen when the system does something you don’t want it to do. That timer is called an anti-flapping timer. If, for example, you go and stand just at the edge of your WiFi such that your phone is constantly connecting to and then losing connection to the network. The Presence Switch will continue to flip ON and OFF which might cause undesirable behaviors. By waiting for five minutes of OFF before setting the Presence Item to OFF you avoid this flapping. It won’t go OFF until it knows you are really gone.

Notice how we only do this for OFF. For ON we immediately turn ON at the first sign that someone has come home.

It doesn’t have to be five minutes. But it does need to be longer than the longest polling period for your sensors. For example, if the Network binding is pinging your phones every minute for presence, the time should be two minutes.

Another name for this is hysteresis. It’s a buffer that prevents a system from rapidly flipping ON/OFF when it is near the control point.

For Bluetooth presence detection sensor I have been using Monitor running on Raspberry Pi Zero with good results. It’s designed to work with phones, dongles and some watches but may not work directly with some Android devices.

The repository has clear instructions for setting up the sensors. I’m using three in an average size single level house (front door, backdoor, living room), configured to respond as a device_tracker responding ON/OFF via MQTT. The code on this thread has worked seamlessly with this setup. Thank you to all the contributors :slight_smile:

Thanks, I’ll give that a look this weekend when I’m planning on testing my Bluetooth set up.

@rlkoshak whats the benefit of using the Timer instead of :

Switch Presence "Someone is Present" <present> // master presence switch, represents to the rest of OH where someone is home
Group:Switch:AND(OFF,ON) Presence_Sensors <present> // all presence sensors belong to this group

// Optionally one can create additional groups to aggregate all the sensors for
// each person if that matters to you, but the sensors need to all be members of
// Presence_Sensors as well

Switch Sensor1Person1 (Presence_Sensors){ expire="5m,command=OFF" } 
Switch Sensor2Person1 (Presence_Sensors){ expire="5m,command=OFF" } 
Switch Sensor1Person2 (Presence_Sensors){ expire="5m,command=OFF" } 

then the rule would be:

rule "Reset Presence and sensors to OFF on startup"
    System started

rule "A presence sensor updated"
        Item Presence_Sensors changed

    if(Presence_Sensors.state == "ON") {
        logInfo(logName, "Someone is home")
    else  {
          logInfo(logName, "Everyone is still away, setting presence to OFF")

It depends on what behavior you want and how your SensorXPersonX Items are updated. Not all sensors will update those Switches every five minutes and instead only update when there is a change. In that case you will have those Items go to OFF even when you are still present which will break the presence detection.

By creating a Timer just to control when the global Presence Switch goes to OFF, the example works regardless of how the individual sensors work and keeps the example more generic.

If you know all your sensors update at least every five minutes then putting the timers on each sensor Item should work.


I’m working on my presence detection a bit more. I’ve had success getting my miniNut Bluetooth device to work with the brilliant Bluetooth binding

and both my wife and I have a nut each on our car fob. Now the issue is that sometimes we go out together in one car, (a chore all married couples have to do from time to time ;-)), so my OH presence doesn’t flip to away.

What I’ve done is add the presence of both our iphones via:

Again, this in isolation works great.

So, my question is on the logic of this…I’ve had a slightly modified version of rlkoshak’s great presence detection script on this thread running but I want to update it so that:

If, and only if, both my miniNut and iPhone are present then I am home
If, and only if, both my wifes miniNut and iPhone are present then she is home
If a guest has a guest miniNut present then guest is present.

In each case if nothing is detected then no one is home…

So, the 3rd part is easy, I’m just wondering how easy it would be to code the if and only if part of the first two???

The very original version of this example handled that case but I dropped it because I wasn’t using it and it added a whole lot of complexity in the Items (but not the Rule luckily.

So here is what you need to do. Create a new Group:Switch:AND(ON,OFF) for each person. The AND(ON,OFF) means that all members of the Group must be ON for the Group’s state to be ON.

Now, instead of putting all the sensors into the Presence_Sensors Group. Instead put all the sensors for person 1 into their Group and all the sensors for person 2 into their separate Group.

Finally, put the new Groups into the Presence_Sensors Group.

Group:Switch:AND(OFF,ON) Presence_Sensors <present>
Group:Switch:AND(ON,OFF) Me_Sensors <present> (Presence_Sensors)
Group:Switch:AND(ON,OFF) Wife_Sensors <present> (Presence_Sensors)

Switch Nut_Me (Me_Sensors)
Switch iPhone_Me (Me_Sensors)
Switch Nut_Wife (Wife_Sensors)
Switch iPhone_Wife (Wife_Sensors)
Switch Nut_Guest (Presence_Sensors)

No changes are required to the Rule.

@tassieKev Monitor looks great. Thank you for the link.

Awesome, thanks for that…learning every day, so AND(OFF,ON) means any of the group and AND(ON,OFF) means all of the group…I can see these being very useful on many occasions!

It is a bit more nuanced than that. In both cases it means “all members of the Group”. That is essentially what AND means. The first argument indicates what all the members of the Group need to be for the Group to be that state. The second argument indicates what the Group’s state is to be if one or more of the members are not the state in the first argument. So

  • AND(OFF,ON) = If all members are OFF, the Group’s state is OFF. Otherwise the Group’s state is ON
  • AND(ON,OFF) = If all members are ON, the Group’s state is ON. Otherwise the Group’s state is OFF

In both cases, the aggregation function is checking all the members of the Group.

If you want to test for any of the Group, you would use OR instead.

  • OR(OFF,ON) - If any member is OFF, the Group is OFF, otherwise ON
  • OR(ON,OFF) - If any member is ON, the Group is ON, otherwise OFF

All good to know, thanks for the explanation. I also like the nesting in the groups :ok_hand:


Thought someone might be interested in the slight twist I’ve made to this presence detection…might help get someone’s ideas flowing…


I have rlkoshak’s generic presence detection in a separate rule, controlled by the presence of my and my wife’s iPhones via icloud binding, if I am home it sets vPresent to ON, if I’m away, it’s OFF.

I wanted to have a secondary level of security based around my motion sensors, so created this little rule to check if someone is home when the motion sensors pick up something. The reason being is obviously if we aren’t at home then the wasp in a bottle thought is that someone is in our house but it can’t be us…

Items Used

    // counts the number of motion sensors items reporting ON
    Group:Number:SUM gMotion
    // Item to represent motion sensors
    Switch vMotion "Motion [:%s]" <motion>

Then you just need to add whatever sensor(s) item you have to the gMotion group.

The Rule

   val logName = "motion"

    rule "Reset vMotion to OFF on startup"
        System started
    	gMotion.members.forEach[ SwitchItem s | s.sendCommand(OFF)]

    rule "A motion sensor updated"
    	Item gMotion changed
        // write to logfile
        logInfo(logName, "gMotion changed to " + gMotion.state.toString)
        // check if gMotion is > 0 and if someone is home
    	if(gMotion.state > 0 && vPresent.state == ON) 
    		logInfo(logName, "Motion Detected but someone is home - nothing to do")
    	    logInfo(logName, "Motion Detected - Checking if anyone is home")	
            // Refresh iPhone location to see if someone has come home but location hasn't caught up
            //Wait 5 seconds for refresh to return results           
                //is someone actually home?
                if(vPresent.state == ON) 
                    logInfo(logName, "Motion Detected - Phew, someone is home - nothing to do")
                    //Set vMotion to ON which will trigger separate rule to arm cameras, flash lights etc
                    vMotion.sendCommand(ON) // set vMotion ON
                    logInfo(logName, "Motion Detected - ALERT - INTRUDER")

Pretty simple really, but a little twist on the original…

It’s taken me a few iterations to make it this simple but this way it follows the generic presence ideal of just turning a dummy variable to ON and then you can run others things from it.

Hopefully someone will find it useful, and I’m very much open to thoughts and comments to make it more robust / better…



I was hoping someone would be able to help, I’ve essentially copied the code from the OP to ensure I can get this working before I start making my changes.

Now, on the whole part works as expected. I just cannot get the Presence_Timer to go OFF once it has been switched ON.

Any ideas why this would be happening?

Many thanks,

Did you install the Expire binding?

Doh! That was exactly the culprit - Thank you so much for the rapid response, working as expected! :slight_smile:

One thing if i may; i noticed the Expire binding is v1, is this still supported/will there be a replacement for v2?

It will be re-implemented as part of the core or perhaps as a profile. It never should have been a binding in the first place. It is questionable whether the binding will continue to be supported in OH 3+. But I’ve implemented a drop in replacement for the binding in Python. JSR223 Jython Replacement for Expire Binding

1 Like

Thats great, thanks for the clarification @rlkoshak :slight_smile:

Just a question as I’ve not loaded a Python script in OH, is this pretty straight forward? I’d rather have this script if it is likely the binding will be deprecated.

Thanks once again.

See NOTE that the way Jython get’s installed is changing shortly but likely not before the final release of OH 2.5. See [beta testers wanted!] Jython addon w/ helper libraries. Instead of the many manual steps described in the helper docs you just need to install it as an add-on like any other.

1 Like

That is awesome, thanks so much @rlkoshak - most appreciated :slight_smile:

Will give it a go and let you know how I get on!

Thanks a lot for the tip. Installing Monitor was easy enough. I don’t have much experience with MQTT, so I don’t know how to integrate this into OH2 yet. Do you have any hints or even rule code you could share? That would probably save me a lot of time :grinning: