Presence detection via iPhone's mDNS Entry. How to integrate into OH2?

Hi everybody,

I’m a newbie regarding OH(2) and currently think about all the possibilities that are feasible by using OH. What’s crucial for me is presence detection. Because everybody who lives in this house has an iPhone I want to use this device as a source for figuring out if a specific person is at home or not. After doing some research I found out that iPhones register themselves to the network’s mDNS service roughly every 1-2 minutes even when locked and inactive. By doing a mDNS query once a second I am able to detect when an iPhone registers itself to the mDNS service for a few seconds. This way I keep track of when I last saw a specific iPhone (an Exec-Binding issues a shell script which calculates this value and updates an “Number” item). That’s already working pretty well and I can see that period counted in seconds in my sitemap. If anyone is interested in the details, please send me a message.

Now comes the (at least for me) tricky part: I want to implement a rule (or is there better way than using a rule?) which triggers actions when a specific iPhone has not been seen for more than 5 minutes:

  1. Set some state variable “person_x_present” to “false”.
  2. Do some further actions reacting to that (or should that be triggered by the update of the state variable just changed?)
  3. There should be a way to disable this automatism by setting a switch “person_x_presense_detection” to false (maybe iPhone is lost or battery empty). You should then be able to set the variable “person_x_present” manually with a switch.

When someone comes home and his iPhone is being detected again the presence-variable should of couse be set to “true” again and trigger further actions as well. But I guess that should work analog to the leaving rule (in a separate rule)?

What I don’t understand is how and where I can define such a state variable and query it’s status for reacting to a change? Ideally this state variable should be persistent so it survices a restart of the OH service.
And how can I define a rule which is triggered only if my “Number” item exceeds a certain limit?

I really do appreciate any help on how to do this. Thanks in advance!

regards,
Stephan

Hi,
I had a similar challange with lights, that should be switches off after a period of time. The solution was persistance.
Probably it can help you, too. See here: Link

I have this rule to run the presence based on PING. You can replace it for your mDNS

Is not exactly what you need but almost does everything you want, just use it as a base.

Please share with the community how did you do the mDNS. It would be great as ping solutions doesn’t work on all phones.

ITEMS

Group gMobiles
Switch Presence			"Presencia Casa [%s]"	<parents_2_3>

Switch Movil_Marta_1  	"Presencia Marta (mov spa) [MAP(presencia_moviles.map):%s]"	 	<woman_2>	(gMobiles)	{ channel="network:device:Marta2:online" }
Switch Movil_Marta_2 	"Presencia Marta (mov dub) [MAP(presencia_moviles.map):%s]"	 	<woman_2>	(gMobiles)	{ channel="network:device:Marta:online" }
Switch Movil_Igor_1 	"Presencia Igor 1 (mov spa) [MAP(presencia_moviles.map):%s]"	<man_3>		(gMobiles)
Switch Movil_Igor_2 	"Presencia Igor 2 (mov dub) [MAP(presencia_moviles.map):%s]"	<man_3>		(gMobiles)	{ channel="network:device:Igor:online" }	

RULES

rule "Periodically check presence"
when
    Time cron "0 */2 * * * ?"
then
        if (Presence.state == ON)
        {
                if(gMobiles.members.filter(s | s.state == ON).size == 0) {
                        logInfo("PresenceCheck", "No phone within reach, checking for flapping")
                        if(gMobiles.members.filter(s | s.changedSince(now.minusMinutes(2))).size == 0) {
                                logInfo("PresenceCheck", "Nobody is at home")
                                sendCommand(Presence, OFF)
                        }
                }
        }
        else
        {
                //For initialisation. If Presence is undefined or off, although it should be on.
                if(gMobiles.members.filter(s | s.state == ON).size > 0) {
                        sendCommand(Presence, ON)
                }
                else if (Presence.state == UNDEF || Presence.state == NULL) {
                        sendCommand(Presence, OFF)
                }
        }

end

rule "Coming home"
when
        Item gMobiles changed
then
        if (Presence.state != ON) {
                if(gMobiles.members.filter(s | s.state == ON).size > 0) {
                        logInfo("PresenceCheck", "Somebody is home")
                        sendCommand(Presence, ON)
                }
        }
