or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

0

# CEC (Consumer Electronics Control)

1

2

Python bindings for libcec, enabling control of CEC-compliant HDMI devices (TVs, receivers, etc.) from Python scripts. The library provides a comprehensive API for device discovery, power management, volume control, input switching, and event-driven programming through callbacks.

3

4

## Package Information

5

6

- **Package Name**: cec

7

- **Language**: Python (C++ extension)

8

- **Installation**: `pip install cec`

9

- **Hardware Requirements**: CEC-capable hardware (Pulse-Eight USB-CEC adapter, Raspberry Pi, etc.)

10

11

## Core Imports

12

13

```python

14

import cec

15

```

16

17

## Basic Usage

18

19

```python

20

import cec

21

22

# Initialize CEC library with default adapter

23

cec.init()

24

25

# Create a device object for the TV

26

tv = cec.Device(cec.CECDEVICE_TV)

27

28

# Control the TV

29

tv.power_on()

30

print("TV is on:", tv.is_on())

31

32

# Volume control

33

cec.volume_up()

34

cec.volume_down()

35

cec.toggle_mute()

36

37

# Clean shutdown (when supported)

38

# cec.close() # Not implemented in current version

39

```

40

41

## Capabilities

42

43

### Adapter Management

44

45

Initialize and manage CEC adapters for communication with the CEC bus.

46

47

```python { .api }

48

def list_adapters():

49

"""

50

List available CEC adapters on the system.

51

52

Returns:

53

list: Available adapter names/paths

54

"""

55

56

def init():

57

"""

58

Initialize CEC library with the default adapter.

59

60

Returns:

61

bool: True if initialization successful

62

63

Raises:

64

RuntimeError: If initialization fails

65

"""

66

67

def init(adapter):

68

"""

69

Initialize CEC library with a specific adapter.

70

71

Args:

72

adapter (str): Adapter name/path from list_adapters()

73

74

Returns:

75

bool: True if initialization successful

76

77

Raises:

78

RuntimeError: If initialization fails

79

"""

80

```

81

82

### Device Discovery

83

84

Discover and enumerate CEC devices on the bus.

85

86

```python { .api }

87

def list_devices():

88

"""

89

List all discovered CEC devices on the bus.

90

91

Returns:

92

dict: Dictionary mapping device logical addresses (int) to Device objects

93

"""

94

```

95

96

### Event System

97

98

Register and manage event callbacks for CEC events like key presses, commands, and state changes.

99

100

```python { .api }

101

def add_callback(handler, events):

102

"""

103

Add an event callback handler.

104

105

Args:

106

handler (callable): Function to handle events, signature varies by event type

107

events (int): Bitmask of event types to listen for

108

109

Returns:

110

bool: True if callback was registered successfully

111

"""

112

113

def remove_callback(handler, events):

114

"""

115

Remove an event callback handler.

116

117

Args:

118

handler (callable): Previously registered callback function

119

events (int): Bitmask of event types to stop listening for

120

121

Returns:

122

bool: True if callback was removed successfully

123

"""

124

```

125

126

### Raw Communication

127

128

Send raw CEC commands directly to devices on the bus.

129

130

```python { .api }

131

def transmit(destination, opcode, parameters=None, initiator=None):

132

"""

133

Transmit a raw CEC command to a specific device.

134

135

Args:

136

destination (int): Target device logical address (0-15)

137

opcode (int): CEC opcode for the command

138

parameters (bytes, optional): Command parameters as byte string

139

initiator (int, optional): Source logical address (0-15). If not specified, uses primary adapter address

140

141

Returns:

142

bool: True if transmission successful

143

"""

144

```

145

146

### Active Source Management

147

148

Manage which device is the active source on the CEC bus.

149

150

```python { .api }

151

def is_active_source(addr):

152

"""

153

Check if device at the given address is the active source.

154

155

Args:

156

addr (int): Device logical address

157

158

Returns:

159

bool: True if device is active source

160

"""

161

162

def set_active_source():

163

"""

164

Set the default device as the active source.

165

166

Returns:

167

bool: True if successful

168

"""

169

170

def set_active_source(device_type):

171

"""

172

Set a specific device type as the active source.

173

174

Args:

175

device_type (int): CEC device type constant

176

177

Returns:

178

bool: True if successful

179

"""

180

```

