### Volume control examples Source: https://roonlabs.github.io/node-roon-api/Output.html Examples of volume control objects showing different types (db, number, incremental) and their properties. Note that the third and fourth examples are missing a colon after 'number' in the source. ```json { "type": "db", "min": -80, "max": 0, "value": -50.5, "step": 0.5 } { "type": "db", "min": -80, "max": 10, "value": 4, "step": 1.0 } { "type": "number" "min": 0, "max": 100, "value": 80, "step": 1.0 } { "type": "number" "min": 1, "max": 99, "value": 65, "step": 1.0 } { "type": "incremental" } ``` -------------------------------- ### start_discovery() Source: https://roonlabs.github.io/node-roon-api/RoonApi.html Begins the discovery process to find and connect to a Roon Core. This method initiates the discovery mechanism. ```APIDOC ## start_discovery() ### Description Begins the discovery process to find and connect to a Roon Core. This method initiates the discovery mechanism. ``` -------------------------------- ### init_services(services) Source: https://roonlabs.github.io/node-roon-api/RoonApi.html Initializes the services you require and that you provide. This method is called to set up the service dependencies for your extension. ```APIDOC ## init_services(services) ### Description Initializes the services you require and that you provide. This method is called to set up the service dependencies for your extension. ### Parameters - **services** (object) - Required - Information about your extension. Used by Roon to display to the end user what is trying to access Roon. - **required_services** (Array.) - Optional - A list of services which the Roon Core must provide. - **optional_services** (Array.) - Optional - A list of services which the Roon Core may provide. - **provided_services** (Array.) - Optional - A list of services which this extension provides to the Roon Core. ``` -------------------------------- ### init_services: register pairing and ping services with core pairing logic Source: https://roonlabs.github.io/node-roon-api/lib.js.html Initializes required and optional services, registers the pairing service (com.roonlabs.pairing:1) with subscribe_pairing, get_pairing, and pair methods, and registers a ping service (com.roonlabs.ping:1). Throws an error if required or optional services are declared without core_paired or core_found options. Handles core pairing and unpairing callbacks. ```javascript RoonApi.prototype.init_services = function(o) { if (!(o.required_services instanceof Array)) o.required_services = []; if (!(o.optional_services instanceof Array)) o.optional_services = []; if (!(o.provided_services instanceof Array)) o.provided_services = []; if (o.required_services.length || o.optional_services.length) if (!this.extension_opts.core_paired && !this.extension_opts.core_found) throw new Error("Roon Extensions options has required or optional services, but has neither .core_paired nor .core_found."); if (this.extension_opts.core_paired) { let svc = this.register_service("com.roonlabs.pairing:1", { subscriptions: [ { subscribe_name: "subscribe_pairing", unsubscribe_name: "unsubscribe_pairing", start: (req) => { req.send_continue("Subscribed", { paired_core_id: this.paired_core_id }); } } ], methods: { get_pairing: (req) => { req.send_complete("Success", { paired_core_id: this.paired_core_id }); }, pair: (req) => { if (this.paired_core_id != req.moo.core.core_id) { if (this.paired_core) { this.pairing_service_1.lost_core(this.paired_core); delete this.paired_core_id; delete this.paired_core; } this.pairing_service_1.found_core(req.moo.core); } }, } }); this.pairing_service_1 = { services: [ svc ], found_core: core => { if (!this.paired_core_id) { let settings = this.get_persisted_state(); settings.paired_core_id = core.core_id; this.set_persisted_state(settings); this.paired_core_id = core.core_id; this.paired_core = core; this.is_paired = true; svc.send_continue_all("subscribe_pairing", "Changed", { paired_core_id: this.paired_core_id }) } if (core.core_id == this.paired_core_id) if (this.extension_opts.core_paired) this.extension_opts.core_paired(core); }, lost_core: core => { if (core.core_id == this.paired_core_id) this.is_paired = false; if (this.extension_opts.core_unpaired) this.extension_opts.core_unpaired(core); }, }; o.provided_services.push(this.pairing_service_1); } o.provided_services.push({ services: [ this.register_service("com.roonlabs.ping:1", { methods: { ping: function(req) { req.send_complete("Success"); }, } })]}) o.required_services.forEach(svcobj => { svcobj.services.forEach(svc => { this.extension_reginfo.required_services.push(svc.name); }); }); } ``` -------------------------------- ### convenience_switch(output, opts, cb) Source: https://roonlabs.github.io/node-roon-api/other_node-roon-api-transport_lib.js.html Convenience-switch an output to the currently selected source control. If opts.control_key is omitted, all controls on the output are convenience switched. ```APIDOC ## convenience_switch(output, opts, cb) ### Description Convenience-switch an output to the currently selected source control. If opts.control_key is omitted, all controls on the output are convenience switched. ### Method RoonApiTransport.prototype.convenience_switch ### Parameters - **output** (Output) - Required - The output that should be convenience-switched. - **opts** (object) - Required - Options. If none, specify empty object ({}). - **opts.control_key** (string) - Optional - The control_key that identifies the source_control that is to be switched. If omitted, then all controls on this output will be convenience switched. - **cb** (RoonApiTransport~resultcallback) - Optional - Called on success or error. ### Response Callback receives an error string (e.g., "NetworkError") or false on success. ``` -------------------------------- ### Implement discovery and config methods for Node and browser Source: https://roonlabs.github.io/node-roon-api/lib.js.html Defines `start_discovery`, `periodic_scan`, `save_config`, and `load_config` for Node.js environments (when `window` is undefined or `nw` is defined). Uses `fs` to read/write `config.json` and `sood.js` for discovery. In browser environments, `save_config` and `load_config` use `localStorage` instead. ```javascript if (typeof(window) == "undefined" || typeof(nw) !== "undefined") { /** * Begin the discovery process to find/connect to a Roon Core. */ RoonApi.prototype.start_discovery = function() { if (this._sood) return; this._sood = require('./sood.js')(this.logger); this._sood_conns = {}; this._sood.on('message', msg => { // this.logger.log(msg); if (msg.props.service_id == "00720724-5143-4a9b-abac-0e50cba674bb" && msg.props.unique_id) { if (this._sood_conns[msg.props.unique_id]) return; this._sood_conns[msg.props.unique_id] = true; this.ws_connect({ host: msg.from.ip, port: msg.props.http_port, onclose: () => { delete(this._sood_conns[msg.props.unique_id]); } }); } }); this._sood.on('network', () => { this._sood.query({ query_service_id: "00720724-5143-4a9b-abac-0e50cba674bb" }); }); this._sood.start(() => { this._sood.query({ query_service_id: "00720724-5143-4a9b-abac-0e50cba674bb" }); setInterval(() => this.periodic_scan(), (10 * 1000)); this.scan_count = -1; }); }; RoonApi.prototype.periodic_scan = function() { this.scan_count += 1; if (this.is_paired) return; if ((this.scan_count < 6) || ((this.scan_count % 6) == 0)) { this._sood.query({ query_service_id: "00720724-5143-4a9b-abac-0e50cba674bb" }); } }; var fs = ((typeof _fs) === 'undefined') ? require('fs') : _fs; /** * Save a key value pair in the configuration data store. * @param {string} key * @param {object} value */ RoonApi.prototype.save_config = function(k, v) { try { let config; try { let content = fs.readFileSync("config.json", { encoding: 'utf8' }); config = JSON.parse(content) || {}; } catch (e) { config = {}; } if (v === undefined || v === null) delete(config[k]); else config[k] = v; fs.writeFileSync("config.json", JSON.stringify(config, null, ' ')); } catch (e) { } }; /** * Load a key value pair in the configuration data store. * @param {string} key * @return {object} value */ RoonApi.prototype.load_config = function(k) { try { let content = fs.readFileSync("config.json", { encoding: 'utf8' }); return JSON.parse(content)[k]; } catch (e) { return undefined; } }; } else { RoonApi.prototype.save_config = function(k, v) { if (v === undefined || v === null) localStorage.removeItem(k); else localStorage.setItem(k, JSON.stringify(v)); }; RoonApi.prototype.load_config = function(k) { try { let r = localStorage.getItem(k); return r ? JSON.parse(r) : undefined; } catch (e) { return undefined; } }; } ``` -------------------------------- ### Register service with subscription handling Source: https://roonlabs.github.io/node-roon-api/lib.js.html Begins the `register_service` method, setting up a return object with `_subtypes` and iterating over `spec.subscriptions`. For each subscription, it stores a subtype and overrides `req.send_complete` with a placeholder that references `req.orig_send_complete`. ```javascript RoonApi.prototype.register_service = function(svcname, spec) { let ret = { _subtypes: { } }; if (spec.subscriptions) { for (let x in spec.subscriptions) { let s = spec.subscriptions[x]; let subname = s.subscribe_name; ret._subtypes[subname] = { }; spec.methods[subname] = (req) => { // XXX make sure req.body.subscription_key exists or respond send_complete with error req.orig_send_complete = req.send_complete; req.send_complete = function() { ``` -------------------------------- ### convenience_switch(output, opts, cbopt) Source: https://roonlabs.github.io/node-roon-api/RoonApiTransport.html Convenience switch an output, taking it out of standby if needed. ```APIDOC ## convenience_switch(output, opts, cbopt) ### Description Convenience switch an output, taking it out of standby if needed. ### Method convenience_switch ### Parameters - **output** (Output) - Required - The output that should be convenience-switched. - **opts** (object) - Required - Options. If none, specify empty object ({}). - **control_key** (string) - Optional - The `control_key` that identifies the `source_control` that is to be switched. If omitted, then all controls on this output will be convenience switched. - **cb** (RoonApiTransport~resultcallback) - Optional - Called on success or error ``` -------------------------------- ### RoonApiImage class definition and get_image method Source: https://roonlabs.github.io/node-roon-api/other_node-roon-api-image_lib.js.html Defines the RoonApiImage constructor, registers the service with name 'com.roonlabs.image:1', and implements get_image to send a request to the core. The callback receives an error (or false), content type, and image buffer on success. ```javascript "use strict"; let SVCNAME = "com.roonlabs.image:1"; /** * Roon API Image Service * @class RoonApiImage * @param {Core} core - The Core providing the service */ function RoonApiImage(core) { this.core = core; } RoonApiImage.services = [ { name: SVCNAME } ]; /** * @callback RoonApiImage~imageresultcallback * @param {string | false} error - an error code or false if no error * @param {string} content_type - the MIME type of the image data * @param {Buffer} image - the image data */ /** *

