"I am home" notifications with dnsmasq

I wanted to get automatically notified when my wife arrives at home so I can walk down from the home office to greet her. Since she's carrying a mobile phone the network knows when she arrives because the phone connects to WiFi and gets a fresh IP address.

My home server is running dnsmasq to hand out IP addresses to devices, and it allows to run a script whenever this is done with the configuration option dhcp-script.

dhcp-script's first parameter is "add", "old" or "del". "add" is used when the device was more than $dhcpLeaseTime away, which is 3 hours in my setup. This was perfect, because so I don't need to take track of leases myself.

The next parameters are the MAC address, IP address and the desired hostname. I decided to use the host name as suffix for the actual "hello" script so I don't have to modify the code when the kids get a mobile phone.

presence-alert-mini.php
#!/usr/bin/env php
<?php
/**
 * Run a script when a device appears in the network the first time
 * after some timeout.
 *
 * Useful for running scripts when a person arrives at home.
 *
 * Use it as dnsmasq "dhcp-script".
 *
 * Create an executable script "hello-$macaddres" for each device.
 * That one will be run if the device gets an IP address the first
 * time after $dhcpLeaseTimeout.
 *
 * @author Christian Weiske <cweiske@cweiske.de>
 */
 
$optind = null;
$options = getopt('v', [], $optind);
 
$verbose = isset($options['v']);
 
$arguments = array_slice($argv, $optind);
if (count($arguments) < 2) {
    fwrite(STDOUT, <<<TXT
Usage: presence-alert.php [-v] <type> <mac> [ip] [host]
 
TXT);
    exit(1);
}
$type = $arguments[0];
$mac  = strtolower($arguments[1]);
$host = $arguments[3] ?? null;
 
if ($type != 'add') {
    //DHCP release gets deleted, we don't care about that
    if ($verbose) {
        echo "Type is not \"add\", ignoring\n";
    }
    exit(0);
}
 
$scriptOptions = [];
if ($host !== null) {
    $scriptOptions[] = __DIR__ . '/hello-' . $host;
}
$scriptOptions[] = __DIR__ . '/hello-' . $mac;
 
foreach ($scriptOptions as $macScript) {
    if (file_exists($macScript)) {
        break;
    }
    $macScript = null;
}
if ($macScript === null) {
    //no script to execute for this mac, so do nothing
    if ($verbose) {
        echo "No script for mac address, ignoring\n";
        echo implode("\n", $scriptOptions) . "\n";
    }
    exit(0);
}
if (!is_executable($macScript)) {
    fwrite(STDERR, "Script is not executable:\n" . $macScript . "\n");
    exit(1);
}
 
//$HOME is not set for some reason when called from dnsmasq
if (getenv('HOME') == '') {
    $userdata = posix_getpwuid(posix_getuid());
    putenv('HOME=' . $userdata['dir']);
}
 
passthru($macScript, $exitCode);
exit($exitCode);
?>

The actual hello script is simple. It sends an XMPP message to me and activates the kitchen Schwibbogen light in case she's arrinving in the evening:

hello-jami
#!/bin/sh
set -e
 
echo "xxx ist zu Hause" | sendxmpp cweiske@cweiske.de
 
if [ $(date +%H) -ge 18 ]; then
    # schwibbogen küche an
    curl -s http://schwib1.home.cweiske.de/relay/0?turn=on > /dev/null
fi

Written by Christian Weiske.

Comments? Please send an e-mail.