181

182

### Volume Control

183

184

Control audio volume and mute state through CEC.

185

186

```python { .api }

187

def volume_up():

188

"""

189

Increase the volume via CEC.

190

191

Returns:

192

bool: True if command sent successfully

193

"""

194

195

def volume_down():

196

"""

197

Decrease the volume via CEC.

198

199

Returns:

200

bool: True if command sent successfully

201

"""

202

203

def toggle_mute():

204

"""

205

Toggle mute state via CEC.

206

Available in libcec 2.0+ only.

207

208

Returns:

209

bool: True if command sent successfully

210

"""

211

```

212

213

### Physical Address Management

214

215

Configure HDMI physical addresses and stream paths.

216

217

```python { .api }

218

def set_stream_path(path):

219

"""

220

Set the HDMI stream path.

221

222

Args:

223

path (int): Physical address as integer

224

225

Returns:

226

bool: True if successful

227

"""

228

229

def set_physical_addr(addr):

230

"""

231

Set the HDMI physical address.

232

233

Args:

234

addr (int): Physical address as integer

235

236

Returns:

237

bool: True if successful

238

"""

239

```

240

241

### Configuration Persistence

242

243

Manage CEC configuration persistence to adapter hardware.

244

245

```python { .api }

246

def can_persist_config():

247

"""

248

Check if the current adapter supports configuration persistence.

249

250

Returns:

251

bool: True if adapter can persist configuration

252

"""

253

254

def persist_config():

255

"""

256

Persist the current CEC configuration to the adapter.

257

258

Returns:

259

bool: True if configuration was persisted successfully

260

"""

261

262

def set_port(device, port):

263

"""

264

Set upstream HDMI port for a device.

265

266

Args:

267

device (int): Device logical address

268

port (int): HDMI port number

269

270

Returns:

271

bool: True if successful

272

"""

273

```

274

275

### Device Objects

276

277

The Device class represents individual CEC devices and provides methods for device-specific control.

278

279

```python { .api }

280

class Device:

281

"""

282

Represents a CEC device on the bus.

283

"""

284

285

def __init__(self, id):

286

"""

287

Create a Device object for the given logical address.

288

289

Args:

290

id (int): Logical address of the device (0-15)

291

"""

292

293

# Read-only properties

294

@property

295

def address(self):

296

"""

297

Logical address of the device.

298

299

Returns:

300

int: Device logical address (0-15)

301

"""

302

303

@property

304

def physical_address(self):

305

"""

306

Physical address of the device in HDMI topology.

307

308

Returns:

309

int: Physical address as integer

310

"""

311

312

@property

313

def vendor(self):

314

"""

315

Vendor ID of the device.

316

317

Returns:

318

int: Vendor identification number

319

"""

320

321

@property

322

def osd_string(self):

323

"""

324

On-Screen Display name of the device.

325

326

Returns:

327

str: Device OSD name

328

"""

329

330

@property

331

def cec_version(self):

332

"""

333

CEC version supported by the device.

334

335

Returns:

336

int: CEC version number

337

"""

338

339

@property

340

def language(self):

341

"""

342

Menu language of the device.

343

344

Returns:

345

str: ISO language code

346

"""

347

348

# Methods

349

def is_on(self):

350

"""

351

Get the power status of the device.

352

353

Returns:

354

bool: True if device is powered on

355

"""

356

357

def power_on(self):

358

"""

359

Power on the device.

360

361

Returns:

362

bool: True if command sent successfully

363

"""

364

365

def standby(self):

366

"""

367

Put the device into standby mode.

368

369

Returns:

370

bool: True if command sent successfully

371

"""

372

373

def is_active(self):

374

"""

375

Check if this device is the active source.

376

377

Returns:

378

bool: True if device is active source

379

"""

380

381

def set_av_input(self, input):

382

"""

383

Select AV input on the device.

384

385

Args:

386

input (int): Input number/identifier

387

388

Returns:

389

bool: True if command sent successfully

390

"""

391

392

def set_audio_input(self, input):

393

"""

394

Select audio input on the device.

395

396

Args:

397

input (int): Audio input number/identifier

398

399

Returns:

400

bool: True if command sent successfully

401

"""

402

403

def transmit(self, opcode, parameters):

404

"""

405

Transmit a raw CEC command to this device.

406

407

Args:

408

opcode (int): CEC opcode for the command

409

parameters (bytes): Command parameters as byte string

410

411

Returns:

412

bool: True if transmission successful

413

"""

414

```

