Building Custom CEC Integrations

This article is for developers and integrators who want to build their own software on top of a Pulse-Eight CEC adapter - for example, capturing CEC traffic to drive logic for non-CEC devices, or building a bridge to another protocol such as REST or MQTT. It's a technical reference, not a step-by-step consumer guide.

This article assumes familiarity with command-line tools and at least one programming language. If you're looking to set up CEC control for Kodi, a home theatre PC, or a meeting room, see the related articles below instead.

What interfaces are available

Before designing an integration, it helps to know what the adapter and libCEC actually expose — and what they don't.


InterfaceAvailableNotes
libCEC (C++ API)The core library. Runs on Windows, Linux, and macOS.
libCEC C wrapper (cecc.h)A plain-C interface around the C++ API, for developers who don't want to link against C++.
.NET bindings (LibCecSharp)Separate repository: cec-dotnet.
Python bindingsInstalled alongside libCEC on Linux by default.
cec-client (CLI)Included with every libCEC install. The quickest way to test and script against.
REST APINot provided by the adapter or libCEC. libCEC is a client library, not a server.
ESP32 / RTOS / embedded MCU librarylibCEC targets desktop and Linux-class platforms. It hasn't been ported to embedded RTOS targets.
Published adapter serial/USB protocol specThe adapter's USB framing protocol is internal to libCEC and isn't published as a standalone spec for third-party reimplementation.
The adapter itself doesn't decode CEC frames.
It's libCEC, running on a host machine, that turns the adapter's raw serial stream into readable CEC messages. Any integration needs to go through libCEC on a host; you can't get meaningful CEC data by reading the adapter's USB stream directly without reimplementing a significant part of libCEC yourself.

The recommended integration pattern

For almost every custom integration - REST, MQTT, home automation, triggering non-CEC hardware from CEC events - the same pattern applies:

  1. Run libCEC on a host machine (a Raspberry Pi, NUC, or PC) that's HDMI-connected into the CEC bus you want to observe or control.
  2. Use cec-client, or link against libCEC directly (C++, C, .NET, or Python), to talk to the adapter.
  3. Build your own thin service on top that exposes whatever interface you actually need — REST, MQTT, a TCP socket, or anything else.

This keeps all the CEC-specific complexity — bus arbitration, framing, vendor quirks — inside libCEC, which is maintained and tested, and keeps your own code focused on the logic you actually care about.

The host must be on the same physical CEC bus as the devices you want to observe or control. The USB-CEC adapter needs to be HDMI-connected into that TV/AV chain — it can't monitor or control devices it isn't wired into.

Capturing CEC traffic: monitoring mode

If your goal is to capture CEC commands — for example, to trigger logic when the TV powers on, switches input, or receives a remote key press — start with monitoring mode.

cec-client -m

This puts the adapter into a passive listening state. It doesn't register as an active device on the bus and doesn't take part in the CEC handshake; it simply observes and logs every frame it sees: source, destination, opcode, parameters, and a timestamp. This gives you a ready-parsed feed of exactly the kind of traffic most integrations want, without your own code needing to do any CEC decoding.

The output is fully scriptable - pipe it into your own service and trigger on whatever opcodes matter to you.

Monitoring mode is listen-only. If your integration also needs to send CEC commands back onto the bus, use a separate, normal (non-monitoring) client connection for that — a single client connection is either passively observing or acting as an addressed logical device, not both at once.

For debugging an integration once it's running, libCEC also provides a GetStats() API call (and a corresponding stats command in cec-client), which reports adapter-level diagnostics — useful when troubleshooting unexpected behaviour on the bus.


Developer resources

The libCEC source and developer documentation are published on GitHub:

  • Developer documentation — covers the available APIs: cec.h (C++), cecc.h (C wrapper), and the .NET bindings.
  • cecc-client.c — a working example implementation using the plain-C API. A good starting point if you're building in C.
  • Pulse-Eight/libcec — the main repository. Example systemd unit files for running libCEC-based services persistently on Linux are included in the systemd/ folder.

Community projects

A number of third-party, community-maintained projects already solve common integration problems and are useful as reference designs:

  • pyCEC — includes a mode that bridges the HDMI-CEC port to a plain TCP server, so a remote client can send and receive CEC commands over the network without needing libCEC or a local HDMI connection.
  • cec-mqtt-bridge — bridges HDMI-CEC devices to MQTT for home automation use, including sending raw CEC commands and reporting device state over MQTT.
These are community projects, not maintained or officially supported by Pulse-Eight. They're a useful reference for how others have structured the "libCEC on a host, thin service on top" pattern, but we can't provide support if you run into issues in that code.

Related Articles

Building something and need a hand?

If you run into adapter-specific issues while developing your integration, get in touch.

UK: 01202 413 610 | US: (858) 748-8250 | support@pulse-eight.com

Was this article helpful? If not, submit a support ticket and our team will help.