Squeezebox Audio Alert Script

Here is a script which uses “playlist save” and “playlist resume” (rather than trying to add the alert song to the end of the playlist and then removing it once it stops playing). I did some testing on this script and it seems to work pretty good. Let me know if you see any issues.

NOTE: This script takes an additional argument “playlist_name” as the first argument. You will want this to be a different value for each player, so you could just pass in the player name. It also takes an optional parameter to not restore the playlist (restore_playlist=0 only works if music was previously stopped… see comments in script below for details).

#!/bin/bash

#squeezebox_alert.sh

#NOTE: Edit "user", "pass", ip and port below
JSONRPC="http://user:[email protected]:9000/jsonrpc.js"

#Example command arguments
#playlist_name="bedroom"
#mac="00:04:20:01:02:03"
#alert_song="//volume1//homeassistant//mp3//beep.mp3"
#alert_volume=60
#NOTE: restore_playlist is optional.(defaults to 1)
#      restore_playlist=0 only works if music was previously stopped
#restore_playlist=0

playlist_name=$1
mac=$2
alert_song=$3
alert_volume=$4
restore_playlist=${5:-1}

echo "restore_playlist=$restore_playlist"

#get power state
power=$(curl -X GET -H "Content-Type: application/json" \
                  -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["power","?"]]}' \
                  $JSONRPC | jq '.result._power')

prev_power=0
if [[ $power =~ .*1.* ]] ; then
  prev_power=1 
fi
echo "prev_power=$prev_power"

#get play mode
mode=$(curl -X GET -H "Content-Type: application/json" \
                 -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["mode","?"]]}' \
                 $JSONRPC | jq '.result._mode')

prev_playmode=0
if [[ $mode =~ .*play.* ]] ; then
  prev_playmode=1
fi	 
echo "prev_playmode=$prev_playmode"

noplay=1
prev_time=0
if [ $prev_playmode -eq 1 ] ; then
  noplay=0
  
  # pause currently playing song
  curl -X GET -H "Content-Type: application/json" \
       -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["pause"]]}' $JSONRPC
  echo "pause currently playing song"

  # get paused time
  prev_time=$(curl -X GET -H "Content-Type: application/json" \
                   -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["time","?"]]}' \
                   $JSONRPC | jq '.result._time')
  echo "prev_time=$prev_time"
fi

# save current playlist
curl -X GET -H "Content-Type: application/json" \
     -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["playlist","save","'"$playlist_name"'","silent:1"]]}' $JSONRPC
echo "save current playlist"

# GET SETTINGS TO RESTORE AFTER PLAYING ALERT SONG
#get current volume 
prev_volume=$(curl -X GET -H "Content-Type: application/json" \
                   -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["mixer","volume","?"]]}' \
                   $JSONRPC | jq '.result._volume')
echo "prev_volume=$prev_volume"

#get current repeat setting
prev_repeat=$(curl -X GET -H "Content-Type: application/json" \
                   -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["playlist","repeat","?"]]}' \
                   $JSONRPC | jq '.result._repeat')
echo "prev_repeat=$prev_repeat"

# SET SETTINGS FOR ALERT SONG
#set alert_volume to command argument value
curl -X GET -H "Content-Type: application/json" \
     -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["mixer","volume",'$alert_volume']]}' $JSONRPC
echo "set alert_volume"

#set repeat setting to 0
curl -X GET -H "Content-Type: application/json" \
     -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["playlist","repeat",0]]}' $JSONRPC
echo "set repeat_setting to 0"

#play alert song (this will clear current playlist)
curl -X GET -H "Content-Type: application/json" \
     -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["playlist","play","'"$alert_song"'"]]}' $JSONRPC
echo "play alert song"

# WAIT FOR ALERT SONG TO STOP PLAYING
echo "wait for alert song to stop playing"
cur_mode="play"
while [[ $cur_mode =~ .*play.* ]]; do
  sleep 1
  cur_mode=$(curl -X GET -H "Content-Type: application/json" \
              -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["mode","?"]]}' \
              $JSONRPC | jq '.result._mode')
done

echo "alert song stopped playing"

# RESTORE PREVIOUS SETTINGS
#restore prev_volume setting
curl -X GET -H "Content-Type: application/json" \
     -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["mixer","volume",'"$prev_volume"']]}' $JSONRPC
echo "restore prev_volume setting"

#restore prev_repeat setting
curl -X GET -H "Content-Type: application/json" \
     -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["playlist","repeat",'"$prev_repeat"']]}' $JSONRPC
echo "restore prev_repeat setting"

# resume previous playlist (always resume if previously playing)
if [ $prev_playmode -eq 1 ] || [ $restore_playlist -eq 1 ] ; then
  curl -X GET -H "Content-Type: application/json" \
       -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["playlist","resume","'"$playlist_name"'","noplay:'$noplay'"]]}' $JSONRPC
  echo "resume previous playlist"
