From 36174303a34f8a827f546397a96f3257efec6aee Mon Sep 17 00:00:00 2001 From: sirmrak Date: Mon, 12 Oct 2026 11:47:51 +0300 Subject: [PATCH] Add files/mqtt_ha_discovery.sh --- files/mqtt_ha_discovery.sh | 109 +++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 files/mqtt_ha_discovery.sh diff --git a/files/mqtt_ha_discovery.sh b/files/mqtt_ha_discovery.sh new file mode 100644 index 0000000..a98ee4e --- /dev/null +++ b/files/mqtt_ha_discovery.sh @@ -0,0 +1,109 @@ +#!/bin/sh +# Sends MQTT Discovery configs, publishes temperature, +# and initializes device states ONLY on the first run after reboot. + +MQTT_HOST=$(uci get openwrt_ha.main.host) +MQTT_PORT=$(uci get openwrt_ha.main.port) +MQTT_USER=$(uci get openwrt_ha.main.user) +MQTT_PASS=$(uci get openwrt_ha.main.pass) +BASE_TOPIC=$(uci get openwrt_ha.main.base_topic 2>/dev/null || echo "openwrt") + +PUB="mosquitto_pub -h $MQTT_HOST -p $MQTT_PORT -u $MQTT_USER -P $MQTT_PASS -r" +STATES_DIR="/tmp/mqtt_ha_states" +mkdir -p "$STATES_DIR" + +is_mac_connected() { + local mac="$1" + for iface in phy0-ap0 phy1-ap0; do + if iw dev "$iface" station dump 2>/dev/null | grep -qi "$mac"; then + return 0 + fi + done + return 1 +} + +convert_state() { + local state="$1" + local type="$2" + if [ "$type" = "alarm" ]; then + [ "$state" = "home" ] && echo "online" || echo "offline" + else + echo "$state" + fi +} + +INIT_DONE_FILE="${STATES_DIR}/.initialized" + +if [ ! -f "$INIT_DONE_FILE" ]; then + logger -t "wifi_tracker" "First run after reboot. Initializing states..." + i=1 + while true; do + device_name="device${i}" + if ! uci -q get openwrt_ha.${device_name}.name >/dev/null 2>&1; then + break + fi + + DEVICE_NAME_TEXT=$(uci get openwrt_ha.${device_name}.name) + DEVICE_MACS=$(uci get openwrt_ha.${device_name}.macs) + DEVICE_TYPE=$(uci -q get openwrt_ha.${device_name}.type) + [ -z "$DEVICE_TYPE" ] && DEVICE_TYPE="tracker" + + AGGREGATED_STATE="not_home" + for mac in $DEVICE_MACS; do + mac_lower=$(echo "$mac" | tr 'A-Z' 'a-z') + if is_mac_connected "$mac"; then + echo "home" > "${STATES_DIR}/${mac_lower}" + AGGREGATED_STATE="home" + else + echo "not_home" > "${STATES_DIR}/${mac_lower}" + fi + done + + if [ "$DEVICE_TYPE" = "alarm" ]; then + TOPIC="${BASE_TOPIC}/alarm/device_${i}/state" + MQTT_PAYLOAD=$(convert_state "$AGGREGATED_STATE" "$DEVICE_TYPE") + else + TOPIC="${BASE_TOPIC}/device_tracker/device_${i}/state" + MQTT_PAYLOAD="$AGGREGATED_STATE" + fi + + $PUB -t "$TOPIC" -m "$MQTT_PAYLOAD" + logger -t "wifi_tracker" "${DEVICE_NAME_TEXT} -> HA: ${MQTT_PAYLOAD} (init)" + i=$((i + 1)) + done + touch "$INIT_DONE_FILE" + logger -t "wifi_tracker" "Initialization complete." +fi + +TEMP_RAW=$(cat /sys/class/thermal/thermal_zone0/temp 2>/dev/null) +if [ -n "$TEMP_RAW" ]; then + TEMP_C=$(echo "$TEMP_RAW" | awk '{ printf "%.1f", $1 / 1000 }') + $PUB -t "${BASE_TOPIC}/sensor/temperature/state" -m "$TEMP_C" +fi + +DISCOVERY_TEMP="{\"name\":\"OpenWrt Temperature\",\"stat_t\":\"${BASE_TOPIC}/sensor/temperature/state\",\"dev_cla\":\"temperature\",\"unit_of_meas\":\"°C\",\"uniq_id\":\"openwrt_temp\",\"dev\":{\"ids\":\"openwrt_router\",\"name\":\"OpenWrt Router\",\"mf\":\"OpenWrt\",\"mdl\":\"Router\"}}" +$PUB -t "homeassistant/sensor/openwrt_router/temp/config" -m "$DISCOVERY_TEMP" + +i=1 +while true; do + device_name="device${i}" + if ! uci -q get openwrt_ha.${device_name}.name >/dev/null 2>&1; then + break + fi + + DEVICE_NAME_TEXT=$(uci get openwrt_ha.${device_name}.name) + DEVICE_TYPE=$(uci -q get openwrt_ha.${device_name}.type) + [ -z "$DEVICE_TYPE" ] && DEVICE_TYPE="tracker" + DEVICE_ID="device_${i}" + + if [ "$DEVICE_TYPE" = "alarm" ]; then + STATE_TOPIC="${BASE_TOPIC}/alarm/device_${i}/state" + DISCOVERY="{\"name\":\"${DEVICE_NAME_TEXT}\",\"stat_t\":\"${STATE_TOPIC}\",\"pl_on\":\"online\",\"pl_off\":\"offline\",\"dev_cla\":\"connectivity\",\"uniq_id\":\"openwrt_alarm_${DEVICE_ID}\",\"dev\":{\"ids\":\"openwrt_router\",\"name\":\"OpenWrt Router\",\"mf\":\"OpenWrt\",\"mdl\":\"Router\"}}" + $PUB -t "homeassistant/binary_sensor/openwrt_router/${DEVICE_ID}/config" -m "$DISCOVERY" + else + STATE_TOPIC="${BASE_TOPIC}/device_tracker/device_${i}/state" + DISCOVERY="{\"name\":\"${DEVICE_NAME_TEXT}\",\"stat_t\":\"${STATE_TOPIC}\",\"pl_home\":\"home\",\"pl_not_home\":\"not_home\",\"src_type\":\"router\",\"uniq_id\":\"openwrt_tracker_${DEVICE_ID}\",\"dev\":{\"ids\":\"openwrt_router\",\"name\":\"OpenWrt Router\",\"mf\":\"OpenWrt\",\"mdl\":\"Router\"}}" + $PUB -t "homeassistant/device_tracker/openwrt_router/${DEVICE_ID}/config" -m "$DISCOVERY" + fi + i=$((i + 1)) +done \ No newline at end of file