New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@svrooij/sonos

Package Overview
Dependencies
Maintainers
1
Versions
85
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@svrooij/sonos

A node library to control your sonos devices, written in typescript

  • 0.4.1
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
401
decreased by-17.49%
Maintainers
1
Weekly downloads
 
Created
Source

Node Sonos (the typescript version)

Support me on Github

A node library to control a sonos device, written in Typescript. See here why I've build it while there already is a sonos library.

Usage

To use the library just add it to your project. npm install @svrooij/sonos. And start using it. This library isn't meant to be used by itself.

You'll need to get the SonosDevice by one of the methods below, and start using the shortcuts, the extra functionality or the exposed services. This library allows you to do everything you can do with the Sonos application.

Shortcuts

Each Sonos Device has the following shortcuts (things you can do by using one of the exposed services):

  • .GetZoneGroupState() - Get current group info.
  • .GetZoneInfo() - Get info about current player.
  • .Play() - Start playing *.
  • .Pause() - Pause playing *.
  • .Next() - Go to next song (when playing the queue) *.
  • .Previous() - Go to previous song (when playing the queue) *.
  • .Stop() - Stop playing (most of the time it's better to pause playback) *.
  • .SeekPosition('0:03:01') - Go to other postion in track *.
  • .SeekTrack(3) - Go to other track in the queue *.

These operations (marked with *) are send to the coordinator if the device is created by the SonosManager. So you can send .Next() to each device in a group and it will be send to the correct device.

Extra functionality

I also implemented extra functionatity for each player. (mostly combining calls):

  • .AddUriToQueue('spotify:track:0GiWi4EkPduFWHQyhiKpRB') - Add a track to be next track in the queue, metadata is guessed.
  • .AlarmList() - List all your alarms
  • .AlarmPatch({ ID: 1, ... }) - Update some properties of one of your alarms.
  • .JoinGroup('Office') - Join an other device by it's name. Will lookup the correct coordinator.
  • .PlayNotification(new PlayNotificationOptions(....)) - Play a single url and revert back to previous music source (playlist/radiostream).
  • .SetAVTransportURI('spotify:track:0GiWi4EkPduFWHQyhiKpRB') - Set playback to this url, metadata is guessed. This doens't start playback all the time!
  • .SwitchToLineIn() - Some devices have a line-in. Use this command to switch to it.
  • .SwitchToQueue() - Switch to queue (after power-on or when playing a radiostream).
  • .SwitchToTV() - On your playbar you can use this to switch to TV input.
  • .TogglePlayback() - If playing or transitioning your playback is paused. If stopped or paused your playback is resumed.

Exposed services

Your sonos device has several services defined in it's device description (available at http://sonos_ip:1400/xml/device_description.xml). This library uses a generator to automatically generate all the services my sonos device has. All these services are exposed in the SonosDevice:

  • .AVTransportService - Control the playback (play, pause, next, stop).
  • .AlarmClockService - Control your alarms.
  • .AudioInService - ?
  • .ConnectionManagerService - ?
  • .ContentDirectoryService - Control your content?
  • .DevicePropertiesService - Change your device properties (led, StereoPair, AutoPlay).
  • .GroupManagementService - Manage your groups (what's the differance with ZoneGroupTopologyService?).
  • .GroupRenderingControlService - RenderingControlService for groups.
  • .MusicServicesService - All your music services.
  • .QPlayService - To authorize QPlay, needs explaining.
  • .QueueService - Queue management
  • .RenderingControlService - Control rendering (eg. volume)
  • .SystemPropertiesService - Manage connected accounts
  • .VirtualLineInService - ?
  • .ZoneGroupTopologyService - Zone management, mostly used under the covers by SonosManager

SonosManager and logical devices

This library has a SonosManager that resolves all your sonos groups for you. It also manages group updates. Every SonosDevice created by this manager has some extra properties that can be used by your application. These properties will automatically be updated on changes.

  • .Coordinator - Point to the devices' group coordinator (or to itself when it's the coordinator).
  • .GroupName - The name of the group this device is in. eg 'Kitchen + 2'

SonosManager - Device discovery

You can discover all the devices in the current network using device discovery

const SonosManager = require('@svrooij/sonos').SonosManager
const manager = new SonosManager()
manager.InitializeWithDiscovery(10)
  .then(console.log)
  .then(() => {
    manager.Devices.forEach(d => console.log('Device %s (%s) is joined in %s', d.Name, d.uuid, d.GroupName))
  })
  .catch(console.error)

SonosManager - Single IP

In some cases device discovery doesn't work (think docker or complex networks), you can also start the manager by submitting one known sonos IP.

const SonosManager = require('@svrooij/sonos').SonosManager
const manager = new SonosManager()
manager.InitializeFromDevice(process.env.SONOS_HOST || '192.168.96.56')
  .then(console.log)
  .then(() => {
    manager.Devices.forEach(d => console.log('Device %s (%s) is joined in %s', d.Name, d.uuid, d.GroupName))
  })
  .catch(console.error)

Advanced usage

This library also supports direct using it without the SonosManager. The group stuff won't work this way!

const SonosDevice = require('@svrooij/sonos').SonosDevice

const sonos = new SonosDevice(process.env.SONOS_HOST || '192.168.96.56')
sonos.LoadDeviceData()
  .then(success => {
    console.log(sonos.Name)
  })
  .catch(console.error)

Events

Sonos devices have a way to subscribe to updates of most device parameters. It works by sending a subscribe request to the device. The Sonos device will then start sending updates to the specified endpoint(s).

This library includes a SonosEventListener which you'll never have to call yourself :wink:. Each service has an .Events property exposing the EventEmitter for that service. If you subscribe to events of a service, it will automatically ask the sonos device to start sending updates for that service. If you stop listening, it will tell sonos to stop sending events.

If you subscribed to events of one service, or on the sonos device events. A small webservice is created automatically to receive the updates from sonos. This webservices is running on port 6329 by default, but can be changed (see below).

The SonosDevice also has an .Events property. Here you'll receive some specific events.

const SonosDevice = require('@svrooij/sonos').SonosDevice
const ServiceEvents = require('@svrooij/sonos').ServiceEvents
const SonosEvents = require('@svrooij/sonos').SonosEvents
const sonosDevice = new SonosDevice(process.env.SONOS_HOST || '192.168.96.56')

// SonosEvents
sonosDevice.Events.on(SonosEvents.CurrentTrack, uri => {
  console.log('Current track changed %s', uri)
})

sonosDevice.Events.on(SonosEvents.CurrentTrackMetadata, data => {
  console.log('Current track metadata %s', JSON.stringify(data))
})

sonosDevice.Events.on(SonosEvents.Volume, volume => {
  console.log('New volume %d', volume)
})

// Events from Services
sonosDevice.AlarmClockService.Events.on(ServiceEvents.Data, data => {
  console.log('AlarmClock data %s', JSON.stringify(data))
})

sonosDevice.AVTransportService.Events.on(ServiceEvents.LastChange, data => {
  console.log('AVTransport lastchange %s', JSON.stringify(data, null, 2))
})
sonosDevice.RenderingControlService.Events.on(ServiceEvents.LastChange, data => {
  console.log('RenderingControl lastchange %s', JSON.stringify(data, null, 2))
})

The SonosEventListener has some configuration options, which you'll need in specific network environments or docker sitiuations. You can configure the following environment variables.

  • SONOS_LISTENER_HOST The hostname or ip of the device running the event listener. This is used as the callback host.
  • SONOS_LISTENER_INTERFACE If the host isn't set, the first non-internal ip of this interface is used.
  • SONOS_LISTENER_PORT The port the event listener should listen on. Also send to the device. 6329 = default

If none of these environment variables are set it will just use the default port and the first found non-internal ip.

Contributing

You can contribute in many ways. Asking good questions, solving bugs, sponsoring me on github. This library is build in my spare time, so don't be rude about it.

If you're using a music service that currently isn't supported for metadata generation, you should check out the metadata generator. It works by taking an url (which you can get by running the get-position-info sample). And generating a Track for it. Use the information out the console to get the right values. The values you'll be looking for are ProtocolInfo, TrackUri, UpnpClass, ItemID and ParentID

Support me on Github

Developer section

This will contain usefull information if you want to fix a bug you've found in this library. You always start with cloning the repo and doing a npm install in the folder. I like consistancy so everything is in a specific order :wink:.

Running example code

This library has two VSCode launch configurations.

One for running the current open example, you can set breakpoints in the example file and in the typescript code! Be sure to change the IP to your own in .vscode/launch.json, so you don't have to edit all the example files.

And it has a launch configuration to run the current Mocha test file, be sure to have a mocha test (in test folder) open.

(Re-)generate services

I've created a one-liner to regenerate all the generated services. SONOS_HOST=192.168.x.x npm run gen-srv. This will parse the device properties and will (re)create all the services in the /src/services folder. New services will have the new- filename prefix, and should be added in the getFilenameForService method.

Compile the library

Because the library is written in typescript, you'll need to compile it before using it. Run npm run build to have the compiler generate the actual library in the lib folder.

Improvements over node-sonos

The original node-sonos is started a long time ago, before async programming in node. Which I'm a contributor as well. Some design decisions cannot be fixed without breaking compatibility with all the applications using it. For instance the .play() function serves multiple purposes, starting playback and switching urls. A lot of applications depend on it, and they would all break if I would remove support for it.

This new library is build from the ground up using node-fetch for the requests and fast-xml-parser for the xml stuff.

One of the most important parts of this new library is the service-generator, it parses the /xml/device_description.xml file from the sonos device. And generates a strong typed service class for it. This means that this library will support everything the sonos controller can do. And it also means that it will tell your which parameters it expects.

  • Strong typed (auto generated) client
  • Starting from auto discovery or one sonos host ip
  • Zone groups as a starting point (logical devices)
  • All events parsed and some custom properties
  • The sonos device will expose all the generated services, or an extended version of them.
  • The sonos device will contain extra features and shortcuts to services.
  • Easier implementing metadata generation for new services.

Big thanks to all the original contributors

Creating a library from scratch is quite hard, and I'm using a lot of stuff from the original library. That wouldn't exists without the contributors.

Keywords

FAQs

Package last updated on 24 Nov 2019

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc