lms-cli-notifications
TypeScript icon, indicating that this package has built-in type declarations

1.0.0 • Public • Published

lms-cli-notifications

Node module for subscribing to and receiving notifications through Logitech Media Server's CLI.

Where in CLI, you subscribe to notifications as follows:

// Telnet to LMS
$ telnet <server_address>:<cli_port>

// Subscribe to 'mixer' notifications
# subscribe mixer

// Also subscribe to 'play' and 'pause' notifications
# subscribe mixer,play,pause

// Unsubscribe from 'play' notifications
# subscribe mixer,pause

// Output when player volume changes:
40%3A61%3A86%3Af0%3A8f%3A19 mixer volume 80

In Node.JS, you would do this:

// ESM
import { NotificationListener } from 'lms-cli-notifications';
// CJS
const { NotificationListener } = require('lms-cli-notifications');

const server = {
  host: '<server_address>',
  port: '<cli_port>'
};

const notificationListener = new NotificationListener({
  server,
  subscribe: 'mixer' // Subscribe to 'mixer' notifications
});

notificationListener.on('notification', (data) => {
  const {playerId, notification, params} = data;
  console.log({playerId, notification, params});
});

await notificationListener.start();

// Also subscribe to 'play' and 'pause' notifications
await notificationListener.subscribe(['play', 'pause']);

// Unsubscribe from 'play' notifications
await notificationListener.unsubscribe('play');

...

// Output when player volume changes:
{
  playerId: '40:61:86:f0:8f:19',
  notification: 'mixer',
  params: [ 'volume', '50' ]
}

Do not confuse subscription in this context with the subscribe tag in queries (which this library does not support).

Install

npm install --save lms-cli-notifications

API

Class: NotificationListener

A NotificationListener encapsulates the process of connecting to a Logitech Media Server's CLI, subscribing to notifications and receiving them (communicating back by way of Events). You would begin by first creating a NotificationListener instance.

new NotificationListener([params])

Creates a NotificationListener instance and associates it with server, or 127.0.0.1:9090 if not specified.

Params

  • params: (NotificationListenerParams) (optional and all properties optional)
    • server:
      • host: (string) address of server to connect to (default: '127.0.0.1`).
      • port: (string) server's CLI port (default: '9090').
      • username: (string) username for login - omit if not applicable.
      • password: (string) password for login - omit if not applicable.
    • subscribe: (string | Array<string>)
      • If string, the notification to subscribe to.
      • If array, the list of notifications to subscribe to.

The subscribe param is included merely for convenience. You can subscribe to notifications at any stage by calling subscribe(). So the following:

const server = { ... };
const notifications = ['client', 'mixer'];

const notificationListener = new NotificationListener({ 
  server,
  subscribe: notifications
});
notificationListener.start();

has the same effect as:

...
const notificationListener = new NotificationListener({ server });
notificationListener.subscribe(notifications);

notificationListener.start();

notificationListener.start()

Establishes connection with the server and subscribes to the notification(s) specified at construction time.

Returns

Promise that resolves to true on success.


notificationListener.stop()

Terminates connection with the server.

Returns

Promise that resolves to true on success.


notificationListener.isConnected()

Whether the NotificationListener instance is connected to the server.

Returns

Boolean


notificationListener.subscribe(notification)

Subscribes to notification.

If server is not yet connected, subscription will be deferred until connection is established.

Params

  • notification (string | Array<string>):
    • If string, a single notification to subscribe to.
    • If array, the list of notifications to subscribe to.

Returns

  • If server is not yet connected, a Promise that resolves after adding notification to the list of pending subscriptions.
  • If server is already connected, a Promise that resolves on successful subscription.
notificationListener.unsubscribe(notification)

Unsubscribes from notification.

Params

  • notification (string | Array<string>):
    • If string, a single notification to unsubscribe from.
    • If array, the list of notifications to unsubscribe from.

Returns

  • If server is not yet connected, a Promise that resolves when notification is removed from the list of pending subscriptions.
  • If server is already connected, a Promise that resolves on successful unsubscription.

notificationListener.getSubscribed()

Returns the list of currently-subscribed notifications. The list will be empty if there is no connection with the server.

Returns

Array<string>


Events

notificationListener.on('connect', (server) => ...)

Emitted when connection to server is established.

Listener Params

  • server:
    • host: (string)
    • port: (string)

notificationListener.on('disconnect', (server) => ...)

Emitted when server is disconnected.

Listener Params

  • server:
    • host: (string)
    • port: (string)

notificationListener.on('notification', (data) => ...)

Emitted when a subscribed notification is received.

NotificationListener parses the raw message received from the server and converts it from something like this:

08%3A00%3A27%3Aa0%3Ad1%3A2c mixer volume 70

into this:

Property Value
playerId <string>* '08:00:27:a0:d1:2c'
notification <string> 'mixer'
params <Array> ['volume', '70']
raw <string> '08%3A00%3A27%3Aa0%3Ad1%3A2c mixer volume 70'
server <Object> { host: ..., port: ... }

Listener Params

  • data: (Notification)
    • playerId: (string)
    • notification: (string)
    • params: (Array<string>)
    • raw: (string) unprocessed notification message
    • server: (object)
      • host: (string)
      • port: (string)

Notifications that are not associated with a specific player, such as 'rescan', will not have the playerId param.


Errors

Breaking change from v0.x to v1.x

In v0.x, error codes are defined as standalone constants.

In v1.x, they are defined in the NotificationListenerErrorCode enum.

notificationListener.start()
  .then(() => {
    ...
  })
  .catch((err) => {
    ...
  });

Where an error is an instance of NotificationListenerError, you can obtain more information about it:

if (err instanceof NotificationListenerError) {
  console.log(`
    Error: ${ err.message },
    Code: ${ err.code },   // Can be undefined
    Cause: ${ err.cause }  // Underlying error (can be undefined)
  `);
  ...
}

Error codes

Enum: NotificationListenerErrorCode Description
AuthError Login attempt failed for a password-protected server.
SendCommandError A command could not be sent to the server. The underlying error can be obtained from err.cause.
CommandResponseTimeout After sending a command to the server, a response is expected but not received within a timeout period of 5 seconds.

Running the Example

// ESM
npm run example -- -h [server address] -p [server CLI port] -u [username] -pw [password]

// CJS
node index.cjs -h [server address] -p [server CLI port] -u [username] -pw [password]

Only include options that are applicable. Generally, you do not have to specify -p since most LMS installations use the default 9090 port for CLI.

Changelog

1.0.0:

  • Migrate to TypeScript and package as ESM / CJS hybrid module

0.1.2:

  • Fix blank credentials causing login timeout

0.1.1:

  • Fix example

0.1.0:

  • Initial release

License

MIT

Package Sidebar

Install

npm i lms-cli-notifications

Weekly Downloads

3

Version

1.0.0

License

MIT

Unpacked Size

120 kB

Total Files

40

Last publish

Collaborators

  • patrickkfkan