Add aggressive HDMI power control to prevent display shutdown

Enhanced Raspberry Pi HDMI power management:

Boot Configuration (/boot/config.txt):
- hdmi_blanking=0 - Disable HDMI blanking
- hdmi_force_hotplug=1 - Force HDMI mode always on
- hdmi_ignore_cec_init=1 - Disable HDMI CEC interference
- hdmi_ignore_edid=0xa5000080 - Disable HDMI sleep mode

New systemd services:
- hdmi-poweron.service - Runs tvservice -p every 30 seconds
- screen-keepalive.service - Aggressive display keep-alive script

Display keep-alive script (.display-keepalive.sh):
- tvservice -p - Force HDMI to stay powered
- xset commands - Keep X11 screensaver off
- xdotool - Mouse movement for activity detection
- xrandr - Disable monitor power profile saving
- 30-second loop for continuous power signaling

Enhanced app-level control (main.py):
- DISPLAY=:0 environment variable for X11 commands
- tvservice integration in signal_screen_activity()
- xrandr power profile management
- More aggressive DPMS disabling

This addresses HDMI being powered down at multiple levels:
1. Firmware level (boot config)
2. System level (systemd services)
3. X11 level (xset, xdotool, xrandr)
4. App level (continuous signaling)

HDMI output should now remain powered throughout playback.
This commit is contained in:
Kiwy Player
2026-01-17 19:59:45 +02:00
parent 8703350b23
commit 72a6d7e704
3 changed files with 114 additions and 10 deletions

View File

@@ -1 +1 @@
1768670593.7002711
1768672780.5973904

View File

