-
Notifications
You must be signed in to change notification settings - Fork 1
pyCEC for CEC Monitoring
pyCEC
is a Python library for interfacing with HDMI CEC (Consumer Electronics Control) devices. This guide will help you set up pyCEC
on a Raspberry Pi or similar device, monitor CEC messages, and decode them into a human-readable format.
- Hardware: Raspberry Pi4.
-
Software: Python 3.x,
pyCEC
library, andcec-utils
.
First, make sure that libcec is installed on your Raspberry Pi. You can install it using the following commands:
sudo apt-get update
sudo apt-get install libcec-dev cec-utils
First, you'll need to install pyCEC
using pip. Open a terminal and run:
pip3 install cec
Ensure that your device has CEC capabilities and the necessary tools installed. You can check for CEC support using:
cec-ctl -d0 --status
Create a Python script to monitor CEC messages. Below is an example script that initializes pyCEC, retrieves device information, and prints out decoded CEC messages.
import cec
import time
# Initialize CEC
adapters = cec.list_adapters()
if len(adapters) > 0:
adapter = adapters[0]
print("Using Adapter %s"%(adapter))
cec.init(adapter)
# CEC logical address to string mapping
logical_address_map = {
0: "TV",
1: "Recording Device 1",
2: "Recording Device 2",
3: "Tuner 1",
4: "Playback Device 1",
5: "Audio System",
6: "Tuner 2",
7: "Tuner 3",
8: "Playback Device 2",
9: "Recording Device 3",
10: "Tuner 4",
11: "Playback Device 3",
12: "Reserved 1",
13: "Reserved 2",
14: "Free use",
15: "Broadcast"
}
# CEC opcodes to string mapping
opcode_map = {
0x00: "Feature Abort",
0x04: "Image View On",
0x05: "Tuner Step Increment",
0x06: "Tuner Step Decrement",
0x07: "Tuner Device Status",
0x08: "Give Tuner Device Status",
0x09: "Record On",
0x0A: "Record Status",
0x0B: "Record Off",
0x0D: "Text View On",
0x0F: "Record TV Screen",
0x1A: "Give Deck Status",
0x1B: "Deck Status",
0x32: "Set Menu Language",
0x33: "Clear Analog Timer",
0x34: "Set Analog Timer",
0x35: "Timer Status",
0x36: "Standby",
0x41: "Play",
0x42: "Deck Control",
0x43: "Timer Cleared Status",
0x44: "User Control Pressed",
0x45: "User Control Released",
0x46: "Give OSD Name",
0x47: "Set OSD Name",
0x64: "Set OSD String",
0x67: "Set Timer Program Title",
0x70: "System Audio Mode Request",
0x71: "Give Audio Status",
0x72: "Set System Audio Mode",
0x7A: "Report Audio Status",
0x7D: "Give System Audio Mode Status",
0x7E: "System Audio Mode Status",
0x80: "Routing Change",
0x81: "Routing Information",
0x82: "Active Source",
0x83: "Give Physical Address",
0x84: "Report Physical Address",
0x85: "Request Active Source",
0x86: "Set Stream Path",
0x87: "Device Vendor ID",
0x89: "Vendor Command",
0x8A: "Vendor Remote Button Down",
0x8B: "Vendor Remote Button Up",
0x8C: "Give Device Vendor ID",
0x8D: "Menu Request",
0x8E: "Menu Status",
0x8F: "Give Device Power Status",
0x90: "Report Power Status",
0x91: "Get Menu Language",
0x92: "Select Analog Service",
0x93: "Select Digital Service",
0x97: "Set Digital Timer",
0x99: "Clear Digital Timer",
0x9A: "Set Audio Rate",
0x9D: "Inactive Source",
0x9E: "CEC Version",
0x9F: "Get CEC Version",
0xA0: "Vendor Command With ID",
0xA1: "Clear External Timer",
0xA2: "Set External Timer",
0xC0: "Initiate ARC",
0xC1: "Report ARC Initiated",
0xC2: "Report ARC Terminated",
0xC3: "Request ARC Initiation",
0xC4: "Request ARC Termination",
0xC5: "Terminate ARC",
0xFF: "Abort"
}
# Dictionary to store logical address to device name mapping
device_name_map = {}
def get_device_names():
devices = cec.list_devices()
print("Devices found:")
print("-----------------------------------------------------------------------------------------------------------------------------------------------------")
for device in devices:
d = cec.Device(device)
logical_address = d.address
name = d.osd_string if d.osd_string else f"Unknown Device {logical_address}"
device_name_map[logical_address] = name
print(f"Logical Address: {logical_address}, Name: {name}, Physical Address: {d.physical_address}, Vendor ID: {d.vendor}, CEC Version: {d.cec_version}, Language: {d.language}")
print("-----------------------------------------------------------------------------------------------------------------------------------------------------")
# Function to decode CEC message
def decode_cec_message(event):
opcode = event['opcode']
initiator = event['initiator']
destination = event['destination']
parameters = event['parameters']
initiator_name = device_name_map.get(initiator, f"Unknown Device {initiator}")
destination_name = "Broadcast" if destination == 15 else device_name_map.get(destination, f"Unknown Device {destination}")
opcode_name = opcode_map.get(opcode, f"Unknown Opcode 0x{opcode:02X}")
parameters_str = ' '.join(f'0x{byte:02X}' for byte in parameters)
print(f"CEC Message: {initiator_name} -> {destination_name} | Opcode: {opcode_name} | Parameters: {parameters_str}")
# Callback function to process received CEC messages
def process_cec_message(event, *param):
for msg in param:
decode_cec_message(msg)
# Get device names at startup
get_device_names()
print("*************Monitoring Messages**********************")
# Register the callback function
cec.add_callback(process_cec_message, cec.EVENT_COMMAND)
# Keep the script running to continue monitoring
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
cec.close()
Save the script as cec-monitor.py and run it using:
python3 cec-monitor.py
The script will print out the details of connected devices and continuously monitor CEC messages. The decode_cec_message function translates the CEC opcodes into human-readable descriptions.
Using Adapter /dev/cec0
Devices found:
-----------------------------------------------------------------------------------------------------------------------------------------------------
Logical Address: 0, Name: TV, Physical Address: 0.0.0.0, Vendor ID: 080046, CEC Version: 1.4, Language: eng
Logical Address: 1, Name: python-cec, Physical Address: 1.2.0.0, Vendor ID: 001582, CEC Version: 1.4, Language: eng
Logical Address: 4, Name: SOUND SYSTEM, Physical Address: 1.0.0.0, Vendor ID: 080046, CEC Version: 1.4, Language: ???
Logical Address: 5, Name: SOUND SYSTEM, Physical Address: 1.0.0.0, Vendor ID: 080046, CEC Version: 1.4, Language: ???
Logical Address: 11, Name: Fire TV Stick, Physical Address: 2.0.0.0, Vendor ID: 000CE7, CEC Version: 1.4, Language: ???
-----------------------------------------------------------------------------------------------------------------------------------------------------
*************Monitoring Messages**********************
CEC Message: Fire TV Stick -> Broadcast | Opcode: Device Vendor ID | Parameters: 0x00 0x0C 0xE7
CEC Message: Fire TV Stick -> python-cec | Opcode: Give Physical Address | Parameters:
CEC Message: TV -> python-cec | Opcode: Give OSD Name | Parameters:
CEC Message: Fire TV Stick -> python-cec | Opcode: Give Device Vendor ID | Parameters:
CEC Message: Fire TV Stick -> python-cec | Opcode: Give OSD Name | Parameters:
CEC Message: Fire TV Stick -> python-cec | Opcode: Get CEC Version | Parameters:
CEC Message: TV -> python-cec | Opcode: Give Device Vendor ID | Parameters:
CEC Message: Fire TV Stick -> python-cec | Opcode: Feature Abort | Parameters: 0x9E 0x00
CEC Message: Fire TV Stick -> python-cec | Opcode: Give Physical Address | Parameters:
CEC Message: Fire TV Stick -> python-cec | Opcode: Give Device Vendor ID | Parameters:
CEC Message: Fire TV Stick -> python-cec | Opcode: Give OSD Name | Parameters:
CEC Message: Fire TV Stick -> python-cec | Opcode: Get CEC Version | Parameters:
CEC Message: TV -> python-cec | Opcode: Give OSD Name | Parameters:
CEC Message: TV -> python-cec | Opcode: Give Device Vendor ID | Parameters:
CEC Message: Fire TV Stick -> python-cec | Opcode: Get CEC Version | Parameters:
CEC Message: Fire TV Stick -> python-cec | Opcode: Get CEC Version | Parameters:
CEC Message: SOUND SYSTEM -> Broadcast | Opcode: Report Physical Address | Parameters: 0x10 0x00 0x04
CEC Message: SOUND SYSTEM -> Broadcast | Opcode: Device Vendor ID | Parameters: 0x08 0x00 0x46
CEC Message: SOUND SYSTEM -> Broadcast | Opcode: Device Vendor ID | Parameters: 0x08 0x00 0x46
CEC Message: SOUND SYSTEM -> Broadcast | Opcode: Report Physical Address | Parameters: 0x10 0x00 0x04
CEC Message: SOUND SYSTEM -> Broadcast | Opcode: Device Vendor ID | Parameters: 0x08 0x00 0x46
CEC Message: SOUND SYSTEM -> Broadcast | Opcode: Device Vendor ID | Parameters: 0x08 0x00 0x46
CEC Message: SOUND SYSTEM -> Broadcast | Opcode: Report Physical Address | Parameters: 0x10 0x00 0x05
CEC Message: SOUND SYSTEM -> Broadcast | Opcode: Device Vendor ID | Parameters: 0x08 0x00 0x46
CEC Message: SOUND SYSTEM -> Broadcast | Opcode: Device Vendor ID | Parameters: 0x08 0x00 0x46
CEC Message: SOUND SYSTEM -> Broadcast | Opcode: Report Physical Address | Parameters: 0x10 0x00 0x05
CEC Message: SOUND SYSTEM -> Broadcast | Opcode: Device Vendor ID | Parameters: 0x08 0x00 0x46
CEC Message: SOUND SYSTEM -> Broadcast | Opcode: Device Vendor ID | Parameters: 0x08 0x00 0x46