Hi everyone,
Here is a little python script I use to query if certain iOS devices are home. You must have the option “wifi iTunes sync” turned on with the device for this to work.
As a caution you do not want to run at a fast interval as it does wake up your device and will have a power impact.
Detection is quick; joining is instant; departing is about 30 seconds due to the ARP timeout period.
I use it by calling it whenever an exit door is open or closed; and set a callback timer for 90 seconds to call it again. This has proven very reliable.
Enjoy!
import subprocess
import sys
import socket
def check_present( ip_addr ):
aSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
aSocket.settimeout(1)
addr = (ip_addr, 5353)
message = b'SJ'
aSocket.sendto(message, addr)
try:
output = subprocess.check_output('arp -na', shell=True)
output = output.decode('utf-8').split('\n')
for entry in output:
mac = entry.split(' ')
if mac[0] != '':
rcvd_ip = mac[1]
rcvd_ip = rcvd_ip[:-1] # remove last Klammer
rcvd_ip = rcvd_ip[1:] # remove first Klammer
mac = mac[3]
mac = mac.split(':')
if rcvd_ip == ip_addr:
if len(mac) == 6:
return True
except subprocess.CalledProcessError:
return False
return False
john_ip = '192.168.xxx.xxx'
kim_ip = '192.168.xxx.xxx'
kenzie_ip = '192.168.xxx.xxx'
connor_ip = '192.168.xxx.xxx'
john = check_present ( john_ip )
kim = check_present ( kim_ip )
kenzie = check_present ( kenzie_ip )
connor = check_present ( connor_ip )
print(str(john)+","+str(kim)+","+str(kenzie)+","+str(connor))
And the template sensor (note I have a long scan interval; because I use the homeassistant.update service to call an update after door activity as mentioned above:
- platform: command_line
name: get_iphone_data
command: "/srv/homeassistant/bin/python3 /home/homeassistant/.homeassistant/query_iphone.py"
scan_interval: 3600
And the broken out binary sensors:
johns_home_query:
device_class: presence
friendly_name: "Query John"
value_template: >-
{{ states('sensor.get_iphone_data').split(",")[0] == "True" }}
kimberleys_home_query:
device_class: presence
friendly_name: "Query Kim"
value_template: >-
{{ states('sensor.get_iphone_data').split(",")[1] == "True" }}
kenzies_home_query:
device_class: presence
friendly_name: "Query Kenzie"
value_template: >-
{{ states('sensor.get_iphone_data').split(",")[2] == "True" }}
connors_home_query:
device_class: presence
friendly_name: "Query Connor"
value_template: >-
{{ states('sensor.get_iphone_data').split(",")[3] == "True" }}
Enjoy, and I apologize for the creaky python skills. I’m looking forward to the comments to improve it – but it’s completely workable as is.