fi

# RESUME PREVIOUSLY PLAYING MUSIC
if [ $prev_playmode -eq 1 ] ; then
  #skip ahead in song to prev_time
  curl -X GET -H "Content-Type: application/json" \
       -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["time",'"$prev_time"']]}' $JSONRPC
  echo "skip ahead in song to prev_time"
fi

#restore prev_power setting
if [ $prev_power -eq 0 ] ; then
  echo "prev_power setting was off, power off"
  curl -X GET -H "Content-Type: application/json" \
       -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["power",0]]}' $JSONRPC
fi
3 Likes

@smazman, this is great!

Seems to work fine now

I need some help: I would like to know how you integrate this in your ha. Do you all only use predefined alarms? I would like to use it like I do it with the “normal” tts with daily changing text (with temperature, humidity, etc) but I don’t understand how to do this with this script.

@mrMuppet, I’m not sure how to do this either. I am currently just using pre-defined audio alerts. I was hoping the TTS component saved the mp3 file in the cache directory with a file name that is equal to the text string (for example, “the_temperature_is_70_degrees.mp3”)… but this doesn’t seem to be the case. There has to be some way to get the last file name from the TTS component. Worst case you could pre-save a hundred or so mp3 files locally with every possible degree and humidity value. :slight_smile: The ideal solution would probably be for the media player component to handle alerts (saving and resuming the current playlist)… but this will be very player dependent so it won’t be easy to implement.

I wonder if this would work… use a chromecast audio (or some other source) just for TTS audio alerts. Connect both the chromecast audio and your squeezebox to the same audio input on your receiver via an audio splitter (Y) cable. You could pause the music on your squeezebox… then play the TTS alert on the chromecast… and then resume the music on the squeezebox. Not elegant, but I think it would work.

The solution i still think of is having a way to save the playlist and song info temporarily in a file. Than i could save it, play via normal TTS and then restore playlist-info from the file…

@mrMuppet: You mean like this?

I updated the script so it will save the settings file (player_name.txt) in the same directory as the script files. See the configuration.yaml example below for an example of how to call the scripts.

NOTE: As before, you will need to update the “JSONRPC=” line in both of the script files.


Example configuration.yaml entries (not complete)

automation:
  - alias: "Play lamp on audio alert"
    trigger:
      - platform: state
        entity_id: switch.lamp
        to: 'on'
    action:
      - service: homeassistant.turn_on
        entity_id: script.play_light_on_alert_in_kitchen

shell_command:
  playlist_save_kitchen:    bash /volume1/homeassistant/squeezebox_alert_save_playlist.sh "kitchen" "00:04:20:01:02:03" 65
  playlist_restore_kitchen: bash /volume1/homeassistant/squeezebox_alert_restore_playlist.sh "kitchen" "00:04:20:01:02:03"

script:
  play_light_on_alert_in_kitchen:
    alias: "Play light alert"
    sequence:
      - service: shell_command.playlist_save_kitchen
      - service: tts.google_say
        entity_id: media_player.kitchen
        data:
           message: 'The lamp is on.'
      - service: shell_command.playlist_restore_kitchen

squeezebox_alert_save_playlist.sh

#!/bin/bash

#squeezebox_alert_save_playlist.sh

#NOTE: Edit "user", "pass", ip and port below
JSONRPC="http://user:[email protected]:9000/jsonrpc.js"

#Example command arguments
#playlist_name="bedroom"
#mac="00:04:20:01:02:03"
#alert_volume=60

playlist_name=$1
mac=$2
alert_volume=$3

#get power state
power=$(curl -X GET -H "Content-Type: application/json" \
                  -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["power","?"]]}' \
                  $JSONRPC | jq '.result._power')

prev_power=0
if [[ $power =~ .*1.* ]] ; then
  prev_power=1 
fi
echo "prev_power=$prev_power"

#get play mode
mode=$(curl -X GET -H "Content-Type: application/json" \
                 -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["mode","?"]]}' \
                 $JSONRPC | jq '.result._mode')

prev_playmode=0
if [[ $mode =~ .*play.* ]] ; then
  prev_playmode=1
fi	 
echo "prev_playmode=$prev_playmode"

noplay=1
prev_time=0
if [ $prev_playmode -eq 1 ] ; then
  noplay=0
  
  # pause currently playing song
  curl -X GET -H "Content-Type: application/json" \
       -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["pause"]]}' $JSONRPC
  echo "pause currently playing song"

  # get paused time
  prev_time=$(curl -X GET -H "Content-Type: application/json" \
                   -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["time","?"]]}' \
                   $JSONRPC | jq '.result._time')
  echo "prev_time=$prev_time"
fi

