Pop search terms in here.

Feed the Birds

MQTT Action Check

I've been noticing a few of my Zigbee switches being a bit weird recently, but only the ones on Zigbee2MQTT. Just to be sure the messages are getting sent over the network properly I threw together this quick script which runs constantly on a Raspberry Pi.

It just listens for messages from my main switch and button devices, then reads the action value reported by Zigbee2MQTT using jq and throws it out to me using the wonderful Pushover service.

#!/usr/bin/env bash

## action_check.sh v0.01 (6th October 2025)
##  Sends the action of a given button press received over MQTT to Pushover

device_models=('E1766' 'E1812' 'WXKG06LM' 'WXKG07LM' 'WXKG11LM' 'WXKG12LM')

while true
do
    mosquitto_sub -h "192.168.1.1" -t "zigbee2mqtt/#" -R | while read -r payload
    do

        if [[ "${payload:0:1}" == "{" ]]; then

            this_model="$(echo "${payload}" | jq -r '.device.model')"

            if [[ " ${device_models[@]} " =~ " ${this_model} " ]]; then

                action_value="$(echo "${payload}" | jq -r '.action')"

                if [[ -n "$action_value" ]] && [[ "$action_value" != "null" ]]; then

                    friendlyName="$(echo "${payload}" | jq -r '.device.friendlyName')"
                    #echo "$friendlyName $action_value"

                    curl -s -o /dev/null \
                        --form-string "token=your_app_token" \
                        --form-string "user=your_user_token" \
                        --form-string "title=$friendlyName" \
                        --form-string "message=$action_value" \
                        --form-string "priority=-2" \
                        https://api.pushover.net/1/messages.json   

                fi

            fi

        fi

    done
    sleep 2
done

The lowest priority -2 setting means that the messages don't generate any notifications, but they are added to the Pushover app's "channel" and can be viewed with a pull-to-refresh. This way I don't get spammed whenever someone presses a light switch. But if you'd prefer that, just nudge the value up.

Of course, systemd takes care of ensuring it's running with a user service. This lives as ~/.config/systemd/user/action-check.service:

[Unit]
Description=MQTT Action Check
After=network-online.target

[Service]
ExecStart=/path/to/action_check.sh
Restart=always
RestartSec=5s
Type=simple
RemainAfterExit=yes
WorkingDirectory=/tmp
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=default.target

This Raspberry Pi was a pretty fresh install, so I needed to enable lingering to ensure it started without any login:

loginctl enable-linger $USER

Then all the usual systemd setup stuff:

systemctl --user daemon-reload
systemctl --user enable action-check.service
systemctl --user start action-check.service
systemctl --user status action-check.service

Naturally, once I had this up and running the problem resolved itself by magic.

← Recent Articles
October 06, 2025