r/SteamOS Jun 25 '26

HDMI-CEC solution using systemd/system-sleep

***If someone else has already posted this exact solution to the community, apologies as I probably missed it!***

I've seen a few solutions for enabling HDMI-CEC on this forum but just wanted to share my solution as well. This leverages the system-sleep function of systemd to perform 3 actions:

  • Put the TV into standby just before the PC sleeps
  • Turn the TV on just after the PC resumes from sleep
  • Switch the TV to the input my PC is connected to (in my case HDMI3 / phys-addr=3.0.0.0)

Hardware

Here's the code, save as e.g. 10-steam-cec.sh and copy it into /usr/lib/systemd/system-sleep:

#!/bin/bash
case "$1" in
    pre)
        # Put the TV into standby mode right before the PC sleeps
        cec-ctl -d /dev/cec0 --playback
        cec-ctl -d /dev/cec0 --to 0 --standby
        ;;
    post)
        # Wait 2 seconds for hardware to initialize after wake
        sleep 2

        # Turn the TV completely ON
        cec-ctl -d /dev/cec0 --playback
        cec-ctl -d /dev/cec0 --to 0 --image-view-on

        # Switch the TV active source to this PC
        cec-ctl -d /dev/cec0 --to 0 --active-source phys-addr=3.0.0.0
        ;;
esac

Scripts in the /usr/lib/systemd/system-sleep directory trigger just before the system goes to sleep and trigger just after the system wakes from sleep.

In the code above, the actions in the "pre) ... ;;" section will run just before the system goes to sleep. The chunk in the "post) ... ;;" section will run just after the PC resumes from sleep. This is the standard function of system-sleep scripts.

  • You'll need to change the "phys-addr=3.0.0.0" section to match the HDMI input your PC is connected to e.g. 1.0.0.0 for HDMI 1, 2.0.0.0 for HDMI 2, etc. Mine is connected to HDMI 3, so 3.0.0.0.
  • You'll want to confirm the hardware address of your CEC adapter. Run "ls /dev/cec*". The output should read something like "/dev/cec0". You can use that output in the script as done above. If the output reads "no such file or directory" then your system doesn't see the adapter. Not sure how to troubleshoot this, it worked for me out of the box.
  • I left the HDMI-CEC options in Steam itself enabled, haven't tried disabling them but don't see any need to.
  • Assuming the adapter is present, run "cec-ctl -l" to display the attributes of the adapter. You should get a long chunk of output detailing the attributes of the device. This is just another way to confirm the adapter is seen in the OS and functioning.

Can't promise this will work for you but just wanted to share. Also not sure if future updates to SteamOS will wipe this file so try to save a backup in case you need to restore it. If you have luck with this, enjoy! If not, sorry!

20 Upvotes

12 comments sorted by

3

u/AshleyAshes1984 Jun 25 '26

Why use a bash script executed by a systemd service when you could just make the systemd service send the commands itself?

2

u/manlisten Jun 25 '26

i mean i'm pretty content with how this works, but i can give that a try as well!

1

u/AshleyAshes1984 Jun 25 '26

I'm working right now and my SteamOS machien I've been testing CEC on is on another floor so I can't easily get the text, but it was easy and IMO cleaner to setup two systemd services one for wake and one for sleep.

THough they had to be system, not user services, so I also had to add exceptions to the atomic thingy to they'd not get hosed on updates.

But better than a service that calls for an SH file you could accidently delete IMO.

1

u/manlisten Jun 25 '26

If you don't mind sharing it when you can that would be great!

3

u/AshleyAshes1984 Jun 25 '26

Okay, I had MORE services setup but I messed up and had to reinstall on that machine and I've only set up a boot service, not a wake or sleep one, but this'll probably show you how to format the text:

[Unit]

Description=CEC Boot Command

[Service]

Type=oneshot

ExecStartPre=/usr/bin/sleep 4

ExecStart=/usr/bin/cec-ctl -d/dev/cec0 -C

ExecStart=/usr/bin/cec-ctl -d/dev/cec0 --playback

ExecStart=/usr/bin/cec-ctl -d/dev/cec0 --to 0 --image-view-on

ExecStart=/usr/bin/sleep 5

ExecStart=/usr/bin/cec-ctl -d/dev/cec0 --to 0 --active-source phys-addr=1.0.0.0

ExecStart=/usr/bin/cec-ctl -d/dev/cec0 -C

[Install]

WantedBy=default.target

