增加了遥控器控制功能
This commit is contained in:
parent
1ae2146ff0
commit
99e35eba95
@ -61,6 +61,13 @@ pressure_use_mock = False
|
|||||||
pressure_port = COM5
|
pressure_port = COM5
|
||||||
pressure_baudrate = 115200
|
pressure_baudrate = 115200
|
||||||
|
|
||||||
|
[REMOTE]
|
||||||
|
port = COM6
|
||||||
|
baudrate = 115200
|
||||||
|
timeout = 0.1
|
||||||
|
enable = True
|
||||||
|
strict_crc = False
|
||||||
|
|
||||||
[SYSTEM]
|
[SYSTEM]
|
||||||
log_level = INFO
|
log_level = INFO
|
||||||
max_cache_size = 10
|
max_cache_size = 10
|
||||||
|
|||||||
@ -77,7 +77,7 @@ class DeviceCoordinator:
|
|||||||
}
|
}
|
||||||
|
|
||||||
# 线程池
|
# 线程池
|
||||||
self.executor = ThreadPoolExecutor(max_workers=4, thread_name_prefix="DeviceCoord")
|
self.executor = ThreadPoolExecutor(max_workers=8, thread_name_prefix="DeviceCoord")
|
||||||
|
|
||||||
self.logger.info("设备协调器初始化完成")
|
self.logger.info("设备协调器初始化完成")
|
||||||
|
|
||||||
@ -180,6 +180,11 @@ class DeviceCoordinator:
|
|||||||
future = self.executor.submit(self._init_pressure)
|
future = self.executor.submit(self._init_pressure)
|
||||||
futures.append(('pressure', future))
|
futures.append(('pressure', future))
|
||||||
|
|
||||||
|
# 遥控器
|
||||||
|
if self.device_configs.get('remote', {}).get('enabled', False):
|
||||||
|
future = self.executor.submit(self._init_remote)
|
||||||
|
futures.append(('remote', future))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 等待所有设备初始化完成
|
# 等待所有设备初始化完成
|
||||||
@ -275,6 +280,21 @@ class DeviceCoordinator:
|
|||||||
self.logger.error(f"初始化{device_name}失败: {e}")
|
self.logger.error(f"初始化{device_name}失败: {e}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def _init_remote(self) -> bool:
|
||||||
|
"""
|
||||||
|
初始化串口遥控器
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
from .remote_control_manager import RemoteControlManager
|
||||||
|
remote = RemoteControlManager(self.socketio, self.config_manager)
|
||||||
|
self.devices['remote'] = remote
|
||||||
|
if remote.initialize():
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(f"初始化遥控器失败: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
def _init_imu(self) -> bool:
|
def _init_imu(self) -> bool:
|
||||||
"""
|
"""
|
||||||
初始化IMU传感器
|
初始化IMU传感器
|
||||||
@ -1090,4 +1110,4 @@ if __name__ == "__main__":
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"\n❌ 测试启动失败: {e}")
|
print(f"\n❌ 测试启动失败: {e}")
|
||||||
import traceback
|
import traceback
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|||||||
266
backend/devices/remote_control_manager.py
Normal file
266
backend/devices/remote_control_manager.py
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
from typing import Optional, Dict, Any
|
||||||
|
import logging
|
||||||
|
import re
|
||||||
|
try:
|
||||||
|
import serial # pyserial
|
||||||
|
except Exception:
|
||||||
|
serial = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
from .base_device import BaseDevice
|
||||||
|
from .utils.config_manager import ConfigManager
|
||||||
|
except ImportError:
|
||||||
|
from base_device import BaseDevice
|
||||||
|
from utils.config_manager import ConfigManager
|
||||||
|
|
||||||
|
|
||||||
|
def _modbus_crc16(data: bytes) -> int:
|
||||||
|
crc = 0xFFFF
|
||||||
|
for b in data:
|
||||||
|
crc ^= b
|
||||||
|
for _ in range(8):
|
||||||
|
if crc & 0x0001:
|
||||||
|
crc = (crc >> 1) ^ 0xA001
|
||||||
|
else:
|
||||||
|
crc >>= 1
|
||||||
|
return crc & 0xFFFF
|
||||||
|
|
||||||
|
|
||||||
|
class RemoteControlManager(BaseDevice):
|
||||||
|
|
||||||
|
def __init__(self, socketio, config_manager: Optional[ConfigManager] = None):
|
||||||
|
self.config_manager = config_manager or ConfigManager()
|
||||||
|
port = self.config_manager.get_config_value('REMOTE', 'port', fallback='COM6')
|
||||||
|
baudrate = int(self.config_manager.get_config_value('REMOTE', 'baudrate', fallback='115200'))
|
||||||
|
timeout = float(self.config_manager.get_config_value('REMOTE', 'timeout', fallback='0.1'))
|
||||||
|
|
||||||
|
instance_config: Dict[str, Any] = {
|
||||||
|
'enabled': True,
|
||||||
|
'port': port,
|
||||||
|
'baudrate': baudrate,
|
||||||
|
'timeout': timeout,
|
||||||
|
'strict_crc': bool(str(self.config_manager.get_config_value('REMOTE', 'strict_crc', fallback='False')).lower() == 'true'),
|
||||||
|
}
|
||||||
|
|
||||||
|
super().__init__("remote", instance_config)
|
||||||
|
self._socketio = socketio
|
||||||
|
self.logger = logging.getLogger(self.__class__.__name__)
|
||||||
|
|
||||||
|
self.port = port
|
||||||
|
self.baudrate = baudrate
|
||||||
|
self.timeout = timeout
|
||||||
|
self.bytesize = getattr(serial, 'EIGHTBITS', 8)
|
||||||
|
self.parity = getattr(serial, 'PARITY_NONE', 'N')
|
||||||
|
self.stopbits = getattr(serial, 'STOPBITS_ONE', 1)
|
||||||
|
self.strict_crc = instance_config['strict_crc']
|
||||||
|
|
||||||
|
self._ser: Optional[serial.Serial] = None
|
||||||
|
self._thread: Optional[threading.Thread] = None
|
||||||
|
self._running = False
|
||||||
|
self._buffer = bytearray()
|
||||||
|
|
||||||
|
def initialize(self) -> bool:
|
||||||
|
try:
|
||||||
|
self.logger.info(f"初始化遥控器串口: {self.port}, {self.baudrate}bps, 8N1")
|
||||||
|
self.set_connected(True)
|
||||||
|
self._device_info['initialized_at'] = time.time()
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(f"遥控器初始化失败: {e}")
|
||||||
|
self.set_connected(False)
|
||||||
|
return False
|
||||||
|
|
||||||
|
def start_streaming(self) -> bool:
|
||||||
|
try:
|
||||||
|
if self._running:
|
||||||
|
return True
|
||||||
|
if serial is None:
|
||||||
|
raise RuntimeError("pyserial 未安装或不可用")
|
||||||
|
self._ser = serial.Serial(
|
||||||
|
port=self.port,
|
||||||
|
baudrate=self.baudrate,
|
||||||
|
bytesize=self.bytesize,
|
||||||
|
parity=self.parity,
|
||||||
|
stopbits=self.stopbits,
|
||||||
|
timeout=self.timeout,
|
||||||
|
)
|
||||||
|
self._running = True
|
||||||
|
self._thread = threading.Thread(target=self._worker_loop, daemon=True)
|
||||||
|
self._thread.start()
|
||||||
|
self.logger.info("遥控器串口监听已启动")
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(f"启动遥控器监听失败: {e}")
|
||||||
|
self._running = False
|
||||||
|
try:
|
||||||
|
if self._ser and self._ser.is_open:
|
||||||
|
self._ser.close()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return False
|
||||||
|
|
||||||
|
def stop_streaming(self) -> bool:
|
||||||
|
try:
|
||||||
|
self._running = False
|
||||||
|
if self._thread and self._thread.is_alive():
|
||||||
|
self._thread.join(timeout=2.0)
|
||||||
|
if self._ser and self._ser.is_open:
|
||||||
|
self._ser.close()
|
||||||
|
self.logger.info("遥控器串口监听已停止")
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(f"停止遥控器监听失败: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def disconnect(self):
|
||||||
|
try:
|
||||||
|
self.stop_streaming()
|
||||||
|
self.set_connected(False)
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(f"断开遥控器失败: {e}")
|
||||||
|
|
||||||
|
def reload_config(self) -> bool:
|
||||||
|
try:
|
||||||
|
self.logger.info("重新加载遥控器配置")
|
||||||
|
self.port = self.config_manager.get_config_value('REMOTE', 'port', fallback=self.port) or self.port
|
||||||
|
self.baudrate = int(self.config_manager.get_config_value('REMOTE', 'baudrate', fallback=self.baudrate))
|
||||||
|
self.timeout = float(self.config_manager.get_config_value('REMOTE', 'timeout', fallback=self.timeout))
|
||||||
|
self._device_info.update({
|
||||||
|
'port': self.port,
|
||||||
|
'baudrate': self.baudrate,
|
||||||
|
'timeout': self.timeout,
|
||||||
|
})
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(f"重新加载遥控器配置失败: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def calibrate(self) -> Dict[str, Any]:
|
||||||
|
return {'status': 'success'}
|
||||||
|
|
||||||
|
def get_status(self) -> Dict[str, Any]:
|
||||||
|
return {
|
||||||
|
'name': self.device_name,
|
||||||
|
'port': self.port,
|
||||||
|
'baudrate': self.baudrate,
|
||||||
|
'timeout': self.timeout,
|
||||||
|
'is_connected': self.is_connected,
|
||||||
|
'is_streaming': self._running,
|
||||||
|
'has_serial': bool(self._ser and getattr(self._ser, 'is_open', False)),
|
||||||
|
'last_error': self._device_info.get('last_error')
|
||||||
|
}
|
||||||
|
|
||||||
|
def cleanup(self) -> None:
|
||||||
|
try:
|
||||||
|
self.stop_streaming()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def check_hardware_connection(self) -> bool:
|
||||||
|
try:
|
||||||
|
return bool(self._ser and self._ser.is_open)
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _emit_code(self, key_code: int):
|
||||||
|
code_hex = f"{key_code:02X}"
|
||||||
|
name_map = {
|
||||||
|
0x11: "start",
|
||||||
|
0x14: "stop",
|
||||||
|
0x13: "up",
|
||||||
|
0x15: "down",
|
||||||
|
0x12: "center",
|
||||||
|
0x0E: "power",
|
||||||
|
0x0F: "screenshot",
|
||||||
|
}
|
||||||
|
name = name_map.get(key_code, 'unknown')
|
||||||
|
payload = {
|
||||||
|
'code': code_hex,
|
||||||
|
'name': name,
|
||||||
|
'timestamp': time.time()
|
||||||
|
}
|
||||||
|
try:
|
||||||
|
msg = f"接收到遥控器按键: code={code_hex}, name={name}"
|
||||||
|
print(msg)
|
||||||
|
self.logger.info(msg)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
if self._socketio:
|
||||||
|
self._socketio.emit('remote_control', payload, namespace='/devices')
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(f"推送遥控器事件失败: {e}")
|
||||||
|
|
||||||
|
def _try_parse_frames(self):
|
||||||
|
while True:
|
||||||
|
if len(self._buffer) < 7:
|
||||||
|
break
|
||||||
|
idx = self._buffer.find(b'\x01\x04\x02\x00')
|
||||||
|
if idx >= 0 and len(self._buffer) - idx >= 7:
|
||||||
|
frame = bytes(self._buffer[idx:idx + 7])
|
||||||
|
calc_crc = _modbus_crc16(frame[:5])
|
||||||
|
recv_crc = frame[5] | (frame[6] << 8)
|
||||||
|
if calc_crc == recv_crc:
|
||||||
|
key_code = frame[4]
|
||||||
|
self._emit_code(key_code)
|
||||||
|
del self._buffer[:idx + 7]
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
if not self.strict_crc and len(frame) >= 7:
|
||||||
|
key_code = frame[4]
|
||||||
|
self._emit_code(key_code)
|
||||||
|
del self._buffer[:idx + 7]
|
||||||
|
continue
|
||||||
|
del self._buffer[idx:idx + 1]
|
||||||
|
continue
|
||||||
|
# ASCII HEX fallback
|
||||||
|
try:
|
||||||
|
text = bytes(self._buffer).decode(errors='ignore')
|
||||||
|
except Exception:
|
||||||
|
break
|
||||||
|
m = re.search(r'01\s*04\s*02\s*00\s*([0-9A-Fa-f]{2})\s*([0-9A-Fa-f]{2})\s*([0-9A-Fa-f]{2})', text)
|
||||||
|
if m:
|
||||||
|
k = int(m.group(1), 16)
|
||||||
|
crcL = int(m.group(2), 16)
|
||||||
|
crcH = int(m.group(3), 16)
|
||||||
|
calc = _modbus_crc16(bytes.fromhex(f'01 04 02 00 {m.group(1)}'))
|
||||||
|
recv = crcL | (crcH << 8)
|
||||||
|
if calc == recv:
|
||||||
|
self._emit_code(k)
|
||||||
|
elif not self.strict_crc:
|
||||||
|
self._emit_code(k)
|
||||||
|
self._buffer.clear()
|
||||||
|
break
|
||||||
|
# no header; trim
|
||||||
|
del self._buffer[:max(0, len(self._buffer) - 3)]
|
||||||
|
break
|
||||||
|
|
||||||
|
def _worker_loop(self):
|
||||||
|
self.logger.info("遥控器串口线程启动")
|
||||||
|
last_rx_ts = time.time()
|
||||||
|
while self._running:
|
||||||
|
try:
|
||||||
|
if not self._ser or not self._ser.is_open:
|
||||||
|
time.sleep(0.05)
|
||||||
|
continue
|
||||||
|
chunk = self._ser.read(64)
|
||||||
|
if chunk:
|
||||||
|
try:
|
||||||
|
hexstr = ' '.join(f'{b:02X}' for b in chunk)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
self._buffer.extend(chunk)
|
||||||
|
self._try_parse_frames()
|
||||||
|
last_rx_ts = time.time()
|
||||||
|
else:
|
||||||
|
time.sleep(0.01)
|
||||||
|
if time.time() - last_rx_ts > 5.0:
|
||||||
|
self.logger.debug("遥控器串口暂无数据")
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(f"遥控器串口读取异常: {e}")
|
||||||
|
time.sleep(0.1)
|
||||||
|
self.logger.info("遥控器串口线程结束")
|
||||||
@ -613,7 +613,14 @@ class ConfigManager:
|
|||||||
'pressure': self.get_device_config('pressure'),
|
'pressure': self.get_device_config('pressure'),
|
||||||
'camera1': self.get_device_config('camera1'),
|
'camera1': self.get_device_config('camera1'),
|
||||||
'camera2': self.get_device_config('camera2'),
|
'camera2': self.get_device_config('camera2'),
|
||||||
'femtobolt': self.get_device_config('femtobolt')
|
'femtobolt': self.get_device_config('femtobolt'),
|
||||||
|
'remote': {
|
||||||
|
'enabled': self.config.getboolean('DEVICES', 'remote_enabled', fallback=True),
|
||||||
|
'port': self.config.get('REMOTE', 'port', fallback='COM6'),
|
||||||
|
'baudrate': self.config.getint('REMOTE', 'baudrate', fallback=115200),
|
||||||
|
'timeout': self.config.getfloat('REMOTE', 'timeout', fallback=0.1),
|
||||||
|
'strict_crc': self.config.getboolean('REMOTE', 'strict_crc', fallback=False)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def _batch_update_device_configs(self, configs: Dict[str, Dict[str, Any]]) -> Dict[str, Any]:
|
def _batch_update_device_configs(self, configs: Dict[str, Dict[str, Any]]) -> Dict[str, Any]:
|
||||||
@ -847,4 +854,4 @@ class ConfigManager:
|
|||||||
return {
|
return {
|
||||||
'success': False,
|
'success': False,
|
||||||
'message': f'批量设置设备配置失败: {str(e)}'
|
'message': f'批量设置设备配置失败: {str(e)}'
|
||||||
}
|
}
|
||||||
|
|||||||
@ -89,7 +89,8 @@ class AppServer:
|
|||||||
'camera': None,
|
'camera': None,
|
||||||
'femtobolt': None,
|
'femtobolt': None,
|
||||||
'imu': None,
|
'imu': None,
|
||||||
'pressure': None
|
'pressure': None,
|
||||||
|
'remote': None,
|
||||||
}
|
}
|
||||||
|
|
||||||
# 注册路由和事件
|
# 注册路由和事件
|
||||||
@ -1834,7 +1835,7 @@ class AppServer:
|
|||||||
def handle_subscribe_device(data):
|
def handle_subscribe_device(data):
|
||||||
"""订阅特定设备数据"""
|
"""订阅特定设备数据"""
|
||||||
device_type = data.get('device_type')
|
device_type = data.get('device_type')
|
||||||
if device_type in ['camera1', 'camera2', 'femtobolt', 'imu', 'pressure']:
|
if device_type in ['camera1', 'camera2', 'femtobolt', 'imu', 'pressure', 'remote']:
|
||||||
self.logger.info(f'客户端订阅{device_type}设备数据')
|
self.logger.info(f'客户端订阅{device_type}设备数据')
|
||||||
emit('subscription_status', {
|
emit('subscription_status', {
|
||||||
'device_type': device_type,
|
'device_type': device_type,
|
||||||
|
|||||||
70
document/串口遥控器遥控界面操作说明.md
Normal file
70
document/串口遥控器遥控界面操作说明.md
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
# 串口遥控器遥控界面操作说明
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
- 通过串口接收遥控器报文,解析键码并通过 WebSocket 推送到前端,实现对检测页面的远程控制。
|
||||||
|
- 后端设备名为 `remote`,事件名为 `remote_control`,命名空间为 `/devices`。
|
||||||
|
|
||||||
|
## 串口配置
|
||||||
|
- 配置文件位置:backend/config.ini
|
||||||
|
- 读取段与键:
|
||||||
|
- [REMOTE] port,缺省 COM6
|
||||||
|
- [REMOTE] baudrate,缺省 115200
|
||||||
|
- [REMOTE] timeout,缺省 0.1 秒
|
||||||
|
- [DEVICES] remote_enabled(是否启用),缺省 true
|
||||||
|
- 串口参数:115200 bps,8 数据位,1 停止位,无校验(8N1)。
|
||||||
|
|
||||||
|
## 报文格式
|
||||||
|
- 参照 Modbus RTU 协议中功能码 0x04(读输入寄存器)的应答帧格式:
|
||||||
|
- 帧结构:`01 04 02 00 [键码] crcL crcH`
|
||||||
|
- 固定头:`01 04 02 00`
|
||||||
|
- 第 5 字节为键码(KeyCode)
|
||||||
|
- CRC16:Modbus RTU 小端(crcL, crcH),计算范围为前 5 个字节
|
||||||
|
- 报文由接收器主动上传,无需主机轮询
|
||||||
|
- 除键码与 CRC 外,前 4 字节保持不变
|
||||||
|
|
||||||
|
## 键码约定
|
||||||
|
- 左:`11`
|
||||||
|
- 右:`14`
|
||||||
|
- 上:`13`
|
||||||
|
- 下:`15`
|
||||||
|
- 中:`12`
|
||||||
|
- 电源:`0E`
|
||||||
|
- 抓屏:`0F`
|
||||||
|
|
||||||
|
## 后端实现
|
||||||
|
- 代码文件:`backend/devices/remote_control_manager.py`
|
||||||
|
- 主要逻辑:
|
||||||
|
- 打开串口并启动后台线程读取数据
|
||||||
|
- 在缓冲区中查找帧头 `01 04 02 00`,截取 7 字节帧
|
||||||
|
- 计算前 5 字节 Modbus CRC16(多项式 0xA001,初值 0xFFFF),校验通过后解析键码
|
||||||
|
- 通过 Socket.IO 向 `/devices` 命名空间推送事件 `remote_control`,载荷示例:
|
||||||
|
- `{ "code": "0F", "name": "screenshot", "timestamp": 1731234567.89 }`
|
||||||
|
|
||||||
|
## 前端对接
|
||||||
|
- 页面:`frontend/src/renderer/src/views/Detection.vue`
|
||||||
|
- 统一设备命名空间 Socket:`devicesSocket = io(BACKEND_URL + '/devices', ...)`
|
||||||
|
- 事件监听与映射:
|
||||||
|
- 监听:`devicesSocket.on('remote_control', handler)`
|
||||||
|
- 根据编码触发页面方法:
|
||||||
|
- `11` → `startVideoClick()`(开始录像)
|
||||||
|
- `14` → `stopVideoClick()`(结束录像)
|
||||||
|
- `0F` → `saveDetectionData()`(截图)
|
||||||
|
- 页面中相关按钮:
|
||||||
|
- 截图按钮:调用 `saveDetectionData`
|
||||||
|
- 开始录像按钮:调用 `startVideoClick`
|
||||||
|
- 结束录像按钮:调用 `stopVideoClick`
|
||||||
|
|
||||||
|
## 运行与验证
|
||||||
|
- 打包后 Electron 主进程会在窗口创建前启动后端服务
|
||||||
|
- 打开检测页面,确保设备命名空间连接成功
|
||||||
|
- 使用遥控器按键,观察页面动作对应触发
|
||||||
|
|
||||||
|
## 常见问题
|
||||||
|
- 无法接收到事件:
|
||||||
|
- 检查后端串口配置是否正确(端口被占用或不存在)
|
||||||
|
- 确认遥控器接收器已连接且在串口管理器线程持续读取
|
||||||
|
- 确认前端已连接到 `/devices` 命名空间并注册了事件监听
|
||||||
|
- CRC 错误:
|
||||||
|
- 检查物理连接和电气参数
|
||||||
|
- 若报文格式与约定不一致,请提供示例报文以调整解析逻辑
|
||||||
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 623 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 628 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 135 KiB |
BIN
document/登录页.png
BIN
document/登录页.png
Binary file not shown.
|
Before Width: | Height: | Size: 63 KiB |
Binary file not shown.
@ -6,7 +6,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "concurrently \"npm run dev:renderer\" \"wait-on http://localhost:3000 && npm run dev:electron\"",
|
"dev": "concurrently \"npm run dev:renderer\" \"wait-on http://localhost:3000 && npm run dev:electron\"",
|
||||||
"dev:renderer": "vite",
|
"dev:renderer": "vite",
|
||||||
"dev:electron": "set NODE_ENV=development&& \"d:\\electron-v36.4.0-win32-x64\\electron.exe\" .",
|
"dev:electron": "electron .",
|
||||||
"build": "npm run build:renderer && npm run build:electron",
|
"build": "npm run build:renderer && npm run build:electron",
|
||||||
"build:renderer": "vite build",
|
"build:renderer": "vite build",
|
||||||
"build:electron": "set HTTP_PROXY=&& set HTTPS_PROXY=&&electron-builder --config ./build/electron-builder.install.json",
|
"build:electron": "set HTTP_PROXY=&& set HTTPS_PROXY=&&electron-builder --config ./build/electron-builder.install.json",
|
||||||
|
|||||||
@ -1007,6 +1007,7 @@ function connectWebSocket() {
|
|||||||
devicesSocket.emit('subscribe_device', { device_type: 'femtobolt' })
|
devicesSocket.emit('subscribe_device', { device_type: 'femtobolt' })
|
||||||
devicesSocket.emit('subscribe_device', { device_type: 'imu' })
|
devicesSocket.emit('subscribe_device', { device_type: 'imu' })
|
||||||
devicesSocket.emit('subscribe_device', { device_type: 'pressure' })
|
devicesSocket.emit('subscribe_device', { device_type: 'pressure' })
|
||||||
|
devicesSocket.emit('subscribe_device', { device_type: 'remote' })
|
||||||
|
|
||||||
// 设备连接成功后启动数据推送
|
// 设备连接成功后启动数据推送
|
||||||
startDeviceDataPush()
|
startDeviceDataPush()
|
||||||
@ -1067,6 +1068,27 @@ function connectWebSocket() {
|
|||||||
tempInfo.value.pressure_data = data
|
tempInfo.value.pressure_data = data
|
||||||
handlePressureData(data)
|
handlePressureData(data)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 监听遥控器事件:根据编码触发页面方法
|
||||||
|
devicesSocket.on('remote_control', (data) => {
|
||||||
|
const code = String((data && data.code) || '').toUpperCase()
|
||||||
|
switch (code) {
|
||||||
|
case '11':
|
||||||
|
startVideoClick()
|
||||||
|
break
|
||||||
|
case '14':
|
||||||
|
stopVideoClick()
|
||||||
|
break
|
||||||
|
case '12':
|
||||||
|
clearAndStartTracking()
|
||||||
|
break
|
||||||
|
case '0F':
|
||||||
|
saveDetectionData()
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
// 监听测试状态事件
|
// 监听测试状态事件
|
||||||
devicesSocket.on('test_status', (data) => {
|
devicesSocket.on('test_status', (data) => {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user