# save current playlist
curl -X GET -H "Content-Type: application/json" \
     -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["playlist","save","'"$playlist_name"'","silent:1"]]}' $JSONRPC
echo "save current playlist"

# GET SETTINGS TO RESTORE AFTER PLAYING ALERT SONG
#get current volume 
prev_volume=$(curl -X GET -H "Content-Type: application/json" \
                   -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["mixer","volume","?"]]}' \
                   $JSONRPC | jq '.result._volume')
echo "prev_volume=$prev_volume"

#get current repeat setting
prev_repeat=$(curl -X GET -H "Content-Type: application/json" \
                   -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["playlist","repeat","?"]]}' \
                   $JSONRPC | jq '.result._repeat')
echo "prev_repeat=$prev_repeat"

#write settings to file
DIRECTORY=$(cd `dirname $0` && pwd)
echo "Save settings to file: $DIRECTORY/$playlist_name.txt"
> "$DIRECTORY/$playlist_name.txt"
printf '%s\n%s\n%s\n%s\n%s\n' $prev_power $prev_playmode $prev_time $prev_volume $prev_repeat > "$DIRECTORY//$playlist_name.txt"

# SET SETTINGS FOR ALERT SONG
#set alert_volume to command argument value
curl -X GET -H "Content-Type: application/json" \
     -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["mixer","volume",'$alert_volume']]}' $JSONRPC
echo "set alert_volume"

#set repeat setting to 0
curl -X GET -H "Content-Type: application/json" \
     -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["playlist","repeat",0]]}' $JSONRPC
echo "set repeat_setting to 0"

---
squeezebox_alert_restore_playlist.sh
---

#!/bin/bash

#squeezebox_alert_restore_playlist.sh

#NOTE: Edit "user", "pass", ip and port below
JSONRPC="http://user:[email protected]:9000/jsonrpc.js"

#Example command arguments
#playlist_name="bedroom"
#mac="00:04:20:01:02:03"

playlist_name=$1
mac=$2

# WAIT FOR ALERT SONG TO STOP PLAYING
echo "wait for alert song to stop playing"
cur_mode="play"
while [[ $cur_mode =~ .*play.* ]]; do
  sleep 1
  cur_mode=$(curl -X GET -H "Content-Type: application/json" \
          -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["mode","?"]]}' \
          $JSONRPC | jq '.result._mode')
done

echo "alert song stopped playing"

# read settings from file
DIRECTORY=$(cd `dirname $0` && pwd)
echo "Restore settings from file: $DIRECTORY/$playlist_name.txt"
IFS=$'\n' read -d '' -r -a lines < "$DIRECTORY/$playlist_name.txt"
prev_power="${lines[0]}"
prev_playmode="${lines[1]}"
prev_time="${lines[2]}"
prev_volume="${lines[3]}"
prev_repeat="${lines[4]}"
echo "prev_power=$prev_power"
echo "prev_playmode=$prev_playmode"
echo "prev_time=$prev_time"
echo "prev_volume=$prev_volume"
echo "prev_repeat=$prev_repeat"

noplay=1
if [ $prev_playmode -eq 1 ] ; then
  noplay=0
fi

# RESTORE PREVIOUS SETTINGS
#restore prev_volume setting
curl -X GET -H "Content-Type: application/json" \
 -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["mixer","volume",'"$prev_volume"']]}' $JSONRPC
echo "restore prev_volume setting"

#restore prev_repeat setting
curl -X GET -H "Content-Type: application/json" \
 -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["playlist","repeat",'"$prev_repeat"']]}' $JSONRPC
echo "restore prev_repeat setting"

# resume previous playlist
curl -X GET -H "Content-Type: application/json" \
 -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["playlist","resume","'"$playlist_name"'","noplay:'$noplay'"]]}' $JSONRPC
echo "resume previous playlist"

# RESUME PREVIOUSLY PLAYING MUSIC
if [ $prev_playmode -eq 1 ] ; then
  #skip ahead in song to prev_time
  curl -X GET -H "Content-Type: application/json" \
   -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["time",'"$prev_time"']]}' $JSONRPC
  echo "skip ahead in song to prev_time"
fi

#restore prev_power setting
if [ $prev_power -eq 0 ] ; then
  echo "prev_power setting was off, power off"
  curl -X GET -H "Content-Type: application/json" \
   -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["power",0]]}' $JSONRPC
fi
7 Likes

I will try this! Seems to be exactly what I wanted! Thanks alot.

I tried it, but i get

