Use Pi-hole DHCP to speed up ping device tracker detection

If you use Pi-Hole as a DHCP server, you can use it to trigger an update to a device tracker as soon as the device connects to the network. This allows the device to be detected much more quickly than the traditional ping (ICMP) device tracker.

The dnsmasq daemon has the option to run a script when it issues a DHCP address. To do this, add a config file, eg: /etc/dnsmasq.d/05-dhcp-script.conf with the line:

dhcp-script=/home/homeassistant/.homeassistant/dhcp.sh

Check the script is executable then restart dnsmasq via the pi-hole interface.

The script receives four parameters from dnsmasq: operation, mac address, ip address and hostname. Iā€™ve used the hostname to identify the device and convert it to the dev_id used by the device tracker. If the script identifies an expected device, it uses the API to set the device status to ā€˜homeā€™.

Youā€™ll need to modify the script with the correct hostnames, dev_ids and your home assistant details.

dhcp.sh:

#!/bin/sh

op="${1:-op}"
mac="${2:-mac}"
ip="${3:-ip}"
hostname="${4}"

# Don't report on deleted leases
if [ $op = "del" ]
then
    exit 0
fi

# Convert $hostname (or $mac, or $ip) into the device_tracker.dev_id.
case $hostname in
"paulus_oneplus")
    dev_id="paulus"
    ;;
"annetherese_n4")
    dev_id="anne_therese"
    ;;
*)
# other devices we're not tracking 
    exit 0
    ;;
esac

curl -H "Content-Type: application/json" -X POST \
	-d '{"dev_id": "'$dev_id'", "location_name":"home"}' \
	https://xxxx.example.com:8123/api/services/device_tracker/see?api_password=yourpassword

Once this is sorted, you can relax the the time between pings, as weā€™re now only relying on it to detect when the device goes away.

Due respects to reddit user /u/blackbear85 for the initial script (which used MQTT instead of kicking the device tracker directly).

11 Likes

Very cool, will try this weekend.

Excellent idea. I donā€™t use my PiHole anymore for DHCP since it lives on a different segment then many devices, Iā€™m going to dig through on the Edgerouter Lite as I think I should be able to do the same. Very cool idea!

Very cool, think you just solved my issues with Google Location Sharing not always updating fast enough when I walked in the door. Just tested it and worked perfectly. Substitutes well until Google Location Sharing catches up.

This was pretty awesome but I had to tweak the script to work with mac addresses. Dnsmasq passes mac addresses lowercase yet home assistant keeps them uppercase so if youā€™re copying from known_devices, the case statement doesnā€™t work.

#!/bin/sh
Log=/var/log/dnsmasqscript.log

op="${1:-op}"
mac="${2:-mac}"
ip="${3:-ip}"
hostname="${4}"

# Don't report on deleted leases
if [ $op = "del" ]
then
	exit 0
fi

# $mac is lowercase while known_devices.yaml is uppercase. Convert to uppercase.
mac=$(echo "$mac" | tr '[:lower:]' '[:upper:]')

#Logging examples below (commented out)
#date >> $Log
#echo $op >> $Log
#echo $mac >> $Log
#echo $ip >> $Log
#echo $hostname >> $Log

# Convert $hostname (or $mac, or $ip) into the device_tracker.dev_id.
# replace $mac in case statement with appropriate variable.
case "$mac" in
	AA:BB:CC:DD:EE:FF)
		dev_id="phone"
		;;
	*)
		# other devices we're not tracking
		exit 0
		;;
esac

curl -H "Content-Type: application/json" -X POST \
	-d '{"dev_id": "'$dev_id'", "location_name":"home"}' \
	https://xxxx.example.com:8123/api/services/device_tracker/see
1 Like

great, this is what I am looking for, since using pi-hole and not the rouer I do have problems with detection.

I use HASSIO, but use pi-hole on a differnt PI3, how would I install your code?

This should still work perfectly when split between two machines. The dhcp-script can be put on the pi-hole box, the only change youā€™ll need to make is to ensure the url of the HASS.IO box is correct in the script.

Works on DD-WRT as well. Nice work.

EDIT: Modified to use arrays vs case-select and lifted @alandtse MAC fixes. IE:

HOSTS[0]="paulus_oneplus"
HOSTS[1]="annetherese_n4"
DEVID[0]="paulus"
DEVID[1]="anne_therese"

With a comparison made against $hostname to HOSTS array (loops through array) and then matching DEVID sent to HASS. Probably a cleaner way than above but saves on typing the case-select comparisons :slight_smile:

My rock solid pihole/pi3 crashed today, leaving entire network down. I canā€™t be sure was for the script, but donā€™t know either what else it could be

I am using this for my EdgeRouter X but try if it works for EdgeRouter Lite.


