import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:star_lock/blue/io_protocol/io_editUser.dart'; import 'package:star_lock/blue/io_protocol/io_factoryDataReset.dart'; import 'package:star_lock/blue/io_protocol/io_getLockStatu.dart'; import 'package:star_lock/blue/io_type.dart'; import 'package:star_lock/tools/toast.dart'; import '../../../blue/blue_manage.dart'; import '../../../blue/io_protocol/io_getStarLockStatusInfo.dart'; import '../../../blue/io_protocol/io_openLock.dart'; import '../../../blue/io_reply.dart'; import '../../../blue/io_tool/io_manager.dart'; import '../../../blue/io_tool/io_tool.dart'; import '../../../blue/io_tool/manager_event_bus.dart'; import '../../../blue/sender_manage.dart'; import '../../../login/login/entity/LoginData.dart'; import '../../../login/login/entity/LoginEntity.dart'; import '../../../network/api_repository.dart'; import '../../../tools/baseGetXController.dart'; import '../../../tools/eventBusEventManage.dart'; import '../../../tools/storage.dart'; import 'lockDetail_state.dart'; class LockDetailLogic extends BaseGetXController{ final LockDetailState state = LockDetailState(); // 监听设备返回的数据 late StreamSubscription _replySubscription; void _initReplySubscription() { _replySubscription = EventBusManager().eventBus!.on().listen((reply) async { // 开门 if(reply is OpenDoorReply) { _replyOpenLock(reply); } // 获取锁状态 if(reply is GetLockStatuReply) { _replyGetLockStatus(reply); } // 编辑锁用户 if(reply is EditUserReply){ _replyEditUserKey(reply); } // 获取星锁状态信息 if(reply is GetStarLockStatuInfoReply){ _replyGetStarLockStatusInfo(reply); } }); } // 开门数据解析 Future _replyOpenLock(Reply reply) async { var privateKey = await Storage.getStringList(saveBluePrivateKey); List getPrivateKeyList = changeStringListToIntList(privateKey!); var signKey = await Storage.getStringList(saveBlueSignKey); List signKeyDataList = changeStringListToIntList(signKey!); var tokenData = reply.data.sublist(2, 6); var saveStrList = changeIntListToStringList(tokenData); print("openDoorToken:$tokenData"); Storage.setStringList(saveBlueToken, saveStrList); // 电量 int power = reply.data[7]; int status = reply.data[6]; print("status:$status"); switch(status){ case 0x00: //成功 print("${reply.commandType}数据解析成功"); state.lockState.value = 2; state.animationController.reset(); state.animationController.forward(); // state.animationController.isCompleted; break; case 0x06: //无权限 print("${reply.commandType}需要鉴权"); print("millisecondsSinceEpoch/1000:${DateTime.now().millisecondsSinceEpoch~/1000}"); IoSenderManage.senderOpenLock( keyID: BlueManage().connectDeviceName, userID: await Storage.getUid(), openMode: 1, openTime: DateTime.now().millisecondsSinceEpoch~/1000, token: tokenData, needAuthor: 1, signKey: signKeyDataList, privateKey: getPrivateKeyList, ); break; case 0x07: //无权限 print("${reply.commandType}用户无权限"); break; case 0x09: // 权限校验错误 print("${reply.commandType}校验错误"); break; default: //失败 print("${reply.commandType}失败"); break; } } // 获取锁状态数据解析 Future _replyGetLockStatus(Reply reply) async { int status = reply.data[2]; switch(status){ case 0x00: //成功 print("${reply.commandType}数据解析成功"); var softVersion = reply.data.sublist(3, 7); print("softVersion:$softVersion"); var power = reply.data[7]; print("power:$power"); // APP 用户数量 var appUserCount = reply.data.sublist(50, 53); print("appUserCount:$appUserCount"); // 黑名单用户数量 var blacklistCount = reply.data[53]; print("blacklistCount:$blacklistCount"); // 蓝牙钥匙数量 var bleKeyCount = reply.data[54]; print("bleKeyCount:$bleKeyCount"); // 剩余可添加用户数量 var remainCount = reply.data.sublist(54, 56); print("remainCount:$remainCount"); // 未上传开锁记录数量 var notUploadCount = reply.data.sublist(56, 58); print("notUploadCount:$notUploadCount"); // 已设置开门密码数量 var pwdCount = reply.data[58]; print("pwdCount:$pwdCount"); // 已设置开门指纹数量 var fingerprintCount = reply.data[59]; print("fingerprintCount:$fingerprintCount"); // 锁当前时间 var lockTime = reply.data.sublist(60, 64); print("lockTime:$lockTime"); // 硬件版本信息,为固件升级提供判断依据 var hardVersion = reply.data.sublist(64, 68); print("hardVersion:$hardVersion"); break; case 0x06: //无权限 print("${reply.commandType}需要鉴权"); break; case 0x07: //无权限 print("${reply.commandType}用户无权限"); break; case 0x09: // 权限校验错误 print("${reply.commandType}权限校验错误"); break; default: //失败 print("${reply.commandType}失败"); break; } } // 编辑用户数据解析 Future _replyEditUserKey(Reply reply) async { var token = reply.data.sublist(2, 6); var saveStrList = changeIntListToStringList(token); print("_replyEditUserKeyToken:$token"); Storage.setStringList(saveBlueToken, saveStrList); int status = reply.data[6]; print("status:$status"); switch(status){ case 0x00: //成功 print("${reply.commandType!.typeValue} 数据解析成功"); break; case 0x06: //无权限 print("${reply.commandType!.typeValue} 需要鉴权"); var privateKey = await Storage.getStringList(saveBluePrivateKey); List getPrivateKeyList = changeStringListToIntList(privateKey!); var publicKey = await Storage.getStringList(saveBluePublicKey); List publicKeyDataList = changeStringListToIntList(publicKey!); IoSenderManage.senderEditUser( lockID:BlueManage().connectDeviceName, authUserID:await Storage.getUid(), keyID:"1", userID:await Storage.getUid(), openMode:1, keyType:1, startDate:0x11223344, expireDate:0x11223344, role:255, password:"123456", needAuthor:1, publicKey:publicKeyDataList, privateKey:getPrivateKeyList, token: token ); break; case 0x07: //无权限 print("${reply.commandType!.typeValue} 用户无权限"); break; case 0x09: // 权限校验错误 print("${reply.commandType!.typeValue} 权限校验错误"); break; default: //失败 print("${reply.commandType!.typeValue} 失败"); break; } } Future _replyGetStarLockStatusInfo(Reply reply) async { int status = reply.data[2]; switch(status){ case 0x00: //成功 print("${reply.commandType}数据解析成功"); // 厂商名称 var vendor = reply.data.sublist(3, 23); print("vendor:$vendor"); // 锁设备类型 var product = reply.data[23]; print("product:$product"); // 产品名称 var model = reply.data.sublist(24, 44); print("model:$model"); // 软件版本 var fwVersion = reply.data.sublist(44, 64); print("fwVersion:$fwVersion"); // 硬件版本 var hwVersion = reply.data.sublist(64, 84); print("hwVersion:$hwVersion"); // 厂商序列号 var serialNum0 = reply.data.sublist(84, 100); print("serialNum0:$serialNum0"); // 成品商序列号 var serialNum1 = reply.data.sublist(100, 116); print("serialNum1:$serialNum1"); // 蓝牙名称 var btDeviceName = reply.data.sublist(116, 132); print("btDeviceName:$btDeviceName"); // 电池剩余电量 var battRemCap = reply.data[132]; print("battRemCap:$battRemCap"); // 重置次数 var restoreCounter = reply.data.sublist(133, 135); print("restoreCounter:$restoreCounter"); // 重置时间 var restoreDate = reply.data.sublist(135, 139); print("restoreDate:$restoreDate"); // 主控芯片型号 var icPartNo = reply.data.sublist(139, 149); print("icPartNo:$icPartNo"); // 有效时间 var indate = reply.data.sublist(149, 153); print("indate:$indate"); break; case 0x06: //无权限 print("${reply.commandType}需要鉴权"); break; case 0x07: //无权限 print("${reply.commandType}用户无权限"); break; case 0x09: // 权限校验错误 print("${reply.commandType}权限校验错误"); break; default: //失败 print("${reply.commandType}失败"); break; } } // 点击开门事件 Future openDoorAction() async { // if(BlueManage().connectDeviceMacAddress.isEmpty){ // Toast.show(msg: "正在连接设备,请稍等。"); // return; // } BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, state.keyInfos.value.bluetooth!.bluetoothDeviceName!, (DeviceConnectionState state) async { if (state == DeviceConnectionState.connected){ var privateKey = await Storage.getStringList(saveBluePrivateKey); List getPrivateKeyList = changeStringListToIntList(privateKey!); var signKey = await Storage.getStringList(saveBlueSignKey); List signKeyDataList = changeStringListToIntList(signKey!); bool isHave = await Storage.ifHaveKey(saveBlueToken); List getTokenList; if(isHave){ var token = await Storage.getStringList(saveBlueToken); getTokenList = changeStringListToIntList(token!); }else{ getTokenList = [0,0,0,0]; } print("openDoorTokenPubToken:$getTokenList"); print("millisecondsSinceEpoch/1000:${DateTime.now().millisecondsSinceEpoch~/1000}"); IoSenderManage.senderOpenLock( keyID: BlueManage().connectDeviceName, userID: await Storage.getUid(), openMode: 1, openTime: DateTime.now().millisecondsSinceEpoch~/1000, token: getTokenList, needAuthor: 1, signKey: signKeyDataList, privateKey: getPrivateKeyList, ); } }, isShowLoading: false); } // 编辑用户事件 Future editLockUserAction() async { BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState state) async { if (state == DeviceConnectionState.connected){ var publicKey = await Storage.getStringList(saveBluePublicKey); List publicKeyDataList = changeStringListToIntList(publicKey!); var privateKey = await Storage.getStringList(saveBluePrivateKey); List getPrivateKeyList = changeStringListToIntList(privateKey!); var token = await Storage.getStringList(saveBlueToken); List getTokenList = changeStringListToIntList(token!); print("openDoorTokenPubToken:$getTokenList"); print("publicKey:$publicKey publicKeyDataList:$publicKeyDataList privateKey:$privateKey getPrivateKeyList:$getPrivateKeyList token:$token getTokenList:$getTokenList"); IoSenderManage.senderEditUser( lockID:BlueManage().connectDeviceName, authUserID:await Storage.getUid(), keyID:"1", userID:await Storage.getUid(), openMode:1, keyType:1, startDate:0x11223344, expireDate:0x11223344, role:255, password:"123456", needAuthor:1, publicKey:publicKeyDataList, privateKey:getPrivateKeyList, token: getTokenList ); } }); } // 备用逻辑,进入管理钥匙界面获取锁状态 Future connectBlue(String bluetoothDeviceId, String bluetoothDeviceName) async { // 进来之后首先连接 BlueManage().connect(bluetoothDeviceId, bluetoothDeviceName, connectStateCallBack: (DeviceConnectionState state) async { if (state == DeviceConnectionState.connected){ var privateKey = await Storage.getStringList(saveBluePrivateKey); List getPrivateKeyList = changeStringListToIntList(privateKey!); // IoSenderManage.senderGetLockStatu( // lockID:BlueManage().connectDeviceName, // userID:await Storage.getUid(), // privateKey:getPrivateKeyList, // ); IoSenderManage.senderGetStarLockStatuInfo( lockID:BlueManage().connectDeviceName, userID:await Storage.getUid(), privateKey:getPrivateKeyList, ); } }, isShowLoading: false); } void startScanAction(){ BlueManage().startScan(true, (v){ print("startScanAllDevice:${v}"); final knownDeviceIndex = v.indexWhere((d) => d.name == state.keyInfos.value.bluetooth!.bluetoothDeviceName!); // 当扫描到的时候 if (knownDeviceIndex >= 0) { BlueManage().connectDeviceMacAddress = v[knownDeviceIndex].id; connectBlue(v[knownDeviceIndex].id, state.keyInfos.value.bluetooth!.bluetoothDeviceName!); eventBus.fire(ScanAllDeviceFindCurrentDeviceConnectedEvent(v[knownDeviceIndex].serviceUuids[0].toString())); BlueManage().stopScan(); } }); } //开始连接 startConnect() { state.lockState.value = 1; state.animationController.forward(); openDoorAction(); Future.delayed(const Duration(seconds: 10), () { if(state.lockState.value == 1){ stopConnect(); state.lockState.value = 4; Toast.show(msg: "连接设备失败,请确保在设备附近,设备未被连接,设备已打开"); state.animationController.reset(); state.animationController.forward(); } }); } //关闭连接 stopConnect() { } @override void onReady() { // TODO: implement onReady super.onReady(); print("onReady()"); _initReplySubscription(); if(Platform.isIOS){ startScanAction(); }else{ getMicrophonePermission() .then((value) { if (value) { // 有权限 startScanAction(); }else{ //没有权限 openAppSettings();//打开app系统设置 } }); } } @override void onInit() { // TODO: implement onInit super.onInit(); print("lockDetail_onInit()"); // 进来获取锁状态 // connectBlue(); // factoryDataResetAction(); } @override void onClose() { // TODO: implement onClose _replySubscription.cancel(); } ///请求录音相机权限 Future getMicrophonePermission() async { // You can request multiple permissions at once. Map statuses = await [ Permission.bluetoothScan, Permission.bluetoothConnect, Permission.location, ].request(); //granted 通过,denied 被拒绝,permanentlyDenied 拒绝且不在提示 if (statuses[Permission.bluetoothScan]!.isGranted && statuses[Permission.bluetoothConnect]!.isGranted && statuses[Permission.location]!.isGranted) { return true; } return false; } }