sh squeezebox_alert_save_playlist.sh
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    60    0     0  100    60      0  41124 --:--:-- --:--:-- --:--:-- 60000
curl: (52) Empty reply from server
squeezebox_alert_save_playlist.sh: [[: not found
prev_power=0
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    59    0     0  100    59      0  41143 --:--:-- --:--:-- --:--:-- 59000
curl: (52) Empty reply from server
squeezebox_alert_save_playlist.sh: [[: not found
prev_playmode=0
curl: (52) Empty reply from server
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    69    0     0  100    69      0  44892 --:--:-- --:--:-- --:--:-- 69000
curl: (52) Empty reply from server
prev_volume=
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    72    0     0  100    72      0  49180 --:--:-- --:--:-- --:--:-- 72000
curl: (52) Empty reply from server
prev_repeat=

What can i do?

Edit: A a small file called “.txt” is saved containing only “0 0 0”

Should have read the code!

Now i get:

sh squeezebox_alert_save_playlist.sh “kitchen” “00:04:20:29:6a:0f” 60
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 176 100 99 100 77 62303 48458 --:–:-- --:–:-- --:–:-- 99000
squeezebox_alert_save_playlist.sh: [[: not found
prev_power=0
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 178 100 102 100 76 61519 45838 --:–:-- --:–:-- --:–:-- 99k
squeezebox_alert_save_playlist.sh: [[: not found
prev_playmode=0
{“method”:“slim.request”,“params”:[“00:04:20:29:6a:0f”,[“playlist”,“save”,“kitchen”,“silent:1”]],“id”:1,“result”:{“__playlist_id”:59142}} % Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 198 100 112 100 86 69221 53152 --:–:-- --:–:-- --:–:-- 109k
prev_volume=“60”
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 203 100 114 100 89 77079 60175 --:–:-- --:–:-- --:–:-- 111k
prev_repeat=“0”
{“result”:{},“method”:“slim.request”,“id”:1,“params”:[“00:04:20:29:6a:0f”,[“mixer”,“volume”,“60”]]}set alert_volume
{“params”:[“00:04:20:29:6a:0f”,[“playlist”,“repeat”,“0”]],“id”:1,“method”:“slim.request”,“result”:{}}set repeat_setting to 0

Edit: Tried it with a Spotify playlist and with a “normal” one.

Edit: Volume set does work. kitchen.txt contains only

0
0
0
“0”
“0”

Edit: I think something is wrong with the “if-…”. Perhaps it has to do with my system: its FreeBSD not Linux…

I don’t get this bash variable thing. Can’t get a working if with a curl variable!

I updated the post above with an example of using the script. I also updated the script so the settings file (player_name.txt) will be saved in the same directory as the script files. It works for me on both regular and spotify (remote stream) playlists.

Yeah, you might be having issues due to bash shell differences… this should really be re-written using python. Anyone???

Got it! Didn’t know that there are differences between sh & bash

Now it totally rocks! Thank you!

Ok, good to hear! How are you using it in home assistant? Are you using a “script:” with a “sequence:” like in my example above? Just wondering.

At the moment i’m still testing. Want to use (and already tried) it as a part of an automation. But I’m not sure about this.

Your script is working, but my Squeezeboxes (radio & touch) are completely out of sync after the resume-script. I think its more a squeezebox-problem than a problem of HASS, so i will try to find a solution in the Squeezebox-Forum.

I did some quick tests with synchronization and it seems to work fine for me. In my tests the script was only ever dealing with one player (kitchen). I did a test where the kitchen player was the sync master and one where it was the sync follower. In both tests the alert was played on both players and both players resumed playing music in sync with each other. Check your squeezebox player settings and make sure “Maintain synchronization while playing” option is selected. I am not synchronizing player volume or power… not sure if it matters. In my test I used a SB Classic and a SB Boom. Note, I generally keep synchronization off and didn’t test the script much with synchronization turned on.

@smazman
I´ve notice one bug with the script.
When the playlist is restored it starts playing even if the player was off before.

I´m using your original script not the two with the save/restore ones.

I can’t reproduce the behavior you mentioned, but I made some updates related to power handling in the original script (first post). I also updated the script in post 15 to take an optional parameter to not restore the playlist (so it should allow similar behavior to the script in the first post). Let me know how it goes.

Thank you I´ll try this.

I was a bit unclear before, I´m using the script in post 15.
Did you do any changes to this one except the flag?

Do I understand it right that there are atm 3 different versions?
First post, used by you
15th post, used by me
and the split version used by mrmuppet

Oh ok sorry, I thought you were using the script in the first post. I’m not sure exactly what I updated in the script at post 15 at this point… I updated it a few times now. Grab the current one and let me know if you still see the issue. If so, try running it from the command line and post the output.

I am actually now using both the script at post 15 and the split script… depending on if I want to play a local mp3 or if I want to use TTS.

Just came across this thread and although I’m not a HA user I do use Domoticz and I just published a perl script that does something very similar to what the bash scripts here do. Check out the wiki entry over at Domoticz:

https://www.domoticz.com/wiki/Logitech_Media_Server#Audio_Alerts_via_Squeezebox_Players