import 'dart:async'; import 'package:usb_serial/usb_serial.dart'; import '../models/serial_config.dart'; import 'device_log.dart'; import 'serial_port_service.dart'; /// 启动自动连接服务 /// /// App 启动时调用 [start],自动连接第一个可用的 USB 串口设备: /// - 固定 115200 波特率 / 8 数据位 / 1 停止位 / 默认其它 /// - 连接失败时每 3 秒重试一次 /// - 连接成功后停止重试;连接断开后重新进入重试循环 class AutoSerialConnect { /// 重试间隔 static const Duration retryInterval = Duration(seconds: 3); /// 自动连接使用的固定参数 static const SerialConfig autoConfig = SerialConfig( baudRate: 115200, dataBits: 8, stopBits: 1, ); final SerialPortService _service; Timer? _retryTimer; StreamSubscription? _stateSub; bool _disposed = false; AutoSerialConnect(this._service); /// 启动自动连接:立即尝试一次,失败则按 [retryInterval] 周期重试 void start() { if (_stateSub != null) return; _stateSub = _service.connectionStateChanges.listen(_onStateChange); unawaited(_tryConnect()); } void _onStateChange(SerialConnectionState s) { if (_disposed) return; switch (s) { case SerialConnectionState.connected: // 连接成功:停止重试 _cancelRetry(); case SerialConnectionState.disconnected: case SerialConnectionState.error: // 设备断开或出错:进入重试 _scheduleRetry(); case SerialConnectionState.connecting: // 正在连接中,忽略 break; } } Future _tryConnect() async { if (_disposed) return; if (_service.isConnected || _service.state == SerialConnectionState.connecting) { return; } final List devices; try { devices = await _service.listDevices(); } catch (e) { DeviceLog.warn('列出 USB 设备失败: $e,${retryInterval.inSeconds}s 后重试'); _scheduleRetry(); return; } if (devices.isEmpty) { DeviceLog.info('未检测到 USB 串口设备,${retryInterval.inSeconds}s 后重试'); _scheduleRetry(); return; } final device = devices.first; final ok = await _service.connect(device, autoConfig); if (!ok) { DeviceLog.warn('串口自动连接失败: ' '${_service.lastError ?? "未知错误"},${retryInterval.inSeconds}s 后重试'); _scheduleRetry(); } } void _scheduleRetry() { if (_disposed) return; if (_retryTimer != null) return; _retryTimer = Timer(retryInterval, () { _retryTimer = null; unawaited(_tryConnect()); }); } void _cancelRetry() { _retryTimer?.cancel(); _retryTimer = null; } /// 释放资源 Future dispose() async { if (_disposed) return; _disposed = true; _cancelRetry(); await _stateSub?.cancel(); _stateSub = null; } }