Overview
These instructions outline how to create a homekit device to play an internet stream on your Sonos device.
These scripts are used with the CMD4 Plugin for Homebridge.
Cmd4 Script
Play Radio Paradise
playMusic.js
#!/usr/bin/env bash
# rp-sonos-cmd4.sh — Homebridge Cmd4 state_cmd to play/stop Radio Paradise on Sonos
# Usage from Cmd4:
# playRadioParadise.sh "<AccessoryName>" on get
# playRadioParadise.sh "<AccessoryName>" on set <0|1>
#
# accepts BOTH:
# 1) "<Accessory>" on get|set [0|1]
# 2) get|set "<Accessory>" on [0|1]
# SONOS_IP=192.168.1.29 ./playRadioParadise.sh "Radio Paradise (Sonos)" on set 1
set -euo pipefail
# --- Sonos target ---
SONOS_IP="${SONOS_IP:-${SONOS_HOST:-}}"
PORT="${PORT:-1400}"
if [[ -z "${SONOS_IP}" ]]; then
echo "SONOS_IP/SONOS_HOST not set" >&2
exit 2
fi
# --- Stream URL ---
RP_URL="${RP_URL:-http://stream.radioparadise.com/aac-320}"
SONOS_URI="x-rincon-mp3radio://${RP_URL}"
START_VOLUME="${START_VOLUME:-}"
# --- Parse args in either order ---
# Expect either:
# A) ACCESSORY=$1 CHAR=$2 ACTION=$3 VALUE=$4
# B) ACTION=$1 ACCESSORY=$2 CHAR=$3 VALUE=$4
A1="${1:-}"; A2="${2:-}"; A3="${3:-}"; A4="${4:-}"
lower() { echo "${1:-}" | tr '[:upper:]' '[:lower:]'; }
if [[ "$(lower "$A1")" == "get" || "$(lower "$A1")" == "set" ]]; then
ACTION="$(lower "$A1")"
ACCESSORY="$A2"
CHAR="$(lower "$A3")"
VALUE="${A4:-}"
else
ACCESSORY="$A1"
CHAR="$(lower "$A2")"
ACTION="$(lower "$A3")"
VALUE="${A4:-}"
fi
AVT_CTRL="http://${SONOS_IP}:${PORT}/MediaRenderer/AVTransport/Control"
REND_CTRL="http://${SONOS_IP}:${PORT}/MediaRenderer/RenderingControl/Control"
soap_avt() {
local action="$1" body="$2"
curl -sS --fail -X POST "$AVT_CTRL" \
-H 'Content-Type: text/xml; charset="utf-8"' \
-H "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#${action}\"" \
--data-binary "<?xml version=\"1.0\"?>
<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body>${body}</s:Body></s:Envelope>"
}
soap_rc() {
local action="$1" body="$2"
curl -sS --fail -X POST "$REND_CTRL" \
-H 'Content-Type: text/xml; charset="utf-8"' \
-H "SOAPACTION: \"urn:schemas-upnp-org:service:RenderingControl:1#${action}\"" \
--data-binary "<?xml version=\"1.0\"?>
<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body>${body}</s:Body></s:Envelope>"
}
is_playing() {
local resp
resp="$(soap_avt "GetTransportInfo" "<u:GetTransportInfo xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID></u:GetTransportInfo>")" || return 1
echo "$resp" | grep -q "<CurrentTransportState>PLAYING</CurrentTransportState>"
}
start_play() {
soap_avt "SetAVTransportURI" "<u:SetAVTransportURI xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\">
<InstanceID>0</InstanceID><CurrentURI>${SONOS_URI}</CurrentURI><CurrentURIMetaData></CurrentURIMetaData>
</u:SetAVTransportURI>" >/dev/null
if [[ -n "${START_VOLUME}" ]]; then
soap_rc "SetVolume" "<u:SetVolume xmlns:u=\"urn:schemas-upnp-org:service:RenderingControl:1\">
<InstanceID>0</InstanceID><Channel>Master</Channel><DesiredVolume>${START_VOLUME}</DesiredVolume>
</u:SetVolume>" >/dev/null
fi
soap_avt "Play" "<u:Play xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\">
<InstanceID>0</InstanceID><Speed>1</Speed>
</u:Play>" >/dev/null
}
stop_play() {
soap_avt "Stop" "<u:Stop xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\">
<InstanceID>0</InstanceID>
</u:Stop>" >/dev/null || true
}
if [[ "$CHAR" != "on" ]]; then
echo "Unsupported characteristic: ${ACCESSORY}" >&2
exit 1
fi
case "$ACTION" in
get)
if is_playing; then echo 1; else echo 0; fi
;;
set)
if [[ "${VALUE:-0}" == "1" ]]; then
start_play
else
stop_play
fi
;;
*)
echo "Unknown action: $ACTION" >&2; exit 1;;
esac
Homebridge Configuration
config.json
...
{
"platform": "Cmd4",
"name": "Cmd4",
"accessories": [
{
"type": "Lightbulb",
"displayName": "Kitchen Radio Paradise",
"on": "1",
"name": "Kitchen Radio Paradise",
"timeout": 30000,
"polling": true,
"interval": 1000,
"stateChangeResponseTime": 3,
"state_cmd": "SONOS_HOST=192.168.1.99 /homebridge/Cmd4Scripts/playRadioParadise.sh"
}
]
}
...
References
| Reference | URL |
|---|---|
| Cmd4 Plugin for Homebridge | https://github.com/ztalbot2000/homebridge-cmd4 |