racket-sonos
| (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 #f for values that are not UPnP devices.
procedure
(sonos-device-name device) → string?
device : sonos-device?
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?)
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?
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"))