rtl_ir_control 1.0.1
rtl_ir_control: ^1.0.1 copied to clipboard
A utility designed to simplify the setup and configuration of Remotec products using Bluetooth Low Energy (BLE).
rtl_ir_control #
A Flutter package for setup and controlling infrared (IR) devices via Bluetooth. This package leverages
esp_blufi and flutter_blue_plus to set up and manage Bluetooth Low Energy (BLE) connections and
download ir code from api call to device.
Features #
- Device scanning and connection management using BLE.
- Blufi setup for Roomate devices.
- Downloading IR code for device control.
Dependencies #
This package relies on the following external packages:
esp_blufi: For BLE communication with ESP-based devices.flutter_blue_plus: For Bluetooth Low Energy operations on Android and iOS.
Setup #
Permission #
To use this package, you must configure Bluetooth permissions for your Flutter app. Below are the steps for Android and iOS.
Android #
Add the following to android/app/src/main/AndroidManifest.xml:
<!-- Tell Google Play Store that your app uses Bluetooth LE
Set android:required="true" if bluetooth is necessary -->
<uses-feature android:name="android.hardware.bluetooth_le" android:required="false" />
<!-- New Bluetooth permissions in Android 12
https://developer.android.com/about/versions/12/features/bluetooth-permissions -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- legacy for Android 11 or lower -->
<uses-permission android:maxSdkVersion="30" android:name="android.permission.BLUETOOTH" />
<uses-permission android:maxSdkVersion="30" android:name="android.permission.BLUETOOTH_ADMIN" />
<!-- legacy for Android 9 or lower -->
<uses-permission android:maxSdkVersion="28"
android:name="android.permission.ACCESS_COARSE_LOCATION" />
iOS #
- In the
ios/Runner/Info.plistlet’s add:
<dict>
<key>NSBluetoothAlwaysUsageDescription</key>
<string>This app needs Bluetooth to function</string>
</dict>
- To use ble in app background, add the following to your Info.plist
<dict>
<key>UIBackgroundModes</key>
<array>
<string>bluetooth-central</string>
</array>
</dict>
Note: Ensure that Bluetooth and location permissions have been granted for the app.
How to use #
1. Scan Devices #
Scan for Roomate devices using a name prefix filter.
import 'package:rtl_ir_control/rtl_ir_control.dart';
void scanDevices() {
// make sure all permissions were granted
_rtlIrControlPlugin.startScan(namePrefix: ['Roomate']);
}
2. Setup Device #
Connect to a device, scan for Wi-Fi networks, and configure Wi-Fi credentials.
import 'package:rtl_ir_control/rtl_ir_control.dart';
Future<void> setupDevice(String id) async {
final blufi = RTLBlufiSetupUtils();
try {
// Set device ID form scan
await blufi.setCurrentId(id);
// Establish connection
await blufi.connect();
// Scan for Wi-Fi networks
var wifiList = await blufi.scanWifiList();
// Select Wi-Fi (replace with your UI logic)
var ssid = await selectWifi(wifiList);
// Get password (replace with your UI logic)
var password = await inputPassword(ssid);
// Provision Wi-Fi credentials
await blufi.configProvision(ssid: ssid, password: password);
print("completed");
} catch (e) {
print("Setup failed: $e");
}
}
// Placeholder UI functions
Future<String> selectWifi(List<String> wifiList) async {
return wifiList.first; // Replace with actual selection logic
}
Future<String> inputPassword(String ssid) async {
return "your_password"; // Replace with actual input logic
}
3. Decoding API Response to IR Codeset #
Convert api response to ir codeset for download
void decodeIrCodeset(String jsonResponse) {
try {
// Decode codeset from API response
RTLIrCodeset codeset = RTLIrCodeset.fromApiJson(jsonResponse);
print("Successfully decoded IR codeset: ${codeset.toString()}");
} catch (e) {
print("Failed to decode IR codeset: $e");
}
}
4. Download IR Codeset #
Download IR codes to bluetooth device
import 'package:rtl_ir_control/rtl_ir_control.dart';
Future<void> downloadCodes(String id, RTLIrCodeset codeset) async {
try {
// Get device instance
var device = RtlIrControl().getDevice(id);
// Connect to device
await device.connect();
// Initialize handler
RoomateDeviceHandler handler = RoomateDeviceHandler(device);
// Download codeset with progress updates
handler.downloadCodeFromCodeset(
channel: 1,
brandName: "LG",
codeNum: "81",
codeset: codeset,
).listen(
(progress) => print("Download progress: $progress%"),
onDone: () => print("Download completed"),
onError: (e) => print("Download failed: $e"),
);
} catch (e) {
print("Code download failed: $e");
}
}
5. Delete IR Codeset #
Delete IR codes with channel
import 'package:rtl_ir_control/rtl_ir_control.dart';
Future<void> deleteCodes(String id, int channel) async {
try {
// Get device instance
var device = RtlIrControl().getDevice(id);
// Connect to device
await device.connect();
// Initialize handler
RoomateDeviceHandler handler = RoomateDeviceHandler(device);
// Delete IR Codeset with channel
await handler.deleteCode(channel);
} catch (e) {
print("Delete code failed: $e");
}
}
Custom Device Handler #
Extend the functionality of rtl_ir_control by creating a custom DeviceHandler tailored to your
Bluetooth device.
import 'package:rtl_ir_control/rtl_ir_control.dart';
class CustomDeviceHandler extends GeneralDeviceHandler {
// Custom UUIDs for your device's BLE service and characteristic
static final RTLBluetoothUuid customServiceUuid =
RTLBluetoothUuid('00001800-0000-1000-8000-00805f9b34fb'); // Generic Access service
static final RTLBluetoothUuid customCharacteristicUuid =
RTLBluetoothUuid('00002a00-0000-1000-8000-00805f9b34fb'); // Device Name characteristic
// Constructor takes an RTLBluetoothDevice instance
CustomDeviceHandler(super.rtlBluetoothDevice);
// Read raw data from the device as a byte list
Future<List<int>> readCustomData() async {
final value = await rtlBluetoothDevice.readData(
customServiceUuid,
customCharacteristicUuid,
);
return value; // Returns raw bytes (e.g., for further processing)
}
// Send a custom command to the device
Future<void> sendCustomCommand(List<int> data) async {
await rtlBluetoothDevice.sendCommand(
customServiceUuid,
customCharacteristicUuid,
data, // Byte list representing your command
);
}
// Stream progress for a custom operation (e.g., firmware update)
Stream<int> performCustomOperation(int param) async* {
for (var i = 0; i <= 100; i += 20) {
await Future.delayed(Duration(milliseconds: 500)); // Simulate async work
yield i; // Emit progress percentage
}
// Replace with your device's specific operation logic
}
}
Once you've created your CustomDeviceHandler, use the following example to call its methods:
// Usage
Future<void> useCustomHandler(String deviceId) async {
try {
// Retrieve and connect to the device
var device = RtlIrControl().getDevice(deviceId);
await device.connect();
// Instantiate your custom handler
var handler = CustomDeviceHandler(device);
// Read data (raw bytes)
List<int> data = await handler.readCustomData();
print("Custom data (bytes): $data");
// Send a sample command
await handler.sendCustomCommand([0x01, 0x02, 0x03]);
print("Command sent successfully");
// Monitor a custom operation's progress
handler.performCustomOperation(42).listen(
(progress) => print("Operation progress: $progress%"),
onDone: () => print("Operation completed"),
);
} catch (e) {
print("Error in custom handler usage: $e");
}
}
Notes #
-
Handle exceptions (e.g., RTLBluetoothException) for errors like timeouts or permission issues.
-
The package is tailored for Roomate devices; adapt for other devices as needed.
-
Use a real API response for apiJson in production.