Home of the Squeezebox™ & Transporter® network music players.
Page 1 of 5 123 ... LastLast
Results 1 to 10 of 42
  1. #1
    Senior Member
    Join Date
    Apr 2008
    Location
    Paris, France
    Posts
    1,520

    Seeking advice on client idle detection / server shutdown

    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.

  2. #2
    Senior Member radish's Avatar
    Join Date
    Apr 2005
    Location
    Red Bank, NJ
    Posts
    5,052
    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.

  3. #3
    Senior Member
    Join Date
    Apr 2008
    Location
    Paris, France
    Posts
    1,520
    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
    So, connected but powered off ???
    Last edited by epoch1970; 2008-06-18 at 11:45.

  4. #4
    Senior Member jth's Avatar
    Join Date
    Apr 2005
    Location
    Phoenix, AZ, USA
    Posts
    367
    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.

  5. #5
    Senior Member
    Join Date
    Apr 2008
    Location
    Paris, France
    Posts
    1,520
    Quote Originally Posted by jth View Post
    I don't know how well you know perl, but you might be able to modify
    the PowerSave plugin to do what you want.
    I know perl... once every 2 years at most ! But I like fiddling with it, and I wanted to check out that plugin at some point in time. I'll take a look at the source.
    Thanks for the idea.

  6. #6
    Senior Member gharris999's Avatar
    Join Date
    Apr 2005
    Location
    Santa Fe, NM
    Posts
    3,352
    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;
    }
    There might be a few of my own modifications in there. I don't remember the url to the original.

    I should say that I don't think this script distinguishes between a player being "stopped" and being "paused."

  7. #7
    Senior Member radish's Avatar
    Join Date
    Apr 2005
    Location
    Red Bank, NJ
    Posts
    5,052
    Quote Originally Posted by epoch1970 View Post
    Thanks.
    I did'nt find a clientstatus, only a serverstatus command.
    <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 ???
    Sure. SB players are never really "off" they're just in off mode. The network connection is still live (so they can be turned back "on" again), so this tells you the player is switched off but still on the network.

  8. #8
    Senior Member
    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:


    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 state
    This works really well for me with 3 SBs, but YMMV. It's a shame the Controller does not really support WOL yet (though it is promised for 7.1).
    Last edited by syburgh; 2008-06-18 at 18:52.

  9. #9
    Senior Member
    Join Date
    Apr 2008
    Location
    Paris, France
    Posts
    1,520
    Quote Originally Posted by syburgh View Post
    This might be useful for you
    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.

  10. #10
    Junior Member
    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.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •