benjp
Posts: 9
Joined: Mon Mar 17, 2014 3:47 pm

Using Python to detect my iPhone

Fri May 23, 2014 4:22 pm

I have created a python program that auto-starts when my Raspberry Pi boots up. I don't want the program to take any action while I am home. I figure that a cool way to do this would be for the program to determine if my phone is connected to my wireless network or not. I've been toying around with having the program ping my phone periodically to see if its on the network, but I can't figure out how to turn the result of the ping into information the python program can use. Any ideas or examples out there? Thanks!

User avatar
FLYFISH TECHNOLOGIES
Posts: 1750
Joined: Thu Oct 03, 2013 7:48 am
Location: Ljubljana, Slovenia
Contact: Website

Re: Using Python to detect my iPhone

Fri May 23, 2014 4:30 pm

Hi,
benjp wrote: can't figure out how to turn the result of the ping into information the python program can use.
An universal solution (applicable also to bash scripting, etc.) is to redirect output of a command to a file and then parse this file.

Output of the command can be redirected to a file using this syntax:
ping -c 1 192.168.0.1 > /tmp/ping_output

Another option is to chain more programs/scripts using pipe for data exchange between them.


Best wishes, Ivan Zilic.
Running out of GPIO pins and/or need to read analog values?
Solution: http://www.flyfish-tech.com/FF32

User avatar
DougieLawson
Posts: 35836
Joined: Sun Jun 16, 2013 11:19 pm
Location: Basingstoke, UK
Contact: Website Twitter

Re: Using Python to detect my iPhone

Fri May 23, 2014 5:30 pm

Your problem is that you don't know the IP address. You can discover the MAC address of it's WiFi but with a DHCP network that can be assigned to any IP address from your DHCP pool (and if the lease expires or the DHCP server is restarted it will be different).

There's a crude way to scan the network from a bash script

Code: Select all

#!/bin/bash
 for i in `seq 30 100`
 do 
   ping -c1 -W1  192.168.1.$i
 done
And we can see which stations are alive with

Code: Select all

 arp -an | grep ':'


The alternative (and better) way is to use nmap
sudo apt-get install nmap
sudo nmap -sn 192.168.1.0/24
which does a much faster ping sweep and does some decoding on MAC addresses.
Note: Having anything humorous in your signature is completely banned on this forum. Wear a tin-foil hat and you'll get a ban.

Any DMs sent on Twitter will be answered next month.

This is a doctor free zone.

benjp
Posts: 9
Joined: Mon Mar 17, 2014 3:47 pm

Re: Using Python to detect my iPhone

Fri May 23, 2014 6:42 pm

@Flyfish - Can I ping the iPhone using its name? That way I can be sure that it will reach my phone even if its assigned a new IP? Could I do this?:

ping -c 1 bens-iphone > /tmp/ping_output

MadCow42
Posts: 106
Joined: Sun Jul 01, 2012 12:48 am

Re: Using Python to detect my iPhone

Fri May 23, 2014 8:19 pm

Set up your router to assign a static IP to your iPhone... most routers can do that. Then, you can ping that IP regularly to see if it's there.

I didn't think that an iPhone would respond to a ping by default, but mine does - just tested it.

So, piping the ping output to a file and parsing the file is not pretty, but it would work.

Kevin.

User avatar
cyrano
Posts: 714
Joined: Wed Dec 05, 2012 11:48 pm
Location: Belgium

Re: Using Python to detect my iPhone

Fri May 23, 2014 9:37 pm

benjp wrote:@Flyfish - Can I ping the iPhone using its name? That way I can be sure that it will reach my phone even if its assigned a new IP? Could I do this?:

ping -c 1 bens-iphone > /tmp/ping_output
Yes.

Unfortunately, with Lion, Apple has put a little gem out that's called "Bonjour Sleep Proxy". Any other Apple device might reply with your phone's name on a first call. Your router, if it's an Apple branded beast. Or an iMac on your network, or some other recent Apple compatible device, a NAS, for instance. It's a way to make battery powered devices "available" on the network while they are in deep sleep. Once it's really needed, the phone will wake up and take over from the proxy, of course. Otherwise, it would need to wake for each and every broadcast mdns call. :ugeek:

So you 'd need to experiment a bit with making multiple calls before deciding if it is your phone or the Sleep Proxy's ghost. Doing it that way will wake up the phone and shorten battery life.

And I'm afraid changing to MAC adress might face the same problem, since even MAC addresses get proxied, IIRC.

And it will make some people hate RendezVous/Bonjour/Avahi/ZeroConfig... even more.

david_wallis
Posts: 41
Joined: Thu Jul 05, 2012 8:21 pm

Re: Using Python to detect my iPhone

Sat May 24, 2014 7:49 am

What about using Bluetooth instead?

benjp
Posts: 9
Joined: Mon Mar 17, 2014 3:47 pm

Re: Using Python to detect my iPhone

Tue May 27, 2014 8:04 pm

Thanks for the input everyone!

I've run into the problem when I ping the phone when it is locked, the ping fails. Wow, this is getting complicated real quick. Is there a way to get the iPhone to listen for pings without draining the battery?

