As part of my home automation system, I like to be able to shutdown my computer remotely. This way I can safely shutdown the computer before powering it off at the wall.
The challenge is: how do I make the computer respond to the message and instigate a shutdown?
This is not a new challenge, and there are personal-project utilities all over the place which achieve the goal. Previously I was doing this with software called MqttClient, a .NET GUI which ran on Windows. Now that I’m splitting my time between multiple operating systems, I wanted a small, cross-platform utility which could run quietly in the background and subscribe to shutdown requests.
Introducing: mqcontrol
mqcontrol is yet another MQTT remote control utility. It’s small, cross-platform, CLI-only and availble as a Docker image. The source is available on GitHub.
How I’m using mqcontrol
Remote hibernate as part of “safe off” script
I’m using mqcontrol as part of a computer shutdown script. When I activate the script, Home Assistant does the following:
- Send the command to hibernate the computer
- Wait for the computer power draw to drop below 20W
- Switch off the computer at the wall after a delay
Here’s a basic version of what that script looks like in Home Assistant YAML configuration:
computer_off_safe:
alias: Turn computer off safely
sequence:
- service: mqtt.publish
data:
topic: "flat/abedroom/pc/hibernate"
payload: ""
- wait_template: "{{ states('sensor.computer_power')|int < 20 }}"
timeout: "00:02:00"
continue_on_timeout: "false"
- delay:
seconds: 2
- service: switch.turn_off
data:
entity_id: switch.computer_plug
mqcontrol runs on the computer and listens for the hibernate command.
On Linux I use systemd to run the following command at boot:
mqcontrol -c "systemctl hibernate" -t flat/abedroom/pc/hibernate
On Windows I use task scheduler to run an analogous command on login:
mqcontrol.exe -c "shutdown /h /t 0" -t flat/abedroom/pc/hibernate
This way it doesn’t matter which OS I’m booted into; the command will always cause a hibernate.
Learnings
For a small one-weekend project, I managed to learn a ton while developing mqcontrol. I’ll be writing more about these for sure!
- Basics of Golang and its tooling.
- Docker BuildKit and three-stage Dockerfile to use build stage for both artifact generation and runtime image creation.
- Docker Buildx to build and push cross-platform Docker images - but using Go cross-compilation on the build platform to eliminate the need for expensive emulation.
- GitHub Actions and Docker-out-of-Docker for releases based on Git tags and automated CI/CD.