Flutter蓝牙设备配置插件esp_provisioning_ble的使用
Flutter蓝牙设备配置插件esp_provisioning_ble的使用
概述
esp_provisioning_ble
是一个用于通过蓝牙低功耗(BLE)对ESP32设备进行配置的库。本文档将详细介绍如何使用该插件,并提供一个完整的示例代码。
入门指南
创建EspProv实例
该包有一个抽象类 ProvTransport
,你需要使用你选择的蓝牙包来实现它。在 示例 文件夹中,有一个使用 flutter_ble_lib_ios_15
包实现的 ProvTransport
。
prov = EspProv(
transport: TransportBLE(peripheral),
security: Security1(
pop: pop,
),
);
transport
属性只接受ProvTransport
类型。security
属性只接受ProvSecurity
类型,其中Security1
是一个实现,用于传递 Proof-of-Possession (PoP)。
建立与设备的会话
建立会话需要调用 establishSession
函数,该函数返回三种类型的 EstablishSessionStatus
:
- Connected: 设备成功建立连接。
- Disconnected: 建立连接时发生错误。
- KeyMismatch: Proof-of-Possession (PoP) 不正确。
var sessionStatus = await prov.establishSession();
log.d("Session Status = $sessionStatus");
switch (sessionStatus) {
case EstablishSessionStatus.Connected:
emit(BleWifiEstablishedConnectionState());
case EstablishSessionStatus.Disconnected:
emit(BleWifiEstablishedConnectionFailedState());
case EstablishSessionStatus.Keymismatch:
emit(BleWifiEstablishedConnectionKeyMismatch());
}
扫描设备的Wi-Fi网络
使用 startScanWiFi
函数扫描Wi-Fi网络,该函数返回一个 WifiAp
对象列表,每个对象包含以下属性:
String ssid
int rssi
bool active
bool private
var listWifi = await prov.startScanWiFi();
log.d('Found ${listWifi.length} Wi-Fi networks');
for (var obj in listWifi) {
log.d('Wi-Fi network: ${obj.ssid}');
}
发送并应用Wi-Fi配置
使用 sendWifiConfig
和 applyWifiConfig
函数分别发送和应用Wi-Fi配置。
await prov.sendWifiConfig(ssid: event.ssid, password: event.password);
await prov.applyWifiConfig();
获取应用Wi-Fi配置的状态
使用 getStatus
函数获取状态,该函数返回一个 ConnectionStatus
类型。ConnectionStatus
包含以下属性:
WifiConnectionState state
: 包含四种状态:- Connected
- Connecting
- Disconnected
- ConnectionFailed: 当状态为
ConnectionFailed
时,WifiConnectFailedReason
属性指示错误类型。
String? deviceIp
: 注册设备的IP地址。WifiConnectFailedReason? failedReason
: 包含两种失败原因:- AuthError: Wi-Fi密码输入错误。
- NetworkNotFound: Wi-Fi SSID输入错误。
ConnectionStatus status = await prov.getStatus();
switch (status.state) {
case WifiConnectionState.Connecting:
add(BleWifiLoadingEvent());
case WifiConnectionState.Connected:
log.d("Device IP: ${status.deviceIp}");
add(BleWifiConnectedEvent());
case WifiConnectionState.Disconnected:
add(BleWifiDisconnectedEvent());
case WifiConnectionState.ConnectionFailed:
add(
BleWifiConnectionFailedEvent(
failedReason: status.failedReason!,
),
);
}
发送自定义数据
使用 sendReceiveCustomData
函数发送和接收自定义数据。
var customAnswerBytes = await prov.sendReceiveCustomData(
Uint8List.fromList(
utf8.encode(customSendMessage),
),
);
var customAnswer = utf8.decode(customAnswerBytes);
log.i("Custom data answer: $customAnswer");
协议通信概述
协议通信(protocomm)组件管理安全会话,并为多种传输方式提供框架。应用程序也可以直接使用 protocomm 层,以扩展特定于应用程序的配置或非配置用例。
可用的配置功能
- 应用级别的通信安全
protocomm_security0
(无安全)protocomm_security1
(Curve25519 密钥交换 + AES-CTR 加密/解密)protocomm_security2
(SRP6a 基于的密钥交换 + AES-GCM 加密/解密)
- Proof-of-possession(仅支持
protocomm_security1
) - Salt 和 Verifier(仅支持
protocomm_security2
)
传输方式
- 蓝牙低功耗(BLE)
- Wi-Fi(SoftAP + HTTPD)
- 控制台,此时设备端自动处理处理器调用。
比较
与 esp_provisioning_softap
包的比较:
Repo | softap support | ble support | cryptography | protobuf |
---|---|---|---|---|
esp_provisioning_softap | ✔️ | ✖️ | ✔️ (2.0.1) | ✔️ (2.0.0) |
esp_provisioning_ble | ✖️ | ✔️ | ✔️ (2.5.0) | ✔️ (3.0.0) |
待办事项
- 测试并创建使用其他蓝牙包的示例。
- flutter_blue_plus
致谢
- 代码基于 esp_provisioning。
- 参考了 esp_provisioning_softap,这是从 esp_softap_provisioning 派生的 Dart 3.0 兼容版本。
示例代码
以下是 esp_provisioning_ble
的一个完整示例代码:
import 'package:flutter/material.dart';
import 'package:esp_provisioning_ble/esp_provisioning_ble.dart';
import 'package:flutter_ble_lib_ios_15/flutter_ble_lib_ios_15.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'ESP32 Provisioning',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: ProvisioningScreen(),
);
}
}
class ProvisioningScreen extends StatefulWidget {
@override
_ProvisioningScreenState createState() => _ProvisioningScreenState();
}
class _ProvisioningScreenState extends State<ProvisioningScreen> {
late CentralManager centralManager;
late Peripheral peripheral;
late EspProv prov;
@override
void initState() {
super.initState();
initBle();
}
Future<void> initBle() async {
centralManager = CentralManager();
await centralManager.requestAuthorization();
centralManager.scanForPeripherals();
centralManager.onStateChange().listen((state) {
if (state == ManagerState.poweredOn) {
centralManager.stopScan();
peripheral = await findPeripheral();
connectToPeripheral(peripheral);
}
});
}
Future<Peripheral> findPeripheral() async {
// Implement your logic to find the specific peripheral
return await centralManager.connectedPeripherals().firstWhere((p) => p.name == 'ESP32');
}
void connectToPeripheral(Peripheral peripheral) async {
await peripheral.connect();
prov = EspProv(
transport: TransportBLE(peripheral),
security: Security1(pop: 'your_proof_of_possession'),
);
var sessionStatus = await prov.establishSession();
print("Session Status = $sessionStatus");
switch (sessionStatus) {
case EstablishSessionStatus.Connected:
print('Session established successfully');
break;
case EstablishSessionStatus.Disconnected:
print('Session establishment failed');
break;
case EstablishSessionStatus.Keymismatch:
print('Proof-of-Possession mismatch');
break;
}
var listWifi = await prov.startScanWiFi();
print('Found ${listWifi.length} Wi-Fi networks');
for (var obj in listWifi) {
print('Wi-Fi network: ${obj.ssid}');
}
await prov.sendWifiConfig(ssid: 'your_ssid', password: 'your_password');
await prov.applyWifiConfig();
ConnectionStatus status = await prov.getStatus();
print('Connection Status: ${status.state}');
if (status.state == WifiConnectionState.Connected) {
print("Device IP: ${status.deviceIp}");
} else if (status.state == WifiConnectionState.ConnectionFailed) {
print("Connection Failed: ${status.failedReason}");
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('ESP32 Provisioning'),
),
body: Center(
child: Text('Provisioning...'),
),
);
}
}
希望这篇文档对你理解和使用 esp_provisioning_ble
插件有所帮助!如果有任何问题或建议,请随时联系我。
更多关于Flutter蓝牙设备配置插件esp_provisioning_ble的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter蓝牙设备配置插件esp_provisioning_ble的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter项目中集成并使用esp_provisioning_ble
插件来配置ESP蓝牙设备,通常涉及几个关键步骤:设置Flutter项目、添加依赖、编写蓝牙配置逻辑等。以下是一个简化的代码案例,展示如何在Flutter中使用esp_provisioning_ble
插件。
步骤 1: 设置Flutter项目
首先,确保你已经有一个Flutter项目。如果没有,可以通过以下命令创建一个新的Flutter项目:
flutter create my_bluetooth_app
cd my_bluetooth_app
步骤 2: 添加依赖
在pubspec.yaml
文件中添加esp_provisioning_ble
依赖(注意:这个插件可能是一个假想的名称,实际使用时需要替换为实际的蓝牙配置插件名称,或者如果这是一个私有插件,你需要通过正确的途径添加它):
dependencies:
flutter:
sdk: flutter
esp_provisioning_ble: ^x.y.z # 替换为实际的版本号
然后运行flutter pub get
来安装依赖。
步骤 3: 编写蓝牙配置逻辑
接下来,在你的Flutter应用中编写蓝牙配置逻辑。以下是一个简化的示例,展示如何使用该插件扫描蓝牙设备并进行配置。
import 'package:flutter/material.dart';
import 'package:esp_provisioning_ble/esp_provisioning_ble.dart'; // 假设这是插件的导入路径
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late ESPProvisioningBLE _espProvisioningBLE;
List<BluetoothDevice> _devices = [];
@override
void initState() {
super.initState();
_espProvisioningBLE = ESPProvisioningBLE();
_startScanning();
}
void _startScanning() async {
_espProvisioningBLE.startScanning().listen((device) {
setState(() {
_devices.add(device);
});
}, onError: (error) {
print('Scanning error: $error');
}, onDone: () {
print('Scanning done');
});
}
void _stopScanning() {
_espProvisioningBLE.stopScanning();
}
void _provisionDevice(BluetoothDevice device) async {
// 假设有一个配置方法,这里仅作为示例
try {
await _espProvisioningBLE.provisionDevice(
device: device,
ssid: 'your_SSID',
password: 'your_PASSWORD',
// 其他配置参数...
);
print('Device provisioned successfully');
} catch (e) {
print('Provisioning error: $e');
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('ESP Bluetooth Provisioning'),
),
body: Column(
children: [
Expanded(
child: ListView.builder(
itemCount: _devices.length,
itemBuilder: (context, index) {
final device = _devices[index];
return ListTile(
title: Text(device.name ?? 'Unknown Device'),
trailing: IconButton(
icon: Icon(Icons.settings),
onPressed: () => _provisionDevice(device),
),
);
},
),
),
ElevatedButton(
onPressed: _stopScanning,
child: Text('Stop Scanning'),
),
],
),
),
);
}
@override
void dispose() {
_stopScanning();
super.dispose();
}
}
// 假设的BluetoothDevice类,实际使用时替换为插件提供的类
class BluetoothDevice {
String? name;
// 其他属性...
BluetoothDevice({this.name});
}
注意事项
- 插件可用性:
esp_provisioning_ble
是一个假设的插件名称。在实际应用中,你需要查找并使用具体的蓝牙配置插件。 - 权限处理:在Android和iOS平台上,你需要处理蓝牙权限和位置权限。这通常涉及到在
AndroidManifest.xml
和Info.plist
文件中添加相应的权限声明。 - 错误处理:示例代码中的错误处理较为简单。在实际应用中,你可能需要更复杂的错误处理和用户反馈机制。
- 插件文档:务必查阅所使用插件的官方文档,以获取最新的API信息和最佳实践。
这个代码案例提供了一个基本的框架,你可以根据实际需求进行调整和扩展。