@david_wallis - Didn't think about Bluetooth. Sounds like a good idea. I have no idea how to go about using it, though. Any pointers or webpages with examples?

RockTractor
Posts: 1
Joined: Thu May 29, 2014 8:49 pm

Re: Using Python to detect my iPhone

Thu May 29, 2014 8:55 pm

It's my understanding that you can wake up your iPhone with a TCP three-way (Synchronize) handshake on port 62078.

oguime
Posts: 19
Joined: Fri Feb 14, 2014 3:14 am

Re: Using Python to detect my iPhone

Sun Jun 22, 2014 3:01 am

It's my understanding that you can wake up your iPhone with a TCP three-way (Synchronize) handshake on port 62078.
I'm also interested in detecting iPhones connected to my network.

Has anyone implemented this?

nekomatic
Posts: 20
Joined: Wed Nov 16, 2011 8:06 pm

Re: Using Python to detect my iPhone

Wed Jul 02, 2014 10:39 pm

Does your wireless router have a status webpage you can access by http? If so, does it show information you could screenscrape and use to determine whether your iPhone is currently on, or has just joined, the network?

DigiPi
Posts: 1
Joined: Wed Aug 27, 2014 4:42 am

Re: Using Python to detect my iPhone

Wed Aug 27, 2014 4:50 am

oguime wrote:
It's my understanding that you can wake up your iPhone with a TCP three-way (Synchronize) handshake on port 62078.
I'm also interested in detecting iPhones connected to my network.

Has anyone implemented this?
I'm very interested in this as well and found the following

http://www.power-home.com/forum/forum_p ... p?TID=3250

So far I have been unsuccessful in reproducing
ph_sendsocketdata1 ( "192.168.1.92", 62078, 6, "\x16" )
with Python sockets though.

Paul Liddicott
Posts: 4
Joined: Tue Jul 29, 2014 6:34 am

Re: Using Python to detect my iPhone

Wed Aug 27, 2014 6:47 am

Hi Benjp,

Earlier this year I attended a Rpi course run by a colleague at work.

We used the Rpi to detect when a phone/laptop etc attempted to join a network.

this was done using MAC address of joining device,

The details are published on the IET website (see link).

http://mycommunity.theiet.org/communiti ... s/173/5822

It was all quite easy to set up, the only requirement was that the wifi card on the pi could operate in promiscuous mode to achieve packet sniffing.

Hope this is of some use.

Paul

domjacko
Posts: 2
Joined: Fri Sep 05, 2014 3:16 pm

Re: Using Python to detect my iPhone

Fri Sep 05, 2014 10:45 pm

I've recently done a Python script to detect if a certain Bluetooth device is in range. It's a really neat way of detecting a device, but obviously the range would be an issue and you'd have to modify it to remove the LED bit and change to what you want
Last edited by domjacko on Mon Oct 26, 2015 4:19 pm, edited 1 time in total.

tronb
Posts: 1
Joined: Wed Jan 21, 2015 9:35 pm

Re: Using Python to detect my iPhone

Wed Jan 21, 2015 9:38 pm

DigiPi,
Did you have any luck getting the code to work on python?
If you do, could you share your code?

Thanks

Absimiliard
Posts: 1
Joined: Wed May 24, 2017 8:26 am

Re: Using Python to detect my iPhone

Wed May 24, 2017 8:33 am

I have implemented a daemon that check for my iphone using bluetooth. I write it in C++ using bluez and this doc
https://people.csail.mit.edu/albert/blu ... /x604.html

But it give you also samples in python in the same documentation :

My server is available on github : https://github.com/marc-despland/alarm-controller

The class that do the detection is src/blueping.cpp

irishcream24
Posts: 1
Joined: Sun Sep 22, 2019 12:43 pm

Re: Using Python to detect my iPhone

Sun Sep 22, 2019 12:45 pm

So I have been working on the same issue for about a year now. I got it to work on my mac fairly quickly, but had a lot of trouble getting it to work right on my PC. I have tried many many different approaches. I have a home automation system that turns on the heating and hot water (via an arduino and RF module) when I or my partner are home (that is our iPhones are detectable on the home WiFi). In the end I used 'nslookup' to find the IP address for the iPhones (in case the IP address did change as they are dynamic (but they actually never do on my router)) and 'nmap' to detect if the iPhone is on the network. If the iPhone is in very deep sleep 'nmap' does not always find the phone, so I have made it check 10 times before it says the phone is not home. Below is part of my home automation code in python. I have used threading. Any questions with the below code let me know.

Code: Select all

    # Dictionary to store variables to reuse on program restart
    v = {
    	'boilerControlCH' : 'HIH', # 'scheduled' or 'HIH' (Honey I'm Home)
    	'boilerControlHW' : 'scheduled',
    	'thermostatSetPoint' : 20.8,
    	'thermostatVariance' : 0.1,
    	'morningTime' : datetime(1970,1,1,6,0,0),
    	'nightTime' : datetime(1970,1,1,23,0,0),
    	'someOneHome' : False,
    	'guest' : False,
    	'minimumTemperatureOO' : False,
    	'minimumTemperature' : 4.0,
    	'iPhoneMark' : {'iPhoneHostname' : 'marks-iphone', 'home' : False},
    	'iPhoneJessica' : {'iPhoneHostname' :'jessicaesiphone', 'home' : False}
    	}
