Skip to content

Instantly share code, notes, and snippets.

@rmtsrc
Created May 13, 2019 09:49
Show Gist options
  • Star 32 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save rmtsrc/dc35cd1458cd995631a4f041ab11ff74 to your computer and use it in GitHub Desktop.
Save rmtsrc/dc35cd1458cd995631a4f041ab11ff74 to your computer and use it in GitHub Desktop.
Using cec-client on a Raspberry Pi to control TV power and inputs via HDMI

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.

Installation

TV Settings

This is specific to Samsung, but will be simlar on other TVs that support CEC.

Enable CEC in: System > General > Anynet+ (HDMI-CEC) (ensure that Auto Turn Off option is enabled).

Software

sudo apt-get install cec-utils

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.

Source: https://blog.gordonturner.com/2016/12/14/using-cec-client-on-a-raspberry-pi/ (2019-05-13)

@gmartinsfaria
Copy link

Hello rmtsrc, let me tell you that you did a pretty nice work here.

I spent a few weeks struggling to figure out how to use CEC to switch my active HDMI sources, and the answer was given to me through your work.
Given that, did you try any other commands to do other functionalities? I mean, I know that supposedly we can send notifications to the TV screen using CEC (specifically, using the command to send OSD messages). In this way, did you try to do any of this? Can you suggest to me how to do it (which command can do this)?
I've been struggling with it, and I greatly appreciate your help.
Best regards,

Gabriel Faria

@t3st-account
Copy link

I have not tried it as I am not at home, but I've found this site wich supposedly has all possible cec commands.
https://www.cec-o-matic.com/
Hope that helps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment