docs/doc/integrations.mdx
Omi is the world's most advanced open-source AI wearable platform. Our mission is to build an open ecosystem for seamless communication, and that includes enabling a wide range of hardware.
This guide will walk you through integrating third-party wearable devices—like Plaud AI, Limitless, or your own custom hardware—into the Omi app. By doing so, you can leverage Omi's powerful features, including high-quality transcription, conversation memory, and a growing app marketplace, for any device.
Integrating a new device involves two main phases:
<CardGroup cols={2}> <Card title="1. Reverse Engineering" icon="magnifying-glass"> Understanding how the device communicates. This typically means capturing and analyzing its Bluetooth Low Energy (BLE) traffic to decode its protocol for commands and data streaming. </Card> <Card title="2. Software Integration" icon="code"> Writing code within the Omi mobile app to manage the connection, communication, and data processing for the new device. </Card> </CardGroup> <Note> This guide focuses on devices that stream audio data, but the principles apply to other data types as well. </Note>Before you begin, ensure you have the following:
<CardGroup cols={2}> <Card title="The Hardware" icon="microchip"> The third-party device you want to integrate </Card> <Card title="Android Phone" icon="android"> Highly recommended for superior BLE traffic capturing capabilities </Card> <Card title="Wireshark" icon="chart-network"> Essential tool for analyzing captured network traffic </Card> <Card title="Omi App Codebase" icon="code-branch"> A local development setup of the Omi app </Card> </CardGroup>| Skill | Level | Description |
|---|---|---|
| BLE Concepts | Basic | Services, Characteristics, UUIDs |
| Dart/Flutter | Intermediate | For app integration |
| Python | Optional | For writing verification scripts |
Your first goal is to become a detective. You need to learn the device's language, which for most wearables is spoken over Bluetooth Low Energy (BLE).
The most effective way to learn the protocol is to capture the communication between the device and its official app.
<Tabs> <Tab title="Android (Recommended)" icon="android"> <Steps> <Step title="Enable Developer Options"> Go to **Settings → About phone** and tap **Build number** seven times. </Step> <Step title="Enable ADB & Snoop Log"> Go to **Settings → System → Developer options**. Enable: - USB debugging - Enable Bluetooth HCI snoop log </Step> <Step title="Restart Bluetooth"> Turn Bluetooth off and on again for the change to take effect. </Step> <Step title="Generate Traffic"> Use the official vendor app to connect to your device. Perform key operations like starting and stopping a recording, changing settings, etc. <Tip>
Record a video of your phone's screen while you perform actions. This will be invaluable when matching timestamps in Wireshark to see which action generated which BLE command.
</Tip>
</Step>
<Step title="Retrieve the Log">
After capturing, disable the snoop log.
**Non-Rooted Devices:** Generate a bug report from Developer options. The log file `btsnoop_hci.log` will be in the ZIP archive under `FS/data/misc/bluetooth/logs/`.
**Rooted Devices:** Pull directly using ADB:
```bash
adb pull /data/misc/bluetooth/logs/btsnoop_hci.log
```
</Step>
<Step title="Analyze in Wireshark">
Open the `btsnoop_hci.log` file in [Wireshark](https://www.wireshark.org/).
<Info>
To find your device's address: `adb shell dumpsys bluetooth_manager`
</Info>
</Step>
</Steps>
<AccordionGroup>
<Accordion title="Option A: Manual Exploration (Quick Start)" icon="hand-pointer">
Apps like [nRF Connect](https://www.nordicsemi.com/Products/Development-tools/nrf-connect-for-mobile) or [LightBlue](https://apps.apple.com/us/app/lightblue-explorer/id557428110) allow you to manually explore your device's services and characteristics. This requires more trial and error but can quickly reveal basic information about UUIDs and simple data formats.
</Accordion>
<Accordion title="Option B: Full Packet Capture with PacketLogger (Recommended)" icon="file-lines">
**Requirements:**
- iOS 13+ device and Lightning/USB-C cable
- Mac computer with macOS
- [Apple Developer Program account](https://developer.apple.com/programs/) (free tier works)
<Steps>
<Step title="Install the Bluetooth Debugging Profile">
On your iOS device, open Safari and navigate to:
```
https://developer.apple.com/bug-reporting/profiles-and-logs/?name=bluetooth
```
Sign in, download the profile, and install it via **Settings → Profile Downloaded**.
</Step>
<Step title="Install Xcode and PacketLogger">
1. Install [Xcode](https://developer.apple.com/xcode/) from the Mac App Store
2. Download **Additional Tools for Xcode** from [Apple's downloads page](https://developer.apple.com/download/all/?q=Additional%20Tools)
3. Find **PacketLogger.app** in the Hardware folder and copy to Applications
</Step>
<Step title="Capture BLE Traffic">
1. Connect your iOS device to your Mac via cable
2. Open PacketLogger and go to **File → New iOS Trace**
3. A pulse icon appears on your iOS device indicating active trace
4. Use the vendor's app to interact with your device
5. Stop and save the capture when finished
</Step>
<Step title="Analyze">
PacketLogger provides excellent built-in analysis, or export to Wireshark via **File → Export** (`.pcap` or `.pklg` format).
</Step>
</Steps>
**PacketLogger Features:**
- Decodes all Bluetooth SIG-defined protocols
- Rich filtering options and text/regex search
- Ability to comment and flag packets
- Export for Wireshark analysis
</Accordion>
</AccordionGroup>
With your log file open, it's time to find the important packets.
<CardGroup cols={2}> <Card title="Filter by Device" icon="filter"> Find your device's address and apply a display filter to isolate its traffic </Card> <Card title="Look for Patterns" icon="chart-line"> For audio streaming, look for large numbers of similar-sized packets sent rapidly </Card> <Card title="Inspect Packet Details" icon="magnifying-glass"> Look for GATT Service UUID, Characteristic UUID, and raw data payload </Card> <Card title="Map the Services" icon="sitemap"> Create a "map" of Service UUIDs, Characteristic UUIDs, and Data Formats </Card> </CardGroup> <Info> **Key Information to Find:** - **Service UUIDs:** High-level containers (e.g., "Audio Service", "Device Information Service") - **Characteristic UUIDs:** Specific data endpoints (e.g., "Audio Stream Data", "Battery Level") - **Data Format:** Encoding of the payload (e.g., Opus, PCM, µ-law, AAC) </Info>The data payload is a hexadecimal string. Your task is to figure out its structure.
<AccordionGroup> <Accordion title="Example: Identifying Opus Frames" icon="waveform"> Let's say you capture several 240-byte data packets. You notice the first byte is always `b8`, and this byte reappears every 40 bytes within the same packet.This is a strong clue! The Opus audio codec uses a Table of Contents (TOC) byte at the start of each frame. The repeating `b8` byte suggests the packet contains six 40-byte Opus frames.
Before integrating, write a small standalone script to confirm your assumptions.
# Example verification using Python and Bleak
import asyncio
from bleak import BleakClient
DEVICE_MAC = "XX:XX:XX:XX:XX:XX"
AUDIO_CHAR_UUID = "your-characteristic-uuid"
async def main():
async with BleakClient(DEVICE_MAC) as client:
def callback(sender, data):
# Decode and verify audio data
print(f"Received {len(data)} bytes")
await client.start_notify(AUDIO_CHAR_UUID, callback)
await asyncio.sleep(10) # Record for 10 seconds
asyncio.run(main())
Now, let's integrate your device into the Omi app's modular architecture.
| Component | Location | Purpose |
|---|---|---|
DeviceConnection | .../device_connection.dart | Abstract class defining the standard interface for all devices |
DeviceTransport | .../transports/ble_transport.dart | Low-level BLE communication handler |
DeviceConnectionFactory | .../device_connection.dart | Constructs the correct connection object based on DeviceType |
```dart
enum DeviceType {
omi,
openglass,
frame,
appleWatch,
plaud,
xyz, // Add your new device type here
}
```
Also update `getTypeOfBluetoothDevice` function and create a helper (e.g., `isXyzDevice`) to identify your device during Bluetooth scans.
```dart
import 'dart:async';
import 'package:omi/backend/schema/bt_device/bt_device.dart';
import 'package:omi/services/devices/device_connection.dart';
import 'package:omi/services/devices/models.dart';
// Define your device's specific UUIDs
const String xyzAudioServiceUuid = '0000...';
const String xyzAudioStreamUuid = '0000...';
const String xyzButtonUuid = '0000...';
class XyzConnection extends DeviceConnection {
XyzConnection(super.device, super.transport);
@override
Future<BleAudioCodec> performGetAudioCodec() async {
// Return the audio codec your device uses
return BleAudioCodec.opus;
}
@override
Future<StreamSubscription?> performGetBleAudioBytesListener({
required void Function(List<int> p1) onAudioBytesReceived,
}) async {
// Subscribe to your device's audio characteristic
final stream = transport.getCharacteristicStream(
xyzAudioServiceUuid,
xyzAudioStreamUuid
);
return stream.listen(onAudioBytesReceived);
}
@override
Future<int> performRetrieveBatteryLevel() async {
// Most devices use standard BLE Battery Service
return super.performRetrieveBatteryLevel();
}
}
```
```dart
class DeviceConnectionFactory {
static DeviceConnection? create(BtDevice device) {
switch (device.type) {
// ... other cases
case DeviceType.appleWatch:
return AppleWatchDeviceConnection(device, transport);
// Add your new case
case DeviceType.xyz:
return XyzConnection(device, transport);
}
}
}
```
Test your integration thoroughly within the Omi app:
| Test | Description |
|---|---|
| Discovery & Connection | Can you successfully discover and connect to the device? |
| Live Transcription | Does real-time transcription work as expected? |
| Battery Level | Is the battery level displayed correctly? |
| Stability | Is the connection stable? Does it handle reconnection gracefully? |
Omi is built by the community. If you've integrated a new device, we strongly encourage you to contribute it back!
<Steps> <Step title="Check the Contribution Guide"> Review our [Contribution Guide](/doc/developer/Contribution) for code standards and PR process. </Step> <Step title="Open a Pull Request"> Submit your integration to the [Omi GitHub repository](https://github.com/BasedHardware/omi). </Step> <Step title="Join the Community"> Discuss your integration with the team and community on [Discord](http://discord.omi.me). </Step> </Steps> <Tip> We offer [paid bounties](https://omi.me/bounties) for specific features and integrations. Check them out! </Tip>