I got the inspiration and did a clean copy/paste of the python code located here: Controlling the Raspberry Pi HDMI port — with MQTT and Home Assistant :: Cavelab blog — Stories from the Cavelab
Perhaps there are simpler ways to do this, but I like MQTT. Step 1 and 2 might look different for you, depending on your motion sensor.
PS: switch is in Dutch, cause I’m Flemish. google translate to the rescue.
Step 1: create a switch, based on MQTT
Home assistant/configuration.yml
mqtt:
switch:
- name: "Keuken beweging"
state_topic: "keuken/sensor/beweging"
command_topic: "keuken/sensor/beweging"
payload_off: 0
payload_on: 1
Step 2: create homekit automation
In my Homekit, this switch is triggered through an automation.
Basically, between 6:30 am and 10:30 pm, it’ll detect presence in the kitchen ,where the Dakboard screen is located. I’m not interested in having my Dakboard/HA screen lit outside of those hours.
Step 3: node-red config
The payload (1 in case of movement) will be in MQTT, where Node-Red comes in. Node-Red actually only adds a timer (after 25 minutes send a “0”, unless movement is detected again), and passes the payload (0 or 1) on to another MQTT topic.
Trigger
Step 4: MQTT client and scripts on the Dakboard/HA kiosk screen
This is based on Raspberry Bullseye, so perhaps it might be different with latest Debian version.
On the Pi, a python script was created that powers the screen off or on. This script is made into a system service, that refreshes every 60 seconds.
mqtt.py
import paho.mqtt.client as mqtt
import time
import subprocess
# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
print("Connected with result code " + str(rc))
# Subscribing in on_connect() means that if we lose the connection and
# reconnect then subscriptions will be renewed.
client.subscribe("rpi-board/screen/set")
# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
print(msg.topic + " " + str(msg.payload.decode('utf-8')))
subprocess.run(["vcgencmd", "display_power", str(msg.payload.decode('utf-8'))])
client.publish("rpi-board/screen", get_screen_status())
# Return the state of the HDMI port power
def get_screen_status():
status = subprocess.run(["vcgencmd", "display_power"], stdout=subprocess.PIPE, text=True)
status_b = status.stdout.split("=")[1].strip()
return status_b
client = mqtt.Client("rpi-board")
client.username_pw_set("mqtt", "<password>")
client.on_connect = on_connect
client.on_message = on_message
client.connect("hassio-mqtt.lan")
client.loop_start()
while True:
client.publish("rpi-board/screen", get_screen_status())
time.sleep(60)
The system service located in /lib/systemd/system/mqtt_status.service
[Unit]
Description=MQTT status
After=multi-user.target
#Wants=network.target
[Service]
Type=simple
ExecStart=/usr/bin/python3 /home/pi/mqtt.py
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
And that’s it.