rtl_ir_control 1.0.2 copy "rtl_ir_control: ^1.0.2" to clipboard
rtl_ir_control: ^1.0.2 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.plist let’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(nameFilter: ['Roomate', 'BLUFI']);
}

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. Read Device Information #

Read device information to get ir data from database

import 'package:rtl_ir_control/rtl_ir_control.dart';

Future<void> readDeviceInfo(String id) async {
  try {
    // Initialize the device using the provided ID
    final device = RtlIrControl().getDevice(id);

    // Establish connection to the device
    await device.connect();

    // Create handler for device operations
    final roomateDeviceHandler = RoomateDeviceHandler(device);
    
    var masterKey = await roomateDeviceHandler.readMasterKey();
    
    var macAddress = await roomateDeviceHandler.readMacAddress();
    
    var deviceName = await roomateDeviceHandler.readDeviceName();
    
    var firmwareVersion = await roomateDeviceHandler.readFirmwareVersion();
    
    var hardwareVersion = await roomateDeviceHandler.readHardwareVersion();
    
    var modelNumber = await roomateDeviceHandler.readRemoteModel();


    // display device information
    print('''
      Master Key: $masterKey
      MAC Address: $macAddress
      Device Name: $deviceName
      Firmware Version: $firmwareVersion
      Hardware Version: $hardwareVersion
      Model Number: $modelNumber
    ''');

    // Ensure device is properly disconnected
    await device.disconnect();
  } catch (e) {
    print("Read device info failed: $e");
  }
}

4. 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");
  }
}

5. Download IR Codeset #

Download IR codes to 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");
  }
}

6. 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.

0
likes
0
points
54
downloads

Publisher

unverified uploader

Weekly Downloads

A utility designed to simplify the setup and configuration of Remotec products using Bluetooth Low Energy (BLE).

Homepage

License

unknown (license)

Dependencies

esp_blufi, flutter, flutter_blue_plus, plugin_platform_interface

More

Packages that depend on rtl_ir_control