and

Code: Select all

   # Check if anyone at home
    def occupancyStatus(person, Bol = False):
    	with lockOccupancyStatus:
    		someOneHome = False
    		
    		if 'iPhone' in person:
    			v[person]['home'] = Bol
    		elif 'retest' in person:
    			pass
    		else:
    			v[person] = Bol
    		
    		if v['guest'] == True:
    			someOneHome = True
    			
    		for key in v:
    			if 'iPhone' in key:
    				if v[key]['home'] == True:
    					someOneHome = True
    		
    		v['someOneHome'] = someOneHome
    		variablesToFile()
    	return
and the main code

Code: Select all

    # iPhone home status threading code
    class nmapClass(threading.Thread):
    	def __init__(self):
    		threading.Thread.__init__(self)
    	def run(self):
    		global exitCounter
    		
    		nmapThread()
    		msg.log('Exited nmapThread')	
    		waitEvent.set()
    		waitEventAdjustable.set()
    		serialDataWaiting.set()
    		exitCounter += 1
    		
    
    def nmapThread():
    	iPhone = {}
    	maxCounts = 10
    	for phone in v:
    		if 'iPhone' in phone:
    			iPhone[phone] = {}
    			iPhone[phone]['hostname'] = v[phone]['iPhoneHostname']
    			iPhone[phone]['count'] = maxCounts
    	#msg.log(iPhone)
    	
    	while exitFlag[0] == 0:
    		for phone in iPhone:
    			if iPhone[phone]['count'] > 0:
    				phoneFound = False
    				IPAddress = '0.0.0.0'
    	
    				# Find iPhones IP address using its hostname
    				commandNsloolup = 'nslookup %s' %iPhone[phone]['hostname']
    				childNslookup = pexpect.popen_spawn.PopenSpawn(commandNsloolup, timeout = None)
    				output = childNslookup.readline()
    				while '\r\n' in output:
    					#msg.log(output)
    					if 'Name:' in output:
    						output = childNslookup.readline()
    						if 'Address:' in output:
    							tempStr = output
    							startPoint = tempStr.find('192')
    							tempStr = tempStr[startPoint:]
    							IPAddress = tempStr.replace('\r\n', '')
    							#msg.log(IPAddress)
    					output = childNslookup.readline()
    
    
    				if IPAddress == '0.0.0.0':
    					pass
    					#msg.error('Error finding IP address for %s' %iPhone[phone]['hostname'], GFI(CF()).lineno)
    				else:
    					#commandNmap = 'nmap -PR -sn %s' %IPAddress
    					#commandNmap = 'nmap -p 62078 -Pn %s' %IPAddress # -p specifies ports to try and access, -Pn removes pinging
    					commandNmap = 'nmap -p 62078 --max-rate 100 %s' %IPAddress
    					childNmap = pexpect.popen_spawn.PopenSpawn(commandNmap, timeout = None)
    					output = childNmap.readline()
    					while '\r\n' in output:
    						if 'Host is up' in output:
    							phoneFound = True
    							break
    						output = childNmap.readline()
    					#if phoneFound:
    					#	break
    	
    	
    				if phoneFound:				
    					iPhone[phone]['count'] = 0
    					
    					if v[phone]['home'] == False:
    						msg.log('%s\'s iPhone has returned home' %phone)
    						occupancyStatus(phone, True)
    						waitEventAdjustable.set()
    					#else:
    						#msg.log('%s\'s iPhone still at home' %phone)
    				else:
    					iPhone[phone]['count'] -= 1
    						
    					if v[phone]['home'] == True and iPhone[phone]['count'] == 0:
    						msg.log('%s\'s iPhone has left home' %phone)
    						occupancyStatus(phone, False)
    						waitEventAdjustable.set()
    					#else:
    						#msg.log('%s\'s iPhone still away from home' %phone)
    
    			elif iPhone[phone]['count'] < 0:
    				msg.error('Error with count variable in iPhone dictionary', GFI(CF()).lineno)
    		
    		
    		longWait = True
    		for phone in iPhone:
    			if iPhone[phone]['count'] > 0:
    				longWait = False
    				#msg.log('%s: %s' %(phone, iPhone[phone]['count']))
    					
    		if longWait:
    			#msg.log('wait long')				
    			# 600 = run every 10 minutes
    			waitEvent.wait(timeout=600)
    			for phone in iPhone:
    				iPhone[phone]['count'] = maxCounts
    		else:
    			#msg.log('wait short')
    			waitEvent.wait(timeout=60)	
    		
    	return
The code may not work if you copy it straight into your own script, as there are some parts missing which I have not copied to try and keep things simple and easy to read, but hopefully the above code gives everyone a sense of how I did things.

Return to “Python”