Files
infoscreen-dev/HDMI_CEC_SETUP.md
RobbStarkAustria 82f43f75ba docs: refactor docs structure and tighten assistant instruction policy
shrink root README into a landing page with a docs map and focused contributor guidance
add TV_POWER_RUNBOOK as the canonical TV power rollout and canary runbook
add CHANGELOG and move project history out of README-style docs
refactor src README into a developer-focused guide (architecture, runtime files, MQTT, debugging)
prune redundant older HDMI docs and keep a canonical HDMI_CEC_SETUP path
update copilot instructions to a high-signal policy format with strict anti-shadow-README design rules
align references across docs to current files, scripts, and TV power behavior
2026-04-01 10:01:58 +02:00

9.6 KiB

HDMI-CEC Setup and Configuration

This is the canonical HDMI-CEC operator document.

Related reference material:

Overview

The Infoscreen Client now includes automatic TV control via HDMI-CEC (Consumer Electronics Control). This allows the Raspberry Pi to turn the connected TV on/off automatically based on event scheduling.

Features

  • Auto TV Power On: TV turns on when an event starts
  • Auto TV Power Off: TV turns off (with delay) when no events are active
  • Smart Event Switching: TV stays on when switching between events
  • Configurable Delay: Prevent rapid on/off cycles with configurable turn-off delay
  • Graceful Shutdown: TV turns off when Display Manager stops

How It Works

Event Lifecycle

  1. Event Starts → TV powers on via HDMI-CEC → Display content
  2. Event Switches → TV stays on → New content displays
  3. Event Ends → Wait for delay period → TV powers off (if no new events)
  4. Service Stops → TV powers off after delay

CEC Commands

The system uses cec-client from the cec-utils package to send commands:

  • Power On: echo "on 0" | cec-client -s -d 1
  • Power Off: echo "standby 0" | cec-client -s -d 1
  • Query Status: echo "pow 0" | cec-client -s -d 1

Installation

1. Install CEC Utils

sudo apt-get update
sudo apt-get install cec-utils

2. Test CEC Connection

Check if your TV is detected:

echo "scan" | cec-client -s -d 1

You should see output showing detected devices, including your TV (usually device 0).

3. Test Manual Control

Turn TV on:

echo "on 0" | cec-client -s -d 1

Turn TV off:

echo "standby 0" | cec-client -s -d 1

Check TV power status:

echo "pow 0" | cec-client -s -d 1

Configuration

Add these environment variables to your .env file:

# HDMI-CEC Configuration
CEC_ENABLED=true              # Enable/disable CEC control (true/false)
CEC_DEVICE=0                  # Target device (0 for TV - recommended, or "TV")
CEC_TURN_OFF_DELAY=30         # Seconds to wait before turning off TV
CEC_POWER_ON_WAIT=5           # Seconds to wait after power ON (for TV boot)
CEC_POWER_OFF_WAIT=2          # Seconds to wait after power OFF

Configuration Options

Variable Default Description
CEC_ENABLED true Enable or disable HDMI-CEC control
CEC_DEVICE 0 CEC device identifier - use 0 for TV (recommended), or "TV" for slower name-based lookup
CEC_TURN_OFF_DELAY 30 Seconds to wait after last event ends before turning off TV
CEC_POWER_ON_WAIT 5 Seconds to wait after sending power ON (allows TV to boot up)
CEC_POWER_OFF_WAIT 2 Seconds to wait after sending power OFF

Delay Configuration Examples

# Quick turn-off (10 seconds)
CEC_TURN_OFF_DELAY=10

# Standard delay (30 seconds) - recommended
CEC_TURN_OFF_DELAY=30

# Long delay (2 minutes)
CEC_TURN_OFF_DELAY=120

# Immediate turn-off (not recommended - may cause flicker)
CEC_TURN_OFF_DELAY=0

Troubleshooting

TV Not Responding

  1. Check CEC is enabled on TV

    • Enter TV settings menu
    • Look for "HDMI-CEC", "Anynet+", "Bravia Sync", or similar
    • Enable the feature
  2. Verify CEC detection

    echo "scan" | cec-client -s -d 1
    

    Should show your TV as device 0

  3. Test direct commands

    # Try turning on
    echo "on 0" | cec-client -s -d 1
    
    # Check power status
    echo "pow 0" | cec-client -s -d 1
    

CEC Utils Not Found

If you see "cec-client not found" errors:

# Install the package
sudo apt-get install cec-utils

# Verify installation
which cec-client

TV Turns Off Too Quickly

Increase the turn-off delay:

# In .env file
CEC_TURN_OFF_DELAY=60  # Wait 60 seconds

TV Doesn't Actually Turn On/Off

If cec-client reports success but the TV doesn't respond:

  1. Increase wait times - Some TVs are slow to respond:

    # In .env file
    CEC_POWER_ON_WAIT=10    # Wait 10 seconds for TV to boot
    CEC_POWER_OFF_WAIT=5    # Wait 5 seconds for TV to power down
    
  2. Check TV CEC settings - Make sure CEC is enabled:

    • Look for "HDMI-CEC", "Anynet+", "SimpLink", or similar in TV settings
    • Some TVs require specific CEC modes (e.g., "Full" vs "Limited")
  3. Test with longer delays:

    echo "on 0" | cec-client -s -d 1
    sleep 10  # Wait and watch the TV
    echo "pow 0" | cec-client -s -d 1  # Check if it actually turned on
    
  4. Try the standby device address:

    # In .env file
    CEC_DEVICE=0  # Use numeric device ID instead of "TV"
    

