[_CODE_] SAD - Squeezebox Server Announcement Device V0.1

EOL, unsupported.

Proof of concept:

function SBS_announcement( SBS_ip          ,   -- IP address of SBS 
                           SBS_port        ,   -- CLI Port of SBS (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

 local socket=require('socket')
 local client = socket.connect( SBS_ip, SBS_port )

 function SBS_CLI( cmd )

  client:send( cmd .. '\n' )
  return client:receive()

 end -- SBS_CLI

 if ( message1 ~= '' ) and ( message1 ~= nil )
  then
   SBS_CLI( player_id .. ' display ' .. tostring(message1) .. ' ' .. tostring(message2) .. ' ' .. tostring( message_duration ) )
   luup.sleep( message_duration * 1000 )
  end
 
 if ( file ~= '' ) and ( file ~= nil )
  then

   -- Save current state of player

   local cur_power     = SBS_CLI( player_id .. ' power ?'            )
   local cur_track     = SBS_CLI( player_id .. ' playlist index ?'   )
   local cur_offset    = SBS_CLI( player_id .. ' time ?'             )
   local cur_mode      = SBS_CLI( player_id .. ' mode ?'             )

   -- Add announcement file to playlist

   local playlist_add = SBS_CLI( player_id .. ' playlist add file://' .. file )
   local tracks       = SBS_CLI( player_id .. ' playlist tracks ?'            )

   tracks = tonumber( string.match( tracks, '%s(%d+)' ) )

   -- Play announcement

   local playlist_set = SBS_CLI( player_id .. ' playlist index ' .. tracks-1 )

   luup.sleep( file_duration * 1000 )
   
   -- Restore previous state of player 

   local playlist_del = SBS_CLI( player_id .. ' playlist delete ' .. tracks-1 )
   local playlist_set = SBS_CLI( cur_track   )
   local time_set     = SBS_CLI( cur_offset  )
   local mode_set     = SBS_CLI( cur_mode    )
   local power_set    = SBS_CLI( cur_power   )

  end

 end -- SBS_announcement


SBS_announcement( '192.168.178.22'               , 
                  9090                           , 
                  '00:04:20:XX:XX:XX'            , 
                  'Text%20for%20Line1'           , 
                  'Text%20for%20Line2'           , 
                  3                              , 
                  '/volume1/public/Musik/anr.wav',
                  5 )

tbc.

Sorry i m new in luup plug in…

Should I just paste under luup in a scene?

Thank you
Regards
Matteo

UI4:
Just paste the code into the ‘MiOS developers’ → ‘Edit Startup Lua’ window, save your changes, create a new scene and put the call to [tt]SBS_announcement[/tt] into the ‘Luup’ tab.

Hi all

I’ve followed the instructions above and added the code to my LUA Startup

and then added the following to the scene I want to run

SBS_announcement( ‘192.168.1.66’ ,
9090 ,
‘00:04:20:27:db:75’ ,
‘This%20Is%20A%20Vera’ ,
‘Announcement’ ,
5 ,
‘playlist play http://translate.google.com/translate_tts?tl=en&q=Just+a+test’,
5 )

I get the text message to appear on my squeezebox screen but it won’t play the google TTS

Any ideas

Cheers

m0jon

Hi All

Finally got this to work with a lot of help from a certain friend

  1. Load this code into apps > develop apps > Edit Startup Lua

[code]function SBS_announcement( SBS_ip , – IP address of SBS
SBS_port , – CLI Port of SBS (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

local socket=require(‘socket’)
local client = socket.connect( SBS_ip, SBS_port )

function SBS_CLI( cmd )

client:send( cmd … ‘\n’ )
return client:receive()

end – SBS_CLI

if ( message1 ~= ‘’ ) and ( message1 ~= nil )
then
SBS_CLI( player_id … ’ display ’ … tostring(message1) … ’ ’ … tostring(message2) … ’ ’ … tostring( message_duration ) )
luup.sleep( message_duration * 1000 )
end

if ( file ~= ‘’ ) and ( file ~= nil )
then

– Save current state of player

local cur_power = SBS_CLI( player_id … ’ power ?’ )
local cur_track = SBS_CLI( player_id … ’ playlist index ?’ )
local cur_offset = SBS_CLI( player_id … ’ time ?’ )
local cur_mode = SBS_CLI( player_id … ’ mode ?’ )

– Add announcement file to playlist

llocal playlist_add = SBS_CLI( player_id … ’ playlist add ’ … file )
local tracks = SBS_CLI( player_id … ’ playlist tracks ?’ )

tracks = tonumber( string.match( tracks, ‘%s(%d+)’ ) )

– Play announcement

local playlist_set = SBS_CLI( player_id … ’ playlist index ’ … tracks-1 )

luup.sleep( file_duration * 1000 )

– Restore previous state of player

local playlist_del = SBS_CLI( player_id … ’ playlist delete ’ … tracks-1 )
local playlist_set = SBS_CLI( cur_track )
local time_set = SBS_CLI( cur_offset )
local mode_set = SBS_CLI( cur_mode )
local power_set = SBS_CLI( cur_power )

end

end – SBS_announcement

[/code]

You will notice that I have removed the bottom section

SBS_announcement( ‘192.168.178.22’ ,
9090 ,
‘00:04:20:XX:XX:XX’ ,
‘Text%20for%20Line1’ ,
‘Text%20for%20Line2’ ,
3 ,
‘/volume1/public/Musik/anr.wav’,
5 )

other wise every time you reload vera she will start speaking

  1. Once loaded click GO the SAVE and once saved RELOAD

  2. Then in a scene of your choice add

SBS_announcement( '192.168.178.22' , 9090 , '00:04:20:XX:XX:XX' , 'Text%20for%20Line1' , 'Text%20for%20Line2' , 3 , 'http://translate.google.com/translate_tts?tl=en&q=The%20garage%20lights%20are%20now%20on', 5 )
Changing the IP address to your squeezebox servers address and add the mac address of your player

  1. save lua > save scene and then click run

Any problems give me a shout

m0jon

Thanks !! It’s perfect !

Just one error with two l in the line :

llocal playlist_add = SBS_CLI( player_id … ’ playlist add ’ … file )

Hello,

A slightly modified version, which received:
[ul][li]an array of messages for the audio announcement, useful for long message[/li]
[li]an optional maximum duration message, [/li]
[li]and a optional volume announcement.[/li][/ul]

The audio annoucement duration is automatically evaluate, play until the squeezebox stop playing or until the maximum duration is reached (120s).

I used it with squeezeplug (http://www.squeezeplug.eu/) on raspberry pi (http://www.raspberrypi.org/), don’t know if it work on a real skeezebox.

You may have to change the language used in the template url (tl=en into tl=fr for French speaking).

[code]function SBS_announcement(SBS_ip, – IP address of SBS
SBS_port, – CLI Port of SBS (default: 9090)
player_id, – MAC address or IP address of player
message1, – line 1
message2, – line 2
message_duration, – in seconds
audio_messages, – audio announcements, max segment length : 100 characters,
– this is a Google limitation
volume, – announcement volume, optional, default: keep current
audio_duration) – maximum, duration of announcement in seconds, optional, default: 120s
local socket=require(‘socket’)
local client = socket.connect(SBS_ip, SBS_port)
local cur_power, cur_track, tracks, cur_offset, cur_mode, cur_vol

if audio_duration == nil then
audio_duration = 120
end

function escape (s)
s = string.gsub(s, “%c”, function (c)
return string.format(“%%%02X”, string.byte(c))
end)
s = string.gsub(s, " ", “+”)
return s
end

function SBS_CLI(cmd)
if cmd == nil then
return nil
end
client:send(player_id … ’ ’ … cmd … ‘\n’)
return string.sub(client:receive(), 28)
end – SBS_CLI

if (message1 ~= ‘’) and (message2 ~= nil) then
SBS_CLI('display ’ … tostring(message1) … ’ ’ … tostring(message2) … ’ ’ … tostring(message_duration))
luup.sleep(message_duration * 1000)
end
if (audio_messages ~= nil) then
– Save current state of player
cur_power = SBS_CLI(‘power ?’)
SBS_CLI(‘power 1’)
luup.sleep(1000)
cur_track = SBS_CLI(‘playlist index ?’)
cur_offset = SBS_CLI(‘time ?’)
cur_mode = SBS_CLI(‘mode ?’)
if string.find(cur_mode, ‘pause’) ~= nil then
cur_mode = ‘mode stop’
end
cur_vol = SBS_CLI(‘mixer volume ?’)
tracks = SBS_CLI(‘playlist tracks ?’)
tracks = tonumber(string.match(tracks, ‘%s(%d+)’))
– Add announcement messages to playlist
for i,v in ipairs(audio_messages) do
v = ‘http://translate.google.com/translate_tts?tl=en&ie=UTF8&q=’ … escape(v)
SBS_CLI('playlist add ’ … v)
end
– Play announcement
if volume ~= nil then
SBS_CLI('mixer volume ’ … tostring(volume))
end
SBS_CLI('playlist index ’ … tracks)
SBS_CLI(‘play’)
while audio_duration > 0 do
luup.sleep(1000)
audio_duration = audio_duration - 1
if string.find(SBS_CLI(‘mode ?’), ‘play’) == nil then
audio_duration = 0
end
end
– Restore previous state of player
for i=1,table.getn(audio_messages) do
SBS_CLI('playlist delete ’ … tracks)
end
SBS_CLI(cur_vol)
SBS_CLI(cur_track)
SBS_CLI(cur_offset)
SBS_CLI(cur_power)
SBS_CLI(cur_mode)
end
SBS_CLI(‘exit’)
end – SBS_announcement
[/code]

Usage examples:

messages = {} ... table.insert(messages, 'Start report') ... table.insert(messages, 'End report.') SBS_announcement('192.168.178.22', 9090, '192.168.178.24', nil, nil, 0, messages)

SBS_announcement('192.168.178.22', 9090, '192.168.178.24', nil, nil, 0, {'Start report, ..., 'End report.'})

Enjoy,

JF

After some tests and information send by private message, it appear that any long running function will delay all others action.

So I update the code to use luup_call_delay instead of the loop with the sleep call. Only for the audio message part.
So, now, even with long audio message, the system continue to respond normally.

[code]function SBS_announcement(SBS_ip, – IP address of SBS
SBS_port, – CLI Port of SBS (default: 9090)
player_id, – MAC address or IP address of player
message1, – line 1
message2, – line 2
message_duration, – in seconds
audio_messages, – audio announcements, max segment length : 100 characters,
– this is a Google limitation
volume, – announcement volume, optional, default: keep current
audio_duration) – maximum, duration of announcement in seconds, optional, default: 120s
local socket=require(‘socket’)
local client = socket.connect(SBS_ip, SBS_port)
local cur_power, cur_track, tracks, cur_offset, cur_mode, cur_vol

if audio_duration == nil then
audio_duration = 120
end

function escape (s)
s = string.gsub(s, “%c”, function (c)
return string.format(“%%%02X”, string.byte(c))
end)
s = string.gsub(s, " ", “+”)
return s
end

function SBS_CLI(cmd)
if cmd == nil then
return nil
end
client:send(player_id … ’ ’ … cmd … ‘\n’)
return string.sub(client:receive(), 28)
end – SBS_CLI

function checkPlayingOrTimeout(rfu)
if audio_duration > 0 then
audio_duration = audio_duration - 1
if string.find(SBS_CLI(‘mode ?’), ‘play’) ~= nil then
luup.call_delay(“checkPlayingOrTimeout”, 1, rfu)
return
end
end
– Restore previous state of player
for i=1,table.getn(audio_messages) do
SBS_CLI('playlist delete ’ … tracks)
end
SBS_CLI(cur_vol)
SBS_CLI(cur_track)
SBS_CLI(cur_offset)
SBS_CLI(cur_power)
SBS_CLI(cur_mode)
SBS_CLI(‘exit’)
end

if (message1 ~= ‘’) and (message2 ~= nil) then
SBS_CLI('display ’ … tostring(message1) … ’ ’ … tostring(message2) … ’ ’ … tostring(message_duration))
luup.sleep(message_duration * 1000)
end
if (audio_messages ~= nil) then
– Save current state of player
cur_power = SBS_CLI(‘power ?’)
SBS_CLI(‘power 1’)
luup.sleep(1000)
cur_track = SBS_CLI(‘playlist index ?’)
cur_offset = SBS_CLI(‘time ?’)
cur_mode = SBS_CLI(‘mode ?’)
if string.find(cur_mode, ‘pause’) ~= nil then
cur_mode = ‘mode stop’
end
cur_vol = SBS_CLI(‘mixer volume ?’)
tracks = SBS_CLI(‘playlist tracks ?’)
tracks = tonumber(string.match(tracks, ‘%s(%d+)’))
– Add announcement messages to playlist
for i,v in ipairs(audio_messages) do
v = ‘http://translate.google.com/translate_tts?tl=en&ie=UTF8&q=’ … escape(v)
SBS_CLI('playlist add ’ … v)
end
– Play announcement
if volume ~= nil then
SBS_CLI('mixer volume ’ … tostring(volume))
end
SBS_CLI('playlist index ’ … tracks)
SBS_CLI(‘play’)
luup.call_delay(“checkPlayingOrTimeout”, 1, ‘’)
end
end – SBS_announcement
[/code]

JF
ps.
I can’t reply to private message, or didn’t find how to do…

So this last piece of code if I understand correctly if inserted into vera.

Will allow me to make announcements TTS and display notification on the client? what sort of squeeze clients support displaying the message?

Also what happens after the announcement will the previous item continue playing?

I’d really like to incorporate TTS into my Squeezebox for annoucements. Sadly I’ve tried all the code snippets and no go on UI5. Anyone that can assist with a step by step?

I figured this out with a little help from friends here on the forums, thanks!

could you link to how you did it?

Sure,

Step 1) Download and copy the the TXT file attached below called SAD - this is taken from the wiki on the SAD device, http://wiki.micasaverde.com/index.php/Squeezebox#SAD_-_Squeezebox_Server_Announcement_Device. You do NOT edit this file at all, just paste it in and save it by clicking go.

Step 2) In UI5, go to APPS, Develop APPS, and click Edit Startup Lua

Step 3) Paste in all that code from the SAD txt file. Click GO. Vera will reload

Step 4) Now create a scene. In the LUUP area, paste in the txt from the file attached below called SAD-SAY

Step 5) Edit the LMS IP (This is your Squeezebox server IP), edit the MAC address of the player you want to announce this. Since my Squeezebox devices are all synched, it really doesnt matter which one I announce it on, they all say it. Edit the text in there what you want to display on the player screen, make sure you use the %20 between words. When editing the speech, make sure you put the + between the words.

Run the scene, and boom, it plays.

thanks

That was good of you… will have some fun with this…