Linux - Screen Control

From Da Nerd Mage Wiki
Jump to navigation Jump to search
Proven on:
Logo Debian.png
12 (bookworm)

This little setup allows for remote control (via MQTT) of the screen(s) of Linux-based computers.

Specifically set up for all-in-one machines & laptops since these are a little difficult to shut off the screen without shutting down the machine itself.

  • sudo apt install vbetool

The Script

The following script needs to run as root...

  • sudo vi /usr/local/bin/screenremote.py
 #!/usr/bin/env python
 
 import paho.mqtt.client as mqttClient
 import time
 import os
 import subprocess
 import socket
 
 ###################################################################################################
 
 hostname = socket.gethostname()
 broker_address = "skynet"
 port = 1883
 topic = hostname + "/#"
 user = "user"
 password = "password"
 client = mqttClient.Client(hostname + "control")
 client.username_pw_set(user, password=password)
 
 ###################################################################################################
 ##    Broker Connection    ##
 ###################################################################################################
 
 Connected = False
 
 def on_connect(client, userdata, flags, rc):
     global Connected
     if rc == 0:
         print("           HostName: ", hostname)
         print("Connected to broker: ", broker_address)
         print("      Subscribed to: ", topic)
         print()
         Connected =True
     else:
         print("Connection failed")
         Connected =False
 
 ###################################################################################################
 ##    Message Handling    ##
 ###################################################################################################
 
 def on_message(client, userdata, message):
     print( " Received message: " + str(message.payload.decode("utf-8")))
     print( "         on topic: " + message.topic)
     #print( "         with QoS: " + str(message.qos))
 
     time.sleep(1)
 
 ### Display control (turn the screen on or off...)
     if message.topic == hostname + "/display":
         command = "/usr/sbin/vbetool dpms " + str(message.payload.decode("utf-8"))
         print( command )
         os.system(command)
 ### Audio control (something for th future...)
     elif message.topic == hostname + "/audio":
         print("audio stuff")
 ### Not any sort of valid topic...
     else:
         print("Not Important to us...")
 
     print()
 
 ###################################################################################################
 
 client.on_connect = on_connect
 client.on_message = on_message
 
 client.connect(broker_address, port=port)
 client.loop_start()
 
 while Connected != True:
     time.sleep(0.1)
 
 client.subscribe(topic)
 
 try:
     while True:
         time.sleep(1)
 
 except KeyboardInterrupt:
     print( "exiting" )
     client.disconnect()
     client.loop_stop()
  • sudo chmod +x /usr/local/bin/screenremote.py

This will respond to MQTT messages:

  • HOSTNAME/display on
  • HOSTNAME/display off

The Service

It works as a systemd service

  • sudo vi /etc/systemd/system/remote-screen-control.service
[Unit]
Description=Watch for MQTT messages to turn screen on/off
After=multi-user.target

[Service]
ExecStart=/usr/local/bin/screenremote.py
Type=simple

[Install]
WantedBy=multi-user.target
  • sudo systemctl enable remote-screen-control.service
  • sudo systemctl start remote-screen-control.service
  • sudo systemctl status remote-screen-control.service

Notes

For some older systems, vbetool fails.

In this case, if the system has X installed (i.e.: it has a GUI), xset might do the job in its place.

  • xset -display :0.0 dpms force off
  • xset -display :0.0 dpms force on