2023-09-07 18:36:16 +08:00
|
|
|
|
import 'dart:async';
|
2025-01-09 14:10:10 +08:00
|
|
|
|
import 'dart:convert';
|
2023-12-11 13:44:15 +08:00
|
|
|
|
import 'dart:io';
|
2025-01-09 14:10:10 +08:00
|
|
|
|
import 'dart:typed_data';
|
2023-09-07 18:36:16 +08:00
|
|
|
|
|
2024-03-18 16:16:51 +08:00
|
|
|
|
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
|
2025-01-20 14:13:56 +08:00
|
|
|
|
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
2024-04-15 16:30:00 +08:00
|
|
|
|
import 'package:get/get.dart';
|
2023-09-07 18:36:16 +08:00
|
|
|
|
import 'package:network_info_plus/network_info_plus.dart';
|
|
|
|
|
|
import 'package:permission_handler/permission_handler.dart';
|
2025-02-24 17:02:38 +08:00
|
|
|
|
import 'package:star_lock/appRouters.dart';
|
2025-01-09 14:10:10 +08:00
|
|
|
|
import 'package:star_lock/app_settings/app_settings.dart';
|
|
|
|
|
|
import 'package:star_lock/blue/io_gateway/io_gateway_configuringWifi.dart';
|
2025-01-10 14:47:50 +08:00
|
|
|
|
import 'package:star_lock/blue/io_gateway/io_gateway_getStatus.dart';
|
2025-03-24 15:14:49 +08:00
|
|
|
|
import 'package:star_lock/blue/io_protocol/io_updataLockSet.dart';
|
2024-08-19 11:01:37 +08:00
|
|
|
|
import 'package:star_lock/login/login/entity/LoginEntity.dart';
|
2025-02-18 14:20:10 +08:00
|
|
|
|
import 'package:star_lock/main/lockDetail/lockDetail/device_network_info.dart';
|
2024-08-19 11:01:37 +08:00
|
|
|
|
import 'package:star_lock/main/lockDetail/lockSet/configuringWifi/configuringWifi/configuringWifiEntity.dart';
|
2025-04-03 10:35:30 +08:00
|
|
|
|
import 'package:star_lock/mine/gateway/addGateway/gatewayConfigurationWifi/gatewayConfigurationWifi_page.dart';
|
2025-01-09 14:10:10 +08:00
|
|
|
|
import 'package:star_lock/mine/gateway/addGateway/gatewayConfigurationWifi/getGatewayConfiguration_entity.dart';
|
2025-01-10 14:47:50 +08:00
|
|
|
|
import 'package:star_lock/mine/gateway/addGateway/selectGateway/getGatewayInfo_model.dart';
|
2025-01-23 14:30:31 +08:00
|
|
|
|
import 'package:star_lock/talk/starChart/entity/star_chart_register_node_entity.dart';
|
|
|
|
|
|
import 'package:star_lock/talk/starChart/star_chart_manage.dart';
|
2023-09-07 18:36:16 +08:00
|
|
|
|
import 'package:star_lock/tools/baseGetXController.dart';
|
2025-03-24 15:14:49 +08:00
|
|
|
|
import 'package:star_lock/tools/commonDataManage.dart';
|
2023-09-07 18:36:16 +08:00
|
|
|
|
|
2024-03-09 17:17:38 +08:00
|
|
|
|
import '../../../../../blue/blue_manage.dart';
|
|
|
|
|
|
import '../../../../../blue/io_protocol/io_configuringWifi.dart';
|
|
|
|
|
|
import '../../../../../blue/io_reply.dart';
|
|
|
|
|
|
import '../../../../../blue/io_tool/io_tool.dart';
|
|
|
|
|
|
import '../../../../../blue/io_tool/manager_event_bus.dart';
|
|
|
|
|
|
import '../../../../../blue/sender_manage.dart';
|
|
|
|
|
|
import '../../../../../network/api_repository.dart';
|
2024-04-22 15:38:19 +08:00
|
|
|
|
import '../../../../../tools/eventBusEventManage.dart';
|
2024-03-09 17:17:38 +08:00
|
|
|
|
import '../../../../../tools/storage.dart';
|
2023-09-07 18:36:16 +08:00
|
|
|
|
import 'configuringWifi_state.dart';
|
|
|
|
|
|
|
2024-12-23 15:19:57 +08:00
|
|
|
|
class ConfiguringWifiLogic extends BaseGetXController {
|
2023-09-07 18:36:16 +08:00
|
|
|
|
final ConfiguringWifiState state = ConfiguringWifiState();
|
2025-04-26 15:15:27 +08:00
|
|
|
|
final int _configurationTimeout = 60; // 配网超时时间(秒)
|
2023-09-07 18:36:16 +08:00
|
|
|
|
|
2025-04-26 15:15:27 +08:00
|
|
|
|
/// 获取WiFi锁服务IP和端口
|
2023-09-07 18:36:16 +08:00
|
|
|
|
Future<void> getWifiLockServiceIpAndPort() async {
|
2025-04-26 15:15:27 +08:00
|
|
|
|
try {
|
|
|
|
|
|
final ConfiguringWifiEntity entity =
|
|
|
|
|
|
await ApiRepository.to.getWifiLockServiceIpAndPort();
|
|
|
|
|
|
if (entity.errorCode! == 0) {
|
|
|
|
|
|
state.configuringWifiEntity.value = entity;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
AppLog.log('获取WiFi锁服务IP和端口失败:${entity.errorCode}');
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
AppLog.log('获取WiFi锁服务IP和端口异常:$e');
|
2024-04-22 15:38:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2023-11-18 10:38:13 +08:00
|
|
|
|
|
2025-04-26 15:15:27 +08:00
|
|
|
|
/// 更新网络信息到服务器
|
2025-04-26 15:51:16 +08:00
|
|
|
|
Future<LoginEntity> updateNetworkInfo({
|
2025-01-09 14:10:10 +08:00
|
|
|
|
required String peerId,
|
|
|
|
|
|
required String wifiName,
|
|
|
|
|
|
required String secretKey,
|
|
|
|
|
|
required String deviceMac,
|
|
|
|
|
|
required String networkMac,
|
|
|
|
|
|
}) async {
|
2025-04-26 15:15:27 +08:00
|
|
|
|
try {
|
|
|
|
|
|
final LoginEntity entity = await ApiRepository.to.settingDeviceNetwork(
|
|
|
|
|
|
deviceType: 2,
|
|
|
|
|
|
deviceMac: deviceMac,
|
2025-04-10 16:54:59 +08:00
|
|
|
|
wifiName: wifiName,
|
|
|
|
|
|
networkMac: networkMac,
|
|
|
|
|
|
secretKey: secretKey,
|
|
|
|
|
|
peerId: peerId,
|
|
|
|
|
|
);
|
2025-04-26 15:51:16 +08:00
|
|
|
|
return entity;
|
2025-04-26 15:15:27 +08:00
|
|
|
|
} catch (e) {
|
|
|
|
|
|
dismissEasyLoading();
|
|
|
|
|
|
state.sureBtnState.value = 0;
|
|
|
|
|
|
AppLog.log('网络配置异常:$e');
|
2025-04-26 15:51:16 +08:00
|
|
|
|
return LoginEntity();
|
2023-09-07 18:36:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 监听设备返回的数据
|
|
|
|
|
|
late StreamSubscription<Reply> _replySubscription;
|
2024-12-23 15:19:57 +08:00
|
|
|
|
|
2023-09-07 18:36:16 +08:00
|
|
|
|
void _initReplySubscription() {
|
2024-12-23 15:19:57 +08:00
|
|
|
|
_replySubscription =
|
|
|
|
|
|
EventBusManager().eventBus!.on<Reply>().listen((Reply reply) async {
|
2023-11-18 10:38:13 +08:00
|
|
|
|
// WIFI配网结果
|
2025-01-09 14:10:10 +08:00
|
|
|
|
if (reply is GatewayConfiguringWifiResultReply) {
|
|
|
|
|
|
_replySenderConfiguringWifiResult(reply);
|
2023-09-07 18:36:16 +08:00
|
|
|
|
}
|
2025-04-26 15:15:27 +08:00
|
|
|
|
// wifi配网命令应答结果
|
2025-04-03 10:35:30 +08:00
|
|
|
|
if (reply is GatewayConfiguringWifiReply) {
|
2025-04-26 15:15:27 +08:00
|
|
|
|
_replySenderConfiguringWifi(reply);
|
2025-01-10 14:47:50 +08:00
|
|
|
|
}
|
2025-01-17 13:58:30 +08:00
|
|
|
|
if (reply is GatewayGetStatusReply) {
|
2025-04-03 10:35:30 +08:00
|
|
|
|
_replyGatewayGetStatusReply(reply);
|
2025-01-17 13:58:30 +08:00
|
|
|
|
}
|
2025-03-24 15:14:49 +08:00
|
|
|
|
// 上传数据获取锁设置
|
|
|
|
|
|
if (reply is UpdataLockSetReply) {
|
|
|
|
|
|
_replyUpdataLockSetReply(reply);
|
|
|
|
|
|
}
|
2023-09-07 18:36:16 +08:00
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-26 15:15:27 +08:00
|
|
|
|
// WIFI配网操作结果处理
|
|
|
|
|
|
Future<void> _replySenderConfiguringWifi(Reply reply) async {
|
|
|
|
|
|
final int status = reply.data[2];
|
|
|
|
|
|
|
|
|
|
|
|
switch (status) {
|
|
|
|
|
|
case 0x00:
|
|
|
|
|
|
AppLog.log('wifi配网命令回复结果:成功');
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
//失败
|
|
|
|
|
|
dismissEasyLoading(); // 关闭loading
|
|
|
|
|
|
showToast('配网失败'.tr);
|
|
|
|
|
|
state.isLoading.value = false;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// WIFI配网结果处理
|
2025-01-09 14:10:10 +08:00
|
|
|
|
Future<void> _replySenderConfiguringWifiResult(Reply reply) async {
|
|
|
|
|
|
final int status = reply.data[2];
|
2025-04-10 16:54:59 +08:00
|
|
|
|
|
2025-04-26 15:15:27 +08:00
|
|
|
|
// 收到响应后,取消蓝牙超时计时器
|
|
|
|
|
|
cancelBlueConnetctToastTimer();
|
2025-02-10 13:40:02 +08:00
|
|
|
|
|
2024-12-23 15:19:57 +08:00
|
|
|
|
switch (status) {
|
2023-09-07 18:36:16 +08:00
|
|
|
|
case 0x00:
|
2025-04-26 15:15:27 +08:00
|
|
|
|
// 配网成功 - 不关闭loading,保持状态直到全部完成
|
2025-04-01 16:23:02 +08:00
|
|
|
|
await Storage.removeLockNetWorkInfoCache();
|
2025-01-09 14:10:10 +08:00
|
|
|
|
|
2025-04-26 15:15:27 +08:00
|
|
|
|
try {
|
|
|
|
|
|
final int secretKeyJsonLength = (reply.data[4] << 8) + reply.data[3];
|
|
|
|
|
|
final List<int> secretKeyList =
|
|
|
|
|
|
reply.data.sublist(5, 5 + secretKeyJsonLength);
|
|
|
|
|
|
String result = utf8String(secretKeyList);
|
|
|
|
|
|
|
|
|
|
|
|
AppLog.log('解析配网信息: $result');
|
|
|
|
|
|
|
|
|
|
|
|
// 解析 JSON 字符串为 Map
|
|
|
|
|
|
Map<String, dynamic> jsonMap = json.decode(result);
|
|
|
|
|
|
|
|
|
|
|
|
// 提取网络信息
|
|
|
|
|
|
String? peerId = jsonMap['peerId'];
|
|
|
|
|
|
String? wifiName = jsonMap['wifiName'];
|
|
|
|
|
|
String? secretKey = jsonMap['secretKey'];
|
|
|
|
|
|
String? deviceMac = jsonMap['deviceMac'];
|
|
|
|
|
|
String? networkMac = jsonMap['networkMac'];
|
|
|
|
|
|
|
|
|
|
|
|
// 验证关键字段
|
|
|
|
|
|
if (peerId == null ||
|
|
|
|
|
|
peerId.isEmpty ||
|
|
|
|
|
|
secretKey == null ||
|
|
|
|
|
|
secretKey.isEmpty) {
|
|
|
|
|
|
throw Exception('Missing required network information');
|
|
|
|
|
|
}
|
2025-01-09 14:10:10 +08:00
|
|
|
|
|
2025-04-26 15:15:27 +08:00
|
|
|
|
// 上报服务器 - 注意: sureBtnState 状态将在 updateNetworkInfo 方法中或其回调中完成重置
|
2025-04-26 15:51:16 +08:00
|
|
|
|
final info = await updateNetworkInfo(
|
2025-07-12 15:50:31 +08:00
|
|
|
|
peerId: peerId,
|
|
|
|
|
|
wifiName: wifiName ?? '',
|
|
|
|
|
|
secretKey: secretKey,
|
|
|
|
|
|
deviceMac: deviceMac ?? '',
|
|
|
|
|
|
networkMac: networkMac ?? '',
|
|
|
|
|
|
);
|
2025-04-26 15:51:16 +08:00
|
|
|
|
if (info.errorCode!.codeIsSuccessful) {
|
|
|
|
|
|
// 设置锁的peerID
|
|
|
|
|
|
StartChartManage().lockNetworkInfo = DeviceNetworkInfo(
|
|
|
|
|
|
wifiName: wifiName,
|
|
|
|
|
|
networkMac: networkMac,
|
|
|
|
|
|
secretKey: secretKey,
|
|
|
|
|
|
peerId: peerId,
|
|
|
|
|
|
);
|
|
|
|
|
|
|
2025-07-12 15:50:31 +08:00
|
|
|
|
state.lockSetInfoData.value?.lockBasicInfo?.networkInfo?.peerId =
|
|
|
|
|
|
peerId;
|
|
|
|
|
|
state.lockSetInfoData.value?.lockBasicInfo?.networkInfo?.wifiName =
|
|
|
|
|
|
wifiName;
|
|
|
|
|
|
|
2025-04-26 15:51:16 +08:00
|
|
|
|
/// 配网成功后,赋值锁的peerId
|
|
|
|
|
|
StartChartManage().lockPeerId = peerId;
|
|
|
|
|
|
|
|
|
|
|
|
// 保存到缓存
|
|
|
|
|
|
await Storage.saveLockNetWorkInfo(jsonMap);
|
|
|
|
|
|
|
2025-04-28 09:20:25 +08:00
|
|
|
|
showToast('配网成功'.tr, something: () {
|
|
|
|
|
|
state.sureBtnState.value = 0; // 确保重置状态
|
|
|
|
|
|
if (state.pageName.value == 'lockSet') {
|
|
|
|
|
|
Get.close(2);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
Get.offAllNamed(Routers.starLockMain);
|
|
|
|
|
|
}
|
|
|
|
|
|
eventBus.fire(SuccessfulDistributionNetwork());
|
2025-07-12 15:50:31 +08:00
|
|
|
|
eventBus.fire(RefreshLockListInfoDataEvent(
|
|
|
|
|
|
clearScanDevices: true, isUnShowLoading: true));
|
|
|
|
|
|
eventBus.fire(RefreshLockDetailInfoDataEvent());
|
2025-04-28 09:20:25 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 获取锁设置
|
|
|
|
|
|
_getUploadLockSet();
|
2025-04-26 15:51:16 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
dismissEasyLoading();
|
2025-04-28 09:20:25 +08:00
|
|
|
|
// showToast('网络配置失败,请重试'.tr);
|
2025-04-26 15:51:16 +08:00
|
|
|
|
state.sureBtnState.value = 0;
|
|
|
|
|
|
}
|
2025-04-26 15:15:27 +08:00
|
|
|
|
} catch (e) {
|
|
|
|
|
|
if (EasyLoading.isShow) {
|
|
|
|
|
|
dismissEasyLoading();
|
|
|
|
|
|
}
|
2025-04-28 09:20:25 +08:00
|
|
|
|
// showToast('解析配网信息失败,请重试'.tr);
|
2025-04-26 15:15:27 +08:00
|
|
|
|
state.sureBtnState.value = 0; // 确保重置状态
|
|
|
|
|
|
AppLog.log('解析配网信息失败: $e');
|
|
|
|
|
|
return; // 添加return阻止后续流程
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
2025-01-09 14:10:10 +08:00
|
|
|
|
|
2025-04-26 15:15:27 +08:00
|
|
|
|
case 0x01:
|
|
|
|
|
|
// WiFi密码错误
|
|
|
|
|
|
if (EasyLoading.isShow) {
|
|
|
|
|
|
dismissEasyLoading();
|
|
|
|
|
|
}
|
2025-04-28 09:20:25 +08:00
|
|
|
|
// showToast('WiFi密码错误,请重新输入'.tr);
|
2025-04-26 15:15:27 +08:00
|
|
|
|
state.sureBtnState.value = 0; // 确保重置状态
|
|
|
|
|
|
break;
|
2025-02-26 11:35:29 +08:00
|
|
|
|
|
2025-04-26 15:15:27 +08:00
|
|
|
|
case 0x02:
|
|
|
|
|
|
// 找不到WiFi
|
|
|
|
|
|
if (EasyLoading.isShow) {
|
|
|
|
|
|
dismissEasyLoading();
|
|
|
|
|
|
}
|
2025-04-28 09:20:25 +08:00
|
|
|
|
// showToast('找不到该WiFi网络,请确认WiFi名称正确'.tr);
|
2025-04-26 15:15:27 +08:00
|
|
|
|
state.sureBtnState.value = 0; // 确保重置状态
|
|
|
|
|
|
break;
|
2025-04-10 16:54:59 +08:00
|
|
|
|
|
2025-04-26 15:15:27 +08:00
|
|
|
|
case 0x03:
|
|
|
|
|
|
// 网络连接超时
|
|
|
|
|
|
if (EasyLoading.isShow) {
|
|
|
|
|
|
dismissEasyLoading();
|
|
|
|
|
|
}
|
2025-04-28 09:20:25 +08:00
|
|
|
|
// showToast('连接WiFi超时,请确保网络信号良好'.tr);
|
2025-04-26 15:15:27 +08:00
|
|
|
|
state.sureBtnState.value = 0; // 确保重置状态
|
2023-09-07 18:36:16 +08:00
|
|
|
|
break;
|
2025-04-26 15:15:27 +08:00
|
|
|
|
|
2023-09-07 18:36:16 +08:00
|
|
|
|
default:
|
2025-04-26 15:15:27 +08:00
|
|
|
|
// 其他错误
|
|
|
|
|
|
if (EasyLoading.isShow) {
|
|
|
|
|
|
dismissEasyLoading();
|
2025-02-26 11:35:29 +08:00
|
|
|
|
}
|
2025-04-28 09:20:25 +08:00
|
|
|
|
// showToast('配网失败 (错误码: $status),请重试'.tr);
|
2025-04-26 15:15:27 +08:00
|
|
|
|
state.sureBtnState.value = 0; // 确保重置状态
|
2023-09-07 18:36:16 +08:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-26 15:15:27 +08:00
|
|
|
|
// 辅助函数:美化 JSON 输出
|
2025-01-09 14:10:10 +08:00
|
|
|
|
String prettyPrintJson(String jsonString) {
|
|
|
|
|
|
var jsonObject = json.decode(jsonString);
|
|
|
|
|
|
return JsonEncoder.withIndent(' ').convert(jsonObject);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-09-07 18:36:16 +08:00
|
|
|
|
// 点击配置wifi
|
|
|
|
|
|
Future<void> senderConfiguringWifiAction() async {
|
2025-02-26 11:35:29 +08:00
|
|
|
|
AppLog.log('开始配网${EasyLoading.isShow}');
|
2025-04-10 16:54:59 +08:00
|
|
|
|
|
2025-04-26 15:15:27 +08:00
|
|
|
|
if (state.sureBtnState.value == 1) {
|
2025-02-10 13:40:02 +08:00
|
|
|
|
AppLog.log('正在配网中请勿重复点击');
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2024-04-22 15:38:19 +08:00
|
|
|
|
|
2025-04-26 15:15:27 +08:00
|
|
|
|
// 获取网关配置信息
|
|
|
|
|
|
try {
|
|
|
|
|
|
final GetGatewayConfigurationEntity entity = await ApiRepository.to
|
|
|
|
|
|
.getGatewayConfigurationNotLoading(timeout: _configurationTimeout);
|
|
|
|
|
|
if (entity.errorCode!.codeIsSuccessful) {
|
|
|
|
|
|
state.getGatewayConfigurationStr = entity.data ?? '';
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// showToast('获取网关配置失败,请重试'.tr);
|
|
|
|
|
|
AppLog.log('获取网关配置失败,请重试');
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 判断是否登录账户
|
|
|
|
|
|
final loginData = await Storage.getLoginData();
|
|
|
|
|
|
if (loginData == null) {
|
|
|
|
|
|
AppLog.log('未检测到登录信息,请重新登录'.tr);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取app用户的peerId
|
|
|
|
|
|
String appPeerId = loginData.starchart?.starchartId ?? '';
|
|
|
|
|
|
if (appPeerId.isEmpty) {
|
|
|
|
|
|
AppLog.log('用户ID获取失败,请重新登录'.tr);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 处理配置字符串
|
|
|
|
|
|
if (state.getGatewayConfigurationStr.isNotEmpty) {
|
|
|
|
|
|
// 解析 JSON 字符串为 Map
|
|
|
|
|
|
Map<String, dynamic> jsonMap =
|
|
|
|
|
|
json.decode(state.getGatewayConfigurationStr);
|
|
|
|
|
|
|
|
|
|
|
|
// 移除指定的键
|
|
|
|
|
|
jsonMap.remove("starCloudUrl");
|
|
|
|
|
|
jsonMap.remove("starLockPeerId");
|
|
|
|
|
|
|
|
|
|
|
|
// 追加新的键值对
|
|
|
|
|
|
jsonMap['userPeerld'] = appPeerId;
|
|
|
|
|
|
|
|
|
|
|
|
// 将 Map 转换回 JSON 字符串
|
|
|
|
|
|
state.getGatewayConfigurationStr =
|
|
|
|
|
|
json.encode(jsonMap).replaceAll(',', ',\n');
|
|
|
|
|
|
|
|
|
|
|
|
// 确保格式化输出
|
|
|
|
|
|
state.getGatewayConfigurationStr =
|
|
|
|
|
|
prettyPrintJson(state.getGatewayConfigurationStr);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 如果为空,则直接赋值
|
|
|
|
|
|
state.getGatewayConfigurationStr = "{\"userPeerld\": \"$appPeerId\"}";
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
AppLog.log('网关配置准备失败:${e.toString()}'.tr);
|
2025-01-09 14:10:10 +08:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-26 15:15:27 +08:00
|
|
|
|
// 先设置sureBtnState状态,以禁用按钮
|
|
|
|
|
|
state.sureBtnState.value = 1;
|
|
|
|
|
|
|
|
|
|
|
|
// 显示loading,如果已经显示则不再重复显示
|
|
|
|
|
|
if (!EasyLoading.isShow) {
|
|
|
|
|
|
showEasyLoading();
|
2025-01-09 14:10:10 +08:00
|
|
|
|
}
|
2025-04-26 15:15:27 +08:00
|
|
|
|
|
|
|
|
|
|
// 设置蓝牙操作超时处理
|
2025-04-28 09:20:25 +08:00
|
|
|
|
showBlueConnetctToastTimer(
|
|
|
|
|
|
action: () {
|
|
|
|
|
|
if (EasyLoading.isShow) {
|
|
|
|
|
|
dismissEasyLoading();
|
|
|
|
|
|
}
|
|
|
|
|
|
state.sureBtnState.value = 0; // 连接超时时重置状态
|
|
|
|
|
|
},
|
|
|
|
|
|
outTimer: 30,
|
|
|
|
|
|
);
|
2025-01-20 14:13:56 +08:00
|
|
|
|
|
2025-04-10 16:54:59 +08:00
|
|
|
|
// 发送配网指令
|
2025-01-22 16:11:57 +08:00
|
|
|
|
BlueManage().blueSendData(
|
|
|
|
|
|
BlueManage().connectDeviceName,
|
|
|
|
|
|
(BluetoothConnectionState connectionState) async {
|
|
|
|
|
|
if (connectionState == BluetoothConnectionState.connected) {
|
2025-04-26 15:15:27 +08:00
|
|
|
|
try {
|
|
|
|
|
|
IoSenderManage.gatewayConfiguringWifiCommand(
|
|
|
|
|
|
ssid: state.wifiNameController.text,
|
|
|
|
|
|
password: state.wifiPWDController.text,
|
|
|
|
|
|
gatewayConfigurationStr: state.getGatewayConfigurationStr,
|
|
|
|
|
|
);
|
|
|
|
|
|
// 注意:此处不要重置sureBtnState状态,等待配网结果回调
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
if (EasyLoading.isShow) {
|
|
|
|
|
|
dismissEasyLoading();
|
|
|
|
|
|
}
|
|
|
|
|
|
cancelBlueConnetctToastTimer();
|
|
|
|
|
|
state.sureBtnState.value = 0; // 发送命令失败时重置状态
|
2025-04-28 09:20:25 +08:00
|
|
|
|
// showToast('发送配网指令失败:${e.toString()}'.tr);
|
2025-04-26 15:15:27 +08:00
|
|
|
|
}
|
2025-04-08 14:34:25 +08:00
|
|
|
|
} else if (connectionState == BluetoothConnectionState.disconnected) {
|
2025-04-26 15:15:27 +08:00
|
|
|
|
if (EasyLoading.isShow) {
|
|
|
|
|
|
dismissEasyLoading();
|
|
|
|
|
|
}
|
2025-04-08 14:34:25 +08:00
|
|
|
|
cancelBlueConnetctToastTimer();
|
2025-04-26 15:15:27 +08:00
|
|
|
|
state.sureBtnState.value = 0; // 蓝牙断开时重置状态
|
2025-04-08 14:34:25 +08:00
|
|
|
|
if (state.ifCurrentScreen.value == true) {
|
|
|
|
|
|
showBlueConnetctToast();
|
|
|
|
|
|
}
|
2025-01-22 16:11:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
2025-04-10 16:54:59 +08:00
|
|
|
|
isAddEquipment: false,
|
2025-01-22 16:11:57 +08:00
|
|
|
|
);
|
2023-09-07 18:36:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-01-10 14:47:50 +08:00
|
|
|
|
// 获取设备状态
|
|
|
|
|
|
Future<void> getDevicesStatusAction() async {
|
|
|
|
|
|
showEasyLoading();
|
|
|
|
|
|
showBlueConnetctToastTimer(action: () {
|
|
|
|
|
|
dismissEasyLoading();
|
|
|
|
|
|
});
|
|
|
|
|
|
BlueManage().blueSendData(BlueManage().connectDeviceName,
|
|
|
|
|
|
(BluetoothConnectionState connectionState) async {
|
|
|
|
|
|
if (connectionState == BluetoothConnectionState.connected) {
|
|
|
|
|
|
IoSenderManage.gatewayGetStatusCommand(
|
|
|
|
|
|
lockID: BlueManage().connectDeviceName,
|
|
|
|
|
|
userID: await Storage.getUid(),
|
|
|
|
|
|
);
|
|
|
|
|
|
} else if (connectionState == BluetoothConnectionState.disconnected) {
|
|
|
|
|
|
dismissEasyLoading();
|
|
|
|
|
|
cancelBlueConnetctToastTimer();
|
|
|
|
|
|
if (state.ifCurrentScreen.value == true) {
|
|
|
|
|
|
showBlueConnetctToast();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}, isAddEquipment: true);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-19 11:01:37 +08:00
|
|
|
|
final NetworkInfo _networkInfo = NetworkInfo();
|
2024-12-23 15:19:57 +08:00
|
|
|
|
|
2023-09-07 18:36:16 +08:00
|
|
|
|
Future<String> getWifiName() async {
|
2025-04-26 15:15:27 +08:00
|
|
|
|
try {
|
|
|
|
|
|
String? ssid = await _networkInfo.getWifiName();
|
|
|
|
|
|
ssid = ssid ?? '';
|
|
|
|
|
|
ssid = ssid.replaceAll(r'"', '');
|
|
|
|
|
|
return ssid;
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
AppLog.log('获取WiFi名称失败: $e');
|
|
|
|
|
|
return '';
|
|
|
|
|
|
}
|
2023-09-07 18:36:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
///定位权限
|
|
|
|
|
|
Future<bool> checkLocationPermission() async {
|
2024-08-19 11:01:37 +08:00
|
|
|
|
final PermissionStatus value = await locationPermission();
|
2024-12-23 15:19:57 +08:00
|
|
|
|
final bool allow = value != PermissionStatus.permanentlyDenied &&
|
|
|
|
|
|
value != PermissionStatus.denied;
|
2023-09-07 18:36:16 +08:00
|
|
|
|
return allow;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-12-23 15:19:57 +08:00
|
|
|
|
Future<PermissionStatus> locationPermission() async =>
|
|
|
|
|
|
Permission.location.request();
|
2023-09-07 18:36:16 +08:00
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
|
void onReady() {
|
|
|
|
|
|
super.onReady();
|
|
|
|
|
|
|
2024-12-23 15:19:57 +08:00
|
|
|
|
if (state.wifiName.value.isEmpty) {
|
2024-08-19 11:01:37 +08:00
|
|
|
|
getWifiName().then((String value) {
|
2024-03-09 17:17:38 +08:00
|
|
|
|
state.wifiNameController.text = value;
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2023-09-07 18:36:16 +08:00
|
|
|
|
|
|
|
|
|
|
getWifiLockServiceIpAndPort();
|
|
|
|
|
|
_initReplySubscription();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
|
void onClose() {
|
2024-01-09 18:02:02 +08:00
|
|
|
|
_replySubscription.cancel();
|
2025-04-26 15:15:27 +08:00
|
|
|
|
cancelBlueConnetctToastTimer(); // 确保取消蓝牙超时计时器
|
2024-01-09 18:02:02 +08:00
|
|
|
|
super.onClose();
|
2023-09-07 18:36:16 +08:00
|
|
|
|
}
|
2025-01-10 14:47:50 +08:00
|
|
|
|
|
|
|
|
|
|
void _replyGatewayGetStatusReply(GatewayGetStatusReply reply) {
|
|
|
|
|
|
final int status = reply.data[2];
|
2025-04-10 16:54:59 +08:00
|
|
|
|
//成功
|
|
|
|
|
|
dismissEasyLoading();
|
|
|
|
|
|
cancelBlueConnetctToastTimer();
|
2025-01-10 14:47:50 +08:00
|
|
|
|
switch (status) {
|
|
|
|
|
|
case 0x00:
|
|
|
|
|
|
//成功
|
|
|
|
|
|
final GetGatewayInfoModel gatewayModel = GetGatewayInfoModel();
|
|
|
|
|
|
// 网关MAC地址
|
|
|
|
|
|
int index = 3;
|
|
|
|
|
|
final List<int> macList = reply.data.sublist(index, index + 20);
|
|
|
|
|
|
final String macStr = utf8String(macList);
|
|
|
|
|
|
// lockInfo['mac'] = macStr;
|
|
|
|
|
|
gatewayModel.mac = macStr;
|
|
|
|
|
|
index = index + 20;
|
|
|
|
|
|
AppLog.log('MAC地址 macList:$macList macStr:$macStr');
|
|
|
|
|
|
|
|
|
|
|
|
// 网关序列号
|
|
|
|
|
|
final List<int> serialNum = reply.data.sublist(index, index + 20);
|
|
|
|
|
|
final String serialNumStr = utf8String(serialNum);
|
|
|
|
|
|
// lockInfo['serialNum'] = serialNumStr;
|
|
|
|
|
|
gatewayModel.serialNum = serialNumStr;
|
|
|
|
|
|
index = index + 20;
|
|
|
|
|
|
AppLog.log('序列号 serialNum:$serialNum serialNumStr:$serialNumStr');
|
|
|
|
|
|
|
|
|
|
|
|
// 网关版本
|
|
|
|
|
|
final List<int> gatewayVersion = reply.data.sublist(index, index + 20);
|
|
|
|
|
|
final String gatewayVersionStr = utf8String(gatewayVersion);
|
|
|
|
|
|
// lockInfo['gatewayVersion'] = gatewayVersionStr;
|
|
|
|
|
|
gatewayModel.gatewayVersion = gatewayVersionStr;
|
|
|
|
|
|
index = index + 20;
|
|
|
|
|
|
// AppLog.log(
|
|
|
|
|
|
// '软件版本 gatewayVersion:$gatewayVersion gatewayVersionStr:$gatewayVersionStr');
|
|
|
|
|
|
|
|
|
|
|
|
// wifiMac地址
|
|
|
|
|
|
final List<int> wifiMac = reply.data.sublist(index, index + 20);
|
|
|
|
|
|
final String wifiMacStr = utf8String(wifiMac);
|
|
|
|
|
|
// lockInfo['wifiMac'] = wifiMacStr;
|
|
|
|
|
|
gatewayModel.wifiMac = wifiMacStr;
|
|
|
|
|
|
index = index + 20;
|
|
|
|
|
|
AppLog.log('wifiMac地址 wifiMac:$wifiMac wifiMacStr:$wifiMacStr');
|
|
|
|
|
|
// gatewayModel.wifiMac = '00:00:00:00:00:00';
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
//失败
|
|
|
|
|
|
dismissEasyLoading();
|
2025-04-28 09:20:25 +08:00
|
|
|
|
// showToast('获取设备状态失败'.tr);
|
2025-01-10 14:47:50 +08:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-01-17 13:58:30 +08:00
|
|
|
|
|
2025-03-24 15:14:49 +08:00
|
|
|
|
// 上传数据获取设置
|
|
|
|
|
|
Future<void> _getUploadLockSet() async {
|
2025-04-28 09:20:25 +08:00
|
|
|
|
final List<String>? token = await Storage.getStringList(saveBlueToken);
|
|
|
|
|
|
final List<int> getTokenList = changeStringListToIntList(token!);
|
|
|
|
|
|
// 蓝牙获取锁设置
|
|
|
|
|
|
await _uploadLockSet(getTokenList);
|
2025-03-24 15:14:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 公共的上传锁设置
|
|
|
|
|
|
Future<void> _uploadLockSet(List<int> token) async {
|
2025-04-28 09:20:25 +08:00
|
|
|
|
final List<String>? privateKey =
|
|
|
|
|
|
await Storage.getStringList(saveBluePrivateKey);
|
|
|
|
|
|
if (privateKey == null || privateKey.isEmpty) {
|
|
|
|
|
|
throw Exception('Private key is empty');
|
|
|
|
|
|
}
|
|
|
|
|
|
final List<int> getPrivateKeyList = changeStringListToIntList(privateKey);
|
2025-04-26 15:15:27 +08:00
|
|
|
|
|
2025-04-28 09:20:25 +08:00
|
|
|
|
final List<String>? signKey = await Storage.getStringList(saveBlueSignKey);
|
|
|
|
|
|
if (signKey == null || signKey.isEmpty) {
|
|
|
|
|
|
throw Exception('Sign key is empty');
|
|
|
|
|
|
}
|
|
|
|
|
|
final List<int> signKeyDataList = changeStringListToIntList(signKey);
|
2025-04-26 15:15:27 +08:00
|
|
|
|
|
2025-04-28 09:20:25 +08:00
|
|
|
|
BlueManage().blueSendData(BlueManage().connectDeviceName,
|
|
|
|
|
|
(BluetoothConnectionState connectionState) async {
|
|
|
|
|
|
if (connectionState == BluetoothConnectionState.connected) {
|
|
|
|
|
|
IoSenderManage.updataLockSetCommand(
|
2025-04-26 15:15:27 +08:00
|
|
|
|
lockID: BlueManage().connectDeviceName,
|
|
|
|
|
|
userID: await Storage.getUid(),
|
|
|
|
|
|
token: token,
|
|
|
|
|
|
needAuthor: 1,
|
|
|
|
|
|
signKey: signKeyDataList,
|
2025-04-28 09:20:25 +08:00
|
|
|
|
privateKey: getPrivateKeyList,
|
|
|
|
|
|
);
|
|
|
|
|
|
} else if (connectionState == BluetoothConnectionState.disconnected) {
|
2025-04-26 15:15:27 +08:00
|
|
|
|
dismissEasyLoading();
|
2025-04-28 09:20:25 +08:00
|
|
|
|
cancelBlueConnetctToastTimer();
|
|
|
|
|
|
if (state.ifCurrentScreen.value == true) {
|
|
|
|
|
|
showBlueConnetctToast();
|
|
|
|
|
|
}
|
2025-04-26 15:15:27 +08:00
|
|
|
|
}
|
2025-04-28 09:20:25 +08:00
|
|
|
|
}, isAddEquipment: true);
|
2025-03-24 15:14:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 上传数据获取锁设置解析
|
|
|
|
|
|
Future<void> _replyUpdataLockSetReply(Reply reply) async {
|
|
|
|
|
|
final int status = reply.data[2];
|
2025-04-26 15:15:27 +08:00
|
|
|
|
// 保持loading状态直到整个过程完成
|
2025-04-10 16:54:59 +08:00
|
|
|
|
cancelBlueConnetctToastTimer();
|
2025-04-26 15:15:27 +08:00
|
|
|
|
|
2025-03-24 15:14:49 +08:00
|
|
|
|
switch (status) {
|
|
|
|
|
|
case 0x00:
|
2025-04-10 16:54:59 +08:00
|
|
|
|
await _lockDataUpload(
|
2025-03-24 15:14:49 +08:00
|
|
|
|
uploadType: 1,
|
|
|
|
|
|
recordType: 0,
|
|
|
|
|
|
records: reply.data.sublist(7, reply.data.length));
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
2025-04-26 15:15:27 +08:00
|
|
|
|
case 0x06:
|
|
|
|
|
|
//无权限,尝试重新获取token
|
|
|
|
|
|
try {
|
|
|
|
|
|
final List<int> token = reply.data.sublist(3, 7);
|
|
|
|
|
|
final List<String> saveStrList = changeIntListToStringList(token);
|
|
|
|
|
|
await Storage.setStringList(saveBlueToken, saveStrList);
|
|
|
|
|
|
_uploadLockSet(token);
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
if (EasyLoading.isShow) {
|
|
|
|
|
|
dismissEasyLoading(); // 错误时关闭loading
|
|
|
|
|
|
}
|
2025-04-28 09:20:25 +08:00
|
|
|
|
// showToast('获取设置权限失败:${e.toString()}'.tr);
|
2025-04-26 15:15:27 +08:00
|
|
|
|
state.sureBtnState.value = 0; // 确保重置状态
|
|
|
|
|
|
}
|
2025-03-24 15:14:49 +08:00
|
|
|
|
break;
|
2025-04-26 15:15:27 +08:00
|
|
|
|
|
2025-03-24 15:14:49 +08:00
|
|
|
|
default:
|
2025-04-26 15:15:27 +08:00
|
|
|
|
if (EasyLoading.isShow) {
|
|
|
|
|
|
dismissEasyLoading(); // 错误时关闭loading
|
|
|
|
|
|
}
|
2025-04-28 09:20:25 +08:00
|
|
|
|
// showToast('获取锁设置失败 (错误码: $status)'.tr);
|
2025-04-26 15:15:27 +08:00
|
|
|
|
state.sureBtnState.value = 0; // 确保重置状态
|
2025-03-24 15:14:49 +08:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 锁数据上传服务器
|
|
|
|
|
|
Future<void> _lockDataUpload(
|
|
|
|
|
|
{required int uploadType,
|
|
|
|
|
|
required int recordType,
|
|
|
|
|
|
required List records}) async {
|
2025-04-28 09:20:25 +08:00
|
|
|
|
final LoginEntity entity = await ApiRepository.to.lockDataUpload(
|
|
|
|
|
|
lockId: state.lockBasicInfo.value.lockId ?? -1,
|
|
|
|
|
|
uploadType: uploadType,
|
|
|
|
|
|
recordType: recordType,
|
|
|
|
|
|
records: records,
|
|
|
|
|
|
isUnShowLoading: true);
|
|
|
|
|
|
if (entity.errorCode!.codeIsSuccessful) {
|
|
|
|
|
|
eventBus
|
|
|
|
|
|
.fire(PassCurrentLockInformationEvent(state.lockSetInfoData.value));
|
2025-02-26 11:35:29 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-01-23 17:36:02 +08:00
|
|
|
|
}
|