415

416

## Constants

417

418

### Event Types

419

420

Event type constants for use with callback registration:

421

422

```python { .api }

423

EVENT_LOG = 1 # Log message events

424

EVENT_KEYPRESS = 2 # Key press events

425

EVENT_COMMAND = 4 # CEC command events

426

EVENT_CONFIG_CHANGE = 8 # Configuration change events (not implemented)

427

EVENT_ALERT = 16 # Alert events

428

EVENT_MENU_CHANGED = 32 # Menu state change events

429

EVENT_ACTIVATED = 64 # Device activation events

430

EVENT_ALL = 127 # All event types combined

431

```

432

433

### Alert Types

434

435

Alert type constants for EVENT_ALERT callbacks:

436

437

```python { .api }

438

CEC_ALERT_SERVICE_DEVICE = 1 # Service device alert

439

CEC_ALERT_CONNECTION_LOST = 2 # Connection lost alert

440

CEC_ALERT_PERMISSION_ERROR = 3 # Permission error alert

441

CEC_ALERT_PORT_BUSY = 4 # Port busy alert

442

CEC_ALERT_PHYSICAL_ADDRESS_ERROR = 5 # Physical address error alert

443

CEC_ALERT_TV_POLL_FAILED = 6 # TV polling failed alert

444

```

445

446

### Menu States

447

448

Menu state constants for EVENT_MENU_CHANGED callbacks:

449

450

```python { .api }

451

CEC_MENU_STATE_ACTIVATED = 0 # Menu activated state

452

CEC_MENU_STATE_DEACTIVATED = 1 # Menu deactivated state

453

```

454

455

### Device Types

456

457

Device type constants for device classification:

458

459

```python { .api }

460

CEC_DEVICE_TYPE_TV = 0 # TV device type

461

CEC_DEVICE_TYPE_RECORDING_DEVICE = 1 # Recording device type

462

CEC_DEVICE_TYPE_RESERVED = 2 # Reserved device type

463

CEC_DEVICE_TYPE_TUNER = 3 # Tuner device type

464

CEC_DEVICE_TYPE_PLAYBACK_DEVICE = 4 # Playback device type

465

CEC_DEVICE_TYPE_AUDIO_SYSTEM = 5 # Audio system device type

466

```

467

468

### Logical Addresses

469

470

Logical address constants for device identification:

471

472

```python { .api }

473

CECDEVICE_UNKNOWN = -1 # Unknown device address

474

CECDEVICE_TV = 0 # TV logical address

475

CECDEVICE_RECORDINGDEVICE1 = 1 # Recording device 1 address

476

CECDEVICE_RECORDINGDEVICE2 = 2 # Recording device 2 address

477

CECDEVICE_TUNER1 = 3 # Tuner 1 address

478

CECDEVICE_PLAYBACKDEVICE1 = 4 # Playback device 1 address

479

CECDEVICE_AUDIOSYSTEM = 5 # Audio system address

480

CECDEVICE_TUNER2 = 6 # Tuner 2 address

481

CECDEVICE_TUNER3 = 7 # Tuner 3 address

482

CECDEVICE_PLAYBACKDEVICE2 = 8 # Playback device 2 address

483

CECDEVICE_RECORDINGDEVICE3 = 9 # Recording device 3 address

484

CECDEVICE_TUNER4 = 10 # Tuner 4 address

485

CECDEVICE_PLAYBACKDEVICE3 = 11 # Playback device 3 address

486

CECDEVICE_RESERVED1 = 12 # Reserved address 1

487

CECDEVICE_RESERVED2 = 13 # Reserved address 2

488

CECDEVICE_FREEUSE = 14 # Free use address

489

CECDEVICE_UNREGISTERED = 15 # Unregistered device address

490

CECDEVICE_BROADCAST = 15 # Broadcast address

491

```

492

493

### CEC Opcodes

494

495

CEC command opcodes for raw communication (selection of commonly used opcodes):

496

497

