« Back to Guides

Bridge Websocket API

The Pixo Bridge exposes a Websocket-based API to interact with the Pixo Control App. This guide details the structure of messages sent in each direction, and provides example Javascript client code.

Contents

Overview

The Pixo Bridge uses a Websocket-based API to interact with the Pixo Control App, which has two main benefits over a simple HTTP interface:

The messages send between the Bridge and a connected client are categorised as "Commands" or "Emissions":

All Command messages have a cmd key to identify them, and all Emissions have an emit key. See the example code to see how messages can be sent, and emissions identified.

Websocket Command Reference

These messages can be sent from a client to the Pixo Bridge. Some Commands have associated Emissions.

List COM Ports

Instruct the Bridge to list information regarding the COM ports which currently have USB devices connected. These devices may not be Pixo devices.

Related emission: Emit COM Ports

// Command payload
let command = {
  cmd: "list-ports",
};

Connect USB

Connect to the USB device at the specified serial port path.

// Command payload
let command = {
  cmd: "connect-usb",
  // The COM port "path" to connect to
  path: string,
};

Auto-Connect USB

Instruct the Bridge to connect to all available USB devices which are not currently conencted.

// Command payload
let command = {
  cmd: "auto-connect-usb",
};

Disconnect USB

Disconnect from the USB device at the specified serial port path.

// Command payload
let command = {
  cmd: "disconnect-usb",
  // The COM port "path" to disconnect
  path: string,
};

List Connected Devices

Instruct the Bridge to list the currently connected devices.

Related emission: Emit Connected Devices

// Command payload
let command = {
  cmd: "list-devices",
};

Get Device Info

Instruct the Bridge to broadcast an instruction to connected devices to return a payload describing their high-level settings.

Related emission: Emit Device Info

// Command payload
let command = {
  cmd: "device-info",
};

Send Message over USB

Send a message over USB to the device at the specified serial port path.

// Command payload
let command = {
  cmd: "send-usb",
  /** The path to the serial port, e.g. "COM6" */
  path: string,
  /** The message string to send to the device, e.g. "twinkle@star|250|2|Y|W" */
  msg: string,
  /** Always send the message immediately, never enqueue it */
  skipQueue?: boolean,
  /** Do not send a confirmation message to the sender */
  noConfirm?: boolean,
  /** Set flags to forward the message to the device as quickly as possible
   *  - other flags are ignored and not required */
  quick?: boolean,
};

Send Message over UDP

Send a message over UDP to the device at the specified IP address.

UDP is coming soon, but is not currently available in the Bridge

// Command payload
let command = {
  cmd: "send-udp",
  /** The IP address of the device, e.g. "192.168.0.9" */
  address: string,
  /** The message string to send to the device, e.g. "twinkle@star|250|2|Y|W" */
  msg: string,
};

Set Bridge Settings

Set zero or more Bridge settings values. Only settings with specified values are changed.

Whether or not any settings were changed, the Bridge emits its current settings values.

Related emission: Emit Bridge Settings

// Command payload
let command = {
  cmd: "bridge-settings",
  /** Optionally specify a new assets directory */
  assetsDir?: string,
};

Extract Phonemes

"Extract" the phonemes from the given list of words. This is used to control mouth shapes of singing characters so they appear to "sing along" to music.

Related emission: Extracted Phonemes

// Command payload
let command = {
  cmd: "extract-phonemes",
  /** Any ID string used to match the emission response to this request (e.g. `Math.random().toString()`) */
  requestId: string,
  /** The list of words to extract phonemes for */
  words: string[],
};

Open Bridge Assets Directory

Open the Bridge's assets directory using the operating system's file explorer. This can be useful for moving a number of asset files around at once.

// Command payload
let command = {
  cmd: "open-assets-dir",
};

Websocket Emission Reference

These messages are sent from a Pixo Bridge to connected Clients. Some Emissions may be sent to a specific client, some may be broadcasted to all connected clients.

Emit Connected Devices

