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.