Difference between revisions of "Linux - Screen Control"
(→Notes) |
|||
(21 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
{{{!}} class="wikitable" style="float: right; width: 322px;" border="2" | |||
{{!}}+ Proven on: | |||
{{!}}- < --="" debian="" --> | |||
{{!}} style="text-align: center; width: 60px;" {{!}} [[File:Logo Debian.png{{!}}60px{{!}}link=https://www.debian.org/{{!}}center{{!}}middle{{!}}frameless]] | |||
{{!}} style="text-align: center; width: 40px;" {{!}} 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. | |||
== The Script == | |||
* <code>sudo apt install vbetool</code> | * <code>sudo apt install vbetool</code> | ||
The following script needs to run as root... | The following script needs to run as root... | ||
* <code>sudo vi /usr/local/bin/screenremote.py</code> | * <code>sudo vi /usr/local/bin/screenremote.py</code> | ||
<syntaxhighlight lang="python" line> | |||
#!/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() | |||
</syntaxhighlight> | |||
* <code>sudo chmod +x /usr/local/bin/screenremote.py</code> | * <code>sudo chmod +x /usr/local/bin/screenremote.py</code> | ||
This will respond to MQTT messages: | This will respond to MQTT messages: | ||
Line 92: | Line 109: | ||
* '''HOSTNAME'''/display on | * '''HOSTNAME'''/display on | ||
* '''HOSTNAME'''/display off | * '''HOSTNAME'''/display off | ||
== The Service == | |||
It works as a '''systemd''' service | |||
* <code>sudo vi /etc/systemd/system/remote-screen-control.service</code> | * <code>sudo vi /etc/systemd/system/remote-screen-control.service</code> | ||
<syntaxhighlight lang="ini" line> | |||
[Unit] | |||
Description=Watch for MQTT messages to turn screen on/off | |||
Documentation=https://wiki.nerdmage.ca/index.php/Linux_-_Screen_Control | |||
After=multi-user.target network.target | |||
[Service] | |||
ExecStart=<code>/usr/local/bin/screenremote.py</code> | |||
Type=simple | |||
Restart=on-failure | |||
[Install] | |||
WantedBy=multi-user.target | |||
</syntaxhighlight> | |||
* <code>sudo systemctl daemon-reload</code> | |||
* <code>sudo systemctl enable remote-screen-control.service</code> | * <code>sudo systemctl enable remote-screen-control.service</code> | ||
* <code>sudo systemctl start remote-screen-control.service</code> | * <code>sudo systemctl start remote-screen-control.service</code> | ||
* <code>sudo systemctl status remote-screen-control.service</code> | * <code>sudo systemctl status remote-screen-control.service</code> | ||
== Notes == | |||
=== non vbetool capable systems === | |||
For some 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. | |||
* <code>xset -display :0.0 dpms force off</code> | |||
* <code>xset -display :0.0 dpms force on</code> | |||
<span style="color: rgb(186, 55, 42);" >As of yet... No solution for systems without '''X'''.</span> | |||
=== Python Weirdness === | |||
Sometimes, '''Python''' & it's tools & modules are a little problematic. | |||
Installing '''Python3''' & '''paho-mqtt''' directly will force this to work. (&, of course, you should force it to be '''Python3'''...) | |||
* <code>sudo apt install python-is-python3 python3-paho-mqtt</code> | |||
=== Broker temporarily offline causes failure === | |||
If this service loses contact with the broker, it does not try to find it again. Must find a solution to this... | |||
Meanwhile: | |||
* <code>sudo systemctl restart remote-screen-control.service</code> | |||
gets it back online. |
Latest revision as of 11:55, 11 October 2024
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.
The Script
sudo apt install vbetool
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
Documentation=https://wiki.nerdmage.ca/index.php/Linux_-_Screen_Control
After=multi-user.target network.target
[Service]
ExecStart=<code>/usr/local/bin/screenremote.py</code>
Type=simple
Restart=on-failure
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable remote-screen-control.service
sudo systemctl start remote-screen-control.service
sudo systemctl status remote-screen-control.service
Notes
non vbetool capable systems
For some 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
As of yet... No solution for systems without X.
Python Weirdness
Sometimes, Python & it's tools & modules are a little problematic.
Installing Python3 & paho-mqtt directly will force this to work. (&, of course, you should force it to be Python3...)
sudo apt install python-is-python3 python3-paho-mqtt
Broker temporarily offline causes failure
If this service loses contact with the broker, it does not try to find it again. Must find a solution to this...
Meanwhile:
sudo systemctl restart remote-screen-control.service
gets it back online.