{"id":24929979,"url":"https://github.com/happycodelucky/ortho-remote-node","last_synced_at":"2025-04-09T21:51:09.370Z","repository":{"id":43001028,"uuid":"171184673","full_name":"happycodelucky/ortho-remote-node","owner":"happycodelucky","description":"Node.js package for interfacing with Teenage Engineering's Ortho Remote","archived":false,"fork":false,"pushed_at":"2023-03-04T04:11:32.000Z","size":1560,"stargazers_count":39,"open_issues_count":6,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-09T21:51:03.933Z","etag":null,"topics":["ble","ble-midi","nodejs","npm-package","orthoremote","puck","teenage-engineering"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/happycodelucky.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-02-17T23:31:24.000Z","updated_at":"2024-09-19T18:01:58.000Z","dependencies_parsed_at":"2023-02-06T12:00:42.054Z","dependency_job_id":null,"html_url":"https://github.com/happycodelucky/ortho-remote-node","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/happycodelucky%2Fortho-remote-node","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/happycodelucky%2Fortho-remote-node/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/happycodelucky%2Fortho-remote-node/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/happycodelucky%2Fortho-remote-node/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/happycodelucky","download_url":"https://codeload.github.com/happycodelucky/ortho-remote-node/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248119403,"owners_count":21050754,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ble","ble-midi","nodejs","npm-package","orthoremote","puck","teenage-engineering"],"created_at":"2025-02-02T13:52:35.756Z","updated_at":"2025-04-09T21:51:09.340Z","avatar_url":"https://github.com/happycodelucky.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![License](https://img.shields.io/github/license/pryomoax/ortho-remote-node.svg?style=for-the-badge)](./LICENSE)\n![Node](https://img.shields.io/npm/v/ortho-remote.svg?style=for-the-badge\u0026label=version)\n[![Maintained](https://img.shields.io/badge/Maintained%3F-yes-green.svg?style=for-the-badge)](https://github.com/pryomoax/ortho-remote-node/graphs/commit-activity)\n\nOrtho Remote client package for Node.js for interacting with [Teenage Engineering](https://www.teenageengineering.com)'s BLE-MIDI [Ortho Remote](https://www.teenageengineering.com/products/orthoremote)\n\nThe `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](https://github.com/skratchdot/ble-midi/blob/master/pdf/Apple-Bluetooth-Low-Energy-MIDI-Specification.pdf) data.\n\nFor more information on BLE-MIDI see [midi.org](https://www.midi.org/midi/specifications/item/bluetooth-le-midi)\n\n![Ortho Remote](https://github.com/pryomoax/ortho-remote-node/raw/main/assets/ortho.png)\n\n- [Installation](#installation)\n- [Troubleshooting](#troubleshooting)\n  * [Linux Permissions](#linux-permissions)\n  * [Low Power States](#low-power-states)\n  * [Persistent Pairing (Not Advertising)](#persistent-pairing--not-advertising-)\n- [Getting Started](#getting-started)\n  * [Examples](#examples)\n  * [Getting Connected](#getting-connected)\n  * [Listening for Events](#listening-for-events)\n  * [Accessing Raw Data](#accessing-raw-data)\n- [API](#api)\n- [Known Issues](#known-issues)\n  * [Rotation Limitations](#rotation-limitations)\n  * [Event Filtering](#event-filtering)\n\n# Installation\nTo install `ortho-remote` for use within your project use [yarn](https://yarnpkg.com) or [npm](https://npmjs.com)\n\n```bash\n$ yarn add ortho-remote\n```\n\n`ortho-remote` is writing in TypeScript and contains the necessary type definitions, so no need to acquire `@type` definitions\n\n# Troubleshooting\nIt's worth adding help on troubleshooting before you get started. There may be times your Ortho Remote cannot be discovered for various reasons.\n\n## Linux Permissions\n\nIf using Linux be sure to check out  [noble](https://github.com/noble/noble) for set up and configuration instructions\n\n## Low Power States\n\nA 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.\n\n## Persistent Pairing (Not Advertising)\n\nBLE-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.\n\n**Ensure you have disconnected** from an Ortho Remote before running any example or writing code.\n\nYou 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...\n\n![disconnect](https://github.com/pryomoax/ortho-remote-node/raw/master/assets/ortho-disconnect.png)\n\n\n# Getting Started\n\nCheck out [examples](./examples) for now for more usage.\n\n## Examples\n\nClone `ortho-remote-node` and run the examples to try things out. [package.json](./package.json) contains many example scripts. Alternatively, for [Visual Sudio Code](https://code.visualstudio.com/) users you have access to the pre-configured launch configurations to run the examples.\n\n```bash\n$ git clone https://github.com/pryomoax/ortho-remote-node.git\n$ cd ortho-remote-node\n$ yarn install\n```\n\nRun one of the following scripts\n\n```bash\n# Device discovery\n$ yarn device-discovery\n\n# Interaction events\n$ yarn events\n```\n\n## Getting Connected\n\nThe 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\n\n```typescript\nimport { DeviceDiscoveryManager } from 'ortho-remote'\n\n// Device connection manager\nconst manager = DeviceDiscoveryManager.defaultManager\n\n/**\n * Main application entry point\n */\nasync function main() {\n    console.log('Starting Ortho Remote discovery')\n\n    // Create a new discovery session\n    const session = manager.startDiscoverySession()\n\n    console.log('Waiting for device...')\n\n    // Convenience to wait the first discovered Ortho Remote\n    const device = await session.waitForFirstDevice()\n\n    console.log(`Found device '${device.id}'`)\n    console.log('Connecting...')\n\n    // Establish device connection\n    if (await device.connect()) {\n        console.log('Connected')\n\n        //\n        // You're connected, observe events and get started...\n        //\n\n        // If the device gets disconnected, exit the app\n        device.on('disconnect', () =\u003e {\n            console.log('Disconnected! Exiting.')\n\n            // On a disconnect, exit\n            process.exit(0)\n        })\n    }\n}\n\n// Boot strap async function\nmain().catch((err) =\u003e {\n    console.log(err)\n    process.exit(1)\n})\n```\n\n## Listening for Events\n\n`ortho-remote` emits events for various interactions. All those interactions are on display in [example-events.ts](./examples/02-events/example-events.ts)\n\n```typescript\nif (await device.connect()) {\n    // Button click\n    device.on('click', () =\u003e {\n        console.log('Clicked!')\n    })\n\n    // Button click, longer than 400ms\n    device.on('longClick', () =\u003e {\n        console.log('Clicked!')\n    })\n\n    // Rotation\n    device.on('rotate', (rotation: number, buttonPressed: boolean) =\u003e {\n        console.log(`Rotated: ${rotation}`)\n    })\n}\n```\n\n## Accessing Raw Data\n\nThe 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.\n\n```typescript\nimport { OrthoRemoteConfig } from 'ortho-remote'\n\n// Configure `OrthoRemote` to not normalize data\nconst orthoConfig: OrthoRemoteConfig = {\n    normalizeData: false,\n}\n\nif (await device.connect(orthoConfig)) {\n    device.on('rotate', (rotation: number, buttonPressed: boolean) =\u003e {\n        console.log(`Rotated: ${rotation}`)\n    })\n}\n```\n\nTo access the [BLE-MIDI](https://github.com/skratchdot/ble-midi/blob/master/pdf/Apple-Bluetooth-Low-Energy-MIDI-Specification.pdf) data in parsed or it's raw form, use the `midi` event\n\n```typescript\nimport { MidiData } from 'ortho-remote'\n\nif (await device.connect()) {\n    device.on('midi', (data: MidiData, rawData: Buffer) =\u003e {\n        // Use BLE-MIDI data\n    })\n}\n```\n\n# API\n\nThe API documention for the package can be found under [docs](docs/api/README.md)\n\n# Known Issues\n\nOrtho 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\n\n## Rotation Limitations\nThe 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.\n\n## Event Filtering\nAs humans we are not to precise with some interactions. Ortho Remotes can send rotation events when depressing/releasing the Ortho Remote button.\n\nI hope to implement event filtering as an option to make it more reliable to use for some applications\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhappycodelucky%2Fortho-remote-node","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhappycodelucky%2Fortho-remote-node","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhappycodelucky%2Fortho-remote-node/lists"}