JSON API : checking whether the system is idle
#1
Question 
Hi,

I am writing a script to shut down XBMC in case it is idling overnight (my son often plays with the remote and starts it without anybody noticing). Since the box it runs on is powered on 24/7, I wanted to prevent CPU cycles going to waste (XBMC running consumes an additional 7W, actually).

Anyway, I am using a "quick and dirty" shell script trigerred by a cron tab (see below). The script checks if music or video is playing and if not, shuts it down. I would like to use a more robust check, and in particular, only shut down XBMC if it is idle (screensaver on). I have unfortunately not found anything in the JSONRPC api that would do that.

Does anybody have oter ideas?

Code:
#!/bin/bash
LOG=/tmp/xbmc-watch.log

# Test to see if XBMC is running first
if pidof xbmc.bin
then
    # XBMC is running
    curl -s -o /tmp/xbmc-video -u xbmc:xbmc -X POST -d '{"jsonrpc": "2.0", "method": "Player.GetItem", "params": {"playerid":1 }, "id": 1}' http://localhost:8080/jsonrpc
    curl -s -o /tmp/xbmc-audio -u xbmc:xbmc -X POST -d '{"jsonrpc": "2.0", "method": "Player.GetItem", "params": {"playerid":0 }, "id": 1}' http://localhost:8080/jsonrpc
    grep -w "error" /tmp/xbmc-video >/dev/null
    if [ $? -eq 0 ]
    then
        grep -w "error" /tmp/xbmc-audio >/dev/null
        if [ $? -eq 0 ]
        then
            #XBMC idling, let's shut it down
            pidof xbmc.bin xargs kill #graceful shutdown
            echo `date` "XBMC-watch killed XBMC (soft)" >> $LOG            
            sleep 2
            if pidof xbmc.bin
            then
                pidof xbmc.bin|xargs kill -9
                echo `date` "XBMC-watch killed XBMC (hard)" >> $LOG
            fi
        else
            echo `date` "XBMC plating audio" >> $LOG
        fi
    else
        echo `date` "XBMC plating video" >> $LOG
    fi
else
    echo `date` "XBMC not running" >> $LOG
fi
Reply
#2
The only way to know whether the screensaver is active or not is by listening to JSON-RPC notifications on a TCP socket and waiting for the OnScreenSaverActivated notification but I guess that's not an option for you because the script would need to run all the time to actually receive the notification and it requires a TCP socket.

PS: You can use Player.GetActivePlayers to see if any player is active.
Always read the online manual (wiki), FAQ (wiki) and search the forum before posting.
Do not e-mail Team Kodi members directly asking for support. Read/follow the forum rules (wiki).
Please read the pages on troubleshooting (wiki) and bug reporting (wiki) before reporting issues.
Reply
#3
Code:
{"jsonrpc": "2.0", "method": "XBMC.GetInfoBooleans", "params": { "booleans": ["System.ScreenSaverActive "] }, "id": 1}

Smile
Image
AWXi - Ajax web interface. Wiki
Reply
#4
(2012-09-22, 18:04)Mizaki Wrote:
Code:
{"jsonrpc": "2.0", "method": "XBMC.GetInfoBooleans", "params": { "booleans": ["System.ScreenSaverActive "] }, "id": 1}

Smile
Ah great! Thank you, Mizaki.

Here's the new version of my script in case anybody has the same need
Code:
#!/bin/bash
LOG=/tmp/xbmc-watch.log
TMP_VID=/tmp/xbmc-video
TMP_MUZ=/tmp/xbmc-audio
TMP_SCR=/tmp/xbmc-screen

# Test to see if XBMC is running first
if pidof xbmc.bin
then
    # XBMC is running
    curl -s -o $TMP_SCR -u xbmc:xbmc -X POST -d '{"jsonrpc": "2.0", "method": "XBMC.GetInfoBooleans", "params": { "booleans": ["System.ScreenSaverActive "] }, "id": 1}' http://localhost:8080/jsonrpc
    curl -s -o $TMP_VID -u xbmc:xbmc -X POST -d '{"jsonrpc": "2.0", "method": "Player.GetItem", "params": {"playerid":1 }, "id": 1}' http://localhost:8080/jsonrpc
    curl -s -o $TMP_MUZ -u xbmc:xbmc -X POST -d '{"jsonrpc": "2.0", "method": "Player.GetItem", "params": {"playerid":0 }, "id": 1}' http://localhost:8080/jsonrpc
    grep -w "error" $TMP_VID >/dev/null
    if [ $? -eq 0 ]
    then
        #Video is not playing        
        grep -w "error" $TMP_MUZ >/dev/null
        if [ $? -eq 0 ]
        then
            #Audio is not playing
            grep -w "true" $TMP_SCR >/dev/null
            if [ $? -eq 0 ]
            then
                #Screensaver is active, likely we forgot to shut XBMC off    
                pidof xbmc.bin xargs kill #graceful shutdown
                echo `date` "XBMC-watch killed XBMC (soft)" >> $LOG            
                sleep 2
                if pidof xbmc.bin
                then
                    pidof xbmc.bin|xargs kill -9
                    echo `date` "XBMC-watch killed XBMC (hard)" >> $LOG
                fi
            else
                echo `date` "XBMC scrensaver inactive" >> $LOG
            fi

        else
            echo `date` "XBMC plating audio" >> $LOG
        fi
    else
        echo `date` "XBMC plating video" >> $LOG
    fi
