roon-kit
TypeScript icon, indicating that this package has built-in type declarations

0.1.0 • Public • Published

Roon Kit

A collection of utility classes that simplify building extensions for Roon. Roon Kit modernizes the existing node-roon-api and adds the following features:

  • Promises and async/await support. Most of the callback based functions of the RoonApiBrowse, RoonApiImage, and RoonApiTransport services have been modified to return promises instead of taking a callback.
  • TypeScript definitions for everything. This adds type checking when building your app with TypeScript and enables better VSCode intellisense even for JavaScript based apps.
  • New RoonExtension class to simplify initializing the RoonApi and subscribing to zones or outputs.
  • Node.js style events for things like zone pairing and subscription callbacks. This lets multiple components subscribe to the same set of API notifications.
  • The paired RoonCore is wrapped with a Revocable Proxy for added safety. This prevents apps from trying to use a core after its be unpaired and helps eliminate a whole class of bugs.

Usage

To use Roon Kit in your project simply install it using your favorite package manager:

$ npm install roon-kit --save

or using Yarn:

$ yarn add roon-kit

Create a RoonExtension class instead of the RoonApi class. You can tell the services you'd like to use and if you'd like the extension to subscribe to output or zones:

const { RoonExtension } = require('roon-kit');

const extension = new RoonExtension({
        description: {
        extension_id:        'roon-kit-now-playing',
        display_name:        "Roon Kit Now Playing Test",
        display_version:     "0.1.0",
        publisher:           'roon-kit',
        email:               'stevenic@microsoft.com',
        website:             'https://github.com/Stevenic/roon-kit'
    },
    RoonApiBrowse: 'not_required',
    RoonApiImage: 'not_required',
    RoonApiTransport: 'required',
    subscribe_outputs: false,
    subscribe_zones: true,
    log_level: 'none'
});

Next you can listen for subscription events if you've enabled those option(s):

extension.on("subscribe_zones", (core, response, body) => {
    // Print new subscriptions
    const addedZones = body.zones ?? body.zones_added ?? [];
    addedZones.forEach(zone => {
        console.log(`Zone['${zone.zone_id}'] subscribed to "${zone.display_name}"`);
        console.log(`Zone['${zone.zone_id}'] "${zone.now_playing?.one_line.line1 ?? 'zone'}" is ${zone.state}`);
    });

    // Print removed subscriptions
    const removedZones = body.zones_removed ?? [];
    removedZones.forEach(zone => {
        console.log(`Zone['${zone.zone_id}'] unsubscribed from "${zone.display_name}"`);
    }); 

    // Print zone state changes
    const changedZones = body.zones_changed ?? [];
    changedZones.forEach(zone => {
        console.log(`Zone['${zone.zone_id}'] "${zone.now_playing?.one_line.line1 ?? 'zone'}" is ${zone.state}`);
    });

    // Print zone seeks
    const seekedZones = body.zones_seek_changed ?? [];
    seekedZones.forEach(zone => {
        console.log(`Zone['${zone.zone_id}'] time remaining: ${zone.queue_time_remaining} seconds`);
    });
});

You can then start discovery and wait for a RoonCore to pair. There's no need to initialize the services as that's managed by the extension class:

extension.start_discovery();
extension.set_status(`extension starting`);

You can get a handled to the current paired core by either subscribing to the "core_paired" event before your start discovery or by calling extension.get_core() after you start discovery. The get_core() method is asynchronous so you can wait for the core using either:

extension.get_core().then((core) => {
    extension.set_status(`core paired`);
});

Or using a more modern async/await pattern:

(async () => {
    const core = await extension.get_core();
    extension.set_status(`core paired`);
})();

Readme

Keywords

Package Sidebar

Install

npm i roon-kit

Weekly Downloads

0

Version

0.1.0

License

MIT

Unpacked Size

96.5 kB

Total Files

33

Last publish

Collaborators

  • stevenic