# HDMI-CEC Setup and Configuration This is the canonical HDMI-CEC operator document. Related reference material: - [HDMI_CEC_DEV_MODE.md](HDMI_CEC_DEV_MODE.md): development-mode behavior. - [HDMI_CEC_FLOW_DIAGRAM.md](HDMI_CEC_FLOW_DIAGRAM.md): flow and sequence diagrams. ## 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 ```bash sudo apt-get update sudo apt-get install cec-utils ``` ### 2. Test CEC Connection Check if your TV is detected: ```bash 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: ```bash echo "on 0" | cec-client -s -d 1 ``` Turn TV off: ```bash echo "standby 0" | cec-client -s -d 1 ``` Check TV power status: ```bash echo "pow 0" | cec-client -s -d 1 ``` ## Configuration Add these environment variables to your `.env` file: ```bash # 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 ```bash # 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** ```bash echo "scan" | cec-client -s -d 1 ``` Should show your TV as device 0 3. **Test direct commands** ```bash # 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: ```bash # Install the package sudo apt-get install cec-utils # Verify installation which cec-client ``` ### TV Turns Off Too Quickly Increase the turn-off delay: ```bash # 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: ```bash # 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**: ```bash 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**: ```bash # In .env file CEC_DEVICE=0 # Use numeric device ID instead of "TV" ``` ### TV Turns Off During Events Check the logs for timing issues: ```bash 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: ```bash # In .env file CEC_ENABLED=false ``` Or via environment variable: ```bash export CEC_ENABLED=false ./scripts/start-display-manager.sh ``` ## Logs and Debugging ### Enable Debug Logging ```bash # In .env file LOG_LEVEL=DEBUG ``` ### Monitor CEC Activity ```bash # 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: ```python # 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: ```bash # In .env file CEC_DEVICE=0 # Most TVs are device 0 ``` Or find your device: ```bash echo "scan" | cec-client -s -d 1 # Look for device addresses in output ``` ### Testing Without a TV For development/testing without a physical TV: ```bash # 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 ```json { "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.