Files
2026-09-11 23:00:52 +00:00

4.0 KiB

Sonos Web Controller

A local, responsive web interface for Sonos with automatic device discovery through SoCo. It controls playback and volume, manages groups, and plays Sonos favorites, items from the current queue, or direct HTTP(S) streams. The application stores no state and does not require a database.

Sonos NestControl dashboard

Security boundary

This application intentionally has no authentication. Run it exclusively on a trusted LAN and never expose it to the internet through port forwarding, a reverse proxy, or a public IP address. Any client with access to port 5000 can control every discovered Sonos device. Firewall rules should restrict access to the local management network.

Requirements

  • Linux x86_64 with Docker Engine and Docker Compose v2
  • Sonos devices and the Docker host on the same LAN/VLAN
  • Multicast/SSDP (UDP 1900) and UPnP traffic allowed between the host and Sonos devices

Start with Docker Compose

git clone https://git.citr.one/tom/Sonos-Web.git
cd Sonos-Web
docker compose up -d --build
docker compose ps

Open http://<docker-host-ip>:5000. View logs with docker compose logs -f. Stop the application with docker compose down.

Why network_mode: host is required

SoCo discovers devices through SSDP multicast and communicates with them directly through UPnP. Docker's standard bridge network does not reliably forward multicast traffic between the LAN and a container. network_mode: host gives the container access to the Linux host's network stack, enabling discovery and device communication. As a result, the Compose configuration does not contain a ports: mapping. Host networking in this configuration is supported reliably only on Linux.

Usage

  • Rooms: Select "Search rooms" to refresh device discovery. Playback, pause, stop, and volume controls are available on every room card. Status and current track information refresh every ten seconds.
  • Groups: Select a coordinator, choose one or more members, and select "Create group." Use "Leave group" to remove a zone from its group.
  • Music: Select a room and play a favorite or queue item. Under "Stream URL," enter a complete http:// or https:// URL. Whether a stream can be played depends on its format and whether the Sonos player can reach it.

Configuration

Variable Default Description
SONOS_DISCOVERY_TIMEOUT 5 Discovery timeout in seconds
SONOS_OPERATION_TIMEOUT 8 SoCo HTTP/SOAP request timeout in seconds
SONOS_MAX_JSON_BYTES 16384 Maximum JSON request body size in bytes
LOG_LEVEL INFO Python log level

Timeout values must be positive and finite. SONOS_OPERATION_TIMEOUT configures the SoCo HTTP/SOAP request timeout. A high-level operation may contain several bounded requests and can therefore take longer overall. Device calls are not left running in the background after an artificial future timeout. The discovery cache is locked only during short in-memory operations. Status requests run independently for each device in a short-lived pool limited to eight threads, so an unreachable room does not prevent status data from being returned for other rooms. Error responses contain a machine-readable error field and a German message intended for the current user interface.

The GET /health endpoint intentionally checks only the web process. Missing or unreachable speakers do not mark the container as unhealthy.

Local development and testing

Use Python 3.12:

python -m venv .venv
. .venv/bin/activate
pip install -r requirements.txt -r requirements-dev.txt
pytest -q
python -m compileall -q app tests

The tests use mocks exclusively. They do not run discovery or contact real speakers.

API overview

  • GET /api/zones
  • POST /api/zones/<uid>/transport (play, pause, stop)
  • PUT /api/zones/<uid>/volume
  • POST /api/groups, DELETE /api/groups/<uid>
  • GET /api/zones/<uid>/favorites, GET /api/zones/<uid>/queue
  • POST /api/zones/<uid>/play/favorite|queue|stream