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
- Websocket Command Reference
- Websocket Emission Reference
- Example Client Code
- Further Reading
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:
- easy emission of messages from the Bridge to the App
- less overhead when sending instructions quickly from the App to the Bridge
The messages send between the Bridge and a connected client are categorised as "Commands" or "Emissions":
- Commands are send from the client to the bridge
- Emissions are send from the bridge to the client
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
- Connect USB
- Auto-Connect USB
- Disconnect USB
- List Connected Devices
- Get Device Info
- Send Message over USB
- Send Message over UDP
- Set Bridge Settings
- Extract Phonemes
- Open Bridge Assets Directory
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);