Controlling a Computer Remotely with MQTT
Summary
I was looking for various ways to control my computers via home automation, and my method of choice MQTT. Thinks like locking screens, rebooting etc. There are various python scripts around, and you can install node-red or other automation systems on each machine, but I wanted something simple, reliable and lightweight.
I found mqcontrol by albertnis to be the best option and simplest for my use case
https://github.com/albertnis/mqcontrol
Install (on a linux machine)
The documentation is good on the github page. As a summary, you can install with the go tools (it is written in go), but I just:
- downloaded an appropriate binary (linux_amd64 in my case) from here https://github.com/albertnis/mqcontrol/releases
- put it in /usr/local/bin
- renamed it mqcontrol
- chmod 755 to make it executable
Making it run as a daemon with systemd (on a linux machine)
The goal was to lock the screen on command and although the documentation talks about setting it up in systemd as a service, there is no way that I could find to lock the current user’s screen this way. It has to be done as a user with the xsession
Recommendations (and working for me) are to create a service file in
$ ~/.config/systemd/user/mqcontrol.service
This is the systemd unit file I used to have the screen lock on an ubuntu machine. When mqcontrol is running, it listens to MQTT and awaits anything posted to the topic computercommands/lounge/lockscreen and will run the command we want.
gnome-screensaver-command -l
is the command we are using to lock the screen. This could be other actions with other graphical user sessions
-i is the MQTT client’s ID (you can use anything unique to your mqtt server)
-h is the MQTT server and port
-t is the topic you want to watch (anything at all posted to this topic will run the command)
-u and -p are the MQTT username/pass
[Unit]
Description="mqcontrol - remote control from mqtt server"
BindsTo=graphical-session.target
[Service]
Type=simple
ExecStart=/usr/local/bin/mqcontrol -i daves_mqcontrol -c "gnome-screensaver-command -l" -h 192.168.1.256:1883 -t computercommands/lounge/lockscreen
Restart=always
[install]
WantedBy=default.target
Enable the service
Enable the user service with:
systemctl --user enable mqcontrol
and it will place a symlink of the systemd file in:
~/.config/systemd/user/default.target.wants/mqcontrol.service
Then make it active with:
systemctl --user start mqcontrol
and it will start any time the user session starts.
Checking on the process & stopping it
If you change the unit file you need to run:
systemctl --user daemon-reload
it will warn you if you haven’t.
Start and stop the daemon with
systemctl --user start mqcontrol
and
systemctl --user stop mqcontrol
Check to see if the daemon is still running with
ps aux |grep mqcontrol
If the EXEC command fails, the daemon will die.
You can check the systemd log for that particular daemon with
journalctl --user-unit mqcontrol -n 10 -f
where -f will follow the log as it changes.
Understanding the Unit File
To see what targets are available
systemctl --user list-units --type=target
I haven’t tried this, but to ensure these services start on boot for the user rather than login, you can apparently use
loginctl enable-linger USERNAME
Use cases
Currently, I use it for locking screens on machines when I leave the room or turn out the lights. I have it integrated with google assistant and amazon alexa voice commands. I could equally hibernate or shut them down.
Another planned use will be to shut down some raspberry pis then have them boot up when needed with external power control (I have some that only need to run when other actions are occurring, and power is controlled via tasmota).
Other Notes
- A docker setup is provided on the github site, and so are windows & mac binaries and details.
- Just watch when you are sending MQTT commands to the topic… anything at all to the topic will activate the script (including NULL). You will need to to do some rerouting if you are trying to tie it in with other on/off commands