```python { .api }

498

# Power Management

499

CEC_OPCODE_STANDBY = 0x36 # Put device in standby

500

CEC_OPCODE_IMAGE_VIEW_ON = 0x04 # Turn on and show image

501

CEC_OPCODE_TEXT_VIEW_ON = 0x0D # Turn on and show text

502

CEC_OPCODE_GIVE_DEVICE_POWER_STATUS = 0x8F # Request power status

503

CEC_OPCODE_REPORT_POWER_STATUS = 0x90 # Report power status

504

505

# Active Source Management

506

CEC_OPCODE_ACTIVE_SOURCE = 0x82 # Set active source

507

CEC_OPCODE_INACTIVE_SOURCE = 0x9D # Set inactive source

508

CEC_OPCODE_REQUEST_ACTIVE_SOURCE = 0x85 # Request active source

509

CEC_OPCODE_SET_STREAM_PATH = 0x86 # Set stream path

510

CEC_OPCODE_ROUTING_CHANGE = 0x80 # Routing change

511

CEC_OPCODE_ROUTING_INFORMATION = 0x81 # Routing information

512

513

# Device Information

514

CEC_OPCODE_GIVE_PHYSICAL_ADDRESS = 0x83 # Request physical address

515

CEC_OPCODE_REPORT_PHYSICAL_ADDRESS = 0x84 # Report physical address

516

CEC_OPCODE_GIVE_OSD_NAME = 0x46 # Request OSD name

517

CEC_OPCODE_SET_OSD_NAME = 0x47 # Set OSD name

518

CEC_OPCODE_GIVE_DEVICE_VENDOR_ID = 0x8C # Request vendor ID

519

CEC_OPCODE_DEVICE_VENDOR_ID = 0x87 # Report vendor ID

520

CEC_OPCODE_GET_CEC_VERSION = 0x9F # Request CEC version

521

CEC_OPCODE_CEC_VERSION = 0x9E # Report CEC version

522

523

# Audio System

524

CEC_OPCODE_GIVE_AUDIO_STATUS = 0x71 # Request audio status

525

CEC_OPCODE_REPORT_AUDIO_STATUS = 0x7A # Report audio status

526

CEC_OPCODE_GIVE_SYSTEM_AUDIO_MODE_STATUS = 0x7D # Request system audio mode

527

CEC_OPCODE_SYSTEM_AUDIO_MODE_STATUS = 0x7E # Report system audio mode

528

CEC_OPCODE_SET_SYSTEM_AUDIO_MODE = 0x72 # Set system audio mode

529

CEC_OPCODE_SYSTEM_AUDIO_MODE_REQUEST = 0x70 # Request system audio mode

530

531

# User Control

532

CEC_OPCODE_USER_CONTROL_PRESSED = 0x44 # User pressed button

533

CEC_OPCODE_USER_CONTROL_RELEASE = 0x45 # User released button

534

535

# Menu Control

536

CEC_OPCODE_MENU_REQUEST = 0x8D # Menu request

537

CEC_OPCODE_MENU_STATUS = 0x8E # Menu status

538

539

# Recording/Timer Control

540

CEC_OPCODE_RECORD_OFF = 0x0B # Stop recording

541

CEC_OPCODE_RECORD_ON = 0x09 # Start recording

542

CEC_OPCODE_RECORD_STATUS = 0x0A # Report recording status

543

CEC_OPCODE_RECORD_TV_SCREEN = 0x0F # Record TV screen

544

CEC_OPCODE_CLEAR_ANALOGUE_TIMER = 0x33 # Clear analogue timer

545

CEC_OPCODE_CLEAR_DIGITAL_TIMER = 0x99 # Clear digital timer

546

CEC_OPCODE_CLEAR_EXTERNAL_TIMER = 0xA1 # Clear external timer

547

CEC_OPCODE_SET_ANALOGUE_TIMER = 0x34 # Set analogue timer

548

CEC_OPCODE_SET_DIGITAL_TIMER = 0x97 # Set digital timer

549

CEC_OPCODE_SET_EXTERNAL_TIMER = 0xA2 # Set external timer

550

CEC_OPCODE_SET_TIMER_PROGRAM_TITLE = 0x67 # Set timer program title

551

CEC_OPCODE_TIMER_CLEARED_STATUS = 0x43 # Timer cleared status

552

CEC_OPCODE_TIMER_STATUS = 0x35 # Timer status

553

554

# Deck Control

555

CEC_OPCODE_DECK_CONTROL = 0x42 # Deck control command

556

CEC_OPCODE_DECK_STATUS = 0x1B # Deck status report

557

CEC_OPCODE_GIVE_DECK_STATUS = 0x1A # Request deck status

558

CEC_OPCODE_PLAY = 0x41 # Play command

559

560

# Tuner Control

561

CEC_OPCODE_GIVE_TUNER_DEVICE_STATUS = 0x08 # Request tuner status

562

CEC_OPCODE_SELECT_ANALOGUE_SERVICE = 0x92 # Select analogue service

563

CEC_OPCODE_SELECT_DIGITAL_SERVICE = 0x93 # Select digital service

564

CEC_OPCODE_TUNER_DEVICE_STATUS = 0x07 # Report tuner status

565

CEC_OPCODE_TUNER_STEP_DECREMENT = 0x06 # Tuner step down

566

CEC_OPCODE_TUNER_STEP_INCREMENT = 0x05 # Tuner step up

567

568

# Menu/Language Control

569

CEC_OPCODE_GET_MENU_LANGUAGE = 0x91 # Request menu language

570

CEC_OPCODE_SET_MENU_LANGUAGE = 0x32 # Set menu language

571

CEC_OPCODE_SET_OSD_STRING = 0x64 # Set OSD string

572

573

# Vendor Commands

574

CEC_OPCODE_VENDOR_COMMAND = 0x89 # Vendor-specific command

575

CEC_OPCODE_VENDOR_COMMAND_WITH_ID = 0xA0 # Vendor command with ID

576

CEC_OPCODE_VENDOR_REMOTE_BUTTON_DOWN = 0x8A # Vendor remote button down

577

CEC_OPCODE_VENDOR_REMOTE_BUTTON_UP = 0x8B # Vendor remote button up

578

579

# Audio Return Channel (ARC)

580

CEC_OPCODE_START_ARC = 0xC0 # Start audio return channel

581

CEC_OPCODE_REPORT_ARC_STARTED = 0xC1 # Report ARC started

582

CEC_OPCODE_REPORT_ARC_ENDED = 0xC2 # Report ARC ended

583

CEC_OPCODE_REQUEST_ARC_START = 0xC3 # Request ARC start

584

CEC_OPCODE_REQUEST_ARC_END = 0xC4 # Request ARC end

585

CEC_OPCODE_END_ARC = 0xC5 # End audio return channel

586

587

# Audio Rate Control

588

CEC_OPCODE_SET_AUDIO_RATE = 0x9A # Set audio sample rate

589

590

# Special/Advanced

591

CEC_OPCODE_CDC = 0xF8 # Capability Discovery and Control

592

CEC_OPCODE_NONE = 0xFD # No operation

593

594

# General

595

CEC_OPCODE_FEATURE_ABORT = 0x00 # Feature not supported

596

CEC_OPCODE_ABORT = 0xFF # Abort message

597

```

