Hi all,
After finding a solution to select a source from the SONOS favourites (SONOS: The easiest way of setting playlist or radio streams), I am trying to find a flexible way of controlling SONOS speakers using API requests to run HA scripts.
The following is a working solution:
script.yml
This API request is called from an own Ruby application, which I call myhome_central_api. This Ruby application is able to call various API requests to systems like DigitalStrom, HomeAssistant and Z-way. I use Node-Red to define Alexa commands that call HA rest_commands. These HA rest_commands then call myhome_central_api API requests, which can be scenes combining different systems (DSS, HA, Z-way) to control lights, vacuum cleaners, door locks, smart switches, SONOS speakers and alike.
Because I didn’t get the Alexa skill Plex working in my local environment (it is not connected directly to the Internet), I am trying to achieve my music control in the same way as described above (Alexa -> Node-Red -> HA -> myhome_central_api -> HA -> SONOS).
The working Ruby function calling the HA script to play a certain SONOS favourite in a certain room looks like this:
def sonos_guestroom(hass_script_name, source)
# API call to Home-assistant - sonos guestroom
# curl -X POST -H “Content-Type: application/json” -H “x-ha-access:1234”
# -d ‘{“entity_id”:“script.sonos_guestroom}’ http://hassio:8123/api/services/script/turn_on
url = URI("http://#{@hass_ip}:#{@hass_port}/api/services/script/turn_on")
%x( curl --location --request POST '#{url}' \
-d '{"entity_id": "script.#{hass_script_name}"}' \
-H 'Authorization: Bearer #{@hass_api_token}' )
puts "hass_api_script_turn_on #{hass_script_name} playing #{source}"
return "hass_api_script_turn_on #{hass_script_name} playing #{source}"
end# hass_api_sonos_guestroom
As I mentioned in my initial post, I would like to make this Ruby function more flexible by providing source and volume to the HA script (not working):
def sonos_guestroom_wip(hass_script_name, source)
# API call to Home-assistant - sonos guestroom
# curl -X POST -H “Content-Type: application/json” -H “x-ha-access:1234”
# -d ‘{“entity_id”:“script.sonos_guestroom}’ http://hassio:8123/api/services/script/turn_on
url = URI("http://#{@hass_ip}:#{@hass_port}/api/services/script/turn_on")
%x( curl --location --request POST '#{url}' \
-d '{"entity_id": "script.#{hass_script_name}"}' \
-d '{"source": "#{source}"}' \
-H 'Authorization: Bearer #{@hass_api_token}' )
puts "hass_api_script_turn_on #{hass_script_name} playing #{source}"
return "hass_api_script_turn_on #{hass_script_name} playing #{source}"
end# hass_api_sonos_guestroom
Sounds pretty complicated, but whatever floats your boat
But this I don’t understand:
HA has support for Sonos, Alexa and Node-RED, so I don’t get why you need the intermediate step going to your myhome_central_api. But it’s probably part of a scene that calls different systems as well.
Anyway, to your non-working API call. Not 100% sure, but I think the issue is that you use a separate -d flag for each element of the data for your service instead of combining them into one element. Try this:
def sonos_guestroom_wip(hass_script_name, source)
# API call to Home-assistant - sonos guestroom
# curl -X POST -H “Content-Type: application/json” -H “x-ha-access:1234”
# -d ‘{“entity_id”:“script.sonos_guestroom}’ http://hassio:8123/api/services/script/turn_on
url = URI("http://#{@hass_ip}:#{@hass_port}/api/services/script/turn_on")
%x( curl --location --request POST '#{url}' \
-d '{"entity_id": "script.#{hass_script_name}", "source": "#{source}"}' \
-H 'Authorization: Bearer #{@hass_api_token}' )
puts "hass_api_script_turn_on #{hass_script_name} playing #{source}"
return "hass_api_script_turn_on #{hass_script_name} playing #{source}"
end# hass_api_sonos_guestroom