Using cec-client on a Raspberry Pi
Most modern HDMI connected devices support Consumer Electronics Control (CEC). It allows devices to send commands to each other, typically to get the TV to switch input and control volume. If you have ever turned on a Game Console and had your TV automatically change input to that device you have seen CEC in action. It is very convenient and useful, sort of a universal remote that works.
Every manufacturer seems to have it’s own branding of CEC (e.g. Samsung Anynet+, LG SimpLink, Sharp Aquos Link) but it may need to be enabled. Check your manual for details.
Using a Raspberry Pi connected to a TV that supports CEC, you can use the command line `cec-client` application to control the inputs and the TV itself. These are notes on how to use `cec-client` and understand the different options.
Details
Hardware: Raspberry Pi 2 Model B
OS: OMSC November 2016 (2016.11-1)
NOTE: This will work with Raspbian as well, as OMSC (Open Source Media Center) just a repackaging of Raspbian.
Scan For Devices
The First step is to use the cec-client on the Raspberry Pi to scan the HDMI devices. This will include the TV, the Raspberry Pi and any other devices, typically listed as either `Recorder #` or `Playback #`.
echo "scan" | cec-client RPI -s -d 1
opening a connection to the CEC adapter... requesting CEC bus information ... CEC bus information =================== device #0: TV address: 0.0.0.0 active source: no vendor: Samsung osd string: TV CEC version: 1.3a power status: on language: eng device #1: Recorder 1 address: 1.0.0.0 active source: no vendor: Unknown osd string: CECTester CEC version: 1.4 power status: standby language: ??? device #2: Recorder 2 address: 2.0.0.0 active source: no vendor: Pulse Eight osd string: CECTester CEC version: 1.4 power status: on language: eng device #4: Playback 1 address: 3.0.0.0 active source: no vendor: Sony osd string: PlayStation 4 CEC version: 1.3a power status: standby language: ??? currently active source: unknown (-1)
As listed, the setup is:
Name | Address | Device |
---|---|---|
Samsung TV | 0.0.0.0 | TV |
Raspberry Pi | 1.0.0.0 | Recorder 1 |
Tivo with Pulse Eight USB-CEC adapter | 2.0.0.0 | Recorder 2 |
PlayStation 4 | 3.0.0.0 | Playback 1 |
NOTE: The Tivo is old enough not to support cec, so originally I bought the Pulse Eight USB-CEC adapter when I was only using the single command approach. With the ability to send a HDMI-cec frame I believe I can remove it from the setup, as I can address the device from the Raspberry Pi. But I am getting ahead of myself…
Single Commands
The following is the simplest way to call the cec-client, with no address specified. However, using this approach I was not able to send commands from one device to another devices.
In other words, from the Raspberry Pi I can only send commands to the Raspberry Pi (make active / inactive source) and not send from the Raspberry Pi commands to make the Tivo or PlayStation active.
It is possible to turn the TV on or off (standby) from the Raspberry Pi.
Turn tv off:
echo "standby 0" | cec-client RPI -s -d 1
Turn tv on:
echo "on 0" | cec-client RPI -s -d 1
Make the RPI active source:
echo "as" | cec-client RPI -s -d 1
Make the RPI inactive source:
echo "is" | cec-client RPI -s -d 1
HDMI-CEC Frames
Honestly it took me longer then it should have to understand how the HDMI-CEC frames worked. Partly it was confusion on my part about what the addresses of the devices were. Running the single commands above with debug on (-d 1) allowed me to see what address/source it was using for the Raspberry Pi, then the rest sort of fell into place.
Use `echo “scan” | cec-client RPI -s -d 1` to determine the source address (2.0.0.0) and source (Recording2) of the Raspberry Pi. Next using http://www.cec-o-matic.com/ I was able to reproduce not only the single commands, but also target other devices from the Raspberry Pi.
Many thanks to http://www.cec-o-matic.com/, without which I don’t think I would have figured out the settings.
NOTE: Change the source to match your Raspberry Pi as reported by running `echo “scan” | cec-client RPI -s -d 1`.
Turn TV on RPI:
– Source: Recording2
– Destination: TV
– Message: Image View On
echo "tx 20:04" | cec-client RPI -s -d 4
Turn TV off RPI:
– Source: Recording2
– Destination: TV
– Message: Standby
echo "tx 20:36" | cec-client RPI -s -d 4
Switch active source to Tivo, from RPI
– Source: Recording2
– Destination: Broadcast
– Message: Active Source, 1.0.0.0
echo "tx 2F:82:10:00" | cec-client RPI -s -d 4
Switch active source to Kodi, from RPI
– Source: Recording2
– Destination: Broadcast
– Message: Active Source, 2.0.0.0
echo "tx 2F:82:20:00" | cec-client RPI -s -d 4
Switch active source to Playstation 4, from RPI
– Source: Recording2
– Destination: Broadcast
– Message: Active Source, 3.0.0.0
echo "tx 2F:82:30:00" | cec-client RPI -s -d 4
Conclusion
Using HDMI-cec frames are much more powerful then sending simple commands, but initially more complicated.
Hopefully these notes will help others get over the cec learning curve.