Tutorial: CEC Turn Off TV When Idle / Screensaver

I wanted to share a guide for anyone trying to get their tv to turn off when via CEC when the screensaver kicks in. The upside of this method is that you can have a period of traditional screensaver before the tv is turned off.

I have a bad habit of walking away with a movie paused, and I hated wasting the power. So here is my workaround. I hope it helps someone else who is also frustrated.
I had been using the screen saver Turn Off, and it worked for a long time. Then somewhere around v18 of CoreElec it stopped turning off my tv if I had a video paused. That screensaver still works fine when sitting idle in the GUI, but never if the video was paused.

The following scripts turn the TV off 60 seconds after any screensaver kicks in. You can adjust the scripts if you want a different time period.

I hope this help other Eco-friendly media lovers.

  1. Install service add-on ‘Kodi Callbacks’
  2. Create two scripts (code below). I placed mine in the downloads folder to make finding them easy.
  3. Enable any screensaver and set it to your preferred wait time like normal.
  4. Configure Kodi Callbacks Tasks
  • Under Tasks
  • Set Task 1 to Script
  • Max number = 1
  • Script executable file - browse to TurnOff.sh (I have mine in /storage/downloads/TurnOff.sh)
  • Set Task 2 to Script
  • Max number = 1
  • Script executable file - browse to TurnOn.sh (I have mine in /storage/downloads/TurnOn.sh)
  1. Configure Kodi Callbacks Events
  • Set event for Event 1 to on Screensaver Activated
  • Task = Task 1
  • Set event for Event 2 to on Screensaver Deactivated
  • Task = Task 2

I suggest using ssh and nano to create the scripts.
Script 1:
TurnOff.sh

#!/bin/bash
sleep 60
echo "standby 0" | cec-client -s

Script 2:
TurnOn.sh

#!/bin/bash
kill -9 $(pgrep -f turnoff.sh)
echo "on 0" | cec-client -s

Notes:

  • Be sure to chmod +x the scrips to make them executable.
  • Remove the sleep 60 statement if you want the tv to go to sleep immediately, and not show the screensaver for 60 seconds. Change the 60 to another time in seconds if you want to show the screensaver for more than 1min before turning off the tv.
  • These scripts assume that your TV is device 0. If your TV is another device then you need to change the 0 to whatever it is. The cec-client is beyond the scope of this guide, but google has your back.
  • I found that the Asteroids screensaver caused the box to freeze after executing the CEC suspend commad. I don’t suggest using that. All the others I tested seem to be fine.
  • This may not work for all TVs as CEC support can be spotty, but it worked on my Samsung and TCL TVs.
  • I had trouble with the Kodi Callback GUI scrolling all the way to the bottom every time I tried to set event 2. You can try another skin, or you can edit the settings file manually. It is in Userdata\addon_data\script.service.kodi.callbacks\settings.xml
  • I am using an S905x (Nexbox A95X) box. I assume this will work on others, but I have not tested it.
  • Corrected an oversight in the second script, and added the line I forgot which kills any pending requests to turn off the TV.
1 Like

nice, but this has the problem of turning off even if you resume action 1 second after the screensaver started.
I have a similar setup - turn off after 5 minutes of inactivity, 2 of which are for the dim screensaver. so I have 2 minutes of regular idle screen, and 3 minutes of dimmed screen, and since the CEC shut down is only sent at the end of the 5 minutes if it’s still idle, I don’t have the issue above.
I use the script “sleepy watchdog” and heavily modify it - it’s also easier with python…

if you want to stick with using the callbacks addon, I’d suggest sending (curl) this json with a test of inactivity, to see if it’s still been idle for the last 60 seconds, before issuing the CEC power off:
data = ‘{“jsonrpc”: “2.0”, “method”: “XBMC.GetInfoBooleans”, “params”: { “booleans”: ["System.IdleTime(60) "] }, “id”: 1}’
use this curl:
curl -X POST http://127.0.0.1:8080/jsonrpc -H ‘Content-Type: application/json’ --data [COMMAND] and look at the boolean result to determine.

There’s also a screensaver addon called Turn Off that has a CEC option.

If you reread my orginal post, you will see that I mention that screensaver, and called out that it doesn’t work when a video was paused.

You are right. I posted the testing version of my second script. I will correct that error.
The revised script corrects that issue, and kills any pending request to turn off the tv.

CEC turns off with video pausing on my Odroid N2 using that screensaver addon so perhaps it’s something hardware specific.

Now there are two options for people.
This method allows you to have a traditional screensaver shown for a period of time, so that may be of interest to some also.

1 Like

Honestly I would like to see this fixed in the code:


Currently it just checks if it’s playing something.
But I guess a check “isPlaying AND isPlaybackPaused AND IsLibCECActiveSource” sounds reasonable to me. Especially if you consider using suspend you can just wakeup and it will continue playing. It doesn’t make sense in a poweroff scenario I guess.
1 Like

So here I made a testbuild:
https://mega.nz/folder/hkoTBDgZ#ICWCm8J4OPtOMtZcPzNREg

It basically current CE nightly + a patch http://ix.io/2poT

It will also Turn TV off when something is playing and paused. Additionally it includes a new setting to set a delay after Screensaver kicks in. My motivation for this is that I have an OLED TV and I like to protect it from burn-in thats why my screensaver is black and kicks in after 1min (as fast as possible) but I’d also like the TV to shutdown after a while but not after 1min (annoying). So I set now a delay (default is 0s) to 120s. So now the Screensaver kicks in after 1min and after 2min the TV is turned off with CEC.

Update 17th June 2020: Fixed a small bug.

Ray

1 Like

As I am just a average use, perhaps you should share that with a Coreelec official team member. I have no power here other than to share what I know.