# Omi SDK for React Native A React Native SDK for connecting to and interacting with Omi devices via Bluetooth Low Energy (BLE). ## Features - Scan for nearby Omi devices - Connect to Omi devices - Get device audio codec information - Stream audio data from the device - Monitor battery levels - Handle connection state changes - Real-time audio transcription using Deepgram ## Development Setup ### Prerequisites - Node.js and npm installed - Xcode (for iOS development) - Android Studio (for Android development) - CocoaPods (for iOS development) ### Installation 1. Clone the repository and navigate to the react-native directory: ```bash git clone https://github.com/BasedHardware/omi.git cd sdks/react-native ``` 2. Install dependencies: ```bash npm install ``` 3. Navigate to the example app directory and install its dependencies: ```bash cd example npm install ``` 4. For iOS development, install CocoaPods dependencies: ```bash cd ios pod install ``` Note: The `pod install` step is crucial and must not be skipped for iOS development. Without it, the app will fail to build with native module errors. ### Running the Example App #### iOS 1. Make sure you've completed all installation steps above 2. Open the example app's workspace in Xcode: ```bash cd example/ios open OmiSDKExample.xcworkspace # Do NOT open the .xcodeproj file ``` 3. Select your target device (Note: Bluetooth functionality is not available in simulators) 4. Build and run the project #### Android 1. Connect your Android device via USB 2. Enable USB debugging on your device 3. Run the app: ```bash cd example npm run android ``` ## Installation in Your Project ```bash npm install @omiai/omi-react-native # or yarn add @omiai/omi-react-native ``` ### Dependencies This SDK relies on [react-native-ble-plx](https://github.com/Polidea/react-native-ble-plx) for BLE communication. ```bash npm install react-native-ble-plx # or yarn add react-native-ble-plx ``` After installing the dependencies, for iOS projects you MUST run: ```bash cd ios pod install ``` ### Platform-Specific Setup For iOS, add the following to your `Info.plist`: ```xml NSBluetoothAlwaysUsageDescription This app uses Bluetooth to connect to Omi devices NSBluetoothPeripheralUsageDescription This app uses Bluetooth to connect to Omi devices ``` For Android, add the following permissions to your `AndroidManifest.xml`: ```xml ``` ## Usage ### Basic Example ```javascript import { OmiConnection, DeviceConnectionState, BleAudioCodec } from '@omiai/omi-react-native'; // Create an instance of OmiConnection const omiConnection = new OmiConnection(); // Scan for devices const stopScan = omiConnection.scanForDevices((device) => { console.log('Found device:', device.name, device.id); }, 10000); // Scan for 10 seconds // Connect to a device async function connectToDevice(deviceId) { const success = await omiConnection.connect(deviceId, (id, state) => { console.log(`Device ${id} connection state changed to: ${state}`); }); if (success) { console.log('Connected successfully!'); // Get the audio codec const codec = await omiConnection.getAudioCodec(); console.log('Device audio codec:', codec); // Start listening for audio data const subscription = await omiConnection.startAudioBytesListener((bytes) => { console.log('Received audio bytes:', bytes.length); // Process audio bytes here }); // Get battery level const batteryLevel = await omiConnection.getBatteryLevel(); console.log('Battery level:', batteryLevel); // Later, stop listening for audio await omiConnection.stopAudioBytesListener(subscription); // Disconnect when done await omiConnection.disconnect(); } } ``` ## API Reference ### OmiConnection The main class for interacting with Omi devices. #### Methods ##### `scanForDevices(onDeviceFound, timeoutMs = 10000)` Scans for nearby Omi devices. - `onDeviceFound`: Callback function that receives an OmiDevice object when a device is found - `timeoutMs`: Scan timeout in milliseconds (default: 10000) - Returns: A function to stop scanning ##### `connect(deviceId, onConnectionStateChanged)` Connects to an Omi device. - `deviceId`: The ID of the device to connect to - `onConnectionStateChanged`: Optional callback for connection state changes - Returns: Promise that resolves to a boolean indicating success ##### `disconnect()` Disconnects from the currently connected device. - Returns: Promise that resolves when disconnected ##### `isConnected()` Checks if connected to a device. - Returns: Boolean indicating if connected ##### `getAudioCodec()` Gets the audio codec used by the device. - Returns: Promise that resolves with the audio codec (BleAudioCodec enum) ##### `startAudioBytesListener(onAudioBytesReceived)` Starts listening for audio bytes from the device. - `onAudioBytesReceived`: Callback function that receives audio bytes as a number array - Returns: Promise that resolves with a subscription that can be used to stop listening ##### `stopAudioBytesListener(subscription)` Stops listening for audio bytes. - `subscription`: The subscription returned by startAudioBytesListener - Returns: Promise that resolves when stopped ##### `getBatteryLevel()` Gets the current battery level from the device. - Returns: Promise that resolves with the battery level percentage (0-100) ### Types #### OmiDevice ```typescript interface OmiDevice { id: string; name: string; rssi: number; } ``` #### DeviceConnectionState ```typescript enum DeviceConnectionState { CONNECTED = 'connected', DISCONNECTED = 'disconnected' } ``` #### BleAudioCodec ```typescript enum BleAudioCodec { PCM16 = 'pcm16', PCM8 = 'pcm8', OPUS = 'opus', UNKNOWN = 'unknown' } ``` ## Troubleshooting ### Common Issues 1. **Build fails with native module errors on iOS** - Ensure you've run `pod install` in the ios directory - Try cleaning the build folder in Xcode (Product → Clean Build Folder) - Make sure you're opening the `.xcworkspace` file, not the `.xcodeproj` file 2. **Device not found during scanning** - Ensure Bluetooth is enabled on your device - Check that you have the necessary permissions - Make sure the Omi device is powered on and in range - Note: Bluetooth scanning does not work in iOS simulators, use a physical device 3. **Connection fails** - Try restarting the Omi device - Ensure the device is not connected to another application - Check battery level of the Omi device 4. **Audio data not received** - Verify that the device supports the audio service - Check that you're properly handling the audio bytes in your callback 5. **Transcription not working** - Ensure you have a valid Deepgram API key - Check that the audio listener is started before enabling transcription - Verify your internet connection is stable 6. **Keyboard overlaps input fields** - The example app includes padding at the bottom of the ScrollView to ensure input fields remain visible when the keyboard is open ## License MIT