首次提交
This commit is contained in:
373
lib/controllers/ControlPanelController.dart
Normal file
373
lib/controllers/ControlPanelController.dart
Normal file
@@ -0,0 +1,373 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user