Hello all,
I am sure this subject has come up before but a quick search did not bring me a definitive answer, so here goes.
I want to detect idle squeezeboxes from the linux server that runs the squeezecenter server. My plan is to have the server shutdown after something like 15 mins without activity, and wake-up on WOL (with a Duet, currently...) I want to avoid sleeping the server when a player has a song in pause. I would like to put it to sleep when players are stopped or off.
I wonder if there is a blessed way of detecting idle clients ?
- Using netstat or tcpstat, I can watch the number of packets out of the server on port 9000/tcp. This is a bit tricky for various reasons (no way to tell the difference between pause and stop, for example)
- Using lsof I can see the files from the library that are being played or paused. Unfortunately, I can't find any sign of file-related activity when listening to radio streams.
So, even getting status from both tools, there is a chance I can shutdown the server while a radio stream is in pause.
I feel all this is somewhat convoluted. I read some of you are using the CLI, but I did not really figured which commands I should pass to the CLI in order to see what the clients are currently doing.
Thanks in advance for your comments and directions.
Results 1 to 10 of 42
-
2008-06-18, 09:29 #1
- Join Date
- Apr 2008
- Location
- Paris, France
- Posts
- 2,193
Seeking advice on client idle detection / server shutdown
-
2008-06-18, 09:35 #2
Use the CLI. I thnk there's a command called playerstatus which will tell you what a player is doing - the docs are all in SC.
-
2008-06-18, 11:43 #3
- Join Date
- Apr 2008
- Location
- Paris, France
- Posts
- 2,193
Thanks.
So I spent half an hour understanding how to send a command using the refsheet represented as a documentation for the CLI. I did'nt find a clientstatus, only a serverstatus command. I started querying my Duet hardware client.
I used the controller to power off the receiver, then I powered off the controller. Obviously, this is a circumstance where the server can safely shut down.
This is what the CLI returns if you care peering through the escapes:
Code:player id 0 ? player id 0 00%3A04%3A20%3A16%3A25%3A82 00%3A04%3A20%3A16%3A25%3A82 connected ? 00%3A04%3A20%3A16%3A25%3A82 connected 1 00%3A04%3A20%3A16%3A25%3A82 power ? 00%3A04%3A20%3A16%3A25%3A82 power 0
Last edited by epoch1970; 2008-06-18 at 11:45.
-
2008-06-18, 12:31 #4
I don't know how well you know perl, but you might be able to modify
the PowerSave plugin to do what you want. PowerSave is able to tell
if individual players are idle - you'd have to modify the code to
take action if all players are idle. Just a thought.
-
2008-06-18, 12:41 #5
- Join Date
- Apr 2008
- Location
- Paris, France
- Posts
- 2,193
-
2008-06-18, 16:10 #6
Max Spicer's perl script, intended to be launched from a reoccurring cron task, pretty much does what you want, I think.
Code:#!/usr/bin/perl -w # $Date: 2005-10-30 14:26:26 +0000 (Sun, 30 Oct 2005) $ $Rev: 9 $ # Copyright 2005 Max Spicer. # Feel free to reuse and modify, but please consider passing modifications back # to me so they can be included in future versions. # If you use this script, please let me know! # Shuts down the server if there aren't any players currently playing. # Designed to be cronned every x minutes during a time range when the server # should be off. # # Example crontab entry: # Shutdown every 30 minutes from 1am to 5:30am # 0,30 1-5 * * * /usr/local/sbin/shutdown.pl use strict; use IO::Socket; use POSIX qw(strftime); # Print debug output if true. Higher values increase verbosity. my $debug = 0; # Turnoff players.. my $turnoff = 1; # Amount of warning time in minutes to give before shutting down my $warnTime = 1; # Change server details below if necessary my $socket = IO::Socket::INET->new (PeerAddr => '127.0.0.1', PeerPort => 9090, Proto => 'tcp', Type => SOCK_STREAM) or die 'Couldn\'t connect to server'; # Get the number of players my $playerCount = sendAndReceive('player count ?'); $debug && print "$playerCount players found\n"; # Interrogate current state of each player my $playersPlaying = 0; my @playerIds; for (my $i = 0; $i < $playerCount; $i++) { # Get the player's internal id and store for future reference $playerIds[$i] = sendAndReceive("player id $i ?"); $debug && print "Player $i has ID $playerIds[$i]\n"; my $playerMode = sendAndReceive("$playerIds[$i] mode ?"); $debug && print "Player ${i}'s mode is $playerMode\n"; if ($playerMode eq 'play') { $playersPlaying++; } } $debug && print "$playersPlaying/$playerCount players playing\n"; if (!$playersPlaying) { $debug && print "Shutting down\n"; my $timeString = POSIX::strftime("%H:%m:%S", localtime()); # Display a warning on each powered-on player for (my $i = 0; $i < $playerCount; $i++) { sendAndReceive("$playerIds[$i] display $timeString%20-%20Warning: Server%20shutting%20down%20in%20$warnTime%20minutes 30"); } if ($turnoff) { # Turn off each powered-on player (this should trigger amp turn-off #print "Turning off SqueezeBoxen..\n"; for (my $i = 0; $i < $playerCount; $i++) { #turn off only the Transporter if ( $playerIds[$i] eq '00%3A04%3A20%3A10%3A01%3A04') { print "Turning off Transporter!\n"; sendAndReceive("$playerIds[$i] power 0"); } } } #stop Squeeze Center system("/sbin/service squeezecenter stop"); # rotate the slimserver logs.. print "Rotating logs..\n"; system("/usr/sbin/logrotate /etc/logrotate.d/squeezecenter"); # Shutdown! print "OK..now we are shutting down..\n"; system("/sbin/shutdown -h +$warnTime No Slim players playing so system is shutting down."); close $socket; # Send given cmd to $socket and return answer with original command removed from # front if present. Routine nicked from code by Felix Mueller. :-) sub sendAndReceive { my $cmd = shift; return if( $cmd eq ""); print $socket "$cmd\n"; $debug > 1 && print "Sent $cmd to server\n"; my $answer = <$socket>; $debug > 1 && print "Server replied: $answer\n"; $answer =~ s/$cmd //i; $answer =~ s/\n//; return $answer; }
I should say that I don't think this script distinguishes between a player being "stopped" and being "paused."
-
2008-06-18, 18:18 #7
<playerid> power <0|1|?|>
will let you find out if a player is on or off.
<playerid> mode ?
will tell you if a player is in stop/play/pause mode
So, connected but powered off ???
-
2008-06-18, 18:41 #8
- Join Date
- Dec 2007
- Posts
- 279
Here's what I use
This might be useful for you
I thought my needs were simple, but ended up with something a bit more complicated after an evening of hacking. The python script below identifies when the dedicated SC7 box is "idle" (eligible for suspend/hibernate). Run with "--help" option for usage info.
Works for me on CentOS 5 and I am using it now.Script has lots of internal documentation and is too long for a forum comment, so here's the link:
- sc-idle.py
- logging.ini (optional)
- /etc/init.d/sc-idle (init script)
- /etc/sysconfig/sc-idle (init script config file)
Overview
All of the following must be true for "idle" timer to begin countdown to suspend/hibernate/shutdown:
- All connected players are stopped, off, or paused
- No open interactive consoles (e.g. ssh, screen, serial, or VGA console). This way one can run a long script (e.g. transcoding, replaygain) using screen without the system becoming "idle"
- A specific file (/tmp/nosleep) does not exist. This makes it easy for scripts and cron jobs to run without the system going "idle"
Once Timer Expires
- After first timeout expires (default is 30 min) the system will: Enter suspend to RAM ("Suspend" in Windows, ACPI S3), from which it can wake and play music quickly (mine resumes using WOL in <10s)
- After 2 days of "idle" state the system will wake itself using the ACPI real time alarm and enter hibernate mode (ACPI S5), which limits risk of a power outage during extended vacations
Both timeouts are configurable from command line and it would be pretty easy to have the system run 'shutdown' instead of 'pm-suspend' if you want a real shutdown.
Example
Using 15 second suspend and 2 min hibernate timeout (called "demo mode", useful for debugging ACPI hardware quirks). The "--quirk-s3-bios" bits you see are necessary to support suspend on my specific hardware
PAUSE TRACK USING SQUEEZEBOX REMOTE
[root@audio0 ~]# /usr/local/sbin/sc-idle.py --demo --pm-arg=--quirk-s3-bios
2008-04-02 18:55:37,921 DEBUG Configured options: {'demo_mode': True, 'daemon': False, 'cli_host': 'localhost', 'pid_path': None, 'pm_arg': '--quirk-s3-bios', 'rtc_padding': 0, 'log_config': '/etc/sc-idle/logging.ini', 'cli_port': 9090, 'poll_delay': 10, 'nosleep_path': '/tmp/nosleep', 'resume_delay': 30}
2008-04-02 18:55:37,922 INFO Monitor started
2008-04-02 18:55:37,923 DEBUG Connected cli on localhost:9090
2008-04-02 18:55:37,928 DEBUG Disconnected cli on localhost:9090
2008-04-02 18:55:37,929 DEBUG System entered idle state
2008-04-02 18:55:37,929 DEBUG Cannot enter hibernate (ACPI S5), need 0:01:59.999716
2008-04-02 18:55:37,930 DEBUG Cannot enter suspend (ACPI S3), need 0:00:14.999438
2008-04-02 18:55:47,928 DEBUG Connected cli on localhost:9090
2008-04-02 18:55:47,934 DEBUG Disconnected cli on localhost:9090
2008-04-02 18:55:47,934 DEBUG System has been idle for 0:00:10.005192
2008-04-02 18:55:47,934 DEBUG Cannot enter hibernate (ACPI S5), need 0:01:49.994582
2008-04-02 18:55:47,935 DEBUG Cannot enter suspend (ACPI S3), need 0:00:04.994352
2008-04-02 18:55:57,933 DEBUG Connected cli on localhost:9090
2008-04-02 18:55:57,939 DEBUG Disconnected cli on localhost:9090
2008-04-02 18:55:57,939 DEBUG System has been idle for 0:00:20.010272
2008-04-02 18:55:57,940 DEBUG Cannot enter hibernate (ACPI S5), need 0:01:39.989510
2008-04-02 18:55:57,940 INFO Enter suspend (ACPI S3) after being idle 0:00:20.010272
2008-04-02 18:55:57,940 INFO Set RTC wake alarm to '2008-04-02 22:57:37'
2008-04-02 18:57:56,353 DEBUG Return from suspend (ACPI S3), waiting 30 sec for activity
2008-04-02 18:58:36,348 DEBUG Connected cli on localhost:9090
2008-04-02 18:58:36,353 DEBUG Disconnected cli on localhost:9090
2008-04-02 18:58:36,354 DEBUG System has been idle for 0:02:58.424532
2008-04-02 18:58:36,354 INFO Enter hibernate (ACPI S5) after being idle 0:02:58.424532
PRESS POWER ON SQUEEZEBOX REMOTE TO WAKE SQUEEZECENTER
2008-04-02 19:00:35,758 DEBUG Return from hibernate (ACPI S5), waiting 30 sec for activity
2008-04-02 19:01:15,751 DEBUG Connected cli on localhost:9090
2008-04-02 19:01:15,756 DEBUG Disconnected cli on localhost:9090
2008-04-02 19:01:15,757 DEBUG System has been idle for 0:05:37.827774
2008-04-02 19:01:15,757 INFO Enter hibernate (ACPI S5) after being idle 0:05:37.827774
PRESS POWER ON SQUEEZEBOX REMOTE TO WAKE SQUEEZECENTER
2008-04-02 19:02:40,748 DEBUG Return from hibernate (ACPI S5), waiting 30 sec for activity
UN-PAUSE TRACK USING SQUEEZEBOX REMOTE
2008-04-02 19:03:20,742 DEBUG Connected cli on localhost:9090
2008-04-02 19:03:20,746 DEBUG SqueezeCenter players are active
2008-04-02 19:03:20,747 DEBUG Disconnected cli on localhost:9090
2008-04-02 19:03:20,747 DEBUG System left idle stateLast edited by syburgh; 2008-06-18 at 18:52.
-
2008-06-19, 05:47 #9
- Join Date
- Apr 2008
- Location
- Paris, France
- Posts
- 2,193
Indeed.
FYI, I use nvram-wakeup in case I need to simply pause the machine for a short while. I currently have an ambient temperature check that can shut down the machine and schedule it to restart 20 mins later.
EDIT: Nevermind, I see you're using that too.
radish, jth, gharris999:
thanks for the clarification and pointers. I hope I can manage from here.
There is a good chance my code ends up implemented as a Net:aemon util.
Last edited by epoch1970; 2008-06-19 at 07:04.
-
2008-06-19, 06:22 #10
- Join Date
- Jun 2008
- Location
- Miami, FL
- Posts
- 20
re: WoL, would it be possible to ssh to the controller and install a simple utility (one of these: http://bcs.lsd.di.uminho.pt/jpo/soft...i-howto-3.html) to wake a *known* slimserver when the controller is turned on?
I say *known* because you'd have to run the utility with the servers' MAC address, but as this doesn't change it shouldn't be a problem.