Emit the list of currently-connected Pixo devices. Each item in the list will either be a USB or UDP device.

This Emission is broadcasted to all clients each time any Pixo device connects to or disconnects from the Bridge.

Emitted in response to: List Connected Devices

// Emission payload
let emission = {
  emit: "connected-devices",
  devices: ({
    type: "usb",
    path: string,
    name?: string,
    persona?: string,
  } | {
    type: "udp",
    address: string,
    name?: string,
    persona?: string,
  })[],
};

Emit COM Ports

Emit information about the COM ports with devices currently connected. These devices may not be Pixo devices.

Emitted in response to: List COM Ports

// Emission payload
let emission = {
  emit: "serial-ports",
  ports: {
    /** e.g. "COM6" */
    path: string,
    /** e.g. "Microsoft" */
    manufacturer: string | undefined,
    /** e.g. "e6609103c3342925" */
    serialNumber: string | undefined,
    /** e.g. "USB\\VID_2E8A&PID_0005&MI_00\\6&13FAD859&0&0000" */
    pnpId: string | undefined,
    /** e.g. "0000.0014.0000.005.004.004.000.000.000" */
    locationId: string | undefined,
    /** e.g. "USB Serial Device (COM6)" */
    friendlyName: string,
    /** e.g. "2E8A" */
    vendorId: string | undefined,
    /** e.g. "0005" */
    productId: string | undefined,
  }[],
};

Emit Device Info

Broadcast information regarding a connected Pixo device. This is broadcasted automatically when a new device is connected.

Emitted in response to: Get Device Info

// Emission payload
let emission = {
  emit: "device-info",
  connType: "usb" | "udp",
  address: string,

  name?: string,
  persona?: string,
  serialNo?: string,

  wifiEnabled?: boolean,
  wifiSsid?: string,

  brightness?: number,

  swVersion?: string,
  hwVersion?: string,
};

Emit Bridge Settings

List the current values of the Bridge settings.

Emitted in response to: Set Bridge Settings

// Emission payload
let emission = {
  emit: "bridge-settings",
  assetsDir: string,
};

Extracted Phonemes

Return the results of a request to extract phonemes.

Emitted in response to: Extract Phonemes

// Emission payload
let emission = {
  emit: "extract-phonemes",
  /** ID string matching that of the request command */
  requestId: string,
  /** The list of words from the request command */
  words: string[],
  /** The results of the phoneme extraction. Each word is paired with the list of extracted phonemes.
   * The list of phonemes may be empty if the word was not found. */
  extracted: {
    word: string,
    phonemes: string[],
  }[],
};

Log

Broadcasts a log message. These may be emitted at any time.

// Emission payload
let emission = {
  emit: "log",
  log: string,
};

Example Client Code

// Example client code to connect to the Pixo Bridge, listen to emissions, and send an example command

const conn = new Websocket("ws://localhost:9000");

conn.on("open", (ev) => {
  console.log(`Bridge connection open`);
});

conn.on("close", (ev) => {
  console.log(`Bridge connection closed`);
});

conn.on("error", (ev) => {
  console.error(`Bridge connection error:`, ev);
});

conn.on("message", (ev) => {
  console.log(`Bridge message:`, ev.data);
  const bridgeMessage = JSON.parse(ev.data);

  switch (bridgeMessage.emit) {
    case "connected-devices":
      // TODO: handle "connected-devices" emission
      break;
    case "device-info":
      // TODO: handle "device-info" emission
      break;
    // etc.
    default:
      console.warn(`Unknown emission:`, bridgeMessage.emit);
  }
});

/** Send a command object to the bridge */
function sendCommand(command) {
  if (conn && conn.readyState === WebSocket.OPEN) {
    const commandStr = JSON.stringify(command);
    conn.send(commandStr);
  } else {
    console.error(`Error sending command:` command);
  }
}

// Send a command
let command = {
  cmd: "auto-connect-usb",
};
sendCommand(command);

Further Reading