end

Thank you Victor and Igor for your input.

@Jaghova: If I see it right the value of your presence switches are set by channel (E.G. channel=“network:device:Igor:online”). I never pulled data off an own channel. How did you define these and how are they updated?

When I have everything up and running I’ll share my solution with the community. The “ping” solution was also my first idea, but mDNS is more flexible, because it does not rely on a fixed ip-adress.

regards,
Stephan

Hey @sboldt,
your approach sounds new to me. I do not own an iPhone but many users might find your solution useful. Would you care to share?? Thanks!

Hi Thom,

of course I wouldn’t care to share. :wink: As I wrote in my last post:

But first I want to have the complete solution up and running.

regards,
Stephan

@sboldt
The ping solution is based on a OH2 binding witch creates a thing and a channel you can use to receive the status of the ping.
In my case, using the router config, I give a fixed IP to my house iPhones using the mac, so every time my phones arrives home has always the same IP and I can make a ping easily.

This solution has a problem, and is that sometimes, iPhone doesn’t replays to ping when blocked.

To define the ping solution, you first have to install the network biding

In default.things file configure the IPs

Thing network:device:Marta 	[ hostname="192.168.1.203", port="0", retry="3", timeout="5000", refresh_interval="60000", use_system_ping="false", dhcplisten="true" ]
Thing network:device:Igor 	[ hostname="192.168.1.202", port="0", retry="3", timeout="5000", refresh_interval="60000", use_system_ping="false", dhcplisten="true" ]
Thing network:device:Marta2 [ hostname="192.168.1.201", port="0", retry="3", timeout="5000", refresh_interval="60000", use_system_ping="false", dhcplisten="true" ]

Then link the channels to the items:

Switch Movil_Marta_1  	"Presencia Marta (mov spa) [MAP(presencia_moviles.map):%s]"	 	<woman_2>	(gMobiles)	{ channel="network:device:Marta2:online" }
Switch Movil_Marta_2 	"Presencia Marta (mov dub) [MAP(presencia_moviles.map):%s]"	 	<woman_2>	(gMobiles)	{ channel="network:device:Marta:online" }
Switch Movil_Igor_1 	"Presencia Igor 1 (mov spa) [MAP(presencia_moviles.map):%s]"	<man_3>		(gMobiles)
Switch Movil_Igor_2 	"Presencia Igor 2 (mov dub) [MAP(presencia_moviles.map):%s]"	<man_3>		(gMobiles)	{ channel="network:device:Igor:online" }

Once set, you will receive ON or OFF attending to the status of the ping.

This is how to do it with ping, if you can please share how mDNS works, may be we can figure out how to set it.

1 Like

When you are satisfied with your solution, it would be great to post it as a new thread in the Tutorials and Examples section, maybe entitled “iPhone Presence Detection using mDNS”. iPhone detection is of much interest and there have been lots of approaches attempted but the mDNS approach is a new one.

A Rule is the appropriate way to implement this. At a high level I would set it up to create/reschedule a five minute Timer when the Number Item is updated. When the Timer goes off you know you haven’t seen that device for five minutes. At that point you can code all sorts of additional actions.

You can manually control it with switches on your sitemap.

You might find the following posts useful:

The above has a simple example of how to set and reschedule a Timer.

Shows how to manage presence detection when you have multiple devices and/or multiple ways to detect each device. It also shows a simple way to override the sensors using a switch.

Shows how to manage persistence so your states remain when OH restarts.

These are not exactly what you are looking for because they don’t care which device is detected. It does the same thing no matter which device is detected or whether no devices are detected.

A somewhat related Design Pattern is:

This basically codifies the use of separate Item/Items to represent the State (i.e. presence) and all the Rules that care use this Item rather than doing calculations themselves. The Presence Detection design pattern uses this one implicitly so this link is mainly to explain why certain things were done the way they were in that Design Pattern.

Let us know if you have any further questions. We are happy to help, particularly if we can get a good and authoritative tutorial on iPhone detection out of it. :wink:

@sboldt do you have any updates on this subject, would love to see a decent presence detection solution for an iPhone.

How about