mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-13 05:06:35 +00:00
improved on/off detection added playlists added sync --This line, and
those below, will be ignored-- M 97_SB_SERVER.pm git-svn-id: https://svn.fhem.de/fhem/trunk@6212 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
9e17d08593
commit
a1e2a2ee2a
@ -10,7 +10,7 @@
|
||||
#
|
||||
# This is absolutley open source. Please feel free to use just as you
|
||||
# like. Please note, that no warranty is given and no liability
|
||||
# granted.
|
||||
# granted
|
||||
#
|
||||
# ############################################################################
|
||||
#
|
||||
@ -149,6 +149,12 @@ sub SB_SERVER_Define( $$ ) {
|
||||
|
||||
$hash->{LASTANSWER} = "none";
|
||||
|
||||
# used for alive checking of the CLI interface
|
||||
$hash->{ALIVECHECK} = "?";
|
||||
|
||||
# the status of the CLI connection (on / off)
|
||||
$hash->{CLICONNECTION} = "?";
|
||||
|
||||
# preset our attributes
|
||||
if( !defined( $attr{$name}{alivetimer} ) ) {
|
||||
$attr{$name}{alivetimer} = 120;
|
||||
@ -187,12 +193,6 @@ sub SB_SERVER_Define( $$ ) {
|
||||
$hash->{READINGS}{serversecure}{TIME} = $tn;
|
||||
}
|
||||
|
||||
# the status of our server alive check mechanism
|
||||
if( !defined( $hash->{READINGS}{alivecheck}{VAL} ) ) {
|
||||
$hash->{READINGS}{alivecheck}{VAL} = "?";
|
||||
$hash->{READINGS}{alivecheck}{TIME} = $tn;
|
||||
}
|
||||
|
||||
|
||||
# the maximum number of favorites on the server
|
||||
if( !defined( $hash->{READINGS}{favoritestotal}{VAL} ) ) {
|
||||
@ -371,12 +371,13 @@ sub SB_SERVER_Ready( $ ) {
|
||||
SB_SERVER_Broadcast( $hash, "SERVER", "OFF" );
|
||||
}
|
||||
|
||||
if( $hash->{TCPDev} ) {
|
||||
SB_SERVER_DoInit( $hash );
|
||||
}
|
||||
return( DevIo_OpenDev( $hash, 1, "SB_SERVER_DoInit") );
|
||||
}
|
||||
|
||||
return( DevIo_OpenDev( $hash, 1, "SB_SERVER_DoInit" ) );
|
||||
#if( $hash->{TCPDev} ) {
|
||||
#SB_SERVER_DoInit( $hash );
|
||||
#}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -405,7 +406,7 @@ sub SB_SERVER_Attr( @ ) {
|
||||
my $name = shift( @_ );
|
||||
my @args = @_;
|
||||
|
||||
Log( 1, "SB_SERVER_Attr: called with @args" );
|
||||
Log( 4, "SB_SERVER_Attr: called with @args" );
|
||||
|
||||
if( $cmd eq "set" ) {
|
||||
if( $args[ 0 ] eq "alivetimer" ) {
|
||||
@ -461,7 +462,12 @@ sub SB_SERVER_Set( $@ ) {
|
||||
DevIo_SimpleWrite( $hash, "listen 0\n", 0 );
|
||||
|
||||
} elsif( $cmd eq "statusRequest" ) {
|
||||
Log3( $hash, 5, "SB_SERVER_Set: statusRequest" );
|
||||
DevIo_SimpleWrite( $hash, "serverstatus 0 200\n", 0 );
|
||||
DevIo_SimpleWrite( $hash, "favorites items 0 " .
|
||||
AttrVal( $name, "maxfavorites", 100 ) . "\n",
|
||||
0 );
|
||||
DevIo_SimpleWrite( $hash, "playlists 0 200\n", 0 );
|
||||
|
||||
} elsif( $cmd eq "cliraw" ) {
|
||||
# write raw messages to the CLI interface per player
|
||||
@ -610,11 +616,19 @@ sub SB_SERVER_DoInit( $ ) {
|
||||
|
||||
if( !$hash->{TCPDev} ) {
|
||||
Log3( $hash, 5, "SB_SERVER_DoInit: no TCPDev available?" );
|
||||
DevIo_CloseDev( $hash );
|
||||
}
|
||||
|
||||
if( $hash->{STATE} eq "disconnected" ) {
|
||||
# server is off after FHEM start, broadcast to clients
|
||||
if( ( ReadingsVal( $name, "power", "on" ) eq "on" ) ||
|
||||
( ReadingsVal( $name, "power", "on" ) eq "?" ) ) {
|
||||
# obviously the first we realize the Server is off
|
||||
readingsSingleUpdate( $hash, "power", "off", 1 );
|
||||
|
||||
# and signal to our clients
|
||||
SB_SERVER_Broadcast( $hash, "SERVER", "OFF" );
|
||||
}
|
||||
return( "" );
|
||||
}
|
||||
|
||||
@ -627,9 +641,10 @@ sub SB_SERVER_DoInit( $ ) {
|
||||
DevIo_SimpleWrite( $hash, "serverstatus 0 200\n", 0 );
|
||||
DevIo_SimpleWrite( $hash, "favorites items 0 " .
|
||||
AttrVal( $name, "maxfavorites", 100 ) . "\n", 0 );
|
||||
DevIo_SimpleWrite( $hash, "playlists 0 200\n", 0 );
|
||||
|
||||
# start the alive checking mechanism
|
||||
readingsSingleUpdate( $hash, "alivecheck", "?", 0 );
|
||||
$hash->{ALIVECHECK} = "?";
|
||||
InternalTimer( gettimeofday() + AttrVal( $name, "alivetimer", 120 ),
|
||||
"SB_SERVER_Alive",
|
||||
$hash,
|
||||
@ -707,7 +722,7 @@ sub SB_SERVER_ParseCmds( $$ ) {
|
||||
}
|
||||
|
||||
} elsif( $cmd eq "fhemalivecheck" ) {
|
||||
readingsSingleUpdate( $hash, "alivecheck", "received", 0 );
|
||||
$hash->{ALIVECHECK} = "received";
|
||||
Log3( $hash, 4, "SB_SERVER_ParseCmds($name): alivecheck received" );
|
||||
|
||||
} elsif( $cmd eq "favorites" ) {
|
||||
@ -728,6 +743,10 @@ sub SB_SERVER_ParseCmds( $$ ) {
|
||||
Log3( $hash, 4, "SB_SERVER_ParseCmds($name): server status" );
|
||||
SB_SERVER_ParseServerStatus( $hash, \@args );
|
||||
|
||||
} elsif( $cmd eq "playlists" ) {
|
||||
Log3( $hash, 4, "SB_SERVER_ParseCmds($name): playlists" );
|
||||
SB_SERVER_ParseServerPlaylists( $hash, \@args );
|
||||
|
||||
} else {
|
||||
# unkown
|
||||
}
|
||||
@ -741,6 +760,10 @@ sub SB_SERVER_Alive( $ ) {
|
||||
my ($hash) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
my $rccstatus = "on";
|
||||
my $pingstatus = "on";
|
||||
my $nexttime = gettimeofday() + AttrVal( $name, "alivetimer", 120 );
|
||||
|
||||
Log3( $hash, 4, "SB_SERVER_Alive($name): called" );
|
||||
|
||||
if( AttrVal( $name, "doalivecheck", "false" ) eq "false" ) {
|
||||
@ -748,29 +771,48 @@ sub SB_SERVER_Alive( $ ) {
|
||||
return;
|
||||
}
|
||||
|
||||
# let's ping the server to figure out if he is reachable
|
||||
# needed for servers that go in hibernate mode
|
||||
# check via the RCC element
|
||||
if( $hash->{RCCNAME} ne "none" ) {
|
||||
# an RCC element has been given as argument
|
||||
$rccstatus = ReadingsVal( $hash->{RCCNAME}, "state", "off" );
|
||||
}
|
||||
|
||||
# check via ping
|
||||
my $p = Net::Ping->new( 'tcp' );
|
||||
if( $p->ping( $hash->{IP}, 2 ) ) {
|
||||
# host is reachable so go on normally
|
||||
$pingstatus = "on";
|
||||
} else {
|
||||
$pingstatus = "off";
|
||||
}
|
||||
# close our ping mechanism again
|
||||
$p->close( );
|
||||
|
||||
|
||||
# set the status of the server accordingly
|
||||
if( ( $rccstatus eq "on" ) || ( $pingstatus eq "on" ) ) {
|
||||
# the server is reachable
|
||||
if( ReadingsVal( $name, "power", "on" ) eq "off" ) {
|
||||
Log3( $hash, 5, "SB_SERVER_Alive($name): ping succesful. " .
|
||||
# the first time we see the server being on
|
||||
Log3( $hash, 5, "SB_SERVER_Alive($name): " .
|
||||
"SB-Server is back again." );
|
||||
# first time we realized server is away
|
||||
DevIo_OpenDev( $hash, 1, "SB_SERVER_DoInit" );
|
||||
|
||||
readingsSingleUpdate( $hash, "power", "on", 1 );
|
||||
readingsSingleUpdate( $hash, "alivecheck", "?", 0 );
|
||||
# signal that to our clients
|
||||
SB_SERVER_Broadcast( $hash, "SERVER", "ON" );
|
||||
$hash->{ALIVECHECK} = "?";
|
||||
$hash->{CLICONNECTION} = "off";
|
||||
|
||||
# quicker update to capture CLI connection faster
|
||||
$nexttime = gettimeofday() + 10;
|
||||
}
|
||||
|
||||
if( ReadingsVal( $name, "alivecheck", "received" ) eq "waiting" ) {
|
||||
# check the CLI connection (sub-state)
|
||||
if( $hash->{ALIVECHECK} eq "waiting" ) {
|
||||
# ups, we did not receive any answer in the last minutes
|
||||
# SB Server potentially dead or shut-down
|
||||
Log3( $hash, 5, "SB_SERVER_Alive($name): overrun SB-Server dead." );
|
||||
|
||||
readingsSingleUpdate( $hash, "power", "off", 1 );
|
||||
readingsSingleUpdate( $hash, "alivecheck", "?", 0 );
|
||||
$hash->{CLICONNECTION} = "off";
|
||||
|
||||
# signal that to our clients
|
||||
SB_SERVER_Broadcast( $hash, "SERVER", "OFF" );
|
||||
@ -781,22 +823,32 @@ sub SB_SERVER_Alive( $ ) {
|
||||
# remove all timers we created
|
||||
RemoveInternalTimer( $hash );
|
||||
} else {
|
||||
if( $hash->{CLICONNECTION} eq "off" ) {
|
||||
# signal that to our clients
|
||||
# to be revisited, should only be sent after CLI established
|
||||
SB_SERVER_Broadcast( $hash, "SERVER", "ON" );
|
||||
}
|
||||
|
||||
$hash->{CLICONNECTION} = "on";
|
||||
|
||||
# just send something to the SB-Server. It will echo it
|
||||
# if we receive the echo, the server is still alive
|
||||
DevIo_SimpleWrite( $hash, "fhemalivecheck\n", 0 );
|
||||
|
||||
readingsSingleUpdate( $hash, "alivecheck", "waiting", 0 );
|
||||
$hash->{ALIVECHECK} = "waiting";
|
||||
}
|
||||
|
||||
} else {
|
||||
# the server is away and therefore presumably in hibernate / suspend
|
||||
Log3( $hash, 5, "SB_SERVER_Alive($name): ping timeout. " .
|
||||
|
||||
} elsif( ( $rccstatus eq "off" ) && ( $pingstatus eq "off" ) ) {
|
||||
if( ReadingsVal( $name, "power", "on" ) eq "on" ) {
|
||||
# the first time we realize the server is off
|
||||
Log3( $hash, 5, "SB_SERVER_Alive($name): " .
|
||||
"SB-Server in hibernate / suspend?." );
|
||||
|
||||
if( ReadingsVal( $name, "power", "off" ) eq "on" ) {
|
||||
# first time we realized server is away
|
||||
$hash->{CLICONNECTION} = "off";
|
||||
readingsSingleUpdate( $hash, "power", "off", 1 );
|
||||
readingsSingleUpdate( $hash, "alivecheck", "?", 0 );
|
||||
$hash->{ALIVECHECK} = "?";
|
||||
|
||||
# signal that to our clients
|
||||
SB_SERVER_Broadcast( $hash, "SERVER", "OFF" );
|
||||
@ -806,14 +858,14 @@ sub SB_SERVER_Alive( $ ) {
|
||||
# remove all timers we created
|
||||
RemoveInternalTimer( $hash );
|
||||
}
|
||||
|
||||
} else {
|
||||
# we shouldn't end up here
|
||||
Log3( $hash, 5, "SB_SERVER_Alive($name): funny server status " .
|
||||
"received. Ping=" . $pingstatus . " RCC=" . $rccstatus );
|
||||
}
|
||||
|
||||
# close our ping mechanism again
|
||||
$p->close( );
|
||||
|
||||
# do an update of the status
|
||||
InternalTimer( gettimeofday() + AttrVal( $name, "alivetimer", 120 ),
|
||||
InternalTimer( $nexttime,
|
||||
"SB_SERVER_Alive",
|
||||
$hash,
|
||||
0 );
|
||||
@ -937,6 +989,13 @@ sub SB_SERVER_ParseServerStatus( $$ ) {
|
||||
} elsif( $_ =~ /^(scanning:)([0-9]*)/ ) {
|
||||
readingsBulkUpdate( $hash, "scanning", $2 );
|
||||
next;
|
||||
} elsif( $_ =~ /^(rescan:)([0-9]*)/ ) {
|
||||
if( $2 eq "1" ) {
|
||||
readingsBulkUpdate( $hash, "scanning", "yes" );
|
||||
} else {
|
||||
readingsBulkUpdate( $hash, "scanning", "no" );
|
||||
}
|
||||
next;
|
||||
} elsif( $_ =~ /^(version:)([0-9\.]*)/ ) {
|
||||
readingsBulkUpdate( $hash, "serverversion", $2 );
|
||||
next;
|
||||
@ -1080,6 +1139,20 @@ sub SB_SERVER_ParseServerStatus( $$ ) {
|
||||
}
|
||||
}
|
||||
|
||||
# the list for the sync masters
|
||||
# make all client create e new sync master list
|
||||
SB_SERVER_Broadcast( $hash, "SYNCMASTER",
|
||||
"FLUSH dont care", undef );
|
||||
|
||||
# now send the list for the sync masters
|
||||
foreach my $player ( keys %players ) {
|
||||
my $uniqueid = join( "", split( ":", $players{$player}{MAC} ) );
|
||||
SB_SERVER_Broadcast( $hash, "SYNCMASTER",
|
||||
"ADD $players{$player}{name} " .
|
||||
"$players{$player}{MAC} $uniqueid", undef );
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1345,6 +1418,83 @@ sub SB_SERVER_CMDStackPop( $ ) {
|
||||
}
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# parse the list of known Playlists
|
||||
# ----------------------------------------------------------------------------
|
||||
sub SB_SERVER_ParseServerPlaylists( $$ ) {
|
||||
my( $hash, $dataptr ) = @_;
|
||||
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
my $namebuf = "";
|
||||
my $uniquename = "";
|
||||
my $idbuf = -1;
|
||||
|
||||
# typically the start index being a number
|
||||
if( $dataptr->[ 0 ] =~ /^([0-9])*/ ) {
|
||||
shift( @{$dataptr} );
|
||||
} else {
|
||||
Log3( $hash, 5, "SB_SERVER_ParseServerPlaylists($name): entry is " .
|
||||
"not the start number" );
|
||||
return;
|
||||
}
|
||||
|
||||
# typically the max index being a number
|
||||
if( $dataptr->[ 0 ] =~ /^([0-9])*/ ) {
|
||||
shift( @{$dataptr} );
|
||||
} else {
|
||||
Log3( $hash, 5, "SB_SERVER_ParseServerPlaylists($name): entry is " .
|
||||
"not the end number" );
|
||||
return;
|
||||
}
|
||||
|
||||
my $datastr = join( " ", @{$dataptr} );
|
||||
|
||||
Log3( $hash, 5, "SB_SERVER_ParseServerPlaylists($name): data to parse: " .
|
||||
$datastr );
|
||||
|
||||
# make all client create e new favorites list
|
||||
SB_SERVER_Broadcast( $hash, "PLAYLISTS",
|
||||
"FLUSH dont care", undef );
|
||||
|
||||
my @data1 = split( " ", $datastr );
|
||||
|
||||
foreach( @data1 ) {
|
||||
if( $_ =~ /^(id:)(.*)/ ) {
|
||||
Log3( $hash, 5, "SB_SERVER_ParseServerPlaylists($name): " .
|
||||
"id:$idbuf name:$namebuf " );
|
||||
if( $idbuf != -1 ) {
|
||||
$uniquename = SB_SERVER_FavoritesName2UID( $namebuf );
|
||||
SB_SERVER_Broadcast( $hash, "PLAYLISTS",
|
||||
"ADD $namebuf $idbuf $uniquename", undef );
|
||||
}
|
||||
$idbuf = $2;
|
||||
$namebuf = "";
|
||||
$uniquename = "";
|
||||
next;
|
||||
} elsif( $_ =~ /^(playlist:)(.*)/ ) {
|
||||
$namebuf = $2;
|
||||
next;
|
||||
} elsif( $_ =~ /^(count:)([0-9]*)/ ) {
|
||||
# the last entry of the return
|
||||
Log3( $hash, 5, "SB_SERVER_ParseServerPlaylists($name): " .
|
||||
"id:$idbuf name:$namebuf " );
|
||||
if( $idbuf != -1 ) {
|
||||
$uniquename = SB_SERVER_FavoritesName2UID( $namebuf );
|
||||
SB_SERVER_Broadcast( $hash, "PLAYLISTS",
|
||||
"ADD $namebuf $idbuf $uniquename", undef );
|
||||
}
|
||||
|
||||
} else {
|
||||
$namebuf .= "_" . $_;
|
||||
next;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
||||
=pod
|
||||
|
Loading…
x
Reference in New Issue
Block a user