* Roon API services provide image_key properties. This translates the image_key into an actual image. * * It is also possible to issue image requests directly using HTTP if that is more convenient: * * http://IP:PORT/api/image/image_key?scale=XXX&width=XXX&height=XXX&format=XXX * * The rules for parameter types and optional/required follow the same as for the options parameter. *

* * @param {string} image_key - the key, as given by another api * @param {object} [options] * @param {('fit'|'fill'|'stretch')} [options.scale] - If this is not set, the image will be returned at original size. Warning: that could be very large! * @param {number} [options.width] - The image width to be returned. Required if the scale property is set * @param {number} [options.height] - The image height to be returned. Required if the scale property is set * @param {('image/jpeg'|'image/png')} [options.format] - If you don't specify, Roon will choose for you. * @param {RoonApiImage~imageresultcallback} cb - Called on success or error */ RoonApiImage.prototype.get_image = function() { var i = 0; let image_key = arguments[i++]; let opts = {}; if (typeof(arguments[i]) != "function") opts = arguments[i++]; let cb = arguments[i++]; opts = Object.assign({ image_key: image_key }, opts); this.core.moo.send_request(SVCNAME+"/get_image", opts, (msg, body) => { if (msg && msg.name == "Success") cb(false, msg.content_type, body); else cb(msg ? msg.name : "NetworkError"); }); }; exports = module.exports = RoonApiImage; ``` -------------------------------- ### group_outputs(outputs, cbopt) Source: https://roonlabs.github.io/node-roon-api/RoonApiTransport.html Create a group of synchronized audio outputs. ```APIDOC ## group_outputs(outputs, cbopt) ### Description Create a group of synchronized audio outputs. ### Method group_outputs ### Parameters - **outputs** (Array.) - Required - The outputs to group. The first output's zone's queue is preserved. - **cb** (RoonApiTransport~resultcallback) - Optional - Called on success or error ``` -------------------------------- ### standby(output, opts, [cb]) Source: https://roonlabs.github.io/node-roon-api/other_node-roon-api-transport_lib.js.html Puts an output into standby. The output is specified by the first parameter, and options can include a control_key to identify a specific source_control. The optional callback is called with an error message or false on success. ```APIDOC ## standby(output, opts, [cb]) ### Description Standby an output. ### Method RoonApiTransport.prototype.standby ### Parameters - **output** (Output) - Required - The output to put into standby. - **opts** (object) - Required - Options. If none, specify empty object ({}). - **opts.control_key** (string) - Optional - The control_key that identifies the source_control that is to be put into standby. If omitted, all source controls on this output that support standby will be put into standby. - **cb** (function) - Optional - Called on success or error. Receives an error message (string) or false on success. ### Callback - On success: cb(false) - On error: cb(errorMessage) where errorMessage is the error name (e.g., 'NetworkError') or false if success. ``` -------------------------------- ### get_image(image_key, optionsopt, cb) Source: https://roonlabs.github.io/node-roon-api/RoonApiImage.html Translates an image_key into an actual image. Supports optional scaling and format parameters. The image can also be fetched via HTTP at `http://IP:PORT/api/image/image_key` with corresponding query parameters. ```APIDOC ## get_image(image_key, optionsopt, cb) ### Description Translates an image_key provided by another Roon API service into actual image data. Can also be performed via HTTP if preferred. ### Parameters - **image_key** (string) - Required - The key as given by another API. - **options** (object, optional) - Optional settings object. - **scale** (string: 'fit' | 'fill' | 'stretch', optional) - Scaling behavior. If not set, returns original size. - **width** (number, optional) - Image width. Required if scale is set. - **height** (number, optional) - Image height. Required if scale is set. - **format** (string: 'image/jpeg' | 'image/png', optional) - Image format. If not specified, Roon chooses automatically. - **cb** (imageresultcallback) - Required - Callback called on success or error. ### HTTP Alternative - Endpoint: `http://IP:port/api/image/image_key` - Optional query parameters: `scale`, `width`, `height`, `format` (same rules as options). ### Callback Upon completion, invokes the callback with parameters: `(error, content_type, image)`. ``` -------------------------------- ### browse(opts, cbopt) Source: https://roonlabs.github.io/node-roon-api/RoonApiBrowse.html Perform a browsing operation. Use this when the user selects an Item. ```APIDOC ## browse(opts, cbopt) ### Description Perform a browsing operation. Use this when the user selects an `Item`. ### Method browse ### Parameters #### Options - **hierarchy** (string) - Required - The hierarchy being browsed. Supported values: "browse", "playlists", "settings", "internet_radio", "albums", "artists", "genres", "composers", "search". - **multi_session_key** (string) - Optional - If your application browses several instances of the same hierarchy at the same time, you can populate this to distinguish between them. Most applications will omit this field. - **item_key** (string) - Optional - The key from an `Item`. If you omit this, the most recent level will be re-loaded. - **input** (string) - Optional - Input from the input box. - **zone_or_output_id** (string) - Optional - Zone ID. This is required for any playback-related functionality to work. - **pop_all** (bool) - Optional - True to pop all levels but the first. - **pop_levels** (int) - Optional - If set, pop n levels. - **refresh_list** (bool) - Optional - If set, refresh the list contents. - **set_display_offset** (int) - Optional - Update the display offset for the current list prior to performing the browse operation. - **cb** (RoonApiBrowse~browseresultcallback) - Optional - Called on success or error. ### Notes - If `pop_all` is true, the session will be reset so that browsing begins from the root of the hierarchy. If false or unset, the core will attempt to resume at the previous browsing position. - It is not valid to provide `pop_all` and `item_key` at the same time. ``` -------------------------------- ### load(opts, cbopt) Source: https://roonlabs.github.io/node-roon-api/RoonApiBrowse.html Retrieve items from a browse level. Item loading is handled separately from browsing. This allows clients to load very large lists in very small increments if needed. ```APIDOC ## load(opts, cbopt) ### Description Retrieve items from a browse level. Item loading is handled separately from browsing. This allows clients to load very large lists in very small increments if needed. ### Method load ### Parameters #### Options - **set_display_offset** (int) - Optional - Update the display offset for the current list. - **level** (int) - Optional - Which level of the browse hierarchy to load from. Defaults to the current (deepest) level. - **offset** (int) - Optional - Offset into the list where loading should begin. Defaults to 0. - **count** (int) - Optional - Number of items to load. Defaults to 100. - **hierarchy** (string) - Required - The hierarchy being browsed. See `browse` for a list of possible values. - **multi_session_key** (string) - Optional - If your application browses several instances of the same hierarchy at the same time, you can populate this to distinguish between them. Most applications will omit this field. - **cb** (RoonApiBrowse~loadresultcallback) - Optional - Called on success or error. ``` -------------------------------- ### RoonApi constructor: validate core_unpaired and initialize extension state Source: https://roonlabs.github.io/node-roon-api/lib.js.html Constructor logic for the RoonApi extension. Validates that core_unpaired is a function if provided, initializes the extension registration info with required and optional service arrays, and sets up logger, log level, options, and pairing state. ```javascript if (o.core_unpaired && typeof(o.core_unpaired) != "function") throw new Error("Roon Extensions options has a .core_unpaired which is not a function"); ``` ```javascript this.extension_reginfo = { extension_id: o.extension_id, display_name: o.display_name, display_version: o.display_version, publisher: o.publisher, email: o.email, required_services: [], optional_services: [], provided_services: [] }; if (o.website) this.extension_reginfo.website = o.website; ``` ```javascript this.logger = new Logger(this); this.log_level = o.log_level; this.extension_opts = o; this.is_paired = false; ``` -------------------------------- ### change_volume(output, how, value, cbopt) Source: https://roonlabs.github.io/node-roon-api/RoonApiTransport.html Change the volume of an output, supporting absolute, relative, and relative_step modes. ```APIDOC ## change_volume(output, how, value, cbopt) ### Description Change the volume of an output. Grouped zones can have differently behaving volume systems (dB, min/max, steps, etc..), so you have to change the volume different for each of those outputs. ### Method change_volume ### Parameters - **output** (Output) - Required - The output to change the volume on. - **how** ('absolute' | 'relative' | 'relative_step') - Required - How to interpret the volume - **value** (number) - Required - The new volume value, or the increment value or step - **cb** (RoonApiTransport~resultcallback) - Optional - Called on success or error ``` -------------------------------- ### control(zone, control, cbopt) Source: https://roonlabs.github.io/node-roon-api/RoonApiTransport.html Execute transport controls like play, pause, stop, previous, and next on a zone. ```APIDOC ## control(zone, control, cbopt) ### Description Execute a transport control on a zone. Be sure that `is__allowed` is true on your {Zone} before allowing the user to operate controls. ### Method control ### Parameters - **zone** (Zone) - Required - The zone or output - **control** ('play' | 'pause' | 'playpause' | 'stop' | 'previous' | 'next') - Required - The control desired - "play" - If paused or stopped, start playback - "pause" - If playing or loading, pause playback - "playpause" - If paused or stopped, start playback. If playing or loading, pause playback. - "stop" - Stop playback and release the audio device immediately - "previous" - Go to the start of the current track, or to the previous track - "next" - Advance to the next track - **cb** (RoonApiTransport~resultcallback) - Optional - Called on success or error ``` -------------------------------- ### seek(zone, how, seconds, cbopt) Source: https://roonlabs.github.io/node-roon-api/RoonApiTransport.html Seek to a time position within the now playing media. ```APIDOC ## seek(zone, how, seconds, cbopt) ### Description Seek to a time position within the now playing media. ### Method seek ### Parameters - `zone` (Zone|Output) - Required - The zone or output - `how` ('relative'|'absolute') - Required - How to interpret the target seek position - `seconds` (number) - Required - The target seek position - `cb` (RoonApiTransport~resultcallback) - Optional - Called on success or error ### Source other/node-roon-api-transport/lib.js, line 221 ``` -------------------------------- ### load_config(key) Source: https://roonlabs.github.io/node-roon-api/RoonApi.html Loads a key value pair from the configuration data store. Returns the value associated with the given key. ```APIDOC ## load_config(key) ### Description Loads a key value pair from the configuration data store. Returns the value associated with the given key. ### Parameters - **key** (string) - Required - The key to load. ### Returns - **object** - The value associated with the key. ``` -------------------------------- ### change_settings(zone, settings, cbopt) Source: https://roonlabs.github.io/node-roon-api/RoonApiTransport.html Change zone settings such as shuffle, auto_radio, and loop mode. ```APIDOC ## change_settings(zone, settings, cbopt) ### Description Change zone settings. ### Method change_settings ### Parameters - **zone** (Zone) - Required - The zone or output - **settings** (object) - Required - The settings to change - **shuffle** (boolean) - Optional - If present, sets shuffle mode to the specified value - **auto_radio** (boolean) - Optional - If present, sets auto_radio mode to the specified value - **loop** ('loop' | 'loop_one' | 'disabled' | 'next') - Optional - If present, sets loop mode to the specified value. 'next' will cycle between the settings. - **cb** (RoonApiTransport~resultcallback) - Optional - Called on success or error ``` -------------------------------- ### RoonApiTransport.prototype.play_from_here method Source: https://roonlabs.github.io/node-roon-api/other_node-roon-api-transport_lib.js.html Sends a request to play from a specific queue item in a zone or output. The callback receives the message and body. ```javascript RoonApiTransport.prototype.play_from_here = function(zone_or_output, queue_item_id, cb) { var zone_or_output_id = zoid(zone_or_output); var req_args = { zone_or_output_id: zone_or_output_id, queue_item_id: queue_item_id }; this.core.moo.send_request(SVCNAME+"/play_from_here", req_args, (msg, body) => { if (cb) cb(msg, body); }); } ``` -------------------------------- ### group_outputs Source: https://roonlabs.github.io/node-roon-api/other_node-roon-api-transport_lib.js.html Creates a group of synchronized audio outputs. The first output's zone's queue is preserved. ```APIDOC ## group_outputs ### Description Creates a group of synchronized audio outputs. The first output's zone's queue is preserved. ### Method RoonApiTransport.prototype.group_outputs ### Parameters - **outputs** (Output[]) - Required - The outputs to group - **cb** (RoonApiTransport~resultcallback) - Optional - Called on success or error ### Response - **error** (string|false) - false on success, or an error message string ``` -------------------------------- ### standby(output, opts, cbopt) Source: https://roonlabs.github.io/node-roon-api/RoonApiTransport.html Standby an output. ```APIDOC ## standby(output, opts, cbopt) ### Description Standby an output. ### Method standby ### Parameters - `output` (Output) - Required - The output to put into standby - `opts` (object) - Required - Options. If none, specify empty object ({}). - `control_key` (string) - Optional - The `control_key` that identifies the `source_control` that is to be put into standby. If omitted, then all source controls on this output that support standby will be put into standby. - `cb` (RoonApiTransport~resultcallback) - Optional - Called on success or error ### Source other/node-roon-api-transport/lib.js, line 130 ``` -------------------------------- ### toggle_standby(output, opts, [cb]) Source: https://roonlabs.github.io/node-roon-api/other_node-roon-api-transport_lib.js.html Toggles the standby state of an output. The output is specified by the first parameter, and options can include a control_key to identify a specific source_control. The optional callback is called with an error message or false on success. ```APIDOC ## toggle_standby(output, opts, [cb]) ### Description Toggle the standby state of an output. ### Method RoonApiTransport.prototype.toggle_standby ### Parameters - **output** (Output) - Required - The output that should have its standby state toggled. - **opts** (object) - Required - Options. If none, specify empty object ({}). - **opts.control_key** (string) - Optional - The control_key that identifies the source_control that is to have its standby state toggled. - **cb** (function) - Optional - Called on success or error. Receives an error message (string) or false on success. ### Callback - On success: cb(false) - On error: cb(errorMessage) where errorMessage is the error name (e.g., 'NetworkError') or false if success. ``` -------------------------------- ### Connect with token using ws_connect_with_token Source: https://roonlabs.github.io/node-roon-api/lib.js.html Connects to a Roon core using a one-time token. After the transport opens, it sends a registration request with the token and calls ev_registered on the response. Returns the moo object. ```javascript RoonApi.prototype.ws_connect_with_token = function({ host, port, token, onclose }) { var moo = this.ws_connect({ host, port, onclose }) moo.transport.onopen = () => { let args = Object.assign({}, this.extension_reginfo); args.token = token; moo.send_request("com.roonlabs.registry:1/register_one_time_token", args, (msg, body) => { ev_registered.call(this, moo, msg, body); }); }; return moo; } ``` -------------------------------- ### change_volume(output, how, value, cb) Source: https://roonlabs.github.io/node-roon-api/other_node-roon-api-transport_lib.js.html Change the volume of an output. The 'how' parameter determines how the value is interpreted (absolute, relative, or relative_step). ```APIDOC ## change_volume(output, how, value, cb) ### Description Change the volume of an output. Grouped zones can have differently behaving volume systems (dB, min/max, steps, etc..), so you have to change the volume differently for each of those outputs. ### Method RoonApiTransport.prototype.change_volume ### Parameters - **output** (Output) - Required - The output to change the volume on. - **how** ('absolute'|'relative'|'relative_step') - Required - How to interpret the volume. - **value** (number) - Required - The new volume value, or the increment value or step. - **cb** (RoonApiTransport~resultcallback) - Optional - Called on success or error. ### Response Callback receives an error string (e.g., "NetworkError") or false on success. ``` -------------------------------- ### new RoonApiImage(core) Source: https://roonlabs.github.io/node-roon-api/RoonApiImage.html Creates a new RoonApiImage instance to provide image retrieval services. ```APIDOC ## new RoonApiImage(core) ### Description Creates a RoonApiImage service instance bound to the given Core. ### Constructor Parameters - **core** (Core) - Required - The Core providing the service. ### Example ```javascript const image = new RoonApiImage(core); ``` ``` -------------------------------- ### toggle_standby(output, opts, cbopt) Source: https://roonlabs.github.io/node-roon-api/RoonApiTransport.html Toggle the standby state of an output. ```APIDOC ## toggle_standby(output, opts, cbopt) ### Description Toggle the standby state of an output. ### Method toggle_standby ### Parameters - `output` (Output) - Required - The output that should have its standby state toggled. - `opts` (object) - Required - Options. If none, specify empty object ({}). - `control_key` (string) - Optional - The `control_key` that identifies the `source_control` that is to have its standby state toggled. - `cb` (RoonApiTransport~resultcallback) - Optional - Called on success or error ### Source other/node-roon-api-transport/lib.js, line 147 ``` -------------------------------- ### seek(zone, how, seconds, cb) Source: https://roonlabs.github.io/node-roon-api/other_node-roon-api-transport_lib.js.html Seek to a time position within the now playing media. The 'how' parameter specifies whether the seek is relative or absolute. ```APIDOC ## seek(zone, how, seconds, cb) ### Description Seek to a time position within the now playing media. ### Method RoonApiTransport.prototype.seek ### Parameters - **zone** (Zone|Output) - Required - The zone or output. - **how** ('relative'|'absolute') - Required - How to interpret the target seek position. - **seconds** (number) - Required - The target seek position. - **cb** (RoonApiTransport~resultcallback) - Optional - Called on success or error. ### Response Callback receives an error string (e.g., "NetworkError") or false on success. ``` -------------------------------- ### mute_all(how, [cb]) Source: https://roonlabs.github.io/node-roon-api/other_node-roon-api-transport_lib.js.html Mutes or unmutes all zones that are mutable. The 'how' parameter specifies the action ('mute' or 'unmute'). The optional callback is called with an error message or false on success. ```APIDOC ## mute_all(how, [cb]) ### Description Mute/unmute all zones (that are mutable). ### Method RoonApiTransport.prototype.mute_all ### Parameters - **how** (string: 'mute'|'unmute') - Required - The action to take: 'mute' or 'unmute'. - **cb** (function) - Optional - Called on success or error. Receives an error message (string) or false on success. ### Callback - On success: cb(false) - On error: cb(errorMessage) where errorMessage is the error name (e.g., 'NetworkError') or false if success. ``` -------------------------------- ### pause_all(cbopt) Source: https://roonlabs.github.io/node-roon-api/RoonApiTransport.html Pause all zones. ```APIDOC ## pause_all(cbopt) ### Description Pause all zones. ### Method pause_all ### Parameters - **cb** (RoonApiTransport~resultcallback) - Optional - Called on success or error ``` -------------------------------- ### mute(output, how, cb) Source: https://roonlabs.github.io/node-roon-api/other_node-roon-api-transport_lib.js.html Mute or unmute an output. The 'how' parameter specifies whether to mute or unmute. ```APIDOC ## mute(output, how, cb) ### Description Mute/unmute an output. ### Method RoonApiTransport.prototype.mute ### Parameters - **output** (Output) - Required - The output to mute. - **how** ('mute'|'unmute') - Required - The action to take. - **cb** (RoonApiTransport~resultcallback) - Optional - Called on success or error. ### Response Callback receives an error string (e.g., "NetworkError") or false on success. ``` -------------------------------- ### new Item() Source: https://roonlabs.github.io/node-roon-api/Item.html Creates a new Item instance for the Roon API Browse Service. The Item object contains properties that describe the item and its behavior in browse requests. ```APIDOC ## new Item() ### Description Creates a new Item instance for the Roon API Browse Service. The Item object contains properties that describe the item and its behavior in browse requests. ### Constructor `new Item()` ### Properties - **title** (string) - Required - Title for this item - **subtitle** (string) - Optional - Subtitle for this item - **image_key** (string) - Optional - Image for this item. - **item_key** (string) - Optional - Pass this into a `browse` request when the user selects this item - **hint** (string) - Optional - A hint about what this item is. Possible values include: `null` (Unknown--display item generically), `"action"` (This item is an action), `"action_list"` (This item will load a list of actions at the next level), `"list"` (This item will load a list at the next level), `"header"` (A display-only header with no click action). Please make sure that your implementations allow for hints to be added in the future. If you see a hint that you do not recognize, treat it as a `null`. List hint = null | action_list. Item hint = null | action | action_list | list | header. - **input_prompt** (object) - Optional - If loading this item requires user input, then input_prompt will be populated. - **prompt** (string) - Required - The prompt to display to the user: e.g. "Search Albums" - **action** (string) - Required - The verb that goes with this action. This should be displayed on a button adjacent to the input. e.g. "Go" - **value** (string) - Optional - If non-null, then the value should be pre-populated - **is_password** (bool) - Required - If true, then this should be displayed as a password input ### Source - other/node-roon-api-browse/lib.js, line 23 ``` -------------------------------- ### new RoonApi(desc) Source: https://roonlabs.github.io/node-roon-api/RoonApi.html Creates a new RoonApi instance. The desc object provides information about your extension, which Roon displays to the end user when requesting access. ```APIDOC ## new RoonApi(desc) ### Description Creates a new RoonApi instance. The desc object provides information about your extension, which Roon displays to the end user when requesting access. ### Parameters - **desc** (object) - Required - Information about your extension. Used by Roon to display to the end user what is trying to access Roon. - **extension_id** (string) - Required - A unique ID for this extension. Something like @com.your_company_or_name.name_of_extension@. - **display_name** (string) - Required - The name of your extension. - **display_version** (string) - Required - A version string that is displayed to the user for this extension. Can be anything you want. - **publisher** (string) - Required - The name of the developer of the extension. - **website** (string) - Required - Website for more information about the extension. - **log_level** (string) - Required - How much logging information to print. "all" for all messages, "none" for no messages, anything else for all messages not tagged as "quiet" by the Roon core. - **core_paired** (function) - Optional - Called when Roon pairs you. - **core_unpaired** (function) - Optional - Called when Roon unpairs you. - **core_found** (function) - Optional - Called when a Roon Core is found. Usually, you want to implement pairing instead of using this. - **core_lost** (function) - Optional - Called when Roon Core is lost. Usually, you want to implement pairing instead of using this. ### Returns - **RoonApi** - The newly created RoonApi instance. ``` -------------------------------- ### Handle registration events in ev_registered Source: https://roonlabs.github.io/node-roon-api/lib.js.html Handles registration events. On lost connection, notifies pairing service and core_lost callback, then clears the core. On successful registration, creates a Core instance, persists the token, and notifies found_core callbacks. ```javascript function ev_registered(moo, msg, body) { if (!msg) { // lost connection if (moo.core) { if (this.pairing_service_1) this.pairing_service_1.lost_core(moo.core); if (this.extension_opts.core_lost) this.extension_opts.core_lost(moo.core); moo.core = undefined; } } else if (msg.name == "Registered") { moo.core = new Core(moo, this, body, this.logger); let settings = this.get_persisted_state(); if (!settings.tokens) settings.tokens = {}; settings.tokens[body.core_id] = body.token; this.set_persisted_state(settings); if (this.pairing_service_1) this.pairing_service_1.found_core(moo.core); if (this.extension_opts.core_found) this.extension_opts.core_found(moo.core); } } ``` -------------------------------- ### Subscription handling in RoonApi service methods Source: https://roonlabs.github.io/node-roon-api/lib.js.html Handles subscription lifecycle: on subscribe, stores the request keyed by subscription_key; on unsubscribe, removes it and sends "Unsubscribed". The commented line warns to verify req.body.subscription_key exists before deleting. ```javascript this.orig_send_complete.apply(this, arguments); delete(ret._subtypes[subname][req.moo.mooid][this.body.subscription_key]); }; ``` ```javascript s.start(req); if (!ret._subtypes[subname].hasOwnProperty(req.moo.mooid)) { ret._subtypes[subname][req.moo.mooid] = { }; } ret._subtypes[subname][req.moo.mooid][req.body.subscription_key] = req; ``` ```javascript spec.methods[s.unsubscribe_name] = (req) => { // XXX make sure req.body.subscription_key exists or respond send_complete with error delete(ret._subtypes[subname][req.moo.mooid][req.body.subscription_key]); if (s.end) s.end(req); req.send_complete("Unsubscribed"); }; ``` -------------------------------- ### RoonApiBrowse.load Source: https://roonlabs.github.io/node-roon-api/other_node-roon-api-browse_lib.js.html Loads a list of items from the Roon browse hierarchy. The method sends a request to the Roon core and invokes the callback with the result or an error. ```APIDOC ## RoonApiBrowse.load ### Description Loads a list of items from the Roon browse hierarchy. The method sends a request to the Roon core and invokes the callback with the result or an error. ### Method This is a JavaScript method call, not an HTTP endpoint. It is invoked as `browse.load(opts, cb)`. ### Parameters #### opts (object) - Required - **opts.count** (int) - Optional - Number of items to load. Defaults to 100. - **opts.hierarchy** (string) - Required - The hierarchy being browsed. See `browse` for a list of possible values. - **opts.multi_session_key** (string) - Optional - If your application browses several instances of the same hierarchy at the same time, you can populate this to distinguish between them. Most applications will omit this field. #### cb (RoonApiBrowse~loadresultcallback) - Optional Called on success or error. ### Request Example ```javascript browse.load({ count: 100, hierarchy: 'albums', multi_session_key: 'my-session' }, (err, body) => { // handle result }); ``` ### Response #### Success Response - **err** (boolean|string) - `false` on success, or an error name (e.g., `"NetworkError"`) on failure. - **body** (object) - The response body containing the loaded items. #### Response Example ```javascript // err = false, body = { items: [...] } ``` ``` -------------------------------- ### mute_all(how, cbopt) Source: https://roonlabs.github.io/node-roon-api/RoonApiTransport.html Mute or unmute all zones that are mutable. ```APIDOC ## mute_all(how, cbopt) ### Description Mute/unmute all zones (that are mutable). ### Method mute_all ### Parameters - **how** ('mute' | 'unmute') - Required - The action to take - **cb** (RoonApiTransport~resultcallback) - Optional - Called on success or error ``` -------------------------------- ### ws_connect(options) Source: https://roonlabs.github.io/node-roon-api/RoonApi.html Connects to the Roon Core via a websocket, bypassing discovery. This method is used when you already know the host and port of the Core. ```APIDOC ## ws_connect(options) ### Description Connects to the Roon Core via a websocket, bypassing discovery. This method is used when you already know the host and port of the Core. ### Parameters - **options** (object) - Required - Connection options. - **host** (string) - Required - hostname or ip to connect to. - **port** (number) - Required - port to connect to. - **onclose** (function) - Optional - Called once when connect to host is lost. ```