diff --git a/fhem/contrib/97_SB_SERVER.pm b/fhem/contrib/97_SB_SERVER.pm
index 5f44a66eb..07ecf0d88 100644
--- a/fhem/contrib/97_SB_SERVER.pm
+++ b/fhem/contrib/97_SB_SERVER.pm
@@ -173,6 +173,11 @@ sub SB_SERVER_Define( $$ ) {
$attr{$name}{maxcmdstack} = 200;
}
+ # the port of the HTTP interface as needed for the coverart url
+ if( !defined( $attr{$name}{httpport} ) ) {
+ $attr{$name}{httpport} = "9000";
+ }
+
# Preset our readings if undefined
my $tn = TimeNow();
@@ -375,10 +380,6 @@ sub SB_SERVER_Ready( $ ) {
return( DevIo_OpenDev( $hash, 1, "SB_SERVER_DoInit") );
}
- #if( $hash->{TCPDev} ) {
- #SB_SERVER_DoInit( $hash );
- #}
-
}
@@ -627,26 +628,15 @@ sub SB_SERVER_DoInit( $ ) {
# and signal to our clients
SB_SERVER_Broadcast( $hash, "SERVER", "OFF" );
SB_SERVER_Broadcast( $hash, "SERVER",
- "IP " . $hash->{IP} .
- ":9000" );
+ "IP " . $hash->{IP} . ":" .
+ AttrVal( $name, "httpport", "9000" ) );
}
return( "" );
}
- # subscribe us
- DevIo_SimpleWrite( $hash, "listen 1\n", 0 );
-
- # and get some info on the server
- DevIo_SimpleWrite( $hash, "pref authorize ?\n", 0 );
- DevIo_SimpleWrite( $hash, "version ?\n", 0 );
- 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 );
-
SB_SERVER_Broadcast( $hash, "SERVER",
- "IP " . $hash->{IP} .
- ":9000" );
+ "IP " . $hash->{IP} . ":" .
+ AttrVal( $name, "httpport", "9000" ) );
# start the alive checking mechanism
$hash->{ALIVECHECK} = "?";
@@ -721,15 +711,43 @@ sub SB_SERVER_ParseCmds( $$ ) {
# signal our players
SB_SERVER_Broadcast( $hash, "SERVER", "ON" );
SB_SERVER_Broadcast( $hash, "SERVER",
- "IP " . $hash->{IP} .
- ":9000" );
+ "IP " . $hash->{IP} . ":" .
+ AttrVal( $name, "httpport", "9000" ) );
}
} elsif( $cmd eq "pref" ) {
if( $args[ 0 ] eq "authorize" ) {
readingsSingleUpdate( $hash, "serversecure", $args[ 1 ], 0 );
+ if( $args[ 1 ] eq "1" ) {
+ # username and password is required
+ if( ( $hash->{USERNAME} ne "?" ) &&
+ ( $hash->{PASSWORD} ne "?" ) ) {
+ DevIo_SimpleWrite( $hash, "login " .
+ $hash->{USERNAME} . " " .
+ $hash->{PASSWORD} . "\n",
+ 0 );
+ } else {
+ Log3( $hash, 3, "SB_SERVER_ParseCmds($name): login " .
+ "required but no username and password specified" );
+ }
+ # next step is to wait for the answer of the LMS server
+ } elsif( $args[ 1 ] eq "0" ) {
+ # no username password required, go ahead directly
+ SB_SERVER_LMS_Status( $hash );
+ } else {
+ Log3( $hash, 3, "SB_SERVER_ParseCmds($name): unkown " .
+ "result for authorize received. Should be 0 or 1" );
+ }
}
+ } elsif( $cmd eq "login" ) {
+ if( ( $args[ 1 ] eq $hash->{USERNAME} ) &&
+ ( $args[ 2 ] eq "******" ) ) {
+ # login has been succesful, go ahead
+ SB_SERVER_LMS_Status( $hash );
+ }
+
+
} elsif( $cmd eq "fhemalivecheck" ) {
$hash->{ALIVECHECK} = "received";
Log3( $hash, 4, "SB_SERVER_ParseCmds($name): alivecheck received" );
@@ -844,9 +862,9 @@ sub SB_SERVER_Alive( $ ) {
# just send something to the SB-Server. It will echo it
# if we receive the echo, the server is still alive
+ $hash->{ALIVECHECK} = "waiting";
DevIo_SimpleWrite( $hash, "fhemalivecheck\n", 0 );
- $hash->{ALIVECHECK} = "waiting";
}
@@ -1530,6 +1548,7 @@ sub SB_SERVER_Notify( $$ ) {
"SB_SERVER_Alive",
$hash,
0 );
+ DevIo_CloseDev( $hash );
} elsif( ReadingsVal( $hash->{RCCNAME}, "state", "off" ) eq "on" ) {
RemoveInternalTimer( $hash );
# do an update of the status, but SB CLI must come up
@@ -1548,11 +1567,74 @@ sub SB_SERVER_Notify( $$ ) {
}
+# ----------------------------------------------------------------------------
+# start up the LMS server status
+# ----------------------------------------------------------------------------
+sub SB_SERVER_LMS_Status( $ ) {
+ my ( $hash ) = @_;
+ my $name = $hash->{NAME}; # own name / hash
+
+ # subscribe us
+ DevIo_SimpleWrite( $hash, "listen 1\n", 0 );
+
+ # and get some info on the server
+ DevIo_SimpleWrite( $hash, "pref authorize ?\n", 0 );
+ DevIo_SimpleWrite( $hash, "version ?\n", 0 );
+ 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 );
+
+ return( true );
+}
+
+
+
+
+# ############################################################################
+# No PERL code beyond this line
+# ############################################################################
1;
=pod
- =begin html
-
-
- =end html
- =cut
+=begin html
+
+
+
SB_SERVER
+
+
+ Define
+
+ define <name> SB_SERVER <ip[:cliserverport]> [<RCC>] [<WOL>] [<username>] [<password>]
+
+
+ This module allows you to control Logitech Media Server and connected Squeezebox Media Players.
+
+ Attention: The <ip[:cliserverport]>
parameter is optional. You just need to configure it if you changed it on the LMS. The default TCP port is 9090.
+
+ Optional
+
+ <[RCC]>
: You can define a FHEM RCC Device, if you want to wake it up when you set the SB_SERVER on.
+ <[WOL]>
: You can define a FHEM WOL Device, if you want to wake it up when you set the SB_SERVER on.
+ <username>
and <password>
: If your LMS is password protected you can define the credentials here.
+
+
+ Set
+
+ set <name> <command>
+
+ This module supports the following commands:
+
+ SB_Server related commands:
+
+ - renew - Renewes the connection to the server
+ - abort - Stops the connection to the server
+ - cliraw <command> - Sends the <command> to the LMS CLI
+ - rescan - Starts the scan of the music library of the server
+ - statusRequest - Update of readings from server and configured players
+
+
+
+
+=end html
+=cut
diff --git a/fhem/contrib/98_SB_PLAYER.pm b/fhem/contrib/98_SB_PLAYER.pm
index eb21a9eef..4925659e1 100644
--- a/fhem/contrib/98_SB_PLAYER.pm
+++ b/fhem/contrib/98_SB_PLAYER.pm
@@ -30,8 +30,6 @@
# PLAYERID the unique identifier of the player. Mostly the MAC
# SERVER based on the IP and the port as given
# IP the IP of the server
-# PORT the Port of the Server
-# CLIPORT the port for the CLI interface of the server
# PLAYERNAME the name of the Player
# CONNECTION the connection status to the server
# CANPOWEROFF is the player supporting power off commands
@@ -89,7 +87,8 @@ sub SB_PLAYER_Initialize( $ ) {
# the attributes we have. Space separated list of attribute values in
# the form name:default1,default2
- $hash->{AttrList} = "volumeStep volumeLimit ";
+ $hash->{AttrList} = "IODev ignore:1,0 do_not_notify:1,0 ";
+ $hash->{AttrList} .= "volumeStep volumeLimit ";
$hash->{AttrList} .= "ttslanguage:de,en,fr ttslink ";
$hash->{AttrList} .= "donotnotify:true,false ";
$hash->{AttrList} .= "idismac:true,false ";
@@ -457,13 +456,13 @@ sub SB_PLAYER_Parse( $$ ) {
if( SB_PLAYER_IsValidMAC( $idbuf ) == 1 ) {
# the MAC Adress is valid
- Log3( undef, 3, "SB_PLAYER_Parse: the unkown ID $id is a valid " .
+ Log3( undef, 3, "SB_PLAYER_Parse: the unknown ID $id is a valid " .
"MAC Adress" );
# this line supports autocreate
return( "UNDEFINED SB_PLAYER_$id SB_PLAYER $idbuf" );
} else {
# the MAC adress is not valid
- Log3( undef, 3, "SB_PLAYER_Parse: the unkown ID $id is NOT " .
+ Log3( undef, 3, "SB_PLAYER_Parse: the unknown ID $id is NOT " .
"a valid MAC Adress" );
return( undef );
}
@@ -471,6 +470,7 @@ sub SB_PLAYER_Parse( $$ ) {
# so the data is for us
my $name = $hash->{NAME};
+ return "" if(IsIgnored($name));
Log3( $hash, 5, "SB_PLAYER_Parse: $name CMD:$cmd ARGS:@args..." );
@@ -491,7 +491,12 @@ sub SB_PLAYER_Parse( $$ ) {
}
} elsif( $cmd eq "remote" ) {
- $hash->{ISREMOTESTREAM} = "$args[ 0 ]";
+ if( defined( $args[ 0 ] ) ) {
+ $hash->{ISREMOTESTREAM} = "$args[ 0 ]";
+ } else {
+ $hash->{ISREMOTESTREAM} = "0";
+ }
+
} elsif( $cmd eq "play" ) {
readingsBulkUpdate( $hash, "playStatus", "playing" );
@@ -1590,36 +1595,53 @@ sub SB_PLAYER_Amplifier( $ ) {
my ( $hash ) = @_;
my $name = $hash->{NAME};
- if( ( $hash->{AMPLIFIER} eq "none" ) || (
- !defined( $defs{$hash->{AMPLIFIER}} ) ) ) {
- # amplifier not specified
- return;
+ if( ( $hash->{AMPLIFIER} eq "none" ) ||
+ (!defined( $defs{$hash->{AMPLIFIER}} ) ) ) {
+ # amplifier not specified
+ return;
}
my $setvalue = "off";
-
+
Log3( $hash, 4, "SB_PLAYER_Amplifier($name): called" );
if( AttrVal( $name, "amplifier", "play" ) eq "play" ) {
- my $thestatus = ReadingsVal( $name, "playStatus", "pause" );
- if( ( $thestatus eq "playing" ) || ( $thestatus eq "paused" ) ) {
- $setvalue = "on";
+ my $thestatus = ReadingsVal( $name, "playStatus", "pause" );
+ if( $thestatus eq "playing" ) {
+ $setvalue = "on";
+ } elsif( ( $thestatus eq "paused" ) ||
+ ( $thestatus eq "stopped" ) ) {
+ $setvalue = "off";
+ } else {
+ $setvalue = "off";
}
} elsif( AttrVal( $name, "amplifier", "on" ) eq "on" ) {
- if( ReadingsVal( $name, "power", "off" ) eq "on" ) {
- $setvalue = "on";
+ if( ReadingsVal( $name, "power", "off" ) eq "on" ) {
+ $setvalue = "on";
+ } else {
+ $setvalue = "off";
}
} else {
- Log3( $hash, 4, "SB_PLAYER_Amplifier($name): ATTR amplifier " .
- "set to wrong value [on|play]" );
+ Log3( $hash, 4, "SB_PLAYER_Amplifier($name): ATTR amplifier " .
+ "set to wrong value [on|play]" );
+ return;
}
- fhem( "set $hash->{AMPLIFIER} $setvalue" );
+ my $actualState = ReadingsVal( "$hash->{AMPLIFIER}", "state", "off" );
+
+ if ( $actualState ne $setvalue) {
+ fhem( "set $hash->{AMPLIFIER} $setvalue" );
+ fhem( "trigger $hash->{AMPLIFIER} $setvalue" );
+ Log3( $hash, 5, "SB_PLAYER_Amplifier($name): set " .
+ "$hash->{AMPLIFIER} $setvalue" );
+ } else {
+ Log3( $hash,5,"SB_PLAYER_Amplifier($name):no amplifier state change");
+ }
return;
-
}
+
# ----------------------------------------------------------------------------
# update the coverart image
# ----------------------------------------------------------------------------
@@ -1876,55 +1898,111 @@ sub SB_SERVER_UpdateVolumeReadings( $$$ ) {
}
-# DO NOT WRITE BEYOND THIS LINE
+# ############################################################################
+# No PERL code beyond this line
+# ############################################################################
1;
=pod
- =begin html
-
-
- SB_PLAYER
-
- Define a Squeezebox Player. Help needs to be done still.
+=begin html
+
+
+SB_PLAYER
+
+
+ Define
+
+ define <name> SB_PLAYER <player_mac_adress> [<ampl>] [<coverart>]
+ This module allows you to control Squeezebox Media Players connected with an defined Logitech Media Server. A SB_SERVER device is need to work.
+ Normally you don't need to define your SB_PLAYERS because autocreate will do that if enabled.
-
- Define
-
- define <name> SB_PLAYER
+
+ <player_mac_adress>
: Mac adress of the player found in the LMS.
+
+ Optional
+
+ <[ampl]>
: You can define a FHEM Device to react when an on or off event is received. With the attribute amplifier you can specify to turn the selected FHEM Device on|off or play|stop.
+ <[coverart]>
: You can define a FHEM weblink. The player will update the weblink with the current coverart. Useful for putting coverarts in the floorplan
+
+
+
+ Set
+
+ set <name> <command> [<parameter>]
+ This module supports the following commands:
+
+ SB_Player related commands:
+
+ - play - starts the playback (might only work if previously paused).
+ - pause [<0|1>] - toggles between play and pause. With parameter 0 it unpause and with 1 it pause the player, doesn't matter which state it has before
+ - stop - stop the playback
+ - next|channelUp - jump to the next track
/* CHECK SYNTAX
+ - prev|channelDown - jump to the previous track or the beginning of the current track.
/* CHECK SYNTAX
+ - mute - toggels between mute and unmuted
+ - volume <n> - sets the volume to <n>. <n> must be a number between 0 and 100
+ - volumeStraight <n> - same as volume
+ - volumeDown|volDown <n> - volume down
/* CHECK SYNTAX
+ - volumeUp|volUp <n> - volume up
/* CHECK SYNTAX
+ - on - set the player on if possible. Otherwise it does play
+ - off - set the player off if possible. Otherwise it does stop
+ - shuffle <on|off> - Enables/Disables shuffle mode
+ - repeat <one|all|off> - Sets the repeat mode
+ - sleep <n> - Sets the player off in <n> seconds and fade the player volume down
+ - favorites <favorit> - Empty the current playlist and start the selected playlist. Favorits are selectable through a dropdown list
+ - talk <text> - Empty the current playlist and speaks the selected text with google TTS
+ - playlist <track|album|artist> <x> - Empty the current playlist starts the track album or artist <x>
+ - playlist <genre> <artist> <album> - Empty the current playlist starts the track which will match the search. You can use * as wildcard for everything
+ Example:
+ set myplayer playlist * Whigfield *
+ - statusRequest - Update of all readings
+ - sync - Sync with other SB_Player for multiroom function. Other players are selectable through a dropdown list. The shown player is the master
/* CHECK BESCHREIBUNG
+ - unsync - Unsync the player from multiroom group
+ - playlists - Empty the current playlist and start the selected playlist. Playlists are selectable through a dropdown list
+ - cliraw <command> - Sends the <command> to the LMS CLI for selected player
+
+
Show
+
+ set sbradio show <line1> <line2> <duration>
+ - line1 - Text for first line
+ - line2 - Text for second line
+ - duration - Duration for apperance in seconds
+
+
Alarms
+
+ You can define up to 2 alarms.
+ set sbradio alarm1 set <weekday> <time>
+ - <weekday> - Number of weekday. The week starts with Sunday and is 0
+ - <time> - Timeformat HH:MM:SS
+ Example:
+ set sbradio alarm1 set 5 12:23:17
+set sbradio alarm2 set 4 17:18:00
+ - alarm<1|2> delete - Delete alarm
+ - alarm<1|2> volume <n> - Set volume for alarm to <n>
+ - alarm<1|2> <enable|disable> - Enable or disable alarm
+ - allalarms <enable|disable> - Enable or disable all alarms
+
+
+
+
+ Generated Readings
+
+ - READING - READING DESCRIPTIONS
/* CHECK TODO
+
- Example:
-
-
-
-
-
- Set
-
- set <name> <value>
- Set any value.
-
-
-
-
- Get
-
-
- Attributes
-
- - setList
- Space separated list of commands, which will be returned upon "set name ?",
- so the FHEMWEB frontend can construct a dropdown and offer on/off
- switches. Example: attr SB_PLAYERName setList on off
-
- - readingFnAttributes
-
-
-
-
-
- =end html
- =cut
-
+
+
+ Attributes
+
+ - volumeLimit
+ Sets the volume limit of the player between 0 and 100. 100 means the function is disabled.
+ - amplifier
+ ATTRIBUTE DESCRIPTION /* CHECK TODO
+
+
+
+
+test
+=end html
+=cut