Ortho Remote client package for Node.js for interacting with Teenage Engineering's BLE-MIDI Ortho Remote
The ortho-remote
package is designed to support multiple devices simultaneously, provide a high-level abstraction for interaction events, as well as provide access to the raw BLE-MIDI data.
For more information on BLE-MIDI see midi.org
To install ortho-remote
for use within your project use yarn or npm
$ yarn add ortho-remote
ortho-remote
is writing in TypeScript and contains the necessary type definitions, so no need to acquire @type
definitions
It's worth adding help on troubleshooting before you get started. There may be times your Ortho Remote cannot be discovered for various reasons.
If using Linux be sure to check out noble for set up and configuration instructions
A Ortho Remote may have entered a low-power state. Simply interact with the dial or click the dial button to wake a Ortho Remote device up.
BLE-MIDI devices on some OSes can retain paired connections. This can be problematic because once paired Ortho Remote will not be discoverable, leading to timed out connections.
Ensure you have disconnected from an Ortho Remote before running any example or writing code.
You may addtionally have to manually disconnect after each run-debug cycle during development, as has been my experience on macOS as it automatically pairs on connection...
Check out examples for now for more usage.
Clone ortho-remote-node
and run the examples to try things out. package.json contains many example scripts. Alternatively, for Visual Sudio Code users you have access to the pre-configured launch configurations to run the examples.
$ git clone https://github.com/pryomoax/ortho-remote-node.git
$ cd ortho-remote-node
$ yarn install
Run one of the following scripts
# Device discovery
$ yarn device-discovery
# Interaction events
$ yarn events
The first thing you are going to want to do is connect to an unpaired Ortho Remote. The snippet below demonstrates the connection to single device
import { DeviceDiscoveryManager } from 'ortho-remote'
// Device connection manager
const manager = DeviceDiscoveryManager.defaultManager
/**
* Main application entry point
*/
async function main() {
console.log('Starting Ortho Remote discovery')
// Create a new discovery session
const session = manager.startDiscoverySession()
console.log('Waiting for device...')
// Convenience to wait the first discovered Ortho Remote
const device = await session.waitForFirstDevice()
console.log(`Found device '${device.id}'`)
console.log('Connecting...')
// Establish device connection
if (await device.connect()) {
console.log('Connected')
//
// You're connected, observe events and get started...
//
// If the device gets disconnected, exit the app
device.on('disconnect', () => {
console.log('Disconnected! Exiting.')
// On a disconnect, exit
process.exit(0)
})
}
}
// Boot strap async function
main().catch((err) => {
console.log(err)
process.exit(1)
})
ortho-remote
emits events for various interactions. All those interactions are on display in example-events.ts
if (await device.connect()) {
// Button click
device.on('click', () => {
console.log('Clicked!')
})
// Button click, longer than 400ms
device.on('longClick', () => {
console.log('Clicked!')
})
// Rotation
device.on('rotate', (rotation: number, buttonPressed: boolean) => {
console.log(`Rotated: ${rotation}`)
})
}
The abstractions in eventing may not work for everyone so ortho-remote
emits BLE-MIDI events, or can be configured to emit raw data in other events like rotate
` instead of them being normalized.
import { OrthoRemoteConfig } from 'ortho-remote'
// Configure `OrthoRemote` to not normalize data
const orthoConfig: OrthoRemoteConfig = {
normalizeData: false,
}
if (await device.connect(orthoConfig)) {
device.on('rotate', (rotation: number, buttonPressed: boolean) => {
console.log(`Rotated: ${rotation}`)
})
}
To access the BLE-MIDI data in parsed or it's raw form, use the midi
event
import { MidiData } from 'ortho-remote'
if (await device.connect()) {
device.on('midi', (data: MidiData, rawData: Buffer) => {
// Use BLE-MIDI data
})
}
The API documention for the package can be found under docs
Ortho Remote was implemented for MIDI applications, and although some interpretation and abstractions have been implemented there are some current restrictions. Hopefully can be resolved in the future
The package cannot set back a rotation
value back to the Ortho Remote. This makes some applications difficult when needing to sync a existing value to an OrthoRemote
object. For example, matching a volume level between devices.
As humans we are not to precise with some interactions. Ortho Remotes can send rotation events when depressing/releasing the Ortho Remote button.
I hope to implement event filtering as an option to make it more reliable to use for some applications