import 'dart:async'; import 'dart:convert'; import 'package:EasyDartModule/EasyDartModule.dart'; import 'package:easydevice/src/app/thapp.dart'; import 'package:ef/ef.dart'; import 'package:flutter/src/widgets/framework.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:vbvs_app/common/color/ServiceConstant.dart'; import 'package:vbvs_app/common/color/app_uri_status.dart'; import 'package:vbvs_app/common/util/DailyLogUtils.dart'; import 'package:vbvs_app/common/util/FirmwareVersionService.dart'; import 'package:vbvs_app/common/util/MyUtils.dart'; import 'package:vbvs_app/common/util/requestWithLog.dart'; import 'package:vbvs_app/component/tool/TopSlideNotification.dart'; import 'package:vbvs_app/model/api_response.dart'; import 'package:vbvs_app/pages/mh_page/device/model/BlueToothDataModel.dart'; import 'package:vbvs_app/pages/mh_page/user/controller/mht_register_controller.dart'; part 'mht_bluetooth_controller.g.dart'; @JsonSerializable() class MHTBlueToothModel { bool? bluetooth = false; //蓝牙开关 double? singal = -100; @JsonKey(ignore: true) List? blueRawData = []; //蓝牙原始数据 @JsonKey(ignore: true) List? deviceDataStatus; //已经请求过状态的数据 int? read = 0; int? deviceType; //绑定设备类型 bool wifiPassShow = false; String? wifiPass; MHTBlueToothModel(); static MHTBlueToothModel fromJson(Map json) => _$MHTBlueToothModelFromJson(json); Map toJson() => _$MHTBlueToothModelToJson(this); } class MHTBlueToothController extends GetControllerEx { MHTBlueToothController() { attr = GetModel(MHTBlueToothModel()).obs; } Timer? _statusTimer; MHTRegisterController registerController = Get.find(); RxString search = "".obs; RxString currentDeviceMac = "".obs; //当前正在绑定的设备,用来显示loading THapp? currentDevice; //当前连接的设备 BlueToothDataModel? currentFullDevice; //当前连接的设备 RxInt blueConnectFlag = 0.obs; //当前蓝牙连接状态 0.正在连接 1.未连接 2.已连接 RxBool bluetoothStatus = false.obs; //蓝牙开启状态 RxInt connectStatus = 0.obs; //当前wifi连接状态 0:未连接 1:已连接 RxInt netType = 0.obs; //当前网络类型 0.正在检测 1.wifi 2.4g设备 3.未知 RxInt wifiConnectStatus = 1.obs; //获取wifi状态 0.正在检测 1.已检测完 RxMap selectWifi = {}.obs; //正在连接wifi信息 int returnPage = 0; //0返回首页 1.返回设备列表 RxInt wifiStatus = 0.obs; //wifi连接状态 0:未连接 1:已连接 RxList wifiList = [].obs; RxMap connect_wifi = {}.obs; RxString? cid = "".obs; RxBool isScanning = false.obs; RxMap localUpgradeMac = {}.obs; //mac 进度 String? currentUpgradeVersion; //最新版本号 String? currentUpgradeName; //最新固件名 String? currentUpgradeUrl; //最新固件下载地址 List firmwareList = []; //固件版本列表 RxBool allSelect = false.obs; //升级是否全选 RxBool autoUpgrade = false.obs; //是否自动升级 void startStatusPolling() { updateDeviceStatus().then((res) { if (res.code == HttpStatusCodes.ok) { updateAll(); } else { safeShowNotification(res.msg ?? "获取设备状态异常".tr); EasyDartModule.logger.info("获取设备状态异常: $res"); DailyLogUtils.writeLog("获取设备状态异常: $res"); } }); if (_statusTimer == null) { _statusTimer = Timer.periodic(Duration(seconds: 2), (timer) { updateDeviceStatus().then((res) { if (res.code == HttpStatusCodes.ok) { updateAll(); } else { safeShowNotification(res.msg ?? "获取设备状态异常".tr); EasyDartModule.logger.info("获取设备状态异常: $res"); DailyLogUtils.writeLog("获取设备状态异常: $res"); } }).catchError((e, stack) { print("updateDeviceStatus 执行异常: $e\n$stack"); safeShowNotification("设备状态请求失败".tr); EasyDartModule.logger.info("设备状态异常: $e"); DailyLogUtils.writeLog("设备状态异常: $e"); }); }); } } void stopStatusPolling() { _statusTimer?.cancel(); _statusTimer = null; } var shouldScan = true.obs; void pauseScanning() { shouldScan.value = false; update(); } // 恢复扫描 void resumeScanning() { shouldScan.value = true; update(); } Future updateDeviceStatus() async { try { String serviceAddress = ServiceConstant.service_address; String serviceName = ServiceConstant.server_service; String serviceApi = ServiceConstant.get_bluetooth_device_status; String queryUrl = "$serviceAddress$serviceName$serviceApi"; if (model.blueRawData != null && model.blueRawData!.isNotEmpty) { final macParams = model.blueRawData! .map((device) => "mac=${Uri.encodeQueryComponent(device.mac!.replaceAll(':', ''))}") .join("&"); if (queryUrl.contains('?')) { queryUrl += '&$macParams'; } else { queryUrl += '?$macParams'; } String? language = ""; if (mhLanguageController.selectLanguage != null) { language = mhLanguageController.selectLanguage.value!.language_code; } if (language != null && language.isNotEmpty) { if (queryUrl.contains("?")) { queryUrl += "&lang=$language"; } else { queryUrl += "?lang=$language"; } } var response = await EasyDartModule.dio.get(queryUrl); var responseData = response.data is String ? jsonDecode(response.data) : response.data; ApiResponse res = ApiResponse.fromJson(responseData, (object) => object); if (res.code != HttpStatusCodes.ok) return res; if (response.data['data'] != null && response.data['data'] is List) { List responseList = response.data['data']; // 新建一个 Map,便于快速通过 mac 查找返回的设备状态 final Map responseMap = { for (var item in responseList) item['mac'.tr].toString().toUpperCase(): item }; // 遍历 blueRawData,更新 bind 状态 for (var device in model.blueRawData!) { final macKey = device.mac!.replaceAll(':', '').toUpperCase(); if (responseMap.containsKey(macKey)) { var item = responseMap[macKey]; // 更新 device 绑定状态等信息 device.bind = item['bind'] ?? device.bind; device.mac = item['bindMac'] ?? device.mac; } } model.deviceDataStatus = List.from(model.blueRawData!); } else { model.deviceDataStatus = []; } updateAll(); return res; } else { model.deviceDataStatus = []; return ApiResponse(code: 1, msg: "".tr); } } catch (e) { print("获取设备状态异常: $e"); EasyDartModule.logger.info("获取设备状态异常: $e"); DailyLogUtils.writeLog("获取设备状态异常: $e"); return ApiResponse(code: -1, msg: "请求失败".tr); } return ApiResponse(code: -1, msg: "未知错误".tr); } bindDeviceAndMAC(BlueToothDataModel bleDevice, BuildContext context) async { try { if ((bleDevice.macA == null || bleDevice.macA.isEmpty) && (bleDevice.macB == null || bleDevice.macB.isEmpty)) { TopSlideNotification.show(context, text: "传感器mac读取失败".tr, textColor: themeController.currentColor.sc9); currentDeviceMac.value = ""; return; } String serviceAddress = ServiceConstant.service_address; String serviceName = ServiceConstant.server_service; String serviceApi = ServiceConstant.device_bind; String queryUrl = "$serviceAddress$serviceName$serviceApi"; var data = { "deviceType": model.deviceType, "mac".tr: bleDevice.mac, "macA": bleDevice.macA, if (bleDevice.macB != null && bleDevice.macB!.isNotEmpty) "macB": bleDevice.macB, if (bleDevice.name != null && bleDevice.name!.isNotEmpty) 'param': { 'name': bleDevice.name, }, }; EasyDartModule.logger.info("绑定传感器数据: $data"); var response = await EasyDartModule.dio.post(queryUrl, data: jsonEncode(data)); if (response != null) { var responseData = response.data is String ? jsonDecode(response.data) : response.data; ApiResponse res = ApiResponse.fromJson(responseData, (object) => object); MyUtils.formatResponse(res, "绑定成功".tr, "绑定成功".tr); if (res.code == HttpStatusCodes.ok) { // PersonController personController = Get.find(); // personController.currentPersonId.value = res.data['id']; //todo 绑定成功需要返回传感器id currentDeviceMac.value = ""; if (res.data != null) { if (currentFullDevice != null) { currentFullDevice!.macAID = res.data['macA']; currentFullDevice!.macBID = res.data['macB']; currentFullDevice!.deviceID = res.data['id']; } } return res; } else { return res; } } else { return ApiResponse(code: -1, msg: "服务器失败".tr); } } catch (e) { EasyDartModule.logger.info("绑定异常: $e"); DailyLogUtils.writeLog("蓝牙绑定: $e"); } return ApiResponse(code: -1, msg: "未知错误".tr); } Future saveHabitData(sleepData) async { bool resFlag = false; String serviceAddress = ServiceConstant.service_address; String serviceName = ServiceConstant.server_service; String serviceApi = ServiceConstant.user_setting; String type = "sleep_habit_${sleepData['mac']}"; String queryUrl = "${serviceAddress}${serviceName}${serviceApi}"; var data = { "type": type, "mac".tr: sleepData['mac'.tr], "time": DateTime.now().millisecondsSinceEpoch, "data": sleepData, }; await requestWithLog( logTitle: "更新睡眠习惯".tr, method: MyHttpMethod.put, queryUrl: queryUrl, data: data, onSuccess: (res) { resFlag = true; }, onFailure: (res) { resFlag = false; }, ); return resFlag; } Future loadHabitDataApi(String mac, {int time = 3}) async { String serviceAddress = ServiceConstant.service_address; String serviceName = ServiceConstant.server_service; String serviceApi = ServiceConstant.user_setting; String type = "sleep_habit_${mac}"; String queryUrl = "${serviceAddress}${serviceName}${serviceApi}?type=${type}"; // 使用 Future 来等待异步操作完成 Map result = {}; await requestWithLog( logTitle: "更新睡眠习惯".tr, method: MyHttpMethod.get, queryUrl: queryUrl, onSuccess: (res) { ef.log("加载睡眠习惯成功: ${res.data}"); result = res.data; // 将返回的数据存入 result }, onFailure: (res) { ef.log("加载睡眠习惯失败: ${res.msg}"); result = {}; // 如果失败,可以返回空的 Map }, ); return result; // 在 requestWithLog 完成之后返回 result } saveJiYiData(sleepData) async { String serviceAddress = ServiceConstant.service_address; String serviceName = ServiceConstant.server_service; String serviceApi = ServiceConstant.user_setting; String type = "sleep_jiyi_${sleepData['mac']}"; String queryUrl = "${serviceAddress}${serviceName}${serviceApi}"; var data = { "type": type, "mac": sleepData['mac'], "time": DateTime.now().millisecondsSinceEpoch, "data": sleepData, }; await requestWithLog( logTitle: "更新睡眠记忆", method: MyHttpMethod.put, queryUrl: queryUrl, data: data, ); } loadJiYiData(String mac, {int time = 3}) async { String serviceAddress = ServiceConstant.service_address; String serviceName = ServiceConstant.server_service; String serviceApi = ServiceConstant.user_setting; String type = "sleep_jiyi_${mac}"; String queryUrl = "${serviceAddress}${serviceName}${serviceApi}?type=${type}"; // 使用 Future 来等待异步操作完成 Map result = {}; await requestWithLog( logTitle: "更新记忆", method: MyHttpMethod.get, queryUrl: queryUrl, onSuccess: (res) { ef.log("加载记忆成功: ${res.data}"); result = res.data; // 将返回的数据存入 result }, onFailure: (res) { ef.log("加载记忆失败: ${res.msg}"); result = {}; // 如果失败,可以返回空的 Map }, ); return result; // 在 requestWithLog 完成之后返回 result } saveMattressTimeData(sleepData) async { String serviceAddress = ServiceConstant.service_address; String serviceName = ServiceConstant.server_service; String serviceApi = ServiceConstant.user_setting; String type = "sleep_new_time_${sleepData['mac']}"; String queryUrl = "${serviceAddress}${serviceName}${serviceApi}"; var data = { "type": type, "mac": sleepData['mac'], "time": DateTime.now().millisecondsSinceEpoch, "data": sleepData, }; await requestWithLog( logTitle: "更新新版倒计时", method: MyHttpMethod.put, queryUrl: queryUrl, data: data, ); } loadMattressTimeData(String mac, {int time = 3}) async { String serviceAddress = ServiceConstant.service_address; String serviceName = ServiceConstant.server_service; String serviceApi = ServiceConstant.user_setting; String type = "sleep_new_time_${mac}"; String queryUrl = "${serviceAddress}${serviceName}${serviceApi}?type=${type}"; // 使用 Future 来等待异步操作完成 Map result = {}; await requestWithLog( logTitle: "更新新版倒计时", method: MyHttpMethod.get, queryUrl: queryUrl, onSuccess: (res) { ef.log("更新新版倒计时成功: ${res.data}"); result = res.data; // 将返回的数据存入 result }, onFailure: (res) { ef.log("更新新版倒计时失败: ${res.msg}"); result = {}; // 如果失败,可以返回空的 Map }, ); return result; // 在 requestWithLog 完成之后返回 result } sendCommand(Map commandData) async { //todo 下发wifi指令 if (commandData == null || commandData.isEmpty) { throw "指令数据不能为空"; } //todo 填充蓝牙指令 String serviceAddress = ServiceConstant.service_address; String serviceName = ServiceConstant.server_service; String serviceApi = ServiceConstant.sendWifiCommand; String queryUrl = "${serviceAddress}${serviceName}${serviceApi}"; await requestWithLog( logTitle: "下发wifi控制指令", method: MyHttpMethod.post, queryUrl: queryUrl, onSuccess: (res) { }, onFailure: (res) { throw "下发wifi控制指令失败: ${res.msg}"; }, ); } //todo 解绑的时候删除自己所拥有的所有设备的睡眠习惯 } void safeShowNotification(String msg) { try { final ctx = Get.context; if (ctx != null && ctx.mounted) { TopSlideNotification.show( ctx, text: msg, textColor: themeController.currentColor.sc9, ); } else { print("TopSlideNotification 未显示:context 不可用或未挂载".tr); } } catch (e, stack) { // print("TopSlideNotification 显示异常: $e\n$stack"); } }