import 'dart:async'; import 'package:classic_bluetooth/classic_bluetooth.dart'; import 'package:device_jieli/device_jieli.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; // import 'package:logger/web.dart'; import 'package:get_storage/get_storage.dart'; import '../../../data/services/ble_manager.dart'; import 'ota_core_contropller.dart'; import 'ota_download_contropller.dart'; import '../views/ota_upgrade_popup_view.dart'; import '../../../core/utils/logger.dart'; /// OTA升级主控制器 - 重构后的简化版本 /// 负责协调各个服务,管理升级流程的整体状态 class OtaUpgradeController extends GetxController { // 服务依赖 - 使用新的合并后的服务 final _coreService = OtaCoreService(); final _downloadService = OtaDownloadService(); final _uiService = OtaUpgradePopUp(); final _bleManager = Get.find(); final _jlota = Jielihome.instance; StreamSubscription? _otaEventSub; // 状态管理 final RxString errorMessage = ''.obs; final RxString latestVersion = ''.obs; final RxString currentVersion = ''.obs; final RxString detailedStatus = ''.obs; final RxString updatedescription = ''.obs; final RxDouble downloadProgress = 0.0.obs; final RxDouble progress = 0.0.obs; final RxInt type = OtaCoreService.NOT_STARTED.obs; final RxBool isUpdateAvailable = false.obs; final RxBool isDownloading = false.obs; final RxBool isUpgrade = false.obs; final RxBool isFetchingDeviceInfo = false.obs; final RxBool showDetailedStatus = false.obs; final RxBool isBleConnected = true.obs; final GetStorage _storage = GetStorage(); String _address = ''; String _updatePackageAddress = ''; String? _lastConnectedDeviceImage; // 新增:存储上一次连接设备的图片链接 get lastConnectedDeviceImage => _lastConnectedDeviceImage; @override void onInit() { super.onInit(); _loadLastConnectedDeviceImage(); // 加载持久化的设备图片 _initializeController(); } @override void onClose() { _jlota.otaCancel(); _otaEventSub?.cancel(); _otaEventSub = null; _bleManager.setEnterOta(false); isUpgrade.value = false; super.onClose(); } /// 从本地存储加载上一次连接设备的图片链接 void _loadLastConnectedDeviceImage() { _lastConnectedDeviceImage = _storage.read('last_connected_device_image'); Logger.d( 'OtaUpgradeController', '加载上一次连接设备的图片: $_lastConnectedDeviceImage'); } /// 初始化控制器 /// 设置事件监听并加载版本信息 Future _initializeController() async { // 首先检查BLE设备连接状态 if (!_coreService.checkBleConnectionStatus()) { //isFetchingDeviceInfo.value = false; //errorMessage.value = 'unconnected'.tr; isBleConnected.value = false; return; } _listenToOtaEvents(); await _loadVersionInfo(); } /// 加载版本信息 /// 获取当前设备版本和最新版本信息,检查是否有更新 Future _loadVersionInfo() async { try { isFetchingDeviceInfo.value = true; errorMessage.value = ''; // 获取当前版本信息 final currentInfo = await _coreService.getCurrentVersionInfo(); currentVersion.value = currentInfo['currentVersion']; // 获取蓝牙地址 final connectedDevices = await ClassicBluetooth.getConnectedDevices(); if (connectedDevices.isNotEmpty) { _address = connectedDevices.first.address; } // 获取最新版本信息 final latestInfo = await _coreService.getLatestVersionInfo(); latestVersion.value = latestInfo['latestVersion']; _updatePackageAddress = latestInfo['updatePackageAddress']; // 设置更新描述信息 updatedescription.value = latestInfo['updateDescription'] ?? 'otaDefaultUpdateDesc'.tr; // 检查是否有更新 isUpdateAvailable.value = _coreService.isNewVersionAvailable( currentVersion.value, latestVersion.value, ); } catch (e) { _handleError('error'.tr, _getUserFriendlyErrorMessage(e)); } finally { isFetchingDeviceInfo.value = false; } } /// 检查更新 /// 显示更新确认对话框或错误提示 Future checkUpdate() async { try { if (latestVersion.value.isNotEmpty) { _uiService.showUpdateDialog(latestVersion.value, _startUpdateProcess); } else { _uiService.showErrorSnackbar('error'.tr, 'otaGetLatestVersionFailed'.tr, backgroundColor: Colors.orange[800]); } } catch (e) { _uiService.showErrorSnackbar('error'.tr, 'otaGetVersionInfoFailed'.tr, backgroundColor: Colors.orange[800]); } } /// 开始更新流程的公共方法 /// 供视图调用的更新入口点 Future startUpdate() async { //立即给用户状态反馈 showDetailedStatus.value = true; detailedStatus.value = 'otaCheckingDeviceStatus'.tr; await _startUpdateProcess(); } /// 检查设备状态后开始下载和升级 Future _startUpdateProcess() async { // 检查设备电量 if (!_coreService.checkBatteryLevel()) { return; } await _startDownload(); } /// 开始下载固件 /// 初始化OTA环境并下载固件包 Future _startDownload() async { try { await _bleManager.setEnterOta(true); await Future.delayed(const Duration(seconds: 2)); // device_jieli 已经在全局 InitialBinding 里 initialize 过; // 这里无需重复 init —— 直接订阅 OTA 事件流即可。 isDownloading.value = true; showDetailedStatus.value = true; type.value = OtaCoreService.DOWNLOADING_UP_FILES; final filePath = await _downloadService.downloadFirmware( downloadUrl: _updatePackageAddress, onProgress: (progress) { downloadProgress.value = progress; }, onStatusUpdate: (status) { detailedStatus.value = status; }, ); isDownloading.value = false; await _startUpgrading(filePath); } catch (e) { isDownloading.value = false; detailedStatus.value = 'otaDownloadFailedCheckNetwork'.tr; showDetailedStatus.value = false; _handleError('otaDownloadFailed'.tr, e.toString()); Logger.d('OtaUpgradeController', '下载失败: $e'); } } /// 开始升级 /// [filePath] 固件文件路径 /// 启动OTA升级过程 Future _startUpgrading(String filePath) async { detailedStatus.value = 'otaPreparingConnection'.tr; await Future.delayed(const Duration(milliseconds: 500)); detailedStatus.value = 'otaConnectingDevice'.tr; _jlota.otaStart(address: _address, firmwareFilePath: filePath); } /// 停止升级 /// 关闭OTA连接 void stopUpgrading() { _jlota.otaCancel(); } /// 重试连接 /// 清除错误信息并重新加载版本信息 void retryConnection() { errorMessage.value = ''; _loadVersionInfo(); } /// 获取状态描述 /// [type] 状态类型 /// 返回对应的状态描述文本 String getStatusMessage(int type) { return OtaCoreService.getStatusMessage(type); } /// 监听OTA事件 /// 订阅 device_jieli 的统一事件流,过滤 OTA 相关事件并转发到分发器。 void _listenToOtaEvents() { _otaEventSub?.cancel(); _otaEventSub = _jlota.events.listen(_handleOtaEvent); } /// 处理 device_jieli 抛出的 OTA / 连接事件。 /// - [OtaStateEvent]: 进度 / 状态机推进 /// - [OtaErrorEvent]: 升级失败 /// - [ConnectionStateEvent]: 设备连接 / 断开(OTA 期间用于"中断"指示) void _handleOtaEvent(JieliEvent event) { if (event is OtaStateEvent) { switch (event.state) { case OtaState.entering: case OtaState.inquiring: case OtaState.notifyingSize: type.value = OtaCoreService.START_UPGRADING; isUpgrade.value = true; detailedStatus.value = 'otaUpgradeStarted'.tr; break; case OtaState.transferring: if (event.percent >= 0) { // device_jieli 发的是 0..100 整数;UI 这边按 0..1 浮点用。 progress.value = event.percent / 100.0; type.value = OtaCoreService.ONUPGRADE; isUpgrade.value = true; detailedStatus.value = 'otaUpgradeProgressWithPercent' .trParams({'percent': event.percent.toStringAsFixed(1)}); } break; case OtaState.verifying: detailedStatus.value = 'otaUpgradeStarted'.tr; break; case OtaState.rebooting: // 设备重启等待,仍在升级中 isUpgrade.value = true; break; case OtaState.done: _handleUpgradeSuccess(); break; case OtaState.failed: _handleUpgradeError(-1); break; case OtaState.cancelled: isUpgrade.value = false; showDetailedStatus.value = false; break; case OtaState.idle: break; } return; } if (event is OtaErrorEvent) { _handleUpgradeError(event.code); return; } if (event is ConnectionStateEvent) { if (event.state == ConnectionStateEvent.connectionDisconnect && isUpgrade.value) { _handleConnectionLost(); } else if (event.state == ConnectionStateEvent.connectionOk && isUpgrade.value) { _handleConnectionSuccess(); } } } /// 处理升级成功 /// 更新状态并显示成功对话框 void _handleUpgradeSuccess() { type.value = OtaCoreService.UPGRADE_SUCCESS; isUpgrade.value = false; detailedStatus.value = 'otaUpgradeSuccessComplete'.tr; showDetailedStatus.value = false; // 更新版本信息 currentVersion.value = latestVersion.value; isUpdateAvailable.value = false; // 显示成功对话框 _uiService.showUpgradeSuccessDialog(); } /// 处理升级错误 /// [errorCode] 错误代码 /// 更新状态并显示错误提示 void _handleUpgradeError(dynamic errorCode) { type.value = OtaCoreService.UPGRADE_FAILED; isUpgrade.value = false; detailedStatus.value = 'otaUpgradeFailedWithCode'.trParams({'code': errorCode.toString()}); showDetailedStatus.value = false; _uiService.showErrorSnackbar( 'otaUpgradeFailedTitle'.tr, 'otaUpgradeFailedDesc'.trParams({'code': errorCode.toString()}), ); } /// 处理连接断开 /// 更新连接状态 void _handleConnectionLost() { type.value = OtaCoreService.CONNECTION_DISCONNECTION; isUpgrade.value = false; detailedStatus.value = 'otaDeviceDisconnected'.tr; showDetailedStatus.value = false; } /// 处理连接成功 /// 更新连接状态 void _handleConnectionSuccess() { type.value = OtaCoreService.CONNECTION_SUCCESS; isUpgrade.value = true; detailedStatus.value = 'otaDeviceConnected'.tr; } /// 统一错误处理 /// [title] 错误标题 /// [message] 错误信息 /// 设置错误状态并显示错误提示 void _handleError(String title, String message) { errorMessage.value = message; _uiService.showErrorSnackbar(title, message); } String _getUserFriendlyErrorMessage(Object error) { if (error is OtaCoreException) { switch (error.type) { case OtaCoreErrorType.deviceInfoUnavailable: return 'otaDeviceInfoUnavailable'.tr; case OtaCoreErrorType.productInfoUnavailable: return 'otaProductInfoUnavailable'.tr; case OtaCoreErrorType.firmwareVersionFormatInvalid: return 'otaFirmwareVersionInvalid'.tr; } } return 'otaVersionInfoFailed'.tr; } }