@@ -151,7 +151,33 @@ setup_raspberry_pi_power_management() {
else
echo "hdmi_blanking=0" | sudo tee -a /boot/config.txt > /dev/null
fi
echo "✓ HDMI screen blanking disabled"
# Disable HDMI CEC (can interfere with power management)
if grep -q "hdmi_ignore_cec_init" /boot/config.txt; then
sudo sed -i 's/^hdmi_ignore_cec_init=.*/hdmi_ignore_cec_init=1/' /boot/config.txt
else
echo "hdmi_ignore_cec_init=1" | sudo tee -a /boot/config.txt > /dev/null
fi
# Force HDMI mode to always be on
if grep -q "hdmi_force_hotplug" /boot/config.txt; then
sudo sed -i 's/^hdmi_force_hotplug=.*/hdmi_force_hotplug=1/' /boot/config.txt
else
echo "hdmi_force_hotplug=1" | sudo tee -a /boot/config.txt > /dev/null
fi
# Disable HDMI sleep mode
if grep -q "hdmi_ignore_edid" /boot/config.txt; then
sudo sed -i 's/^hdmi_ignore_edid=.*/hdmi_ignore_edid=0xa5000080/' /boot/config.txt
else
echo "hdmi_ignore_edid=0xa5000080" | sudo tee -a /boot/config.txt > /dev/null
fi
echo "✓ HDMI configuration locked in /boot/config.txt"
echo " - HDMI blanking disabled"
echo " - HDMI CEC disabled"
echo " - HDMI hotplug forced"
echo " - HDMI sleep mode disabled"
fi
# Disable screensaver and screen blanking in X11
@@ -295,7 +321,71 @@ EOF
chmod +x "$KEEPALIVE_SCRIPT"
echo "✓ Screen keep-alive service created"
# Create systemd service to run keep-alive service
# Create systemd service to keep HDMI powered on
echo "Creating HDMI power control service..."
sudo tee /etc/systemd/system/hdmi-poweron.service > /dev/null << 'EOF'
[Unit]
Description=Keep HDMI Display Powered On
After=multi-user.target display-manager.service
[Service]
Type=simple
ExecStart=/bin/bash -c 'while true; do /usr/bin/tvservice -p 2>/dev/null; sleep 30; done'
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable hdmi-poweron.service
sudo systemctl start hdmi-poweron.service
echo "✓ HDMI power control service enabled"
# Create aggressive display keep-alive script
echo "Creating aggressive display keep-alive script..."
DISPLAY_KEEPALIVE="$SCRIPT_DIR/.display-keepalive.sh"
cat > "$DISPLAY_KEEPALIVE" << 'EOF'
#!/bin/bash
# Aggressive display keep-alive for Raspberry Pi
# Prevents HDMI from powering down
DISPLAY_TIMEOUT=30
while true; do
# Keep HDMI powered on (tvservice command)
if command -v tvservice &> /dev/null; then
/usr/bin/tvservice -p 2>/dev/null
fi
# Disable screensaver
if command -v xset &> /dev/null; then
DISPLAY=:0 xset s off 2>/dev/null
DISPLAY=:0 xset -dpms 2>/dev/null
DISPLAY=:0 xset dpms force on 2>/dev/null
DISPLAY=:0 xset s reset 2>/dev/null
fi
# Move mouse to trigger activity
if command -v xdotool &> /dev/null; then
DISPLAY=:0 xdotool mousemove_relative 1 1 2>/dev/null
DISPLAY=:0 xdotool mousemove_relative -1 -1 2>/dev/null
fi
# Disable monitor power saving
if command -v xrandr &> /dev/null; then
DISPLAY=:0 xrandr --output HDMI-1 --power-profile performance 2>/dev/null || true
fi
sleep $DISPLAY_TIMEOUT
done
EOF
chmod +x "$DISPLAY_KEEPALIVE"
echo "✓ Display keep-alive script created"
# Update systemd screen keep-alive service to use this script
sudo tee /etc/systemd/system/screen-keepalive.service > /dev/null << EOF
[Unit]
Description=Keep Screen Awake During Signage Player
@@ -304,9 +394,12 @@ PartOf=graphical-session.target
[Service]
Type=simple
ExecStart=/bin/bash -c 'while true; do xset s reset 2>/dev/null; sleep 30; done'
User=$ACTUAL_USER
ExecStart=/bin/bash $DISPLAY_KEEPALIVE
Restart=always
RestartSec=5
Environment="DISPLAY=:0"
Environment="XAUTHORITY=%h/.Xauthority"
[Install]
WantedBy=graphical-session.target
@@ -314,7 +407,7 @@ EOF
sudo systemctl daemon-reload
sudo systemctl enable screen-keepalive.service
echo "✓ Systemd screen keep-alive service enabled"
echo "✓ Aggressive screen keep-alive service enabled"
echo ""
echo "⚠️ Note: Some changes require a system reboot to take effect."

View File

@@ -934,17 +934,28 @@ class SignagePlayer(Widget):
1. xset s reset - Reset screensaver timeout
2. xset dpms force on - Force display on
3. xdotool - Move mouse to trigger activity
4. tvservice - Keep HDMI powered on (Raspberry Pi)
5. xrandr - Disable monitor power saving
"""
try:
# Method 1: Reset screensaver timer using xset
os.system('xset s reset 2>/dev/null')
os.system('DISPLAY=:0 xset s reset 2>/dev/null')
# Method 2: Force display on
os.system('xset dpms force on 2>/dev/null')
os.system('DISPLAY=:0 xset dpms force on 2>/dev/null')
# Method 3: Move mouse slightly (subtle, user won't notice)
if os.system('xdotool mousemove_relative 1 1 2>/dev/null') == 0:
os.system('xdotool mousemove_relative -1 -1 2>/dev/null')
# Method 3: Disable DPMS
os.system('DISPLAY=:0 xset -dpms 2>/dev/null')
# Method 4: Move mouse slightly (subtle, user won't notice)
if os.system('DISPLAY=:0 xdotool mousemove_relative 1 1 2>/dev/null') == 0:
os.system('DISPLAY=:0 xdotool mousemove_relative -1 -1 2>/dev/null')
# Method 5: Keep HDMI powered on (Raspberry Pi specific)
os.system('/usr/bin/tvservice -p 2>/dev/null')
# Method 6: Disable monitor power saving via xrandr
os.system('DISPLAY=:0 xrandr --output HDMI-1 --power-profile performance 2>/dev/null || true')
Logger.debug("SignagePlayer: Screen activity signal sent (display kept awake)")