It involves some configuration but I tried to put as much details I can on how to use.
I will help you if see any issue in setting it up.

UPDATE: It seems that when dnsmasq restarts (after a pi-hole update), it triggers an update of old clients. This could cause devices to be marked as home incorrectly.

This tweak will prevent the update happening if dnsmasq has been running for less than 30s.

uptime=`ps -o etimes= -p $PPID`
# Don't report on deleted leases, or when dnsmasq restarts
if [ $op = "del" ] || [ $uptime -lt 30 ]
then
    exit 0
fi
1 Like

Very cool way of implementing device tracking with PI Hole, exactly what i want to do.

Iā€™d love to give it a go, but iā€™m running HassOS, i donā€™t know how i get in to the docker container to add the script.

Anyone have any ideas on how i might do that?

I forgot I had this script running and for the later versions of HA, authentication is required to do a curl command. The result is I was getting very random login failure messages from the ip of my pi-hole device which was perplexing me. It finally clicked that those login failures were caused by this script.

The fix is to get a long lived access token, and modify the curl script as follows:
Replace ABCDEFGH with the access token.

curl -H "Content-Type: application/json" -X POST \
	-d '{"dev_id": "'$dev_id'", "location_name":"home"}' \
        -H 'Authorization: Bearer ABCDEFGH' 
	https://xxxx.example.com:8123/api/services/device_tracker/see

The dev docs are a bit hard to understand, so this post has some good instructions pasted below:

  1. I logged into an existing user account for appdaemon on HA,
  2. Navigated to /profile,
  3. Clicked on long-lived tokens ā†’ create token,
1 Like

I am trying a new approach. I am sending the device MAC as the device id. This way I will handle the device mapping in the home assistant environment and not in pi hole scripts.

I have defined a ping device tracker for each device that I want to track:

  - platform: ping
    interval_seconds: XX
    consider_home: YY
    hosts:
      11_22_33_44_55_66: !secret phone_ip

I still donā€™t know if this is a good approach, so comments are welcome. Here is the dhcp script.

#!/bin/sh

Log=/var/log/dnsmasqscript.log

op="${1:-op}"
mac="${2:-mac}"
ip="${3:-ip}"
hostname="${4}"

# Don't report on deleted leases
if [ $op = "del" ]
then
  exit 0
fi

# $mac is lowercase while known_devices.yaml is uppercase. Convert to uppercase.
# mac=$(echo "$mac" | tr '[:lower:]' '[:upper:]')

#Logging examples below (commented out)
#date >> $Log
#echo $op >> $Log
#echo $mac >> $Log
#echo $ip >> $Log
#echo $hostname >> $Log

# Change to have name without :
dev_id=$(echo "$mac" | tr : _)

# Update home assistant
curl -H "Content-Type: application/json" -X POST -d '{"dev_id": "'$dev_id'", "location_name": "home"}' -H 'Authorization: Bearer XXXXXXXXXXX' http://192.168.0.11:8123/api/services/device_tracker/see

My understanding is with 0.94, this actually may not work anymore depending on if your device_tracker is using the device registry. What have people been doing instead? @eyalco did your ping tracker work?

EDTI:
New curl command to directly update the state instead of using the device_tracker.see command.

curl -H "Content-Type: application/json" -X POST \
        -d '{"state":"home"}' \
        -H 'Authorization: Bearer ABCDEFGH' \
        https://xxxx.example.com:8123/api/states/device_tracker.${dev_id}
1 Like

are there any other better ways to achieve people detection from Pi-Hole now after 2 years?
Thanks

1 Like

Would be nice to have official presence detection supported with the pi-hole DHCP server through the pi-hole integration.

@mib1185 any change on that? (checked that you have made the last commit for the integration)

@chiphead Iā€™m not the code owner, nor do I have any use case by my own to extend the feature set ā€¦ so from my side there were no new features added to the pi-hole integration.
If you would like to have the device tracker platform integrated into the integration based on the dhcp service of pi-hole, you are free to do it on your own (contributions are always welcome :wink: ) or place a feature request here ā†’ Feature Requests - Home Assistant Community

I made an feature request:

I love the Idea of this but I am absolutely clueless on how to exactly implement these scripts.

Could you be so kind and write an absolute newbie-howto on this topic? Like:

  1. This is the complete code for the config file with all mentioned fixes (I am confused by which part replaces the other)
  2. You need to do exactly this on your pi-hole, take these measures to be able to undo possible fails while doing so (I guess it is ā€œedit 05-dhcp-script.confā€ and create a copy first, but there might be things I miss)
  3. Write exactly this in your configurations.yaml
  4. These are the positions where you have to fill in your own credentials

Would be very, very much appreciated, thank you. Seems like the official suggestion has never been picked up :frowning: