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
399 lines
9.6 KiB
Markdown
399 lines
9.6 KiB
Markdown
# 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.
|