else
    echo `date` "XBMC not running" >> $LOG
fi
rm $TMP_MUZ $TMP_VID $TMP_SCR

Reply
#5
I think the most efficient way would be a service addon within xbmc. Start the service at startup, periodically check xbmc.getGlobalIdleTime(). If it's more than a set amount, call xbmc.shutdown()

No external monitoring required =)
Reply
#6
(2012-09-23, 02:01)Bstrdsmkr Wrote: I think the most efficient way would be a service addon within xbmc. Start the service at startup, periodically check xbmc.getGlobalIdleTime(). If it's more than a set amount, call xbmc.shutdown()

No external monitoring required =)
Indeed, that' much more elegant!

V.

Reply
#7
Hi V-Turn,

I like idea behind your script Smile

I have no expirence in shell scripts so if you could help me out that would be grate

I copied your script to my home folder named it sinke.sh

when I try to run it I get

Code:
: No such file or directoryin/bash
./sinke.sh: line 6: $'\r': command not found
./sinke.sh: line 47: syntax error: unexpected end of file

thanks

foget it Smile editing from windows made mess of code
Reply
#8
For reference:
Frodo (JSON-RPC API v6) will need the correct Content-type, try:

Code:
curl -s -u xbmc:xbmc -X POST -H 'Content-type: application/json' -d '{"jsonrpc": "2.0", "method": "XBMC.GetInfoBooleans", "params": { "booleans": ["System.ScreenSaverActive "] }, "id": 1}' http://localhost:8080/jsonrpc

And using Bash there is no need for temp files and Grep:

Code:
ScreenSaverActive=$(curl -s -u xbmc:xbmc -X POST -H 'Content-type: application/json' -d '{"jsonrpc": "2.0", "method": "XBMC.GetInfoBooleans", "params": { "booleans": ["System.ScreenSaverActive "] }, "id": 1}' http://localhost:8080/jsonrpc)

case $ScreenSaverActive in
  *System.ScreenSaverActive*true*)
    echo ScreenSaver is active
  ;;
  *)
    echo No ScreenSaver
  ;;
esac

And if you prefer if/then/else go with
Code:
if [[ "$ScreenSaverActive" =~ true ]]
then
  echo yes
else
  echo no
fi
or even shorter
Code:
if [[ "$ScreenSaverActive" =~ true ]] ; then echo yes ; else echo no ; fi
and for the impatientTongue
Code:
[[ "$ScreenSaverActive" =~ true ]] && echo yes
Reply
#9
Thank you Zany! I just came back here to get some help because it did not work after my upgrade to Frodo, and it was a great surprise to see that this was already answered. Waw! Smile
Reply
#10
Thanks for your posts. i want only to add that you can also use the idletime direct to indicate if something is active on your xbmc session

my script xbmcIsIdle.sh:

Code:
#!/bin/bash

if netstat -tulpen | egrep -q ':8080.*xbmc\.bin'; then
    IsIdle=$(curl -s -u xbmc:xbmc -X POST -H 'Content-type: application/json' -d '{"jsonrpc": "2.0", "method": "XBMC.GetInfoBooleans", "params": { "booleans": ["System.IdleTime(600) "] }, "id": 1}' http://localhost:8080/jsonrpc)
    Video=$(curl -s -u xbmc:xbmc -X POST -H 'Content-type: application/json' -d '{"jsonrpc": "2.0", "method": "Player.GetItem", "params": {"playerid":1 }, "id": 1}' http://localhost:8080/jsonrpc)
    Audio=$(curl -s -u xbmc:xbmc -X POST -H 'Content-type: application/json' -d '{"jsonrpc": "2.0", "method": "Player.GetItem", "params": {"playerid":0 }, "id": 1}' http://localhost:8080/jsonrpc)

    # echo "IsIdle: $IsIdle"
    # echo "Video: $Video"
    # echo "Audio: $Audio"

    if [[ "$IsIdle" =~ true || "$IsIdle" =~ error ]]; then
    # system idle or could not requested
    if [[ ! "$Video" =~ error || ! "$Audio" =~ error ]]; then
        # system idle but video oder audio active
        exit 0
    else
        exit 1
    fi
    else
    # system not idle
    exit 0
    fi
else
    exit 1
fi
Reply
#11
Why not just set idle action in gui? It will, when idle, turn off or susend xbmc (along with the computer if so desired)
If you have problems please read this before posting

Always read the XBMC online-manual, FAQ and search the forum before posting.
Do not e-mail XBMC-Team members directly asking for support. Read/follow the forum rules.
For troubleshooting and bug reporting please make sure you read this first.

Image

"Well Im gonna download the code and look at it a bit but I'm certainly not a really good C/C++ programer but I'd help as much as I can, I mostly write in C#."
Reply
#12
(2013-04-14, 13:23)topfs2 Wrote: Why not just set idle action in gui? It will, when idle, turn off or susend xbmc (along with the computer if so desired)
Doh, I did not think of that... I was worried that this would shut down the machine as well, let me try that.

V.
Reply
#13
@V-Turn: Any way you could help me with: http://forum.xbmc.org/showthread.php?tid=194147
Reply
#14
(2014-05-06, 00:43)N_Perfors Wrote: @V-Turn: Any way you could help me with: http://forum.xbmc.org/showthread.php?tid=194147
@N_Perfors, sorry I went back to using the embedded functionality as this worked great.
Reply

Logout Mark Read Team Forum Stats Members Help
JSON API : checking whether the system is idle0