monotux.tech

ISC Kea lease hook script

isc-kea, MQTT, Home Assistant, YAML

This is just an update for MQTT based presence detection, but using the ISC Kea lease hook library to send MQTT messages.

The script #

First, the shell script I’m using. It’s more or less stolen from the ISC Kea documentation, but I’ve added a : in each empty function to avoid syntax errors. :-)

#!/bin/bash

unknown_handle() {
    echo "Unhandled function call ${*}"
    exit 123
}

publish_mqtt () {
    MAC=$1
    STATE=$2
    HOSTNAME=$3
    UNIQUE_ID=$(echo "$MAC" | tr -d ":")
    TIME=$(date +%s)
    JSON=$(jq -n --arg mac "$MAC" --arg state "$STATE" --arg time "$TIME" --arg hostname "$HOSTNAME" '{mac: $mac, state: $state, update: $time, hostname: $hostname }' )
    AUTO_DISCOVERY=$(jq -n --arg state_topic "location/${MAC}/state"\
                           --arg name "${HOSTNAME}" \
                           --arg payload_home "home"\
                           --arg payload_not_home "not_home"\
                           --arg source_type "router"\
                           '{state_topic: $state_topic, name: $name, payload_home: $payload_home, payload_not_home: $payload_not_home, source_type: $source_type }')

    mosquitto_pub -h {{ dnsmasq_mqtt_address }} -u {{ dnsmasq_mqtt_username }} -P {{ dnsmasq_mqtt_password }} -t "homeassistant/device_tracker/${UNIQUE_ID}/config" -m "$AUTO_DISCOVERY"
    mosquitto_pub -h {{ dnsmasq_mqtt_address }} -u {{ dnsmasq_mqtt_username }} -P {{ dnsmasq_mqtt_password }} -t "location/$MAC/attributes" -m "$JSON"
    mosquitto_pub -h {{ dnsmasq_mqtt_address }} -u {{ dnsmasq_mqtt_username }} -P {{ dnsmasq_mqtt_password }} -t "location/$MAC/state" -m "$STATE"
}

lease4_renew () {
    publish_mqtt "$LEASE4_HWADDR" "home" "$LEASE4_HOSTNAME"
}

lease4_expire () {
    publish_mqtt "$LEASE4_HWADDR" "not_home" "$LEASE4_HOSTNAME"
}

lease4_recover () {
    publish_mqtt "$LEASE4_HWADDR" "home" "$LEASE4_HOSTNAME"
}

leases4_committed () {
    :
}


lease4_release () {
    publish_mqtt "$LEASE4_HWADDR" "not_home" "$LEASE4_HOSTNAME"
}

lease4_decline () {
    :
}

lease6_renew () {
    :
}

lease6_rebind () {
    :
}

lease6_expire () {
    :
}

lease6_recover () {
    :
}

leases6_committed () {
    :
}

lease6_release () {
    :
}

lease6_decline () {
    :
}

case "$1" in
    "lease4_renew")
        lease4_renew
        ;;
    "lease4_expire")
        lease4_expire
        ;;
    "lease4_recover")
        lease4_recover
        ;;
    "leases4_committed")
        leases4_committed
        ;;
    "lease4_release")
        lease4_release
        ;;
    "lease4_decline")
        lease4_decline
        ;;
    "lease6_renew")
        lease6_renew
        ;;
    "lease6_rebind")
        lease6_rebind
        ;;
    "lease6_expire")
        lease6_expire
        ;;
    "lease6_recover")
        lease6_recover
        ;;
    "leases6_committed")
        leases6_committed
        ;;
    "lease6_release")
        lease6_release
        ;;
    "lease6_decline")
        lease6_decline
        ;;
    *)
        unknown_handle "${@}"
        ;;
esac

Nothing interesting, just using the same script and jq to generate the json payload. Just remember to make the script executable, and have mosquitto, bash & jq installed.

ISC Kea configuration #

And for the final configuration in ISC Kea:

{
    "hooks-libraries": [
        {
            "library": "/usr/local/lib/libdhcp_run_script.so",
            "parameters": {
                "name": "/full_path_to/script_name.sh",
                "sync": false
            }
        }
    ]
}

That’s it, now your ISC Kea will send a MQTT message for when new leases are handed out, and when old ones expires. I’m using this as a device tracker in Home Assistant.

Home Assistant configuration #

I used to manually setup these device trackers in Home Assistant as it was quite easy:

# Before using autodiscovery
device_tracker:
  - name: "Oscar iPhone"
    state_topic: !secret oscar_iphone_attributes_topic
    value_template: "{{ value_json.state }}"
    source_type: "router"

…but I’ve now taken the approx. 2 minutes needed to read the auto discovery documentation, and implement it in my lease script above.