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:

  1. downloaded an appropriate binary (linux_amd64 in my case) from here https://github.com/albertnis/mqcontrol/releases
  2. put it in /usr/local/bin
  3. renamed it mqcontrol
  4. 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

Leave a Reply

Your email address will not be published. Required fields are marked *

Post comment