598

599

### Library Feature Constants

600

601

Feature availability constants for checking library capabilities:

602

603

```python { .api }

604

HAVE_CEC_ADAPTER_DESCRIPTOR = 0 or 1 # Whether library supports adapter descriptors

605

```

606

607

## Advanced Usage Examples

608

609

### Event Handling

610

611

```python

612

import cec

613

614

def log_callback(event, level, time, message):

615

"""Handle log messages."""

616

print(f"CEC Log [{level}]: {message}")

617

618

def command_callback(event, source, destination, opcode, parameters):

619

"""Handle CEC commands."""

620

print(f"CEC Command: {source} -> {destination}, opcode: {opcode}")

621

622

def key_callback(event, key_code, duration):

623

"""Handle key press events."""

624

print(f"Key pressed: {key_code}, duration: {duration}")

625

626

# Register callbacks

627

cec.add_callback(log_callback, cec.EVENT_LOG)

628

cec.add_callback(command_callback, cec.EVENT_COMMAND)

629

cec.add_callback(key_callback, cec.EVENT_KEYPRESS)

630

631

# Initialize and use CEC

632

cec.init()

633

634

# Your application logic here...

635

636

# Remove callbacks when done

637

cec.remove_callback(log_callback, cec.EVENT_LOG)

638

cec.remove_callback(command_callback, cec.EVENT_COMMAND)

639

cec.remove_callback(key_callback, cec.EVENT_KEYPRESS)

640

```

