Squeezebox
m (→SAD - Squeezebox Server Announcement Device) |
|||
(30 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
+ | [[Category:Plugins]] | ||
+ | [[Category:How To]] | ||
+ | |||
+ | '''Using the SqueezeBox Plugin''' | ||
+ | |||
== Displaying cover art for the current song == | == Displaying cover art for the current song == | ||
Line 80: | Line 85: | ||
client:send("00:04:20:XX:XX:XX mixer volume +10\n") | client:send("00:04:20:XX:XX:XX mixer volume +10\n") | ||
client:send("00:04:20:XX:XX:XX mixer volume -10\n") | client:send("00:04:20:XX:XX:XX mixer volume -10\n") | ||
+ | |||
+ | ==== Switching players (undocumented and untested) ==== | ||
+ | |||
+ | Syntax: | ||
+ | |||
+ | switchplayer from:<MAC address of player1> to:<MAC address of player2> | ||
+ | |||
+ | Example: | ||
+ | |||
+ | client:send("switchplayer from:00:00:00:00:00:01 to:00:00:00:00:00:02\n") | ||
+ | |||
+ | [Reference: http://www.mail-archive.com/plugins@lists.slimdevices.com/msg46077.html] | ||
+ | |||
+ | ==== Playing a file ==== | ||
+ | |||
+ | Syntax: | ||
+ | |||
+ | <MAC address of player> playlist play file:///<filename> | ||
+ | |||
+ | Example: | ||
+ | |||
+ | Windows: | ||
+ | 77:d3:XX:XX:XX:XX playlist play file:///I:/NewMusic/Schwanensee%20(aus%20Kinderbuch)/Content/01%20-%20Track%201.flac | ||
+ | |||
+ | Synology NAS: | ||
+ | 77:d3:XX:XX:XX:XX playlist play file:///disk1/music/file.mp3 | ||
== Sending IR codes (SB2/3 and Transporter) == | == Sending IR codes (SB2/3 and Transporter) == | ||
Line 103: | Line 134: | ||
local playerid = '00:04:20:XX:XX:XX' | local playerid = '00:04:20:XX:XX:XX' | ||
local remote_name = 'Onkyo_RC-738M' -- as defined in the LIRC configuration file for this remote | local remote_name = 'Onkyo_RC-738M' -- as defined in the LIRC configuration file for this remote | ||
− | local command_name = 'PWR' -- as defined in | + | local command_name = 'PWR' -- as defined in the LIRC configuration file for this remote |
| | ||
local client = socket.connect( SBS_IP_address, SBS_CLI_port ) | local client = socket.connect( SBS_IP_address, SBS_CLI_port ) | ||
Line 117: | Line 148: | ||
Successfully tested with: SBS 7.3.2, IRBlaster/IR-Learning wizard 5.4, Skymaster DVR 7400. | Successfully tested with: SBS 7.3.2, IRBlaster/IR-Learning wizard 5.4, Skymaster DVR 7400. | ||
+ | |||
+ | == Squeezebox Control beta plugin (by MCV/radarengineer) == | ||
+ | |||
+ | http://forum.micasaverde.com/index.php/topic,10108.0.html | ||
+ | |||
+ | http://forum.micasaverde.com/index.php?topic=5097.msg28878#msg28878 | ||
+ | |||
+ | == LOUIS4Vera == | ||
+ | |||
+ | http://forum.micasaverde.com/index.php?topic=5232.0 | ||
+ | |||
+ | == LIRC2LuupDevice4SBS == | ||
+ | |||
+ | http://forum.micasaverde.com/index.php?topic=5709.0 | ||
+ | |||
+ | == SAD - Squeezebox Server Announcement Device == | ||
+ | |||
+ | '''Old''' implementation: | ||
+ | http://forum.micasaverde.com/index.php?topic=6952.0 | ||
+ | |||
+ | '''New''' implementation (LIFO queue per player, luup.sleep replaced with luup.call_delay; copy into the 'Startup Lua' window; should be rewritten with coroutines ...): | ||
+ | |||
+ | <source lang="text"> | ||
+ | --------------------------------------------------------------------------------------------------- | ||
+ | |||
+ | -- V1.2 | ||
+ | |||
+ | LMS_players = {} | ||
+ | |||
+ | --------------------------------------------------------------------------------------------------- | ||
+ | |||
+ | function LMS_CLI( server_ip, server_port, player_id, cmd ) | ||
+ | |||
+ | local socket = require( 'socket' ) | ||
+ | |||
+ | local client = socket.connect( server_ip, server_port ) | ||
+ | |||
+ | client:send( player_id .. ' ' .. cmd .. '\n' ) | ||
+ | |||
+ | local res = client:receive() | ||
+ | |||
+ | client:close() | ||
+ | |||
+ | return res | ||
+ | |||
+ | end -- LMS_CLI | ||
+ | |||
+ | --------------------------------------------------------------------------------------------------- | ||
+ | |||
+ | function LMS_Say( LMS_ip , -- IP address of LMS | ||
+ | LMS_port , -- CLI Port of LMS (default: 9090) | ||
+ | player_id , -- MAC address of player | ||
+ | message1 , -- line 1 | ||
+ | message2 , -- line 2 | ||
+ | message_duration, -- in seconds | ||
+ | file , -- audio announcement | ||
+ | file_duration , -- duration of announcement in seconds | ||
+ | repeats ) -- number of announcements | ||
+ | |||
+ | -- V1.4 catch empty announcement (would result in a stuck queue ...) | ||
+ | |||
+ | if ( file ~= '' ) and ( file ~= nil ) | ||
+ | then | ||
+ | |||
+ | if LMS_players[ player_id ] == nil | ||
+ | then | ||
+ | LMS_players[ player_id ] = {} | ||
+ | end | ||
+ | |||
+ | if LMS_players[ player_id ].is_saying -- nil is false | ||
+ | then | ||
+ | |||
+ | local queue_index = LMS_players[ player_id ].waiting_in_queue or 0 | ||
+ | |||
+ | queue_index = queue_index + 1 | ||
+ | |||
+ | LMS_players[ player_id ].waiting_in_queue = queue_index | ||
+ | |||
+ | if LMS_players[ player_id ].queue == nil | ||
+ | then | ||
+ | LMS_players[ player_id ].queue = {} | ||
+ | end | ||
+ | |||
+ | if LMS_players[ player_id ].queue[ queue_index ] == nil | ||
+ | then | ||
+ | LMS_players[ player_id ].queue[ queue_index ] = {} | ||
+ | end | ||
+ | |||
+ | LMS_players[ player_id ].queue[ queue_index ].LMS_ip = LMS_ip | ||
+ | LMS_players[ player_id ].queue[ queue_index ].LMS_port = LMS_port | ||
+ | LMS_players[ player_id ].queue[ queue_index ].message1 = message1 | ||
+ | LMS_players[ player_id ].queue[ queue_index ].message2 = message2 | ||
+ | LMS_players[ player_id ].queue[ queue_index ].message_duration = message_duration | ||
+ | LMS_players[ player_id ].queue[ queue_index ].file = file | ||
+ | LMS_players[ player_id ].queue[ queue_index ].file_duration = file_duration | ||
+ | LMS_players[ player_id ].queue[ queue_index ].repeats = repeats | ||
+ | |||
+ | else | ||
+ | |||
+ | LMS_players[ player_id ].is_saying = true | ||
+ | |||
+ | if LMS_players[ player_id ].current_cmd == nil | ||
+ | then | ||
+ | LMS_players[ player_id ].current_cmd = {} | ||
+ | end | ||
+ | |||
+ | LMS_players[ player_id ].current_cmd.LMS_ip = LMS_ip | ||
+ | LMS_players[ player_id ].current_cmd.LMS_port = LMS_port | ||
+ | LMS_players[ player_id ].current_cmd.file = file | ||
+ | LMS_players[ player_id ].current_cmd.file_duration = file_duration | ||
+ | LMS_players[ player_id ].current_cmd.repeats = repeats | ||
+ | |||
+ | if LMS_players[ player_id ].current_state == nil | ||
+ | then | ||
+ | LMS_players[ player_id ].current_state = {} | ||
+ | end | ||
+ | |||
+ | LMS_players[ player_id ].current_state.power = LMS_CLI( LMS_ip, LMS_port, player_id, 'power ?' ) | ||
+ | LMS_players[ player_id ].current_state.track = LMS_CLI( LMS_ip, LMS_port, player_id, 'playlist index ?' ) | ||
+ | LMS_players[ player_id ].current_state.offset = LMS_CLI( LMS_ip, LMS_port, player_id, 'time ?' ) | ||
+ | LMS_players[ player_id ].current_state.mode = LMS_CLI( LMS_ip, LMS_port, player_id, 'mode ?' ) | ||
+ | |||
+ | if ( message1 ~= '' ) and ( message1 ~= nil ) and ( message_duration > 0 ) | ||
+ | then | ||
+ | |||
+ | LMS_CLI( LMS_ip, LMS_port, player_id, 'display ' .. tostring(message1) .. ' ' .. tostring(message2) .. ' ' .. tostring( message_duration ) ) | ||
+ | |||
+ | luup.call_delay( 'LMS_Say_play_file', message_duration, player_id ) | ||
+ | |||
+ | else | ||
+ | |||
+ | LMS_Say_play_file( player_id ) | ||
+ | |||
+ | end | ||
+ | |||
+ | end | ||
+ | |||
+ | end | ||
+ | |||
+ | end -- LMS_Say | ||
+ | |||
+ | --------------------------------------------------------------------------------------------------- | ||
+ | |||
+ | function LMS_Say_play_file( player_id ) | ||
+ | |||
+ | local cmd = LMS_players[ player_id ].current_cmd | ||
+ | local state = LMS_players[ player_id ].current_state | ||
+ | |||
+ | if ( cmd.file ~= '' ) | ||
+ | and | ||
+ | ( cmd.file ~= nil ) | ||
+ | and | ||
+ | ( cmd.repeats > 0 ) | ||
+ | then | ||
+ | |||
+ | -- Add announcement file to playlist | ||
+ | |||
+ | local playlist_add = LMS_CLI( cmd.LMS_ip, cmd.LMS_port, player_id, 'playlist add ' .. cmd.file ) | ||
+ | |||
+ | -- V1.1: Sometimes type( state.tracks_total ) is a function ... | ||
+ | -- V1.2: countdown | ||
+ | |||
+ | local count_down = 5 | ||
+ | |||
+ | repeat | ||
+ | |||
+ | -- V1.5: bugfix | ||
+ | state.tracks_total = LMS_CLI( cmd.LMS_ip, cmd.LMS_port, player_id, 'playlist tracks ?' ) | ||
+ | |||
+ | count_down = count_down - 1 | ||
+ | |||
+ | -- V1.5: bugfix | ||
+ | until ( type( state.tracks_total ) == 'string' ) or ( count_down < 1 ) | ||
+ | |||
+ | -- V1.5: bugfix | ||
+ | state.tracks_total = tonumber( string.match( state.tracks_total, '%s(%d+)' ) ) | ||
+ | |||
+ | LMS_Say_play_file_execute( player_id ) | ||
+ | |||
+ | else | ||
+ | |||
+ | LMS_check_queue( player_id ) | ||
+ | |||
+ | end | ||
+ | |||
+ | end -- LMS_Say_play_file | ||
+ | |||
+ | --------------------------------------------------------------------------------------------------- | ||
+ | |||
+ | function LMS_Say_play_file_execute( player_id ) | ||
+ | |||
+ | local cmd = LMS_players[ player_id ].current_cmd | ||
+ | local state = LMS_players[ player_id ].current_state | ||
+ | |||
+ | -- V1.5: bugfix | ||
+ | local playlist_set = LMS_CLI( cmd.LMS_ip, cmd.LMS_port, player_id, 'playlist index ' .. tostring( state.tracks_total - 1 ) ) | ||
+ | |||
+ | cmd.repeats = cmd.repeats - 1 | ||
+ | |||
+ | if cmd.repeats >= 0 | ||
+ | then | ||
+ | |||
+ | luup.call_delay( 'LMS_Say_play_file_execute', cmd.file_duration, player_id ) | ||
+ | |||
+ | else | ||
+ | |||
+ | LMS_check_queue( player_id ) | ||
+ | |||
+ | end | ||
+ | |||
+ | end -- LMS_Say_play_file_execute | ||
+ | |||
+ | --------------------------------------------------------------------------------------------------- | ||
+ | |||
+ | function LMS_check_queue( player_id ) | ||
+ | |||
+ | local cmd = LMS_players[ player_id ].current_cmd | ||
+ | local state = LMS_players[ player_id ].current_state | ||
+ | |||
+ | -- Restore previous state of player | ||
+ | |||
+ | -- V1.5: bugfix | ||
+ | local playlist_del = LMS_CLI( cmd.LMS_ip, cmd.LMS_port, player_id, 'playlist delete ' .. tostring( state.tracks_total - 1 ) ) | ||
+ | local playlist_set = LMS_CLI( cmd.LMS_ip, cmd.LMS_port, '' , state.track ) | ||
+ | local time_set = LMS_CLI( cmd.LMS_ip, cmd.LMS_port, '' , state.offset ) | ||
+ | local mode_set = LMS_CLI( cmd.LMS_ip, cmd.LMS_port, '' , state.mode ) | ||
+ | local power_set = LMS_CLI( cmd.LMS_ip, cmd.LMS_port, '' , state.power ) | ||
+ | |||
+ | local waiting = LMS_players[ player_id ].waiting_in_queue or 0 | ||
+ | |||
+ | -- Check queue | ||
+ | |||
+ | if waiting > 0 | ||
+ | then | ||
+ | |||
+ | local q = LMS_players[ player_id ].queue[ waiting ] | ||
+ | |||
+ | LMS_players[ player_id ].waiting_in_queue = waiting - 1 | ||
+ | |||
+ | LMS_players[ player_id ].is_saying = false | ||
+ | |||
+ | LMS_Say( q.LMS_ip , | ||
+ | q.LMS_port , | ||
+ | player_id , | ||
+ | q.message1 , | ||
+ | q.message2 , | ||
+ | q.message_duration, | ||
+ | q.file , | ||
+ | q.file_duration , | ||
+ | q.repeats ) | ||
+ | |||
+ | else | ||
+ | |||
+ | LMS_players[ player_id ].is_saying = false | ||
+ | |||
+ | end | ||
+ | |||
+ | end -- LMS_check_queue | ||
+ | |||
+ | --------------------------------------------------------------------------------------------------- | ||
+ | |||
+ | -- V1.3 'repair' a stuck queue | ||
+ | |||
+ | max_LMS_queue_length = 5 | ||
+ | |||
+ | function LMS_queues_watchdog() | ||
+ | |||
+ | if type( LMS_players ) == 'table' | ||
+ | then | ||
+ | |||
+ | for mac, _ in pairs( LMS_players ) | ||
+ | do | ||
+ | |||
+ | local w_i_q = LMS_players[ mac ].waiting_in_queue | ||
+ | |||
+ | if ( w_i_q or 0 ) > max_LMS_queue_length | ||
+ | then | ||
+ | |||
+ | LMS_players[ mac ].waiting_in_queue = 0 | ||
+ | LMS_players[ mac ].is_saying = false | ||
+ | |||
+ | end | ||
+ | |||
+ | end | ||
+ | |||
+ | end | ||
+ | |||
+ | luup.call_delay( 'LMS_queues_watchdog', 5 * 60, '' ) | ||
+ | |||
+ | end -- LMS_queues_watchdog | ||
+ | |||
+ | luup.call_delay( 'LMS_queues_watchdog', 70, '' ) | ||
+ | |||
+ | ------------------------------------------------------------------------------------------------------------ | ||
+ | </source> | ||
+ | |||
+ | == SPB - Squeezebox Preset Button device == | ||
+ | |||
+ | SPB maps preset buttons to Luup events. | ||
+ | |||
+ | http://forum.micasaverde.com/index.php/topic,9059.0.html | ||
+ | |||
+ | == USP - Unified Squeezebox Plugin (Technology demo only) == | ||
+ | |||
+ | http://forum.micasaverde.com/index.php/topic,10020.0.html | ||
+ | |||
+ | == squeezedVera and squeezedVeraScenes == | ||
+ | |||
+ | squeezedVera is a plugin for the Logitech Squeezebox, and it gives you the possibility to run scripts in different ways that can control your z-wave devices through Vera. | ||
+ | |||
+ | squeezedVeraScenes will run the same scripts as squeezedVera but here you define conditions for when they shall run in a configuration file, e.g at sunset on Mondays and Tuesdays. You can also define different scenes with different behaviour. | ||
+ | |||
+ | http://forum.micasaverde.com/index.php/topic,1047.0.html | ||
+ | |||
+ | == Morphing the Sonos plugin into a Squeezebox plugin == | ||
+ | |||
+ | http://forum.micasaverde.com/index.php/topic,9532.0.html | ||
+ | |||
+ | == Importing LMS devices into MiOS == | ||
+ | |||
+ | Use Whitebear Media Server or the native UPnP support in LMS 7.7.2+ to import your LMS devices into MiOS: | ||
+ | |||
+ | http://forum.micasaverde.com/index.php/topic,10220.0.html | ||
+ | |||
+ | == Using Google's TTS engine for announcements == | ||
+ | |||
+ | Requirement: http://wiki.micasaverde.com/index.php/Squeezebox#SAD_-_Squeezebox_Server_Announcement_Device | ||
+ | |||
+ | local lul_temp = luup.variable_get("urn:upnp-org:serviceId:TemperatureSensor1","CurrentTemperature", 111) | ||
+ | if ( tonumber( lul_temp ) > 25 ) or ( luup.sunrise() - os.time() > 86400 - 300 ) | ||
+ | then | ||
+ | os.execute( 'cd /tmp; wget -U Mozilla -O GHBewAnn.mp3 "http://translate.google.com/translate_tts?tl=de&q=Gewaechshaus+wird+bewaessert.+Innentemperatur:+'..tostring( lul_temp )..'+Grad+Celsius."; ftpput -u **** -p **** 192.168.x.y public/HA_Announcements/GHBewAnn.mp3 GHBewAnn.mp3' ) | ||
+ | SBS_announcement( '192.168.a.b' , | ||
+ | 9090 , | ||
+ | '00:04:20:xx:xx:xx' , | ||
+ | 'Gewaechshaus%20wird%20bewaessert' , | ||
+ | tostring(lul_temp)..'%20Grad%20Celsius' , | ||
+ | 5 , | ||
+ | '/volume1/public/HA_Announcements/GHBewAnn.mp3', | ||
+ | 10 ) | ||
+ | luup.call_action( "urn:upnp-ap15e-com:serviceId:SND1", "SendMail", { subject = 'Gewaechshaus wird bewaessert ('..tostring(lul_temp)..')', body = os.date('%Y-%m-%d %H:%M:%S '..os.time()) }, 25 ) | ||
+ | end | ||
+ | |||
+ | or even simpler: | ||
+ | |||
+ | <MAC address> playlist play http://translate.google.com/translate_tts?tl=en&q=Just+a+test | ||
+ | |||
+ | ==Controlling the BASETech RGB LED light bulb== | ||
+ | |||
+ | http://wiki.micasaverde.com/index.php/BASETech_RGB_LED | ||
+ | |||
+ | ==Squeezebox clone== | ||
+ | |||
+ | http://wiki.micasaverde.com/index.php/Raspberry_Pi_-_Interfacing_with_Vera#Squeezebox |
Latest revision as of 19:56, 4 May 2013
Using the SqueezeBox Plugin
[edit] Displaying cover art for the current song
1. Create new camera device(s) for the room(s) equipped with Squeezebox(es)
2. Configure the new camera device(s):
- IP address: IP address and port of your Squeezebox Server (<ip address>:<port number>)
- Path: music/current/cover.jpg?player=<MAC address> (replace <MAC address> with the MAC address of the player; IP address should work too)
[edit] Using the SBS CLI
[edit] Luup/Lua skeleton
socket=require('socket') local client = socket.connect('<IP address of SBS>', 9090) client:send("<CLI command>\n") local result=client:receive() ...
For a list of valid <CLI command> navigate to: SBS's Home / Technical Information / Help / Command Line Interface
[edit] Some examples for <CLI command>
<duration> does not work for Squeezebox Radio due to Slimdevices bug #15749.
[edit] Displaying text
Syntax:
<MAC address of player> display <line1> <line2> <duration>
Example:
client:send("00:04:20:XX:XX:XX display Hello%20World%201 Hello%20World%202 10\n")
[edit] 'Pressing' a button on the Squeezebox remote
Syntax:
<MAC address of player> button <buttoncode>
Example:
client:send("00:04:20:XX:XX:XX button brightness_toggle\n") client:send("00:04:20:XX:XX:XX button volume_up\n") client:send("00:04:20:XX:XX:XX button volume_down\n")
<buttoncode> as defined in Default.map; telnet to your SBS port 9090, type 'subscribe button' (without quotes), press <RETURN>, press the buttons of the remote to get the buttoncodes.
[edit] Skipping to the previous/next track
Syntax:
<MAC address of player> playlist index <index|+index|-index|?> <fadeInSecs>
Example:
client:send("00:04:20:XX:XX:XX playlist index -1\n") client:send("00:04:20:XX:XX:XX playlist index +1\n")
[edit] Pause/Unpause playing
Syntax:
<MAC address of player> pause <0|1|> <fadeInSecs> <suppressShowBriefly>
Example:
client:send("00:04:20:XX:XX:XX pause\n")
[edit] Changing the volume level
Syntax:
<MAC address of player> mixer volume <0 .. 100|-100 .. +100|?>
Example:
client:send("00:04:20:XX:XX:XX mixer volume +10\n") client:send("00:04:20:XX:XX:XX mixer volume -10\n")
[edit] Switching players (undocumented and untested)
Syntax:
switchplayer from:<MAC address of player1> to:<MAC address of player2>
Example:
client:send("switchplayer from:00:00:00:00:00:01 to:00:00:00:00:00:02\n")
[Reference: http://www.mail-archive.com/plugins@lists.slimdevices.com/msg46077.html]
[edit] Playing a file
Syntax:
<MAC address of player> playlist play file:///<filename>
Example:
Windows: 77:d3:XX:XX:XX:XX playlist play file:///I:/NewMusic/Schwanensee%20(aus%20Kinderbuch)/Content/01%20-%20Track%201.flac
Synology NAS: 77:d3:XX:XX:XX:XX playlist play file:///disk1/music/file.mp3
[edit] Sending IR codes (SB2/3 and Transporter)
1. Plug an IR emitter into the phones jack of your Squeezebox/Transporter.
2. Install IRBlaster.
3. Restart your SBS.
4. Install the IR remote files for the IR devices you are going to control or use the IR-Learning Wizard (part of IRBlaster) to record the codes of your remote(s).
Now you are ready to send IR codes via Lua (adjust SBS_IP_address, SBS_CLI_port, playerid, remote_name, and command_name accordingly):
socket=require('socket') local SBS_IP_address = '192.168.178.22' local SBS_CLI_port = 9090 local playerid = '00:04:20:XX:XX:XX' local remote_name = 'Onkyo_RC-738M' -- as defined in the LIRC configuration file for this remote local command_name = 'PWR' -- as defined in the LIRC configuration file for this remote local client = socket.connect( SBS_IP_address, SBS_CLI_port ) function sendIR( device_MAC, remote, command ) client:send( device_MAC .. ' irblaster send ' .. remote .. ' ' .. command .. '\n' ) client:receive() end sendIR( playerid, remote_name, command_name )
Successfully tested with: SBS 7.3.2, IRBlaster/IR-Learning wizard 5.4, Skymaster DVR 7400.
[edit] Squeezebox Control beta plugin (by MCV/radarengineer)
http://forum.micasaverde.com/index.php/topic,10108.0.html
http://forum.micasaverde.com/index.php?topic=5097.msg28878#msg28878
[edit] LOUIS4Vera
http://forum.micasaverde.com/index.php?topic=5232.0
[edit] LIRC2LuupDevice4SBS
http://forum.micasaverde.com/index.php?topic=5709.0
[edit] SAD - Squeezebox Server Announcement Device
Old implementation: http://forum.micasaverde.com/index.php?topic=6952.0
New implementation (LIFO queue per player, luup.sleep replaced with luup.call_delay; copy into the 'Startup Lua' window; should be rewritten with coroutines ...):
--------------------------------------------------------------------------------------------------- -- V1.2 LMS_players = {} --------------------------------------------------------------------------------------------------- function LMS_CLI( server_ip, server_port, player_id, cmd ) local socket = require( 'socket' ) local client = socket.connect( server_ip, server_port ) client:send( player_id .. ' ' .. cmd .. '\n' ) local res = client:receive() client:close() return res end -- LMS_CLI --------------------------------------------------------------------------------------------------- function LMS_Say( LMS_ip , -- IP address of LMS LMS_port , -- CLI Port of LMS (default: 9090) player_id , -- MAC address of player message1 , -- line 1 message2 , -- line 2 message_duration, -- in seconds file , -- audio announcement file_duration , -- duration of announcement in seconds repeats ) -- number of announcements -- V1.4 catch empty announcement (would result in a stuck queue ...) if ( file ~= '' ) and ( file ~= nil ) then if LMS_players[ player_id ] == nil then LMS_players[ player_id ] = {} end if LMS_players[ player_id ].is_saying -- nil is false then local queue_index = LMS_players[ player_id ].waiting_in_queue or 0 queue_index = queue_index + 1 LMS_players[ player_id ].waiting_in_queue = queue_index if LMS_players[ player_id ].queue == nil then LMS_players[ player_id ].queue = {} end if LMS_players[ player_id ].queue[ queue_index ] == nil then LMS_players[ player_id ].queue[ queue_index ] = {} end LMS_players[ player_id ].queue[ queue_index ].LMS_ip = LMS_ip LMS_players[ player_id ].queue[ queue_index ].LMS_port = LMS_port LMS_players[ player_id ].queue[ queue_index ].message1 = message1 LMS_players[ player_id ].queue[ queue_index ].message2 = message2 LMS_players[ player_id ].queue[ queue_index ].message_duration = message_duration LMS_players[ player_id ].queue[ queue_index ].file = file LMS_players[ player_id ].queue[ queue_index ].file_duration = file_duration LMS_players[ player_id ].queue[ queue_index ].repeats = repeats else LMS_players[ player_id ].is_saying = true if LMS_players[ player_id ].current_cmd == nil then LMS_players[ player_id ].current_cmd = {} end LMS_players[ player_id ].current_cmd.LMS_ip = LMS_ip LMS_players[ player_id ].current_cmd.LMS_port = LMS_port LMS_players[ player_id ].current_cmd.file = file LMS_players[ player_id ].current_cmd.file_duration = file_duration LMS_players[ player_id ].current_cmd.repeats = repeats if LMS_players[ player_id ].current_state == nil then LMS_players[ player_id ].current_state = {} end LMS_players[ player_id ].current_state.power = LMS_CLI( LMS_ip, LMS_port, player_id, 'power ?' ) LMS_players[ player_id ].current_state.track = LMS_CLI( LMS_ip, LMS_port, player_id, 'playlist index ?' ) LMS_players[ player_id ].current_state.offset = LMS_CLI( LMS_ip, LMS_port, player_id, 'time ?' ) LMS_players[ player_id ].current_state.mode = LMS_CLI( LMS_ip, LMS_port, player_id, 'mode ?' ) if ( message1 ~= '' ) and ( message1 ~= nil ) and ( message_duration > 0 ) then LMS_CLI( LMS_ip, LMS_port, player_id, 'display ' .. tostring(message1) .. ' ' .. tostring(message2) .. ' ' .. tostring( message_duration ) ) luup.call_delay( 'LMS_Say_play_file', message_duration, player_id ) else LMS_Say_play_file( player_id ) end end end end -- LMS_Say --------------------------------------------------------------------------------------------------- function LMS_Say_play_file( player_id ) local cmd = LMS_players[ player_id ].current_cmd local state = LMS_players[ player_id ].current_state if ( cmd.file ~= '' ) and ( cmd.file ~= nil ) and ( cmd.repeats > 0 ) then -- Add announcement file to playlist local playlist_add = LMS_CLI( cmd.LMS_ip, cmd.LMS_port, player_id, 'playlist add ' .. cmd.file ) -- V1.1: Sometimes type( state.tracks_total ) is a function ... -- V1.2: countdown local count_down = 5 repeat -- V1.5: bugfix state.tracks_total = LMS_CLI( cmd.LMS_ip, cmd.LMS_port, player_id, 'playlist tracks ?' ) count_down = count_down - 1 -- V1.5: bugfix until ( type( state.tracks_total ) == 'string' ) or ( count_down < 1 ) -- V1.5: bugfix state.tracks_total = tonumber( string.match( state.tracks_total, '%s(%d+)' ) ) LMS_Say_play_file_execute( player_id ) else LMS_check_queue( player_id ) end end -- LMS_Say_play_file --------------------------------------------------------------------------------------------------- function LMS_Say_play_file_execute( player_id ) local cmd = LMS_players[ player_id ].current_cmd local state = LMS_players[ player_id ].current_state -- V1.5: bugfix local playlist_set = LMS_CLI( cmd.LMS_ip, cmd.LMS_port, player_id, 'playlist index ' .. tostring( state.tracks_total - 1 ) ) cmd.repeats = cmd.repeats - 1 if cmd.repeats >= 0 then luup.call_delay( 'LMS_Say_play_file_execute', cmd.file_duration, player_id ) else LMS_check_queue( player_id ) end end -- LMS_Say_play_file_execute --------------------------------------------------------------------------------------------------- function LMS_check_queue( player_id ) local cmd = LMS_players[ player_id ].current_cmd local state = LMS_players[ player_id ].current_state -- Restore previous state of player -- V1.5: bugfix local playlist_del = LMS_CLI( cmd.LMS_ip, cmd.LMS_port, player_id, 'playlist delete ' .. tostring( state.tracks_total - 1 ) ) local playlist_set = LMS_CLI( cmd.LMS_ip, cmd.LMS_port, '' , state.track ) local time_set = LMS_CLI( cmd.LMS_ip, cmd.LMS_port, '' , state.offset ) local mode_set = LMS_CLI( cmd.LMS_ip, cmd.LMS_port, '' , state.mode ) local power_set = LMS_CLI( cmd.LMS_ip, cmd.LMS_port, '' , state.power ) local waiting = LMS_players[ player_id ].waiting_in_queue or 0 -- Check queue if waiting > 0 then local q = LMS_players[ player_id ].queue[ waiting ] LMS_players[ player_id ].waiting_in_queue = waiting - 1 LMS_players[ player_id ].is_saying = false LMS_Say( q.LMS_ip , q.LMS_port , player_id , q.message1 , q.message2 , q.message_duration, q.file , q.file_duration , q.repeats ) else LMS_players[ player_id ].is_saying = false end end -- LMS_check_queue --------------------------------------------------------------------------------------------------- -- V1.3 'repair' a stuck queue max_LMS_queue_length = 5 function LMS_queues_watchdog() if type( LMS_players ) == 'table' then for mac, _ in pairs( LMS_players ) do local w_i_q = LMS_players[ mac ].waiting_in_queue if ( w_i_q or 0 ) > max_LMS_queue_length then LMS_players[ mac ].waiting_in_queue = 0 LMS_players[ mac ].is_saying = false end end end luup.call_delay( 'LMS_queues_watchdog', 5 * 60, '' ) end -- LMS_queues_watchdog luup.call_delay( 'LMS_queues_watchdog', 70, '' ) ------------------------------------------------------------------------------------------------------------
[edit] SPB - Squeezebox Preset Button device
SPB maps preset buttons to Luup events.
http://forum.micasaverde.com/index.php/topic,9059.0.html
[edit] USP - Unified Squeezebox Plugin (Technology demo only)
http://forum.micasaverde.com/index.php/topic,10020.0.html
[edit] squeezedVera and squeezedVeraScenes
squeezedVera is a plugin for the Logitech Squeezebox, and it gives you the possibility to run scripts in different ways that can control your z-wave devices through Vera.
squeezedVeraScenes will run the same scripts as squeezedVera but here you define conditions for when they shall run in a configuration file, e.g at sunset on Mondays and Tuesdays. You can also define different scenes with different behaviour.
http://forum.micasaverde.com/index.php/topic,1047.0.html
[edit] Morphing the Sonos plugin into a Squeezebox plugin
http://forum.micasaverde.com/index.php/topic,9532.0.html
[edit] Importing LMS devices into MiOS
Use Whitebear Media Server or the native UPnP support in LMS 7.7.2+ to import your LMS devices into MiOS:
http://forum.micasaverde.com/index.php/topic,10220.0.html
[edit] Using Google's TTS engine for announcements
Requirement: http://wiki.micasaverde.com/index.php/Squeezebox#SAD_-_Squeezebox_Server_Announcement_Device
local lul_temp = luup.variable_get("urn:upnp-org:serviceId:TemperatureSensor1","CurrentTemperature", 111) if ( tonumber( lul_temp ) > 25 ) or ( luup.sunrise() - os.time() > 86400 - 300 ) then os.execute( 'cd /tmp; wget -U Mozilla -O GHBewAnn.mp3 "http://translate.google.com/translate_tts?tl=de&q=Gewaechshaus+wird+bewaessert.+Innentemperatur:+'..tostring( lul_temp )..'+Grad+Celsius."; ftpput -u **** -p **** 192.168.x.y public/HA_Announcements/GHBewAnn.mp3 GHBewAnn.mp3' ) SBS_announcement( '192.168.a.b' , 9090 , '00:04:20:xx:xx:xx' , 'Gewaechshaus%20wird%20bewaessert' , tostring(lul_temp)..'%20Grad%20Celsius' , 5 , '/volume1/public/HA_Announcements/GHBewAnn.mp3', 10 ) luup.call_action( "urn:upnp-ap15e-com:serviceId:SND1", "SendMail", { subject = 'Gewaechshaus wird bewaessert ('..tostring(lul_temp)..')', body = os.date('%Y-%m-%d %H:%M:%S '..os.time()) }, 25 ) end
or even simpler:
<MAC address> playlist play http://translate.google.com/translate_tts?tl=en&q=Just+a+test
[edit] Controlling the BASETech RGB LED light bulb
http://wiki.micasaverde.com/index.php/BASETech_RGB_LED
[edit] Squeezebox clone
http://wiki.micasaverde.com/index.php/Raspberry_Pi_-_Interfacing_with_Vera#Squeezebox