Skip to main content

Sonos (hc-sonos)

The hc-sonos plugin discovers Sonos speakers on your network, registers them as HomeCore media_player devices, and keeps transport state in sync through MQTT.

It also keeps its own standalone HTTP API. That is intentional. You can use the plugin directly if you want, but once a speaker is registered in HomeCore the preferred automation path is through the HomeCore device ID.

SDK adoption

hc-sonos is built on the official Rust plugin SDK (hc-plugin-sdk-rs) and supports the full management protocol: heartbeat monitoring, remote configuration, and dynamic log level.

What the plugin provides

Each discovered speaker is registered automatically as a media_player device. You do not need to pre-create the device in HomeCore.

For each player, HomeCore can see:

  • playback state such as playing and paused
  • volume and mute state
  • current track title, artist, and album
  • group coordinator and group members
  • available Sonos favorites
  • available Sonos playlists

This means HomeCore rules can target sonos_living_room or sonos_kitchen directly instead of calling a hardcoded speaker URL.

Discovery and automatic registration

hc-sonos uses SSDP discovery and registers speakers as they are found.

If you have no manual overrides configured, the plugin derives a HomeCore device ID from the room name:

Sonos roomHomeCore device ID
Living Roomsonos_living_room
Kitchensonos_kitchen
Officesonos_office

Manual configuration is still useful when you want to:

  • assign a stable custom HomeCore device ID
  • override the display name
  • assign an area
  • pin a specific speaker UUID to specific metadata

Manual configuration is not required for baseline discovery and use.

Configuration

# config/config.toml

[homecore]
broker_host = "127.0.0.1"
broker_port = 1883
plugin_id = "plugin.sonos"
password = ""

[sonos]
discovery_interval_secs = 300
discovery_timeout_secs = 5
manual_hosts = []

[api]
enabled = true
host = "0.0.0.0"
port = 5005
callback_host = "192.168.1.10"

Optional speaker overrides

If you want a speaker to use a specific HomeCore ID, set it explicitly by Sonos UUID:

[[devices]]
uuid = "RINCON_347E5C3D12E401400"
hc_id = "sonos_main_living_room"
name = "Living Room"
area = "living_room"

Without an override, the plugin will still discover and register the speaker automatically.

HomeCore device behavior

Once registered, a Sonos player appears like any other HomeCore device:

curl -s "http://localhost:8080/api/v1/devices?device_type=media_player" \
-H "Authorization: Bearer $TOKEN" | jq

You can also inspect one player directly:

curl -s http://localhost:8080/api/v1/devices/sonos_living_room \
-H "Authorization: Bearer $TOKEN" | jq

Typical state attributes include:

AttributeMeaning
stateplaying, paused, or stopped
volumeCurrent volume 0-100
mutedMute state
media_titleCurrent track title
media_artistCurrent artist
media_albumCurrent album
media_durationTrack duration in seconds
media_positionCurrent playback position in seconds
group_coordinatorHomeCore device ID of the coordinator
group_membersArray of grouped player IDs
available_favoritesArray of Sonos favorite names
available_playlistsArray of Sonos playlist names

Controlling Sonos through HomeCore

For normal automation, use the HomeCore device command path:

# Play
curl -s -X PATCH http://localhost:8080/api/v1/devices/sonos_living_room/state \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"action": "play"}'

# Pause
curl -s -X PATCH http://localhost:8080/api/v1/devices/sonos_living_room/state \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"action": "pause"}'

# Set volume
curl -s -X PATCH http://localhost:8080/api/v1/devices/sonos_living_room/state \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"action": "set_volume", "volume": 30}'

Named content commands

The Sonos plugin also exposes named content commands through HomeCore. This is the important part for rules.

# Play a Sonos favorite by name
curl -s -X PATCH http://localhost:8080/api/v1/devices/sonos_living_room/state \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"action": "play_favorite", "favorite": "Dinner Jazz"}'

# Play a Sonos playlist by name
curl -s -X PATCH http://localhost:8080/api/v1/devices/sonos_living_room/state \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"action": "play_playlist", "playlist": "Dinner"}'

# Generic media command form
curl -s -X PATCH http://localhost:8080/api/v1/devices/sonos_living_room/state \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"action": "play_media", "media_type": "favorite", "name": "Dinner Jazz"}'

The plugin resolves the named favorite or playlist internally. Your automation does not need to know the transport URI.

Rule example

id       = ""
name = "Dinner music"
enabled = true
priority = 10

[trigger]
type = "device_state_changed"
device = "dining_room.music_switch"
attribute = "on"
to = true

[[actions]]
type = "set_device_state"
device = "living_room.sonos"
state = { action = "play_favorite", favorite = "Dinner Jazz" }

This is preferable to an HTTP CallService action because:

  • the rule references a stable HomeCore canonical device name
  • the plugin remains free to rediscover speakers and change IPs
  • Sonos favorites and playlists stay named content, not embedded transport details

Standalone HTTP API

The plugin's own HTTP API remains available and supported. This is useful for:

  • standalone operation outside HomeCore
  • manual testing and debugging
  • advanced Sonos-specific workflows not yet modeled as HomeCore device commands

Examples:

# Direct plugin endpoint
curl http://localhost:5005/Living%20Room/play

# Browse favorites
curl http://localhost:5005/favorites | jq

# Browse playlists
curl http://localhost:5005/playlists | jq

For end-user automation inside HomeCore, prefer the HomeCore device ID path first and use the plugin HTTP API as the escape hatch.

Troubleshooting

ProblemWhat to check
Speaker never appears in HomeCoreConfirm the plugin is running and the speaker is visible on the same LAN
Speaker appears but commands do nothingCheck available = true on the device and verify the plugin can reach the speaker
Favorites or playlists are emptyWait for discovery/content refresh, then inspect available_favorites and available_playlists on the device
Rules still use Sonos URLsReplace call_service actions with set_device_state targeting the HomeCore device ID
GENA callbacks failVerify api.callback_host is reachable from the Sonos speakers