470 lines
15 KiB
Dart
Executable File

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get/get.dart';
import 'package:network_info_plus/network_info_plus.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:star_lock/appRouters.dart';
import 'package:star_lock/app_settings/app_settings.dart';
import 'package:star_lock/blue/io_gateway/io_gateway_configuringWifi.dart';
import 'package:star_lock/blue/io_gateway/io_gateway_getStatus.dart';
import 'package:star_lock/blue/io_protocol/io_updataLockSet.dart';
import 'package:star_lock/login/login/entity/LoginEntity.dart';
import 'package:star_lock/main/lockDetail/lockDetail/device_network_info.dart';
import 'package:star_lock/main/lockDetail/lockSet/configuringWifi/configuringWifi/configuringWifiEntity.dart';
import 'package:star_lock/mine/gateway/addGateway/gatewayConfigurationWifi/gatewayConfigurationWifi_page.dart';
import 'package:star_lock/mine/gateway/addGateway/gatewayConfigurationWifi/getGatewayConfiguration_entity.dart';
import 'package:star_lock/mine/gateway/addGateway/selectGateway/getGatewayInfo_model.dart';
import 'package:star_lock/talk/starChart/entity/star_chart_register_node_entity.dart';
import 'package:star_lock/talk/starChart/star_chart_manage.dart';
import 'package:star_lock/tools/baseGetXController.dart';
import 'package:star_lock/tools/commonDataManage.dart';
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';
import '../../../../../tools/eventBusEventManage.dart';
import '../../../../../tools/storage.dart';
import 'configuringWifi_state.dart';
class ConfiguringWifiLogic extends BaseGetXController {
final ConfiguringWifiState state = ConfiguringWifiState();
Future<void> getWifiLockServiceIpAndPort() async {
final ConfiguringWifiEntity entity =
await ApiRepository.to.getWifiLockServiceIpAndPort();
if (entity.errorCode! == 0) {
state.configuringWifiEntity.value = entity;
}
}
void updateNetworkInfo({
required String peerId,
required String wifiName,
required String secretKey,
required String deviceMac,
required String networkMac,
}) async {
final LoginEntity entity = await ApiRepository.to.settingDeviceNetwork(
deviceType: 2,
deviceMac: deviceMac,
wifiName: wifiName,
networkMac: networkMac,
secretKey: secretKey,
peerId: peerId,
);
if (entity.errorCode!.codeIsSuccessful) {
// 设置锁的peerID
StartChartManage().lockNetworkInfo = DeviceNetworkInfo(
wifiName: wifiName,
networkMac: networkMac,
secretKey: secretKey,
peerId: peerId,
);
await _getUploadLockSet();
}
}
// 监听设备返回的数据
late StreamSubscription<Reply> _replySubscription;
void _initReplySubscription() {
_replySubscription =
EventBusManager().eventBus!.on<Reply>().listen((Reply reply) async {
// WIFI配网结果
if (reply is GatewayConfiguringWifiResultReply) {
_replySenderConfiguringWifiResult(reply);
}
if (reply is GatewayConfiguringWifiReply) {
_replySenderConfiguringWifiResult(reply);
}
if (reply is GatewayGetStatusReply) {
_replyGatewayGetStatusReply(reply);
}
// if (reply is GatewayGetStatusReply) {
// _replyStatusInfo(reply);
// }
// 上传数据获取锁设置
if (reply is UpdataLockSetReply) {
_replyUpdataLockSetReply(reply);
}
AppLog.log('蓝牙回调处理完毕${EasyLoading.isShow}');
});
}
// WIFI配网结果
Future<void> _replySenderConfiguringWifiResult(Reply reply) async {
final int status = reply.data[2];
// state.sureBtnState.value = 0;
// 取消loading超时定时器
state.loadingTimer?.cancel();
state.loadingTimer = null;
switch (status) {
case 0x00:
await Storage.removeLockNetWorkInfoCache();
final int secretKeyJsonLength = (reply.data[4] << 8) + reply.data[3];
final List<int> secretKeyList =
reply.data.sublist(5, 5 + secretKeyJsonLength);
String result = utf8String(secretKeyList);
// 解析 JSON 字符串为 Map
Map<String, dynamic> jsonMap = json.decode(result);
// 提取 peerId
String? peerId = jsonMap['peerId'];
String? wifiName = jsonMap['wifiName'];
String? secretKey = jsonMap['secretKey'];
String? deviceMac = jsonMap['deviceMac'];
String? networkMac = jsonMap['networkMac'];
/// 配网成功后,赋值锁的peerId
StartChartManage().lockPeerId = peerId ?? '';
state.isLoading.value = false;
// 保存到缓存
await Storage.saveLockNetWorkInfo(jsonMap);
// 上报服务器
updateNetworkInfo(
peerId: peerId ?? '',
wifiName: wifiName ?? '',
secretKey: secretKey ?? '',
deviceMac: deviceMac ?? '',
networkMac: networkMac ?? '');
break;
default:
//失败
dismissEasyLoading(); // 关闭loading
cancelBlueConnetctToastTimer();
if (state.loadingTimer != null) {
state.loadingTimer!.cancel();
state.loadingTimer = null;
}
showToast('配网失败'.tr);
state.isLoading.value = false;
break;
}
}
// 辅助函数:美化 JSON 输出
String prettyPrintJson(String jsonString) {
var jsonObject = json.decode(jsonString);
return JsonEncoder.withIndent(' ').convert(jsonObject);
}
// 点击配置wifi
Future<void> senderConfiguringWifiAction() async {
AppLog.log('开始配网${EasyLoading.isShow}');
if (state.isLoading.isTrue) {
AppLog.log('正在配网中请勿重复点击');
return;
}
if (state.wifiNameController.text.isEmpty) {
showToast('请输入wifi名称'.tr);
return;
}
if (state.wifiPWDController.text.isEmpty) {
showToast('请输入WiFi密码'.tr);
return;
}
// if (state.sureBtnState.value == 1) {
// return;
// }
// state.sureBtnState.value = 1;
final GetGatewayConfigurationEntity entity =
await ApiRepository.to.getGatewayConfigurationNotLoading(timeout: 60);
if (entity.errorCode!.codeIsSuccessful) {
state.getGatewayConfigurationStr = entity.data ?? '';
}
// 判断是否登录账户
final loginData = await Storage.getLoginData();
// 获取app用户的peerId
String appPeerId = loginData?.starchart?.starchartId ?? '';
// 如果已有值,则追加
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\"}";
}
showEasyLoading();
showBlueConnetctToastTimer(action: () {
dismissEasyLoading();
state.isLoading.value = false;
});
// 发送配网指令
BlueManage().blueSendData(
BlueManage().connectDeviceName,
(BluetoothConnectionState connectionState) async {
if (connectionState == BluetoothConnectionState.connected) {
IoSenderManage.gatewayConfiguringWifiCommand(
ssid: state.wifiNameController.text,
password: state.wifiPWDController.text,
gatewayConfigurationStr: state.getGatewayConfigurationStr,
);
} else if (connectionState == BluetoothConnectionState.disconnected) {
dismissEasyLoading();
cancelBlueConnetctToastTimer();
state.isLoading.value = false;
// state.sureBtnState.value = 0;
if (state.ifCurrentScreen.value == true) {
showBlueConnetctToast();
}
}
},
isAddEquipment: false,
);
state.isLoading.value = true;
}
// 获取设备状态
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);
}
final NetworkInfo _networkInfo = NetworkInfo();
Future<String> getWifiName() async {
String ssid = '';
ssid = (await _networkInfo.getWifiName())!;
ssid = ssid ?? '';
ssid = ssid.replaceAll(r'"', '');
return ssid ?? '';
}
///定位权限
Future<bool> checkLocationPermission() async {
final PermissionStatus value = await locationPermission();
final bool allow = value != PermissionStatus.permanentlyDenied &&
value != PermissionStatus.denied;
return allow;
}
Future<PermissionStatus> locationPermission() async =>
Permission.location.request();
@override
void onReady() {
super.onReady();
if (state.wifiName.value.isEmpty) {
getWifiName().then((String value) {
state.wifiNameController.text = value;
});
}
getWifiLockServiceIpAndPort();
_initReplySubscription();
// getDevicesStatusAction();
}
@override
void onInit() {
super.onInit();
}
@override
void onClose() {
_replySubscription.cancel();
super.onClose();
}
void _replyGatewayGetStatusReply(GatewayGetStatusReply reply) {
final int status = reply.data[2];
//成功
dismissEasyLoading();
cancelBlueConnetctToastTimer();
switch (status) {
case 0x00:
//成功
// state.sureBtnState.value = 0;
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();
showToast('配网失败'.tr);
if (state.loadingTimer != null) {
state.loadingTimer!.cancel();
state.loadingTimer = null;
}
break;
}
}
// 上传数据获取设置
Future<void> _getUploadLockSet() async {
showEasyLoading();
showBlueConnetctToastTimer(action: () {
dismissEasyLoading();
});
final List<String>? token = await Storage.getStringList(saveBlueToken);
final List<int> getTokenList = changeStringListToIntList(token!);
await _uploadLockSet(getTokenList);
}
// 公共的上传锁设置
Future<void> _uploadLockSet(List<int> token) async {
final List<String>? privateKey =
await Storage.getStringList(saveBluePrivateKey);
final List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
final List<String>? signKey = await Storage.getStringList(saveBlueSignKey);
final List<int> signKeyDataList = changeStringListToIntList(signKey!);
IoSenderManage.updataLockSetCommand(
lockID: BlueManage().connectDeviceName,
userID: await Storage.getUid(),
token: token,
needAuthor: 1,
signKey: signKeyDataList,
privateKey: getPrivateKeyList);
}
// 上传数据获取锁设置解析
Future<void> _replyUpdataLockSetReply(Reply reply) async {
final int status = reply.data[2];
dismissEasyLoading(); // 关闭loading
cancelBlueConnetctToastTimer();
switch (status) {
case 0x00:
await _lockDataUpload(
uploadType: 1,
recordType: 0,
records: reply.data.sublist(7, reply.data.length));
break;
case 0x06:
//无权限
final List<int> token = reply.data.sublist(3, 7);
final List<String> saveStrList = changeIntListToStringList(token);
Storage.setStringList(saveBlueToken, saveStrList);
_uploadLockSet(token);
break;
default:
dismissEasyLoading();
cancelBlueConnetctToastTimer();
break;
}
}
// 锁数据上传服务器
Future<void> _lockDataUpload(
{required int uploadType,
required int recordType,
required List records}) async {
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) {
showToast('配网成功'.tr, something: () {
state.isLoading.value = false;
if (state.pageName.value == 'lockSet') {
Get.close(2);
} else {
Get.offAllNamed(Routers.starLockMain);
}
eventBus
.fire(PassCurrentLockInformationEvent(state.lockSetInfoData.value));
eventBus.fire(SuccessfulDistributionNetwork());
});
}
}
}