#!/bin/sh set -u KUMA_BASE="${KUMA_BASE:-https://up.notsosm.art}" TOKEN_FILE="/root/nr-flow-validator/infra/.secrets/kuma-push-token" STATE_FILE="/root/nr-flow-validator/infra/.secrets/.zb-restart-count" [ -s "$TOKEN_FILE" ] || exit 1 TOKEN="$(tr -d '[:space:]' < "$TOKEN_FILE")" reason="" # 1. Container liveness. running=$(docker inspect zigbee2mqtt --format '{{.State.Running}}' 2>/dev/null) [ "$running" = "true" ] || reason="container_running=${running:-unknown}" # 2. Crash-loop detection: RestartCount climbing since last run. rc=$(docker inspect zigbee2mqtt --format '{{.RestartCount}}' 2>/dev/null | tr -d '[:space:]') if [ -n "$rc" ] && [ -f "$STATE_FILE" ]; then prev=$(tr -d '[:space:]' < "$STATE_FILE") if [ "${prev:-0}" -lt "$rc" ] 2>/dev/null; then reason="${reason:+$reason }crashed_recently(restarts=$rc from $prev)" fi fi printf '%s' "${rc:-0}" > "$STATE_FILE" # 3. Bridge state — informational only. z2m publishes /bridge/state on # transitions, NOT continuously, so a missing message in a short window # is expected during steady operation and must not cause a false DOWN. # The restart-count check above is the authoritative crash-loop signal. state=$(docker exec mosquitto mosquitto_sub -R -t 'zigbee2mqtt/bridge/state' -C 1 -W 6 2>/dev/null | tr -d '[:space:]') if [ -z "$reason" ] && [ "$state" != '{"state":"online"}' ]; then note="bridge_idle_or_down" fi if [ -n "$reason" ]; then status="down" msg="coordinator: ${reason}" else status="up" msg="coordinator ok${note:+ ($note)}" fi curl -fsS -m 10 -o /dev/null --get \ --data-urlencode "status=$status" \ --data-urlencode "msg=$msg" \ "$KUMA_BASE/api/push/$TOKEN"