Files
ReinLoopTest/ReinLoop/core/connection_manager.py
T
2026-07-30 11:12:31 +08:00

133 lines
4.5 KiB
Python

# connection_manager.py
"""连接管理器:负责 MT2-AM8 模块 (Modbus TCP) 的连接/断开。
纯业务逻辑,无 UI 依赖。通过回调与 UI 层通信。
"""
import time
from PcControl import MT2AM8Client
class ConnectionManager:
"""管理 MT2-AM8 模块连接的生命周期"""
def __init__(self):
self.modbus_client = None # MT2AM8Client (TCP 读压力/流量,控电机)
self._pressure_addr = 0 # 压力传感器模拟量通道地址
self._flowmeter_addr = None # 流量计模拟量通道地址(None=使用手动输入)
self._motor_addr = 0 # 电机模拟量输出通道地址
self._on_log = None # 日志回调
self._on_status_change = None # 状态变化回调
def set_log_callback(self, callback):
"""设置日志回调: callback(message: str)"""
self._on_log = callback
def set_status_callback(self, callback):
"""设置状态变化回调: callback(connected: bool, status_text: str)"""
self._on_status_change = callback
def log(self, message):
"""内部日志输出"""
if self._on_log:
self._on_log(message)
def is_connected(self) -> bool:
"""检查是否已连接"""
return self.modbus_client is not None and self.modbus_client.connected
def connect(self, tcp_ip: str, tcp_port: int, pressure_addr: int,
motor_addr: int, flowmeter_addr: int,
pressure_range: float = 400, flow_range: float = 100) -> bool:
"""连接到 MT2-AM8 模块
Args:
tcp_ip: 模块 IP 地址
tcp_port: TCP 端口
pressure_addr: 压力传感器模拟量通道地址
motor_addr: 电机模拟量输出通道地址
flowmeter_addr: 流量计模拟量通道地址
pressure_range: 压力表量程上限
flow_range: 流量计量程上限
Returns:
是否连接成功
"""
try:
self.log("正在连接设备...")
# 保存地址配置
self._pressure_addr = pressure_addr
self._motor_addr = motor_addr
self._flowmeter_addr = flowmeter_addr
# 创建 MT2-AM8 客户端
self.modbus_client = MT2AM8Client(
host=tcp_ip,
port=tcp_port,
pressure_range=pressure_range,
flow_range=flow_range,
)
if not self.modbus_client.connect():
self.log(f"连接 MT2-AM8 模块失败: {tcp_ip}:{tcp_port}")
return False
self.log(f"成功连接到 MT2-AM8 模块: {tcp_ip}:{tcp_port}")
self.log(f"压力地址: {pressure_addr}, 电机地址: {motor_addr}, 流量计地址: {flowmeter_addr}")
if self._on_status_change:
self._on_status_change(True, "已连接")
return True
except Exception as e:
self.log(f"连接异常: {str(e)}")
return False
def disconnect(self):
"""断开连接"""
if self.modbus_client:
self.modbus_client.disconnect()
self.modbus_client = None
self.log("已断开连接")
if self._on_status_change:
self._on_status_change(False, "未连接")
def read_pressure(self):
"""读取当前压力值(转换为实际物理量)
Returns:
实际压力值 (kPa), 读取失败返回 None
"""
if not self.is_connected():
return None
return self.modbus_client.get_pressure(self._pressure_addr)
def read_flow(self):
"""读取当前流量值(转换为实际物理量)
若未配置流量计地址,直接返回 None,由调用方使用控制栏手动输入值。
Returns:
实际流量值 (L/min), 未配置地址或读取失败返回 None
"""
if not self.is_connected() or self._flowmeter_addr is None:
return None
return self.modbus_client.get_flow(self._flowmeter_addr)
def set_motor_position(self, xa: float) -> bool:
"""设置电机位置(通过模拟量输出控制阀门开度)
Args:
xa: 目标行程 (0~x_max)
Returns:
是否设置成功
"""
if not self.is_connected():
return False
return self.modbus_client.set_motor_position(xa, channel=self._motor_addr)