Active iOS device tracking

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.

1 Like