TV Turns Off During Events

Check the logs for timing issues:

tail -f ~/infoscreen-dev/logs/display_manager.log | grep -i cec

Look for:

  • "Turning TV ON via HDMI-CEC" when events start
  • "Scheduling TV turn-off" when events end
  • "Cancelled TV turn-off timer" when new events arrive

Disable CEC Temporarily

To disable CEC without uninstalling:

# In .env file
CEC_ENABLED=false

Or via environment variable:

export CEC_ENABLED=false
./scripts/start-display-manager.sh

Logs and Debugging

Enable Debug Logging

# In .env file
LOG_LEVEL=DEBUG

Monitor CEC Activity

# Watch CEC-related log entries
tail -f ~/infoscreen-dev/logs/display_manager.log | grep -E "(CEC|TV|turn)"

Typical Log Sequence

[INFO] HDMI-CEC controller initialized (device: TV, turn_off_delay: 30s)
[INFO] TV detected as ON
[INFO] Starting display for event: presentation_slides.pdf
[INFO] Turning TV ON via HDMI-CEC...
[INFO] TV turned ON successfully
[INFO] Display started successfully for presentation_slides.pdf
... (event runs) ...
[INFO] No active events in time window - stopping current display
[INFO] Scheduling TV turn-off in 30s...
... (30 seconds later) ...
[INFO] Turning TV OFF via HDMI-CEC...
[INFO] TV turned OFF successfully

Hardware Requirements

Compatible Hardware

  • Raspberry Pi 4/5: Full HDMI-CEC support
  • Raspberry Pi 3: Full HDMI-CEC support
  • TV: Must support HDMI-CEC (check TV manual)

HDMI Cable

  • Use a high-quality HDMI cable
  • CEC signals are part of the HDMI standard, but cheap cables may have issues
  • Cable length should be under 5 meters for reliable CEC

TV Brands and CEC Names

Different manufacturers use different names for HDMI-CEC:

Brand CEC Name
Samsung Anynet+
LG SimpLink
Sony Bravia Sync
Panasonic VIERA Link
Toshiba CE-Link
Sharp Aquos Link
Philips EasyLink
Generic HDMI-CEC

Advanced Usage

Manual CEC Commands

You can manually control the TV using the CEC controller:

# In Python code or interactive shell
from display_manager import HDMICECController

cec = HDMICECController(enabled=True, device="TV", turn_off_delay=30)

# Turn on immediately
cec.turn_on()

# Turn off immediately
cec.turn_off(delayed=False)

# Turn off with delay
cec.turn_off(delayed=True)

# Cancel pending turn-off
cec.cancel_turn_off()

Custom CEC Device

If your TV isn't responding to device "TV", try using the numeric address:

# In .env file
CEC_DEVICE=0  # Most TVs are device 0

Or find your device:

echo "scan" | cec-client -s -d 1
# Look for device addresses in output

Testing Without a TV

For development/testing without a physical TV:

# Disable CEC
CEC_ENABLED=false

# Or install cec-client but commands will harmlessly fail

Integration with Event Scheduler

The CEC controller integrates seamlessly with the event scheduler:

  1. Timed Events: TV turns on at event start time, off after event end time + delay
  2. Continuous Events: TV stays on during event sequences
  3. Manual Control: Events can still be manually started/stopped
  4. Power Saving: TV automatically turns off when idle

Example Event Schedule

{
  "event_type": "presentation",
  "start": "2025-11-12 09:00:00",
  "end": "2025-11-12 09:30:00",
  "presentation": {
    "files": [{"name": "morning.pdf"}]
  }
}

Timeline:

  • 09:00:00: Event starts → TV turns ON → Presentation displays
  • 09:30:00: Event ends → Presentation stops → TV turn-off scheduled
  • 09:30:30: (30s later) → TV turns OFF

Security Considerations

  • CEC commands are broadcast over HDMI (local only)
  • No network exposure
  • Only controls connected TV on same HDMI bus
  • No authentication required (physical connection = authorization)

Performance Impact

  • Minimal CPU usage (< 1%)
  • CEC commands complete in 1-2 seconds
  • No impact on display performance
  • Commands run in background threads

Known Limitations

  1. Single TV: Controls one TV per HDMI output
  2. CEC Support Required: TV must support HDMI-CEC
  3. Command Reliability: Some TVs respond slower than others
  4. No Status Feedback: Limited ability to verify TV actually turned on/off
  5. HDMI Connection Required: Must be physically connected via HDMI

Future Enhancements

Potential future improvements:

  • Multi-monitor support
  • TV volume control
  • Input source switching
  • Enhanced status detection
  • Custom CEC command sequences
  • Event-specific CEC behaviors

Support and Feedback

If you encounter issues:

  1. Check logs: ~/infoscreen-dev/logs/display_manager.log
  2. Verify CEC is working: echo "scan" | cec-client -s -d 1
  3. Test manual commands: echo "on 0" | cec-client -s -d 1
  4. Check TV settings for CEC enable
  5. Review this documentation

For bugs or feature requests, please file an issue on GitHub.