#!/bin/ash # Allow further customization via ENV variables : ${MQTT_BASETOPIC:="owrtwifi"} : ${MQTT_STATUS_TOPIC:="${MQTT_BASETOPIC}/status/mac-"} : ${MQTT_MAINTENANCE_TOPIC:="${MQTT_BASETOPIC}/maintenance"} : ${MQTT_USER:=""} : ${MQTT_PASSWORD:=""} : ${MQTT_ID:="${MQTT_BASETOPIC}"} DEFAULT_MODE="event" DEFAULT_MQTT_SERVER="10.1.1.50" DEFAULT_LAST_SEEN_UPDATE_PERIOD_S=120 MODE=$DEFAULT_MODE MQTT_SERVER=$DEFAULT_MQTT_SERVER LAST_SEEN_UPDATE_PERIOD_S=$DEFAULT_LAST_SEEN_UPDATE_PERIOD_S SCRIPT_NAME="$(basename "$(test -L "$0" && readlink "$0" || echo "$0")")" # Parse command line args test_for_mode() { param_mode=$1 if [ "${param_mode}" == "event" -o "${param_mode}" == "lastseen" ]; then MODE=$param_mode return 0 fi return 1 } test_for_ipv4() { param_ip=$1 echo $param_ip | grep -E '\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}\b' > /dev/null if [ $? -eq 0 ]; then MQTT_SERVER=$param_ip return 0 fi return 1 } test_for_update_periode_s() { param_up=$1 expr $param_up : '[0-9][0-9]*$' if [ $? -eq 0 ]; then LAST_SEEN_UPDATE_PERIOD_S=$param_up return 0 fi return 1 } print_usage() { cat << EOF Supported optional parameters: mode: "event" or "lastseen" (default: ${DEFAULT_MODE}) In event mode changes of registered mac addresses are imediately pushed to the MQTT server In lastseen mode the registered mac addresses are periodically pushed to the MQTT server MQTT server IP: the IPv4 address of the MQTT server (default ${DEFAULT_MQTT_SERVER}) Udate periode [s]: only relevant for lastseen mode (default ${LAST_SEEN_UPDATE_PERIOD_S}) Examples: ${SCRIPT_NAME} ${SCRIPT_NAME} 192.168.1.2 ${SCRIPT_NAME} lastseen 300 EOF } get_dhcp_name() { MAC=$1 DHCP_NAME=$(grep ${MAC} /tmp/dhcp.leases | awk '{print $4}') if [ "$DHCP_NAME" = "*" ]; then return 1 else echo ${DHCP_NAME} return 0 fi } for param in "$@"; do test_for_mode $param || \ test_for_ipv4 $param || \ test_for_update_periode_s $param || \ { print_usage; exit 1; } done if [ "${MODE}" == "event" ]; then echo "${SCRIPT_NAME}, mode: ${MODE}, MQTT server: ${MQTT_SERVER}" iw event | \ while read LINE; do if echo $LINE | grep -q -E "(new|del) station"; then EVENT=$(echo ${LINE} | awk '/(new|del) station/ {print $2}') MAC=$(echo ${LINE} | awk '/(new|del) station/ {print $4}') echo "Mac: ${MAC} did ${EVENT}" mosquitto_pub \ -h ${MQTT_SERVER} \ -u ${MQTT_USER} -P ${MQTT_PASSWORD} -i ${MQTT_ID} \ -t "${MQTT_STATUS_TOPIC}${MAC//:/-}/event" \ -m $EVENT DHCP_NAME=$(get_dhcp_name ${MAC}) && mosquitto_pub \ -h ${MQTT_SERVER} \ -u ${MQTT_USER} -P ${MQTT_PASSWORD} -i ${MQTT_ID} \ -t "${MQTT_STATUS_TOPIC}${MAC//:/-}/dhcp-name" \ -m ${DHCP_NAME} \ -r fi done elif [ "${MODE}" == "lastseen" ]; then echo "${SCRIPT_NAME}, mode: ${MODE}, MQTT server: ${MQTT_SERVER}, period: ${LAST_SEEN_UPDATE_PERIOD_S}" while true; do CURRENT_TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S") CURRENT_TIMESTAMP_EPOCH=$(date -d "${CURRENT_TIMESTAMP}" +%s) CURRENT_TIMESTAMP_ISO8601=$(date -d "${CURRENT_TIMESTAMP}" -Iseconds) # Publish own lastseen state mosquitto_pub \ -h ${MQTT_SERVER} \ -u ${MQTT_USER} -P ${MQTT_PASSWORD} -i ${MQTT_ID} \ -t "${MQTT_MAINTENANCE_TOPIC}/lastseen/epoch" \ -m ${CURRENT_TIMESTAMP_EPOCH} \ -r # Publish lastseen state of wifi devices for INTERFACE in $(iw dev | grep Interface | cut -f 2 -s -d" "); do # for each interface, get mac addresses of connected stations/clients MAC_LIST=$(iw dev ${INTERFACE} station dump | grep Station | cut -f 2 -s -d" ") for MAC in ${MAC_LIST}; do echo "lastseen epoch ${MAC//:/-} ${CURRENT_TIMESTAMP_EPOCH}" mosquitto_pub \ -h ${MQTT_SERVER} \ -u ${MQTT_USER} -P ${MQTT_PASSWORD} -i ${MQTT_ID} \ -t "${MQTT_STATUS_TOPIC}${MAC//:/-}/lastseen/epoch" \ -m ${CURRENT_TIMESTAMP_EPOCH} \ -r echo "lastseen iso8601 ${MAC//:/-} ${CURRENT_TIMESTAMP_ISO8601}" mosquitto_pub \ -h ${MQTT_SERVER} \ -u ${MQTT_USER} -P ${MQTT_PASSWORD} -i ${MQTT_ID} \ -t "${MQTT_STATUS_TOPIC}${MAC//:/-}/lastseen/iso8601" \ -m ${CURRENT_TIMESTAMP_ISO8601} \ -r DHCP_NAME=$(get_dhcp_name ${MAC}) && mosquitto_pub \ -h ${MQTT_SERVER} \ -u ${MQTT_USER} -P ${MQTT_PASSWORD} -i ${MQTT_ID} \ -t "${MQTT_STATUS_TOPIC}${MAC//:/-}/dhcp-name" \ -m ${DHCP_NAME} \ -r done done sleep $LAST_SEEN_UPDATE_PERIOD_S done fi