feat(device): 启动自动连接 USB 串口 + 隐藏设置页配置项 + 标题栏连接状态

- 新增 AutoSerialConnect 服务:启动后自动连接第一个 USB 串口设备,
  固定 115200/8/N/1,连接失败时每 3s 重试,断开后重新进入重试循环
- main.dart 通过 ProviderContainer 在 runApp 之前触发 autoSerialConnectProvider
- 移除设置页「串口配置」菜单项及对应面板分支
- StatusBar 在「设备运行状态」前增加串口连接状态指示(已连接/连接中/未连接)
This commit is contained in:
Developer
2026-06-04 16:57:45 +08:00
parent 3ab2232845
commit 37d2af70b7
5 changed files with 186 additions and 12 deletions

View File

@@ -0,0 +1,109 @@
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<SerialConnectionState>? _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<void> _tryConnect() async {
if (_disposed) return;
if (_service.isConnected ||
_service.state == SerialConnectionState.connecting) {
return;
}
final List<UsbDevice> 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<void> dispose() async {
if (_disposed) return;
_disposed = true;
_cancelRetry();
await _stateSub?.cancel();
_stateSub = null;
}
}