374 lines
9.9 KiB
Dart
374 lines
9.9 KiB
Dart
import 'package:flutter/material.dart';
|
||
import 'package:get/get.dart';
|
||
import 'package:web_frontend/models/DeviceInfo.dart';
|
||
import 'package:web_frontend/models/LogType.dart';
|
||
import 'package:web_frontend/models/UserInfo.dart';
|
||
import 'package:web_frontend/services/WebSocketService.dart';
|
||
|
||
class ControlPanelController extends GetxController {
|
||
final WebSocketService webSocketService = Get.find<WebSocketService>();
|
||
|
||
// 用户相关
|
||
final users = <UserInfo>[].obs;
|
||
final selectedUser = Rx<UserInfo?>(null);
|
||
|
||
// 设备相关
|
||
final devices = <DeviceInfo>[].obs;
|
||
final searchKeyword = ''.obs;
|
||
|
||
// 信号强度过滤
|
||
final rssiFilterValue = (-70).obs; // 默认-70dBm
|
||
|
||
// 日志相关
|
||
final connectionLogs = <LogEntry>[].obs;
|
||
final deviceLogs = <LogEntry>[].obs;
|
||
final allLogs = <LogEntry>[].obs;
|
||
|
||
final autoScroll = true.obs;
|
||
final ScrollController logScrollController = ScrollController();
|
||
|
||
// 命令输入
|
||
final commandController = TextEditingController();
|
||
|
||
// 日志过滤器
|
||
final showAllLogs = true.obs;
|
||
final showConnectionLogs = true.obs;
|
||
final showDeviceLogs = true.obs;
|
||
|
||
// 过滤后的设备列表(包含名称搜索和信号强度过滤)
|
||
List<DeviceInfo> get filteredDevices {
|
||
List<DeviceInfo> result = devices.toList();
|
||
|
||
// 名称/ID 模糊查询
|
||
if (searchKeyword.value.isNotEmpty) {
|
||
result = result
|
||
.where((device) =>
|
||
device.name
|
||
.toLowerCase()
|
||
.contains(searchKeyword.value.toLowerCase()) ||
|
||
device.id
|
||
.toLowerCase()
|
||
.contains(searchKeyword.value.toLowerCase()))
|
||
.toList();
|
||
}
|
||
|
||
// 信号强度过滤(只显示信号强度大于等于设定值的设备)
|
||
result =
|
||
result.where((device) => device.rssi >= rssiFilterValue.value).toList();
|
||
|
||
// 按信号强度排序(从强到弱)
|
||
result.sort((a, b) => b.rssi.compareTo(a.rssi));
|
||
|
||
return result;
|
||
}
|
||
|
||
// 获取当前显示的日志
|
||
List<LogEntry> get displayLogs {
|
||
if (showAllLogs.value) {
|
||
return allLogs.toList();
|
||
}
|
||
|
||
final logs = <LogEntry>[];
|
||
if (showConnectionLogs.value) {
|
||
logs.addAll(connectionLogs);
|
||
}
|
||
if (showDeviceLogs.value) {
|
||
logs.addAll(deviceLogs);
|
||
}
|
||
logs.sort((a, b) => a.time.compareTo(b.time));
|
||
return logs;
|
||
}
|
||
|
||
@override
|
||
void onInit() {
|
||
super.onInit();
|
||
_initWebSocketHandlers();
|
||
}
|
||
|
||
@override
|
||
void onClose() {
|
||
commandController.dispose();
|
||
logScrollController.dispose();
|
||
super.onClose();
|
||
}
|
||
|
||
void _initWebSocketHandlers() {
|
||
webSocketService.registerMessageHandler(_handleWebSocketMessage);
|
||
}
|
||
|
||
// void _handleWebSocketMessage(Map<String, dynamic> data) {
|
||
// final type = data['type'] as String?;
|
||
|
||
// switch (type) {
|
||
// case 'user_list':
|
||
// _updateUserList(data['users']);
|
||
// break;
|
||
|
||
// case 'device_selected':
|
||
// _addConnectionLog('已连接到设备: ${data['targetUuid']}', LogType.success);
|
||
// break;
|
||
|
||
// case 'device_message':
|
||
// _handleDeviceMessage(data['data']);
|
||
// break;
|
||
|
||
// case 'error':
|
||
// _addConnectionLog('错误: ${data['message']}', LogType.error);
|
||
// break;
|
||
|
||
// default:
|
||
// if (type != null) {
|
||
// _addConnectionLog('收到消息类型: $type', LogType.info);
|
||
// }
|
||
// }
|
||
// }
|
||
void _handleWebSocketMessage(Map<String, dynamic> data) {
|
||
final type = data['type'] as String?;
|
||
|
||
switch (type) {
|
||
case 'user_list':
|
||
_updateUserList(data['users']);
|
||
break;
|
||
|
||
case 'device_selected':
|
||
_addConnectionLog('已连接到设备: ${data['targetUuid']}', LogType.success);
|
||
// 设备连接成功后,自动触发扫描
|
||
_addConnectionLog('设备已就绪,自动开始扫描...', LogType.info);
|
||
webSocketService.startScan();
|
||
_addDeviceLog('自动发送扫描命令', LogType.info);
|
||
break;
|
||
|
||
case 'device_message':
|
||
_handleDeviceMessage(data['data']);
|
||
break;
|
||
|
||
case 'error':
|
||
_addConnectionLog('错误: ${data['message']}', LogType.error);
|
||
break;
|
||
|
||
default:
|
||
if (type != null) {
|
||
_addConnectionLog('收到消息类型: $type', LogType.info);
|
||
}
|
||
}
|
||
}
|
||
|
||
void _updateUserList(List<dynamic> usersData) {
|
||
users.value = usersData.map((u) => UserInfo.fromJson(u)).toList();
|
||
|
||
if (selectedUser.value != null &&
|
||
!users.any((u) => u.uuid == selectedUser.value!.uuid)) {
|
||
selectedUser.value = null;
|
||
devices.clear();
|
||
}
|
||
|
||
_addConnectionLog('设备列表更新: ${users.length} 个在线设备', LogType.info);
|
||
}
|
||
|
||
void _handleDeviceMessage(Map<String, dynamic> data) {
|
||
final deviceDataType = data['type'] as String?;
|
||
|
||
switch (deviceDataType) {
|
||
case 'device_list':
|
||
_updateDeviceList(data['devices']);
|
||
break;
|
||
|
||
case 'bluetooth_data':
|
||
_addDeviceLog('收到蓝牙数据: ${data['data']}', LogType.device);
|
||
break;
|
||
|
||
case 'bluetooth_status':
|
||
final isConnected = data['isConnected'] as bool? ?? false;
|
||
_addDeviceLog('蓝牙状态: ${isConnected ? "已连接" : "未连接"}',
|
||
isConnected ? LogType.success : LogType.warning);
|
||
break;
|
||
|
||
case 'scan_start':
|
||
_addDeviceLog('开始扫描蓝牙设备...', LogType.info);
|
||
break;
|
||
|
||
case 'scan_stop':
|
||
_addDeviceLog('停止扫描', LogType.info);
|
||
break;
|
||
|
||
default:
|
||
_addDeviceLog('设备消息: $data', LogType.device);
|
||
}
|
||
}
|
||
|
||
void _updateDeviceList(List<dynamic> devicesData) {
|
||
devices.value = devicesData.map((d) => DeviceInfo.fromJson(d)).toList();
|
||
// _addDeviceLog('发现 ${devices.length} 个蓝牙设备', LogType.success);
|
||
}
|
||
|
||
// 添加连接日志(WebSocket相关)
|
||
void _addConnectionLog(String message, LogType type) {
|
||
final log = LogEntry(
|
||
message: message,
|
||
time: DateTime.now(),
|
||
type: type,
|
||
);
|
||
connectionLogs.add(log);
|
||
_updateAllLogs(log);
|
||
_scrollToBottom();
|
||
|
||
// 限制日志数量
|
||
if (connectionLogs.length > 500) {
|
||
connectionLogs.removeAt(0);
|
||
}
|
||
}
|
||
|
||
// 添加设备日志
|
||
void _addDeviceLog(String message, LogType type) {
|
||
final log = LogEntry(
|
||
message: message,
|
||
time: DateTime.now(),
|
||
type: type,
|
||
deviceId: selectedUser.value?.uuid,
|
||
);
|
||
deviceLogs.add(log);
|
||
_updateAllLogs(log);
|
||
_scrollToBottom();
|
||
|
||
if (deviceLogs.length > 500) {
|
||
deviceLogs.removeAt(0);
|
||
}
|
||
}
|
||
|
||
// 添加日志(供外部调用)
|
||
void addLog(String message, LogType type) {
|
||
_addConnectionLog(message, type);
|
||
}
|
||
|
||
void _updateAllLogs(LogEntry log) {
|
||
allLogs.add(log);
|
||
if (allLogs.length > 1000) {
|
||
allLogs.removeAt(0);
|
||
}
|
||
}
|
||
|
||
void _scrollToBottom() {
|
||
if (autoScroll.value) {
|
||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||
if (logScrollController.hasClients) {
|
||
logScrollController.animateTo(
|
||
logScrollController.position.maxScrollExtent,
|
||
duration: const Duration(milliseconds: 300),
|
||
curve: Curves.easeOut,
|
||
);
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
// ==================== 公共方法 ====================
|
||
|
||
// 更新信号强度过滤值
|
||
void updateRssiFilter(int value) {
|
||
rssiFilterValue.value = value;
|
||
_addConnectionLog('信号强度过滤设置为: ${value} dBm', LogType.info);
|
||
}
|
||
|
||
// 重置信号强度过滤
|
||
void resetRssiFilter() {
|
||
rssiFilterValue.value = -100;
|
||
_addConnectionLog('信号强度过滤已重置', LogType.info);
|
||
}
|
||
|
||
// 选择设备并建立连接
|
||
void selectUser(UserInfo? user) {
|
||
if (user == null) return;
|
||
|
||
selectedUser.value = user;
|
||
devices.clear();
|
||
|
||
// 通过 WebSocket 选择设备,建立连接
|
||
webSocketService.selectDevice(user.uuid);
|
||
_addConnectionLog('正在连接设备: ${user.deviceModel}', LogType.info);
|
||
}
|
||
|
||
// 发送自定义数据
|
||
void sendCustomData() {
|
||
if (selectedUser.value == null) {
|
||
_addConnectionLog('请先选择设备', LogType.warning);
|
||
return;
|
||
}
|
||
|
||
final command = commandController.text.trim();
|
||
if (command.isEmpty) {
|
||
_addConnectionLog('请输入命令或数据', LogType.warning);
|
||
return;
|
||
}
|
||
|
||
webSocketService.sendDataToDevice(command);
|
||
_addDeviceLog('发送数据: $command', LogType.info);
|
||
commandController.clear();
|
||
}
|
||
|
||
// 开始扫描蓝牙设备
|
||
void sendScanCommand() {
|
||
if (selectedUser.value == null) {
|
||
_addConnectionLog('请先选择设备', LogType.warning);
|
||
return;
|
||
}
|
||
webSocketService.startScan();
|
||
_addDeviceLog('发送扫描命令', LogType.info);
|
||
}
|
||
|
||
// 停止扫描
|
||
void sendStopScanCommand() {
|
||
if (selectedUser.value == null) {
|
||
_addConnectionLog('请先选择设备', LogType.warning);
|
||
return;
|
||
}
|
||
webSocketService.stopScan();
|
||
_addDeviceLog('发送停止扫描命令', LogType.info);
|
||
}
|
||
|
||
// 连接蓝牙设备
|
||
void connectToDevice(DeviceInfo device) {
|
||
if (selectedUser.value == null) {
|
||
_addConnectionLog('请先选择设备', LogType.warning);
|
||
return;
|
||
}
|
||
webSocketService.connectToDevice(device.id);
|
||
_addDeviceLog('连接蓝牙设备: ${device.name}', LogType.info);
|
||
}
|
||
|
||
// 断开蓝牙设备
|
||
void disconnectDevice() {
|
||
if (selectedUser.value == null) {
|
||
_addConnectionLog('请先选择设备', LogType.warning);
|
||
return;
|
||
}
|
||
webSocketService.disconnectDevice();
|
||
_addDeviceLog('断开蓝牙设备连接', LogType.info);
|
||
}
|
||
|
||
// 清空日志
|
||
void clearLogs() {
|
||
allLogs.clear();
|
||
connectionLogs.clear();
|
||
deviceLogs.clear();
|
||
_addConnectionLog('日志已清空', LogType.info);
|
||
}
|
||
|
||
// 切换自动滚动
|
||
void toggleAutoScroll(bool value) {
|
||
autoScroll.value = value;
|
||
}
|
||
|
||
// 切换日志过滤器
|
||
void toggleShowAllLogs(bool value) {
|
||
showAllLogs.value = value;
|
||
}
|
||
|
||
void toggleShowConnectionLogs(bool value) {
|
||
showConnectionLogs.value = value;
|
||
}
|
||
|
||
void toggleShowDeviceLogs(bool value) {
|
||
showDeviceLogs.value = value;
|
||
}
|
||
}
|