racket-sonos
1 Device helpers
sonos-device?
sonos-device-name
2 Reading the Sonos topology
sonos-groups
3 Group values
sonos-group
4 Example
Index
9.3

racket-sonos🔗ℹ

Hans Dijkema

 (require racket-sonos) package: racket-sonos

The racket-sonos library adds Sonos topology support to racket-upnp. It recognises Sonos and IKEA SYMFONISK devices and turns the vendor-specific zone-group topology into logical media renderers. A logical renderer can represent a single speaker, a stereo pair, a bonded home-theatre setup, or a group of rooms.

The library does not perform device discovery itself. Use query-upnp-devices from racket-upnp, then pass the complete discovery result to sonos-groups.

1 Device helpers🔗ℹ

procedure

(sonos-device? device)  boolean?

  device : any/c
Returns a true value when device is a UPnP device that advertises a ZoneGroupTopology service, identifies its manufacturer as Sonos, or has a model name containing SYMFONISK. The textual comparisons are case-insensitive.

Returns #f for values that are not UPnP devices.

procedure

(sonos-device-name device)  string?

  device : sonos-device?
Returns the friendly room name of device. For the common names Living Room - Sonos One and Kitchen - SYMFONISK Bookshelf, this function returns Living Room and Kitchen, respectively. Other friendly names are returned unchanged.

Raises exn:fail:contract? when device is not recognised by sonos-device?.

2 Reading the Sonos topology🔗ℹ

procedure

(sonos-groups devices)  (listof sonos-group?)

  devices : (listof upnp-device?)
Finds the first ZoneGroupTopology service among devices, invokes its GetZoneGroupState action, and returns the logical Sonos groups in the response.

Pass the complete result of (query-upnp-devices 'all). In particular, devices must contain the UPnP media-renderer device for every group coordinator that should be returned. A topology group whose coordinator cannot be matched to a media renderer is omitted and a warning is logged.

Returns the empty list when none of the supplied devices provides the topology service or when the service returns an empty state. Network and SOAP failures from upnp-service-call, and malformed topology XML, are reported as exceptions.

3 Group values🔗ℹ

struct

(struct sonos-group (id
    name
    coordinator-id
    member-ids
    bonded?
    stereo?
    grouped?
    renderer)
    #:extra-constructor-name make-sonos-group
    #:transparent)
  id : (or/c #f string?)
  name : string?
  coordinator-id : (or/c #f string?)
  member-ids : (listof string?)
  bonded? : boolean?
  stereo? : boolean?
  grouped? : boolean?
  renderer : media-renderer?
Represents one logical renderer from the Sonos zone-group topology. Values returned by sonos-groups have the following fields:

  • id is the topology’s group identifier. It falls back to the coordinator identifier when the topology does not supply one.

  • name combines the distinct visible room names with  + . The suffix  (stereo) or  (bonded) describes bonded configurations.

  • coordinator-id is the normalised UDN of the device that coordinates playback. A leading uuid: and any suffix after a Sonos RINCON_ identifier are removed.

  • member-ids contains the normalised identifiers of all members, including invisible bonded members.

  • bonded? is true for stereo pairs and other bonded arrangements, such as a soundbar with satellites.

  • stereo? is true when the channel map contains both the left and right front channels.

  • grouped? is true when more than one visible member belongs to the group. A bonded setup with only one visible room is therefore not necessarily grouped.

  • renderer is the coordinator’s media-renderer? value. Supply this value to the playback operations provided by racket-upnp.

4 Example🔗ℹ

This example discovers all UPnP devices, reads the Sonos topology, and prints the logical renderers:

(require racket-sonos
         racket-upnp)
 
(define devices
  (query-upnp-devices 'all))
 
(for ([group (in-list (sonos-groups devices))])
  (printf "~a: ~a member(s)~a~n"
          (sonos-group-name group)
          (length (sonos-group-member-ids group))
          (if (sonos-group-grouped? group)
              " (grouped)"
              "")))

To control a group, use its coordinator renderer. For example:

(define groups
  (sonos-groups devices))
 
(unless (null? groups)
  (media-renderer-play-uri!
   (sonos-group-renderer (first groups))
   "http://192.0.2.10:8080/audio/example.mp3"))

Index🔗ℹ

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

 

Device helpers
Example
Group values
make-sonos-group
racket-sonos
racket-sonos
Reading the Sonos topology
sonos-device-name
sonos-device?
sonos-group (struct)
sonos-group-bonded?
sonos-group-coordinator-id
sonos-group-grouped?
sonos-group-id
sonos-group-member-ids
sonos-group-name
sonos-group-renderer
sonos-group-stereo?
sonos-group?
sonos-groups
struct:sonos-group