Flutter Telink BLE
A comprehensive Flutter plugin for Telink BLE Mesh devices, providing seamless integration with Telink's BLE Mesh SDK for both Android and iOS platforms.
Overview
Flutter Telink BLE enables Flutter applications to communicate with Telink BLE Mesh devices, supporting device provisioning, mesh network management, device control, group operations, and OTA firmware updates. This plugin wraps the native Telink BLE Mesh SDKs for Android and iOS, providing a clean, idiomatic Dart API.
Features
✅ Device Discovery & Provisioning
- Scan for unprovisioned BLE mesh devices
- Provision devices into mesh network
- Configure device parameters
✅ Mesh Network Management
- Initialize and configure mesh networks
- Connect/disconnect from mesh
- Monitor connection state changes
- Persistent mesh configuration
✅ Device Control
- On/Off control
- Brightness/Level control
- Color temperature control
- Custom command support
✅ Group Management
- Create and delete groups
- Add/remove devices from groups
- Group-based control
✅ OTA Updates
- Over-the-air firmware updates
- Progress monitoring
- GATT and Mesh OTA support
✅ Event Streams
- Real-time device discovery
- Connection state updates
- OTA progress tracking
- Mesh message notifications
Requirements
Android
- Android 5.0 (API level 21) or higher
- BLE 4.0+ support
- Location permissions (for BLE scanning)
- Bluetooth permissions
iOS
- iOS 9.0 or higher
- Core Bluetooth support
- Background mode capabilities (optional)
Flutter
- Flutter SDK 3.3.0 or higher
- Dart SDK 3.6.2 or higher
Installation
Add this to your package's pubspec.yaml file:
dependencies:
flutter_telink_ble: ^0.0.1
Then run:
flutter pub get
Android Setup
Add the following permissions to your android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<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" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
iOS Setup
Add the following to your ios/Runner/Info.plist:
<key>NSBluetoothAlwaysUsageDescription</key>
<string>This app needs Bluetooth to communicate with BLE mesh devices</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>This app needs Bluetooth to communicate with BLE mesh devices</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs location access for BLE scanning</string>
Quick Start
1. Initialize the Mesh Network
import 'package:flutter_telink_ble/flutter_telink_ble.dart';
final telinkBle = FlutterTelinkBle();
// Configure your mesh network
final config = TelinkMeshConfig(
networkKey: '7dd7364cd842ad18c17c2b820c84c3d6', // 16-byte hex string
netKeyIndex: 0,
appKeys: {
0: '63964771734fbd76e3b40519d1d94a48', // App key index 0
},
ivIndex: 0,
sequenceNumber: 0,
localAddress: 0x0001, // Your provisioner address
);
// Initialize
await telinkBle.initialize(config);
2. Scan for Devices
// Start scanning
telinkBle.scanForDevices().listen((device) {
print('Found device: ${device.name} (${device.uuid})');
print('Signal strength: ${device.rssi} dBm');
print('MAC address: ${device.macAddress}');
});
// Stop scanning after 10 seconds
await Future.delayed(Duration(seconds: 10));
await telinkBle.stopScan();
3. Provision a Device
final provisionConfig = DeviceProvisionConfig(
uuid: device.uuid,
address: 0x0002, // Unicast address for the new device
macAddress: device.macAddress,
);
final result = await telinkBle.provisionDevice(provisionConfig);
if (result.success) {
print('Device provisioned successfully!');
print('Address: 0x${result.address.toRadixString(16)}');
} else {
print('Provisioning failed: ${result.error}');
}
4. Connect to Mesh
// Connect to the mesh network
final connected = await telinkBle.connectToMesh();
if (connected) {
print('Connected to mesh network');
}
// Listen for connection state changes
telinkBle.connectionStateStream.listen((state) {
print('Connection state: ${state.state}');
if (state.state == MeshConnectionState.connected) {
print('Mesh network is ready');
}
});
5. Control Devices
// Turn a device on/off
await telinkBle.sendOnOffCommand(0x0002, true); // Turn on
await telinkBle.sendOnOffCommand(0x0002, false); // Turn off
// Set brightness (0-100)
await telinkBle.sendLevelCommand(0x0002, 75);
// Set color temperature
await telinkBle.sendColorCommand(0x0002, Colors.warmWhite);
6. Manage Groups
// Add device to a group
await telinkBle.addDeviceToGroup(
deviceAddress: 0x0002,
groupAddress: 0xC000, // Group address
);
// Control all devices in the group
await telinkBle.sendOnOffCommand(0xC000, true); // Turn on all devices in group
7. OTA Firmware Update
// Load firmware file
final firmwareData = await File('path/to/firmware.bin').readAsBytes();
// Start OTA update
await telinkBle.startOTA(0x0002, firmwareData);
// Monitor progress
telinkBle.otaProgressStream.listen((progress) {
print('OTA Progress: ${progress.percentage}%');
if (progress.state == OTAState.success) {
print('OTA update completed successfully!');
} else if (progress.state == OTAState.failed) {
print('OTA update failed: ${progress.error}');
}
});
API Reference
Core Classes
FlutterTelinkBle
Main plugin class providing access to all BLE mesh operations.
Methods:
Future<bool> initialize(TelinkMeshConfig config)- Initialize mesh networkFuture<void> dispose()- Cleanup resourcesStream<UnprovisionedDevice> scanForDevices()- Scan for unprovisioned devicesFuture<void> stopScan()- Stop device scanningFuture<ProvisionResult> provisionDevice(DeviceProvisionConfig config)- Provision a deviceFuture<bool> connectToMesh()- Connect to mesh networkFuture<void> disconnectFromMesh()- Disconnect from meshStream<MeshConnectionStateEvent> get connectionStateStream- Connection state updatesFuture<void> sendOnOffCommand(int address, bool isOn)- Send on/off commandFuture<void> sendLevelCommand(int address, int level)- Send brightness commandFuture<void> sendColorCommand(int address, Color color)- Send color commandFuture<void> addDeviceToGroup(int deviceAddress, int groupAddress)- Add device to groupFuture<void> removeDeviceFromGroup(int deviceAddress, int groupAddress)- Remove device from groupFuture<void> startOTA(int deviceAddress, Uint8List firmwareData)- Start OTA updateStream<OTAProgress> get otaProgressStream- OTA progress updates
Data Models
TelinkMeshConfig
Configuration for mesh network initialization.
TelinkMeshConfig({
required String networkKey, // 32-char hex string (16 bytes)
required int netKeyIndex, // 0-4095
required Map<int, String> appKeys, // App keys by index
required int ivIndex, // IV index
required int sequenceNumber, // Sequence number
required int localAddress, // Unicast address (0x0001-0x7FFF)
})
UnprovisionedDevice
Represents a discovered unprovisioned device.
UnprovisionedDevice({
required String uuid, // Device UUID
required String name, // Device name
required int rssi, // Signal strength
required Map<String, dynamic> advertisementData,
String? macAddress, // MAC address
})
DeviceProvisionConfig
Configuration for provisioning a device.
DeviceProvisionConfig({
required String uuid, // Device UUID
required int address, // Unicast address to assign
String? macAddress, // Optional MAC address
})
ProvisionResult
Result of a provisioning operation.
ProvisionResult({
required bool success, // Success status
required int address, // Assigned address
String? error, // Error message if failed
})
MeshConnectionStateEvent
Connection state change event.
enum MeshConnectionState {
disconnected,
connecting,
connected,
failed,
}
OTAProgress
OTA update progress information.
enum OTAState {
started,
inProgress,
success,
failed,
}
OTAProgress({
required OTAState state,
required int percentage, // 0-100
String? error, // Error message if failed
})
Address Ranges
BLE Mesh uses 16-bit addresses with specific ranges:
- Unassigned:
0x0000 - Unicast (individual devices):
0x0001-0x7FFF - Virtual:
0x8000-0xBFFF - Group:
0xC000-0xFEFF - All Proxies:
0xFFFC - All Friends:
0xFFFD - All Relays:
0xFFFE - All Nodes:
0xFFFF
Example Application
Check out the example directory for a complete demo application that demonstrates:
- Mesh network initialization
- Device scanning and provisioning
- Device control (on/off, brightness, color)
- Group management
- OTA firmware updates
- Connection state monitoring
To run the example:
cd example
flutter run
Architecture
The plugin follows Flutter's standard plugin architecture:
lib/
├── flutter_telink_ble.dart # Main plugin class
├── flutter_telink_ble_platform_interface.dart # Platform interface
├── flutter_telink_ble_method_channel.dart # Method channel implementation
└── models/ # Data models
android/
└── src/main/kotlin/
└── info/thanhtunguet/flutter_telink_ble/
├── FlutterTelinkBlePlugin.kt # Android implementation
├── FlutterEventHandler.kt # Event handling
├── ConnectionManager.kt # Connection management
└── TelinkBleMeshLib/ # Telink Android SDK
ios/
└── Classes/
└── FlutterTelinkBlePlugin.swift # iOS implementation (coming soon)
Platform-Specific Implementation
Android
The Android implementation uses TelinkBleMeshLib with the following key components:
- MeshService: Core mesh network service
- EventHandler: Handles mesh events and streams them to Flutter
- ConnectionManager: Manages mesh connections with auto-reconnect
- Parameter classes: Configuration for various operations
iOS
iOS implementation is in progress and will use TelinkSigMeshLib.
Troubleshooting
Android
Scanning doesn't find devices:
- Ensure Bluetooth and Location services are enabled
- Check that all required permissions are granted at runtime
- Verify BLE hardware support on the device
Connection fails:
- Ensure device is provisioned with correct network key
- Check that device is in range
- Verify mesh configuration matches the device's provisioning
Build errors:
- Ensure you're using Android API level 21 or higher
- Check that all dependencies are properly included
- Clean and rebuild:
flutter clean && flutter pub get
iOS
Coming soon
Performance Tips
- Scanning: Stop scanning when you find the device you need to save battery
- Commands: Avoid sending commands too rapidly; allow time for responses
- Groups: Use group addresses to control multiple devices efficiently
- OTA: Ensure strong signal strength (RSSI > -70 dBm) for reliable OTA updates
- Connections: Disconnect from mesh when not in use to save battery
Contributing
Contributions are welcome! Please follow these guidelines:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Development Setup
# Clone the repository
git clone https://github.com/thanhtunguet/flutter_telink_ble.git
cd flutter_telink_ble
# Install dependencies
flutter pub get
# Run tests
flutter test
# Run example app
cd example
flutter run
Changelog
See CHANGELOG.md for version history.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- Telink Semiconductor for their BLE Mesh SDK
- The Flutter team for the excellent plugin infrastructure
- Contributors and testers who help improve this plugin
Support
Related Resources
Made with ❤️ by Thanh Tung Pham
Libraries
- flutter_telink_ble
- flutter_telink_ble_method_channel
- flutter_telink_ble_platform_interface
- models/device_provision_config
- models/mesh_connection_state
- models/models
- Data models for Flutter Telink BLE plugin
- models/ota_progress
- models/provision_result
- models/telink_mesh_config
- models/unprovisioned_device