Flutter北欧半导体nRF Mesh网络控制插件nordic_nrf_mesh_faradine的使用
Flutter北欧半导体nRF Mesh网络控制插件nordic_nrf_mesh_faradine的使用
nordic_nrf_mesh_faradine
一个用于通过北欧半导体SDK管理并实现Mesh网络通信的Flutter插件。
特性
此插件封装了以下两个库:
提供了Dart-only API,并具有以下功能:
- 创建、加载和管理Mesh网络模型
- (De)provision BLE Mesh节点
- 扫描附近的BLE设备
- 连接到BLE Mesh节点并用作代理进行Mesh网络通信
- 加密和解密Mesh PDUs(并非所有Mesh消息类型都受支持)
- 基于事件的API(使用
StreamControllers
) - 管理Mesh组
- 管理节点的发布和订阅
- 管理Mesh provisioners
- Key Refresh Procedure(在Android上部分支持)
(注意: 蓝牙扫描和连接功能由flutter_reactive_ble完成)
如何使用
安装
在Flutter应用中安装插件
安装插件
-
在
pubspec.yaml
文件中运行以下命令添加此包:flutter pub add nordic_nrf_mesh_faradine
-
对于Android:
- 打开项目的
/android/settings.gradle
文件,在底部粘贴插件的示例app设置。 - 修改
/android/gradle/wrapper/gradle-wrapper.properties
文件中的distributionUrl
,将版本号从默认的8.3
改为7.4
。这可以确保Gradle与插件兼容。 - 同步Gradle文件或重启IDE以解决构建错误。
- 打开项目的
-
本地使用:
- 克隆仓库。
- 执行
git submodule update --init
。
-
更新构建脚本:
- Android: 复制插件示例应用的
gradle
脚本到/android/settings.gradle
。 - iOS:
- 将插件示例应用的
Podfile
脚本复制到自己的项目中(当前未测试)。
- 将插件示例应用的
- Android: 复制插件示例应用的
初始化
导入插件:
import 'package:nordic_nrf_mesh_faradine/nordic_nrf_mesh_faradine.dart';
要开始使用插件,首先实例化NordicNrfMesh
对象:
final nordicNrfMesh = NordicNrfMesh();
通过这个单例对象可以访问主API。
Mesh网络特性
为了能够使用Mesh功能,每次运行时都需要加载Mesh网络。可以通过以下方式获取网络:
final MeshManagerApi meshManager = nordicNrfMesh.meshManagerApi;
final MeshNetwork meshNetwork = await meshManager.loadMeshNetwork();
或者:
final String networkAsJson = '{"mesh": "network"}';
final MeshManagerApi meshManager = nordicNrfMesh.meshManagerApi;
final MeshNetwork meshNetwork = await meshManager.importMeshNetworkJson(networkAsJson);
虽然上述方法简单易用,但它们不会实时更新。因此,我们强烈建议用户使用事件流来获取实时数据:
class MyPluginWrapper {
late IMeshNetwork? _meshNetwork;
late final NordicNrfMesh _nordicNrfMesh;
late final MeshManagerApi _meshManagerApi;
late final StreamSubscription<IMeshNetwork?> onNetworkUpdateSubscription;
late final StreamSubscription<IMeshNetwork?> onNetworkImportSubscription;
late final StreamSubscription<IMeshNetwork?> onNetworkLoadingSubscription;
void init() {
_nordicNrfMesh = NordicNrfMesh();
_meshManagerApi = _nordicNrfMesh.meshManagerApi;
_meshNetwork = _meshManagerApi.meshNetwork;
// 订阅网络更新事件
onNetworkUpdateSubscription = _meshManagerApi.onNetworkUpdated.listen((event) {
_meshNetwork = event;
});
onNetworkImportSubscription = _meshManagerApi.onNetworkImported.listen((event) {
_meshNetwork = event;
});
onNetworkLoadingSubscription = _meshManagerApi.onNetworkLoaded.listen((event) {
_meshNetwork = event;
});
}
void dispose() {
onNetworkUpdateSubscription.cancel();
onNetworkLoadingSubscription.cancel();
onNetworkImportSubscription.cancel();
}
}
(De)Provisioning
节点必须被provision才能加入网络。此功能通过NordicNrfMesh
实例提供。以下是签名:
Future<ProvisionedMeshNode> provisioning(
final MeshManagerApi meshManagerApi,
final BleMeshManager bleMeshManager,
final DiscoveredDevice device,
final String serviceDataUuid, {
final ProvisioningEvent? events,
});
Future<ConfigNodeResetStatus> deprovision(
final MeshManagerApi meshManagerApi,
final ProvisionedMeshNode meshNode,
);
(如需示例用法,请参考示例应用。)
蓝牙功能
(注意: 蓝牙扫描和连接功能由flutter_reactive_ble完成)
扫描设备
不同的扫描器通过NordicNrfMesh
实例可用。API以Mesh为中心,您可以轻松获取手机周围的Mesh设备,也可以通过NordicNrfMesh.scanWithServices
进行自定义扫描。
连接到设备
要实现连接功能,必须使用BleManager
和BleManagerCallbacks
抽象类。
为方便起见,我们在此插件中提供了一个特定于Mesh节点的实现。要处理与Mesh代理节点的BLE连接,需要创建并初始化一个BleMeshManager
实例:
final bleMeshManager = BleMeshManager();
bleMeshManager.callbacks = MyBleCallbacks(meshManager); // 必须设置
(上面代码中的MyBleCallbacks
必须继承自BleMeshManagerCallbacks
。)
之后,您需要扫描设备,然后调用connect
方法:
DiscoveredDevice device;
// 扫描范围内的设备
[...]
// 如果找到设备,则连接
bleMeshManager.connect(device);
自定义BLE功能
如果您的用例未实现,您可以自行实现。不过,您仍然可以通过以下代码获取对flutter_reactive_ble
插件其他功能的访问权限:
final blePlugin = FlutterReactiveBle();
示例应用
如需更深入的使用,请参考示例应用,它展示了部分常用功能。在基于选项卡的布局中,它提供了以下示例用法:
- 基本Mesh网络管理
- 扫描并provision新节点(带有基于事件的UI)
- 扫描、连接并发送消息给已provision的节点
相关链接
- Android-nRF-Mesh-Library(fork版本)
- iOS-nRF-Mesh-Library(fork版本)
- Bluetooth Mesh Profile v1.0.1
- flutter_reactive_ble
(注意: 此插件使用了北欧半导体库的fork版本。这样做是为了能够扩展这些库以包含一些DooZ特定的API,但并未更改源代码。)
示例代码
以下是完整的示例代码,展示了如何使用插件的基本功能:
import 'package:flutter/material.dart';
import 'package:nordic_nrf_mesh_faradine/nordic_nrf_mesh_faradine.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
[@override](/user/override)
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late NordicNrfMesh _nordicNrfMesh;
late MeshManagerApi _meshManagerApi;
late IMeshNetwork? _meshNetwork;
[@override](/user/override)
void initState() {
super.initState();
_nordicNrfMesh = NordicNrfMesh();
_meshManagerApi = _nordicNrfMesh.meshManagerApi;
_meshNetwork = _meshManagerApi.meshNetwork;
// 订阅网络更新事件
_meshManagerApi.onNetworkUpdated.listen((event) {
setState(() {
_meshNetwork = event;
});
});
}
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('nordic_nrf_mesh_faradine 示例'),
),
body: Center(
child: Text(_meshNetwork != null
? 'Mesh网络已加载: ${_meshNetwork!.name}'
: '加载Mesh网络...'),
),
),
);
}
}
更多关于Flutter北欧半导体nRF Mesh网络控制插件nordic_nrf_mesh_faradine的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
nordic_nrf_mesh_faradine
是一个用于 Flutter 的插件,旨在帮助开发者通过 Nordic Semiconductor 的 nRF Mesh 网络控制设备。这个插件提供了与 nRF Mesh 网络进行交互的接口,允许开发者从 Flutter 应用程序中控制和管理 Mesh 网络中的设备。
以下是如何使用 nordic_nrf_mesh_faradine
插件的基本步骤:
1. 添加依赖
首先,在 pubspec.yaml
文件中添加 nordic_nrf_mesh_faradine
插件的依赖:
dependencies:
flutter:
sdk: flutter
nordic_nrf_mesh_faradine: ^latest_version
然后运行 flutter pub get
以获取依赖。
2. 导入插件
在你的 Dart 文件中导入插件:
import 'package:nordic_nrf_mesh_faradine/nordic_nrf_mesh_faradine.dart';
3. 初始化 Mesh 网络
在使用插件之前,你需要初始化 Mesh 网络。通常,这涉及到加载或创建一个 Mesh 网络配置。
NordicNrfMeshFaradine mesh = NordicNrfMeshFaradine();
Future<void> initializeMesh() async {
await mesh.initialize();
// 加载或创建 Mesh 网络配置
// await mesh.loadNetworkConfiguration();
}
4. 扫描设备
你可以使用插件扫描附近的 Mesh 设备:
Future<void> scanForDevices() async {
await mesh.startScanning();
mesh.deviceStream.listen((device) {
print('Found device: ${device.name}');
});
}
5. 连接设备
扫描到设备后,你可以连接到特定的设备:
Future<void> connectToDevice(MeshDevice device) async {
await mesh.connect(device);
print('Connected to device: ${device.name}');
}
6. 控制设备
连接成功后,你可以发送控制命令到设备。例如,控制灯的开/关:
Future<void> turnOnLight(MeshDevice device) async {
await mesh.sendCommand(device, MeshCommand.turnOn);
}
Future<void> turnOffLight(MeshDevice device) async {
await mesh.sendCommand(device, MeshCommand.turnOff);
}
7. 断开连接
完成操作后,断开与设备的连接:
Future<void> disconnectFromDevice(MeshDevice device) async {
await mesh.disconnect(device);
print('Disconnected from device: ${device.name}');
}
8. 处理错误
在使用过程中,可能会遇到各种错误。你可以通过捕获异常来处理这些错误:
Future<void> controlDevice(MeshDevice device) async {
try {
await connectToDevice(device);
await turnOnLight(device);
await Future.delayed(Duration(seconds: 2));
await turnOffLight(device);
await disconnectFromDevice(device);
} catch (e) {
print('Error: $e');
}
}
9. 释放资源
在应用程序退出或不再需要 Mesh 网络时,释放资源:
Future<void> disposeMesh() async {
await mesh.dispose();
}
10. 示例代码
以下是一个完整的示例代码,展示了如何使用 nordic_nrf_mesh_faradine
插件来扫描、连接并控制 Mesh 设备:
import 'package:flutter/material.dart';
import 'package:nordic_nrf_mesh_faradine/nordic_nrf_mesh_faradine.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: MeshControlScreen(),
);
}
}
class MeshControlScreen extends StatefulWidget {
[@override](/user/override)
_MeshControlScreenState createState() => _MeshControlScreenState();
}
class _MeshControlScreenState extends State<MeshControlScreen> {
NordicNrfMeshFaradine mesh = NordicNrfMeshFaradine();
List<MeshDevice> devices = [];
[@override](/user/override)
void initState() {
super.initState();
initializeMesh();
}
Future<void> initializeMesh() async {
await mesh.initialize();
// await mesh.loadNetworkConfiguration();
}
Future<void> scanForDevices() async {
await mesh.startScanning();
mesh.deviceStream.listen((device) {
setState(() {
devices.add(device);
});
});
}
Future<void> controlDevice(MeshDevice device) async {
try {
await mesh.connect(device);
await mesh.sendCommand(device, MeshCommand.turnOn);
await Future.delayed(Duration(seconds: 2));
await mesh.sendCommand(device, MeshCommand.turnOff);
await mesh.disconnect(device);
} catch (e) {
print('Error: $e');
}
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('nRF Mesh Control'),
),
body: ListView.builder(
itemCount: devices.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(devices[index].name),
onTap: () => controlDevice(devices[index]),
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: scanForDevices,
child: Icon(Icons.search),
),
);
}
[@override](/user/override)
void dispose() {
mesh.dispose();
super.dispose();
}
}