641

642

### Device Enumeration and Control

643

644

```python

645

import cec

646

647

# Initialize CEC

648

adapters = cec.list_adapters()

649

if adapters:

650

print(f"Available adapters: {adapters}")

651

cec.init(adapters[0]) # Use first adapter

652

else:

653

cec.init() # Use default adapter

654

655

# Discover devices

656

devices = cec.list_devices()

657

print(f"Discovered devices: {devices}")

658

659

# Create device objects and query information

660

for device_addr in devices:

661

device = cec.Device(device_addr)

662

print(f"Device {device_addr}:")

663

print(f" Physical Address: {device.physical_address}")

664

print(f" OSD Name: {device.osd_string}")

665

print(f" Vendor: {device.vendor}")

666

print(f" CEC Version: {device.cec_version}")

667

print(f" Language: {device.language}")

668

print(f" Is On: {device.is_on()}")

669

print(f" Is Active: {device.is_active()}")

670

```

671

672

### Raw Command Transmission

673

674

```python

675

import cec

676

677

cec.init()

678

679

# Set arbitrary device as active source (physical address 2.0.0.0)

680

destination = cec.CECDEVICE_BROADCAST

681

opcode = cec.CEC_OPCODE_ACTIVE_SOURCE

682

parameters = b'\x20\x00' # Physical address 2.0.0.0

683

684

success = cec.transmit(destination, opcode, parameters)

685

print(f"Command transmission {'successful' if success else 'failed'}")

686

687

# Send standby command to TV

688

tv_addr = cec.CECDEVICE_TV

689

standby_opcode = cec.CEC_OPCODE_STANDBY

690

success = cec.transmit(tv_addr, standby_opcode, b'')

691

print(f"Standby command {'sent' if success else 'failed'}")

692

```

693

694

### Configuration Management

695

696

```python

697

import cec

698

699

cec.init()

700

701

# Check if adapter supports configuration persistence

702

if cec.can_persist_config():

703

print("Adapter supports configuration persistence")

704

705

# Set physical address

706

success = cec.set_physical_addr(0x2000) # Physical address 2.0.0.0

707

if success:

708

print("Physical address set")

709

710

# Persist configuration

711

if cec.persist_config():

712

print("Configuration persisted to adapter")

713

else:

714

print("Failed to persist configuration")

715

else:

716

print("Failed to set physical address")

717

else:

718

print("Adapter does not support configuration persistence")

719

```

720

721

## Error Handling

722

723

The CEC library may raise exceptions or return False/None for failed operations:

724

725

- **RuntimeError**: Raised during initialization failures or critical errors

726

- **False return values**: Most functions return False when commands fail to send

727

- **None return values**: Some functions return None when unable to retrieve information

728

- **Empty lists**: Device/adapter listing functions return empty lists when none found

729

730

Always check return values and handle potential exceptions:

731

732

```python

733

import cec

734

735

try:

736

# Initialize with error handling

737

adapters = cec.list_adapters()

738

if not adapters:

739

print("No CEC adapters found")

740

exit(1)

741

742

cec.init(adapters[0])

743

print("CEC initialized successfully")

744

745

# Device operations with return value checking

746

tv = cec.Device(cec.CECDEVICE_TV)

747

748

if tv.power_on():

749

print("TV power on command sent")

750

else:

751

print("Failed to send TV power on command")

752

753

# Volume control with return value checking

754

if cec.volume_up():

755

print("Volume up command sent")

756

else:

757

print("Failed to send volume up command")

758

759

except RuntimeError as e:

760

print(f"CEC initialization failed: {e}")

761

except Exception as e:

762

print(f"Unexpected error: {e}")

763

```

764

765

## Platform Considerations

766

767

- **Linux**: Requires libcec development libraries and appropriate permissions for CEC device access

768

- **Windows**: Requires building libcec from source as binary distributions don't include required development files

769

- **macOS**: Install libcec via Homebrew (`brew install libcec`)

770

- **Raspberry Pi**: Built-in CEC support, no additional hardware required

771

- **Hardware**: Most computer graphics cards don't support CEC; requires dedicated CEC adapter (Pulse-Eight USB-CEC) or compatible hardware