更新控制跳转
This commit is contained in:
@@ -138,7 +138,7 @@ class _HomePageState extends State<MainPageBBottomChange>
|
|||||||
Future<void> dealWebSource(int index) async {
|
Future<void> dealWebSource(int index) async {
|
||||||
WebviewTestController webviewTestController = Get.find();
|
WebviewTestController webviewTestController = Get.find();
|
||||||
if (index == 2) {
|
if (index == 2) {
|
||||||
await webviewTestController.web.jsbridge?.dart.pageActive();
|
await webviewTestController.web.jsbridge?.dart.pageActive(true);
|
||||||
} else {
|
} else {
|
||||||
await webviewTestController.web.jsbridge?.dart.pageInActive();
|
await webviewTestController.web.jsbridge?.dart.pageInActive();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,10 +25,12 @@ import 'package:vbvs_app/pages/mh_page/test/WebviewTestModel.dart';
|
|||||||
|
|
||||||
class DeviceComponentWidget extends StatefulWidget {
|
class DeviceComponentWidget extends StatefulWidget {
|
||||||
BlueToothDataModel bleDevice;
|
BlueToothDataModel bleDevice;
|
||||||
|
var deviceType;
|
||||||
|
|
||||||
DeviceComponentWidget({
|
DeviceComponentWidget({
|
||||||
super.key,
|
super.key,
|
||||||
required this.bleDevice,
|
required this.bleDevice,
|
||||||
|
required this.deviceType,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -212,8 +214,8 @@ class _DeviceComponentWidgetState extends State<DeviceComponentWidget> {
|
|||||||
blueteethBindController.currentDeviceMac.value =
|
blueteethBindController.currentDeviceMac.value =
|
||||||
widget.bleDevice.mac;
|
widget.bleDevice.mac;
|
||||||
blueteethBindController.updateAll();
|
blueteethBindController.updateAll();
|
||||||
String mac =
|
String mac = await getBindTHMAC(
|
||||||
await getBindTHMAC(context, widget.bleDevice);
|
context, widget.bleDevice, widget.deviceType);
|
||||||
if (mac != null && mac.isNotEmpty) {
|
if (mac != null && mac.isNotEmpty) {
|
||||||
bool flag =
|
bool flag =
|
||||||
await fillTHMac(mac, widget.bleDevice, context);
|
await fillTHMac(mac, widget.bleDevice, context);
|
||||||
@@ -481,19 +483,17 @@ class _DeviceComponentWidgetState extends State<DeviceComponentWidget> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
//获取传感器mac
|
//获取智能床/床垫mac
|
||||||
Future<String> getBindTHMAC(
|
Future<String> getBindTHMAC(
|
||||||
BuildContext context, BlueToothDataModel device) async {
|
BuildContext context, BlueToothDataModel device, Map deviceType) async {
|
||||||
const int maxRetries = 2;
|
const int maxRetries = 2;
|
||||||
const Duration timeout = Duration(seconds: 5);
|
const Duration timeout = Duration(seconds: 5);
|
||||||
String? macAddress;
|
String? macAddress;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 连接设备
|
// 连接设备
|
||||||
THapp bledevice = THapp(device: device.scanResult.device);
|
THapp bledevice = THapp(device: device.scanResult.device);
|
||||||
await bledevice.connect();
|
await bledevice.connect();
|
||||||
var res2 = bledevice.isConnected;
|
var res2 = bledevice.isConnected;
|
||||||
|
|
||||||
if (!res2) {
|
if (!res2) {
|
||||||
edm.EasyDartModule.logger.error("蓝牙连接失败");
|
edm.EasyDartModule.logger.error("蓝牙连接失败");
|
||||||
DailyLogUtils.printLog("蓝牙连接失败");
|
DailyLogUtils.printLog("蓝牙连接失败");
|
||||||
@@ -504,58 +504,18 @@ class _DeviceComponentWidgetState extends State<DeviceComponentWidget> {
|
|||||||
);
|
);
|
||||||
throw Exception("蓝牙连接失败");
|
throw Exception("蓝牙连接失败");
|
||||||
}
|
}
|
||||||
|
|
||||||
blueteethBindController.blueConnectFlag.value = 2;
|
blueteethBindController.blueConnectFlag.value = 2;
|
||||||
blueteethBindController.currentDevice = bledevice;
|
blueteethBindController.currentDevice = bledevice;
|
||||||
await Future.delayed(Duration(seconds: 2));
|
await Future.delayed(Duration(seconds: 2));
|
||||||
var read = bledevice.getresource('fff0/fff1');
|
|
||||||
await read!.characteristic.setNotifyValue(true);
|
|
||||||
var write = bledevice.getresource('fff0/fff2');
|
|
||||||
|
|
||||||
for (int attempt = 0; attempt < maxRetries; attempt++) {
|
if (deviceType['type'] == 3) {
|
||||||
var completer = Completer<String>();
|
//智能床垫
|
||||||
|
macAddress = await getMacFromType3(bledevice, timeout);
|
||||||
StreamSubscription? subscription;
|
} else if (deviceType['type'] == 2) {
|
||||||
subscription = read.characteristic.onValueReceived.listen((onData) {
|
//智能床
|
||||||
if (onData.length >= 14) {
|
macAddress = await getMacFromType2(bledevice, timeout);
|
||||||
// 按照你提供的协议,返回数据长度至少 17字节,这里保险起见 14起步
|
} else {
|
||||||
String parsedMac = parseMacFromBleResponse(onData);
|
throw Exception("不支持的设备类型");
|
||||||
completer.complete(parsedMac);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 发送查询命令
|
|
||||||
var order = [
|
|
||||||
0xFF,
|
|
||||||
0xFF,
|
|
||||||
0xFF,
|
|
||||||
0xFF,
|
|
||||||
0x00,
|
|
||||||
0x03,
|
|
||||||
0x40,
|
|
||||||
0x01,
|
|
||||||
0x01,
|
|
||||||
0x00,
|
|
||||||
0x45,
|
|
||||||
0xFD
|
|
||||||
];
|
|
||||||
await write!.characteristic.write(order);
|
|
||||||
|
|
||||||
try {
|
|
||||||
macAddress = await completer.future.timeout(timeout);
|
|
||||||
await subscription.cancel();
|
|
||||||
break; // 成功拿到,跳出重试
|
|
||||||
} catch (e) {
|
|
||||||
await subscription.cancel();
|
|
||||||
if (attempt == maxRetries - 1) {
|
|
||||||
TopSlideNotification.show(
|
|
||||||
context,
|
|
||||||
text: "获取MAC地址超时,请重试".tr,
|
|
||||||
textColor: themeController.currentColor.sc9,
|
|
||||||
);
|
|
||||||
throw Exception("获取MAC地址失败");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (macAddress == null) {
|
if (macAddress == null) {
|
||||||
@@ -629,6 +589,87 @@ class _DeviceComponentWidgetState extends State<DeviceComponentWidget> {
|
|||||||
);
|
);
|
||||||
return flag;
|
return flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<String> getMacFromType3(THapp bledevice, Duration timeout) async {
|
||||||
|
final read = bledevice.getresource('fff0/fff1');
|
||||||
|
await read!.characteristic.setNotifyValue(true);
|
||||||
|
final write = bledevice.getresource('fff0/fff2');
|
||||||
|
|
||||||
|
const int maxRetries = 2;
|
||||||
|
for (int attempt = 0; attempt < maxRetries; attempt++) {
|
||||||
|
final completer = Completer<String>();
|
||||||
|
final subscription = read.characteristic.onValueReceived.listen((data) {
|
||||||
|
if (data.length >= 14) {
|
||||||
|
completer.complete(parseMacFromBleResponse(data));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
final order = [
|
||||||
|
0xFF,
|
||||||
|
0xFF,
|
||||||
|
0xFF,
|
||||||
|
0xFF,
|
||||||
|
0x00,
|
||||||
|
0x03,
|
||||||
|
0x40,
|
||||||
|
0x01,
|
||||||
|
0x01,
|
||||||
|
0x00,
|
||||||
|
0x45,
|
||||||
|
0xFD
|
||||||
|
];
|
||||||
|
await write!.characteristic.write(order);
|
||||||
|
|
||||||
|
try {
|
||||||
|
final mac = await completer.future.timeout(timeout);
|
||||||
|
await subscription.cancel();
|
||||||
|
return mac;
|
||||||
|
} catch (_) {
|
||||||
|
await subscription.cancel();
|
||||||
|
if (attempt == maxRetries - 1) rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw Exception("获取MAC超时");
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String> getMacFromType2(THapp bledevice, Duration timeout) async {
|
||||||
|
try {
|
||||||
|
final read = bledevice.getresource('ffe0/ffe1');
|
||||||
|
await read!.characteristic.setNotifyValue(true);
|
||||||
|
|
||||||
|
final write =
|
||||||
|
bledevice.getresource('ffe0/ffe1'); // 与 read 同 characteristic
|
||||||
|
const int maxRetries = 2;
|
||||||
|
for (int attempt = 0; attempt < maxRetries; attempt++) {
|
||||||
|
final completer = Completer<String>();
|
||||||
|
final subscription = read.characteristic.onValueReceived.listen((data) {
|
||||||
|
if (data.length >= 17) {
|
||||||
|
completer.complete(parseMacFromTH2Response(data));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
final order = [0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x0C, 0x0B, 0x0A];
|
||||||
|
int checksum = order.reduce((a, b) => a + b) & 0xFFFF;
|
||||||
|
order.add(checksum & 0xFF); // 低位
|
||||||
|
order.add((checksum >> 8) & 0xFF); // 高位
|
||||||
|
|
||||||
|
await write!.characteristic.write(order);
|
||||||
|
|
||||||
|
try {
|
||||||
|
final mac = await completer.future.timeout(timeout);
|
||||||
|
await subscription.cancel();
|
||||||
|
return mac;
|
||||||
|
} catch (_) {
|
||||||
|
await subscription.cancel();
|
||||||
|
if (attempt == maxRetries - 1) rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
ef.log("[获取设备 MAC]:失败:$e");
|
||||||
|
}
|
||||||
|
|
||||||
|
throw Exception("获取MAC超时");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String parseMacFromBleResponse(List<int> data) {
|
String parseMacFromBleResponse(List<int> data) {
|
||||||
@@ -650,3 +691,21 @@ String parseMacFromBleResponse(List<int> data) {
|
|||||||
throw Exception("BLE返回数据格式不正确");
|
throw Exception("BLE返回数据格式不正确");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String parseMacFromTH2Response(List<int> data) {
|
||||||
|
if (data.length < 17) {
|
||||||
|
throw Exception("数据长度不足,无法解析MAC");
|
||||||
|
}
|
||||||
|
|
||||||
|
int status = data[8];
|
||||||
|
if (status != 0x03 && status != 0x04) {
|
||||||
|
throw Exception("未连接心率带");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提取9~14字节的MAC地址
|
||||||
|
List<int> macBytes = data.sublist(9, 15);
|
||||||
|
return macBytes
|
||||||
|
.map((b) => b.toRadixString(16).padLeft(2, '0'))
|
||||||
|
.join(":")
|
||||||
|
.toUpperCase();
|
||||||
|
}
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ class DeviceInfoWidget extends GetView {
|
|||||||
});
|
});
|
||||||
await future;
|
await future;
|
||||||
await webviewTestController.web.jsbridge?.dart
|
await webviewTestController.web.jsbridge?.dart
|
||||||
.pageActive();
|
.pageActive(false);
|
||||||
MainPageBBottomChange.jumpTo(2);
|
MainPageBBottomChange.jumpTo(2);
|
||||||
Get.until((route) =>
|
Get.until((route) =>
|
||||||
Get.currentRoute ==
|
Get.currentRoute ==
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ class _MHTBindDeviceTypePageState extends State<MHTBindDeviceTypePage> {
|
|||||||
bottom: 26.rpx), // 添加每个设备之间的间隔
|
bottom: 26.rpx), // 添加每个设备之间的间隔
|
||||||
child: _buildDeviceCard(
|
child: _buildDeviceCard(
|
||||||
context,
|
context,
|
||||||
title: device['name'], // 这里假设 device 是一个 Map
|
title: device['name'],
|
||||||
imageUrl: device['image'],
|
imageUrl: device['image'],
|
||||||
type: device['type'],
|
type: device['type'],
|
||||||
desc: device['desc'] ?? [],
|
desc: device['desc'] ?? [],
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ import 'package:vbvs_app/pages/mh_page/device/controller/mht_bluetooth_controlle
|
|||||||
import 'package:vbvs_app/pages/mh_page/device/model/BlueToothDataModel.dart';
|
import 'package:vbvs_app/pages/mh_page/device/model/BlueToothDataModel.dart';
|
||||||
|
|
||||||
class MHTBlueteethDevicePage extends StatefulWidget {
|
class MHTBlueteethDevicePage extends StatefulWidget {
|
||||||
var data;
|
var deviceType;
|
||||||
MHTBlueteethDevicePage({super.key, required this.data});
|
MHTBlueteethDevicePage({super.key, required this.deviceType});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<MHTBlueteethDevicePage> createState() => _MHTBlueteethDevicePageState();
|
State<MHTBlueteethDevicePage> createState() => _MHTBlueteethDevicePageState();
|
||||||
@@ -146,10 +146,8 @@ class _MHTBlueteethDevicePageState extends State<MHTBlueteethDevicePage> {
|
|||||||
final filteredResults = results.where((r) {
|
final filteredResults = results.where((r) {
|
||||||
final localName = r.advertisementData.localName;
|
final localName = r.advertisementData.localName;
|
||||||
final isTarget = r.rssi > signalThreshold &&
|
final isTarget = r.rssi > signalThreshold &&
|
||||||
isTargetDevice(localName, widget.data['reg'].cast<String>());
|
isTargetDevice(localName, widget.deviceType['reg'].cast<String>());
|
||||||
|
|
||||||
if (!isTarget) return false;
|
if (!isTarget) return false;
|
||||||
|
|
||||||
final name = r.advertisementData.advName.toLowerCase();
|
final name = r.advertisementData.advName.toLowerCase();
|
||||||
String macAddress = r.device.remoteId.str;
|
String macAddress = r.device.remoteId.str;
|
||||||
final mac = macAddress.replaceAll(':', '');
|
final mac = macAddress.replaceAll(':', '');
|
||||||
@@ -164,7 +162,7 @@ class _MHTBlueteethDevicePageState extends State<MHTBlueteethDevicePage> {
|
|||||||
return true;
|
return true;
|
||||||
}).map((r) {
|
}).map((r) {
|
||||||
return BlueToothDataModel.fromScanResult(
|
return BlueToothDataModel.fromScanResult(
|
||||||
r, widget.data['type']?.toInt(),
|
r, widget.deviceType['type']?.toInt(),
|
||||||
bind: false,
|
bind: false,
|
||||||
name: r.advertisementData.localName,
|
name: r.advertisementData.localName,
|
||||||
mac: r.device.remoteId.str.replaceAll(':', ''));
|
mac: r.device.remoteId.str.replaceAll(':', ''));
|
||||||
@@ -638,6 +636,7 @@ class _MHTBlueteethDevicePageState extends State<MHTBlueteethDevicePage> {
|
|||||||
.map((device) {
|
.map((device) {
|
||||||
return DeviceComponentWidget(
|
return DeviceComponentWidget(
|
||||||
bleDevice: device,
|
bleDevice: device,
|
||||||
|
deviceType: widget.deviceType,
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.toList()
|
.toList()
|
||||||
|
|||||||
@@ -379,7 +379,8 @@ class _MHTPeopleInfoPageState extends State<MHTPeopleInfoPage> {
|
|||||||
decoration: BoxDecoration(),
|
decoration: BoxDecoration(),
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
FocusScope.of(context).unfocus();
|
FocusScope.of(context)
|
||||||
|
.requestFocus(FocusNode());
|
||||||
Future.delayed(
|
Future.delayed(
|
||||||
const Duration(milliseconds: 250),
|
const Duration(milliseconds: 250),
|
||||||
() {
|
() {
|
||||||
@@ -444,13 +445,14 @@ class _MHTPeopleInfoPageState extends State<MHTPeopleInfoPage> {
|
|||||||
decoration: BoxDecoration(),
|
decoration: BoxDecoration(),
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
FocusScope.of(context).unfocus();
|
FocusScope.of(context)
|
||||||
|
.requestFocus(FocusNode());
|
||||||
Future.delayed(
|
Future.delayed(
|
||||||
const Duration(milliseconds: 250),
|
const Duration(milliseconds: 250),
|
||||||
() {
|
() {
|
||||||
showWeightPickerDialog(
|
showWeightPickerDialog(
|
||||||
context,
|
context,
|
||||||
initialWeight: "0",
|
initialWeight: "50",
|
||||||
onConfirm: (int selectedWeight) {
|
onConfirm: (int selectedWeight) {
|
||||||
setState(() {
|
setState(() {
|
||||||
peopleList[index]['weight'] =
|
peopleList[index]['weight'] =
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ class _HomeDeviceStausWidgetState extends State<HomeDeviceStausWidget> {
|
|||||||
});
|
});
|
||||||
await future;
|
await future;
|
||||||
await webviewTestController.web.jsbridge?.dart
|
await webviewTestController.web.jsbridge?.dart
|
||||||
.pageActive();
|
.pageActive(false);
|
||||||
MainPageBBottomChange.jumpTo(2);
|
MainPageBBottomChange.jumpTo(2);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
DailyLogUtils.writeError("发生异常: $e");
|
DailyLogUtils.writeError("发生异常: $e");
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ class WebviewTestController extends GetControllerEx<WebviewTestModel> {
|
|||||||
ef.log('updateBlueToothStatus: $args');
|
ef.log('updateBlueToothStatus: $args');
|
||||||
// bluetooth = args[0];
|
// bluetooth = args[0];
|
||||||
MHTHomeController deviceController = Get.find();
|
MHTHomeController deviceController = Get.find();
|
||||||
|
await deviceController.getDeviceList(group: 'room');
|
||||||
final allDevices = deviceController.deviceList.values
|
final allDevices = deviceController.deviceList.values
|
||||||
.expand((list) => list)
|
.expand((list) => list)
|
||||||
.toList();
|
.toList();
|
||||||
@@ -112,12 +113,7 @@ class WebviewTestController extends GetControllerEx<WebviewTestModel> {
|
|||||||
ef.log('queryInstantData: $args');
|
ef.log('queryInstantData: $args');
|
||||||
// bluetooth = args[0];
|
// bluetooth = args[0];
|
||||||
return instantData;
|
return instantData;
|
||||||
});
|
});
|
||||||
bridge.sdk.queryInstantData((args) async {
|
|
||||||
ef.log('queryInstantData: $args');
|
|
||||||
// bluetooth = args[0];
|
|
||||||
return instantData;
|
|
||||||
});
|
|
||||||
bridge.sdk.startTimer((args) async {
|
bridge.sdk.startTimer((args) async {
|
||||||
ef.log('queryInstantData: $args');
|
ef.log('queryInstantData: $args');
|
||||||
MHTHomeController homeController = Get.find();
|
MHTHomeController homeController = Get.find();
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ var mhroutes = {
|
|||||||
"/deviceListPage": (context) => DeviceListPage(),
|
"/deviceListPage": (context) => DeviceListPage(),
|
||||||
"/mHTDeviceTypePage": (context, {arguments}) => MHTBindDeviceTypePage(),
|
"/mHTDeviceTypePage": (context, {arguments}) => MHTBindDeviceTypePage(),
|
||||||
"/mHTBlueteethDevicePage": (context, {arguments}) =>
|
"/mHTBlueteethDevicePage": (context, {arguments}) =>
|
||||||
MHTBlueteethDevicePage(data: arguments),
|
MHTBlueteethDevicePage(deviceType: arguments),
|
||||||
"/mHTwifiPage": (contxt, {arguments}) => MHTWifiPage(deviceInfo: arguments),
|
"/mHTwifiPage": (contxt, {arguments}) => MHTWifiPage(deviceInfo: arguments),
|
||||||
"/calibrationPage": (contxt) => MHTCalibrationPage(),
|
"/calibrationPage": (contxt) => MHTCalibrationPage(),
|
||||||
"/bindDeviceSuccess": (contxt) => MHTBindDeviceSuccess(),
|
"/bindDeviceSuccess": (contxt) => MHTBindDeviceSuccess(),
|
||||||
|
|||||||
Reference in New Issue
Block a user