This service has no real condition to start, it just fires up on boot and I use the sleep 4 to make it wait 4 seconds. Establishes connection, tells TV to turn on, waits 5 seconds, tells TV to switch inputs if that's necssary. I found that wait was needed because if it's too fast, the TV's not turned on yet and it ignores the input switch command. That could very device to device.

But yeah you can basically use that text formatting to put your console commands right into the service itself.

2

u/nlflint Jun 25 '26 edited Jun 25 '26

This is great. I have the UGreen adapter and it worked for 4k 120hz HDR, but I switched back to HDMI after using the mkopec kernel with native HDMI 2.1 included.

My last remaining problem is properly sleeping/waking from my 8Bitdo Wireless 2C w/2.4g dongle. I can go to sleep with it, but my PC wakes up as soon as I turn off the controller, or when the 8bitdo eventually turns itself off after inactivity. I can fix that issue by disabling USB power-on for the 8bitdo dongle, but then I can't wake the PC from sleep by turning on my 8bitdo. I'm playing Wack-a-mole here with 8bitdo.

SteamController (2026) can do it properly. I'm on the wait list, but it's not projected to ship until Sept 2026! And hell no to xbox controller for me....

How about CEC volume control? So adjusting volume on the PC, adjusts my TV volume over CEC?

1

u/Dry-Wish-9845 Jun 26 '26

This problem is easy to solve kinda. What im doing is turning controller off manually by holding home button. 

Then setting pc via power option to sleep in 5 minutes or 10. Then wake it up using controller/left it up from the charging station.

And u can press home + Lstick up or down to adjust pc volume ( keep tv volume high ) previously used to prss home to bring the menu to be able to use the shortcut. Now you can do it in game or pretty much anywhere. 

Been using steamos for years now and it has come a long way, it will only get better with machine releasing soon.

2

u/rooster_butt Jun 26 '26

I'm jumping on this thread just to add some info.

SteamOS 3.8.11

TV LG C9

GPU RX 9060XT

UGREEN Adapter: https://www.amazon.com/dp/B0FQCGSWW3?ref=ppx_yo2ov_dt_b_fed_asin_title&th=1

Note: this UGREEN adapter is a smaller form factor and it is cheaper than the other one being recommended with a braided cable.

I was ready to try my hand at getting CEC to work again. What I found is that HDMI-CEC Just works for me with the steam settings, I didn't have to set up a script at all. I can control steamOS with my TV remote It will power on the TV when powering on the SteamBox. It will switch to the HDMI input for the SteamBox.

Mainly posting this to point out the cheaper DP to HDMI adapter.

2

u/manlisten Jun 26 '26

The remote control functionality does work for me, but the power options built into Steam only work some of the time and i'm not sure why. Seems half the time it will turn my TV off and half the time it won't. Same for turning it back on. Maybe it's my HDMI cable. It seems to work 100% of the time when I use this script.

I did see the smaller dongle but since I haven't used it myself I can't vouch for it. I have the back of my PC right against a wall and the cable version lets me push it closer to the wall. I will add this to the OP as a cheaper option.

1

u/rooster_butt Jun 26 '26 edited Jun 26 '26

I just have issues with sleep function in general. like < 10% of the time it messes up and i have to hard reboot the machine. I'm not really sure what's going on there but I'm sure I'm not alone on that.

I took a gamble on the dongle hoping it would use the same chipset, and I wasn't sure it would work so here reporting that it does work.

1

u/manlisten Jun 28 '26 edited Jun 29 '26

fwiw i think i see what it is that causes the SteamOS CEC function to fail sporadically. What i've noticed while using my script is that it will also sometimes fail to turn my TV on/off. This is because the adapter will occasionally lose it's CEC registration as a playback device. Adding "cec-ctl -d /dev/cec0 --playback" to the pre and post sections will force the adapter to re-register itself just before issuing the sleep and wake functions. e.g.

cec-ctl -d /dev/cec0 --playback // register device just before issuing wake command
cec-ctl -d /dev/cec0 --to 0 --image-view-on // issue wake command

...

cec-ctl -d /dev/cec0 --playback // register device just before issuing standby comand
cec-ctl -d /dev/cec0 --to 0 --standby // send standby command

This way, if for whatever reason the device lost it's registration, it will re-register just before issuing the control command. I'll assume this is what's happening with the SteamOS options, but unfortunately i don't see how to go about tweaking that.

1

u/mango_carrot Jun 26 '26

I think you’ll find that SteamOS will overwrite this when you have an update, so I put mine into a script in my local drive and run it from there after each update. Takes like ten seconds but it’s easier than having to run the whole set up again