Skip to content
Get started

Sendspin

The sendspin component adds support for Sendspin, a multi-room synchronized audio protocol. The hub manages the connection to a Sendspin server and distributes state updates to any Sendspin child components.

The device uses mDNS to discover Sendspin servers on the network, so mDNS traffic must not be blocked on your network. TCP port 8928 must also be reachable between the device and the server.

On its own, the hub does not expose any user-facing entities. Once a Sendspin server is present on the network, it will connect to the device and begin sending group state updates, but audio playback, control, and metadata require the corresponding child components to be configured as well. The Sendspin Switch can stop the client so no server connects.

Every connection to a Sendspin server is encrypted. By default any server on the network may play on the device. Turn off unpaired access to allow only servers that have paired with it.

This platform only works on ESP32-based chips, with the ESP-IDF framework.

IMPORTANT

The device needs a Sendspin 1.0.0-rc1 server, such as Music Assistant 2.11.0b4 or newer. Servers using an earlier protocol version cannot connect.

WARNING

The Sendspin protocol is not yet finalized and this component is considered experimental. Breaking changes may occur in future ESPHome releases as the protocol and component evolve.

# Example configuration entry
sendspin:
  • id (Optional, ID): Manually specify the ID for this hub. Required if you want to reference this hub explicitly from child components.
  • task_stack_in_psram (Optional, boolean): Place the internal HTTP server and protocol task stacks in PSRAM to reduce internal RAM usage. Requires the Psram component to be configured. Defaults to false.
  • manufacturer (Optional, string): The manufacturer the device reports to the Sendspin server. Defaults to the author part of the project name when one is set, otherwise ESPHome.
  • model (Optional, string): The model the device reports to the Sendspin server. Defaults to the project part of the project name when one is set, otherwise the device’s name.
  • firmware_version (Optional, string): The firmware version the device reports to the Sendspin server. Defaults to the project version when one is set, otherwise the ESPHome version.
  • static_pairing_code (Optional, string): A fixed pairing code of exactly 8 decimal digits. Always quote the value, including in secrets.yaml when using !secret, for example "01234567", since an unquoted number is rejected. Cannot be combined with a dynamic pairing code. See Static Pairing Code.
  • unpaired_access (Optional, boolean): Whether servers that have not paired with the device may play on it. Set to false once a server is paired so only paired servers can play. Defaults to true. To change it at runtime, use a Sendspin Switch of type unpaired_access instead; the two cannot be combined.

A server pairs with the device once, and the device stores the result. A paired server can always play, even when unpaired access is off. The device can offer these ways to pair:

Set static_pairing_code to a fixed 8-digit code, then enter that code on the server. Pick a random code that is unique to the device. An attempt must also be confirmed on the device with the sendspin.confirm_pairing_window action, for example from a button press. on_open_pairing_window runs when an attempt is waiting for that confirmation.

Confirming opens a pairing window of 5 minutes. It closes early when pairing succeeds, after 5 wrong codes, when the server disconnects, or when sendspin.cancel_pairing_window runs. After it closes, the next attempt has to be confirmed again.

The device shows a new 6-digit code for each attempt, which you enter on the server. Configure on_display_pairing_code to show the code, or publish it with a Sendspin Text Sensor of type pairing_code. Attempts do not need to be confirmed on the device, and there is no pairing window. After 20 wrong codes, though, further attempts wait until sendspin.confirm_pairing_window runs, which resets the count. Give the device a way to run it, such as a button. on_open_pairing_window runs when an attempt is waiting.

Only one pairing code method can be offered. The device offers a dynamic pairing code when on_display_pairing_code or a pairing_code text sensor is configured, so neither can be combined with static_pairing_code.

While unpaired_access is true, any server on the network may play on the device without pairing. When it is false, servers that have not paired can still connect to pair, but cannot play. A Sendspin Switch of type unpaired_access can turn it on and off at runtime instead.

WARNING

With unpaired_access: false, make sure the device offers a static or dynamic pairing code. Otherwise no new server can pair, so only servers that already paired can play.

  • on_pairing_succeeded (Optional, Automation): An automation to perform when a server finishes pairing with the device. The variable server_id (std::string) holds the server’s ID.
  • on_pairing_failed (Optional, Automation): An automation to perform when a pairing attempt fails. The variables server_id (std::string) and reason (StringRef) are available. reason is one of attempt_timeout, concurrent_attempt, method_not_supported, pairing_code_mismatch, user_cancelled or unknown. Compare it directly, for example reason == "user_cancelled", and use reason.c_str() to log it.
  • on_open_pairing_window (Optional, Automation): An automation to perform when a pairing attempt is waiting to be confirmed on the device: a static pairing code attempt while no pairing window is open, or a dynamic pairing code attempt after 20 wrong codes. Run sendspin.confirm_pairing_window to allow it.
  • on_close_pairing_window (Optional, Automation): An automation to perform when the attempt that ran on_open_pairing_window ends, whatever the outcome. Use it to dismiss a prompt.
  • on_display_pairing_code (Optional, Automation): An automation to perform when a server asks the device to show a dynamic pairing code. The variable code (std::string) holds the 6-digit code.
  • on_clear_pairing_code (Optional, Automation): An automation to perform when the dynamic pairing code is no longer needed.

This action switches the Sendspin client to the next active group.

on_...:
- sendspin.switch:

This action confirms a pairing attempt on the device. Run it in response to a user action such as a button press.

  • With a static pairing code, it opens the pairing window. If no attempt is waiting yet, the window still opens, so you can press the button before starting pairing on the server.
  • With a dynamic pairing code, it resets the count of wrong codes, so a waiting attempt can continue.
on_...:
- sendspin.confirm_pairing_window:

This action closes the pairing window, so a waiting pairing attempt is not confirmed.

on_...:
- sendspin.cancel_pairing_window:

Pair with a static code that is confirmed with a button press:

sendspin:
static_pairing_code: !secret sendspin_pairing_code
on_open_pairing_window:
- logger.log: "Press the button to pair"
binary_sensor:
- platform: gpio
pin: GPIOXX
name: "Pair Button"
on_press:
- sendspin.confirm_pairing_window:

Pair with a dynamic code that is shown as a text sensor, with a button for when attempts need confirming:

sendspin:
text_sensor:
- platform: sendspin
name: "Pairing Code"
type: pairing_code
binary_sensor:
- platform: gpio
pin: GPIOXX
name: "Pair Button"
on_press:
- sendspin.confirm_pairing_window:
  • Sendspin Image: Displays album and artist artwork streamed from the group on a connected display.
  • Sendspin Group Media Player: Exposes group-wide playback and volume controls as a Home Assistant media player entity.
  • Sendspin Media Source: Plays synchronized audio from a Sendspin group through a Speaker Source media player.
  • Sendspin Sensor: Exposes numeric metadata about the currently playing audio (track progress, track duration, etc.).
  • Sendspin Switch: Enables and disables the Sendspin client, and turns unpaired access on and off.
  • Sendspin Text Sensor: Exposes metadata about the currently playing audio (title, artist, album, etc.), and the pairing code.