Files
ReinLoopTest/ReinLoop/core/simulated_device.py

87 lines
2.8 KiB
Python

"""Deterministic in-memory device used for hardware-free ReinLoop tests.
The public methods intentionally mirror the MT2AM8 client and the small
subset of the legacy PLC/motor clients used by ``tool/gui.py``. No sockets,
serial ports, or Modbus objects are created here.
"""
import time
class SimulatedDevice:
"""A small pressure/flow/valve model for offline control-loop testing."""
def __init__(self, pressure_range=400.0, flow_range=100.0,
initial_pressure=0.0):
self.pressure_range = float(pressure_range)
self.flow_range = float(flow_range)
self.pressure = float(initial_pressure)
self.flow = min(self.flow_range, 50.0)
self.position = 1000.0
self.connected = False
self.last_update = time.monotonic()
self.command_log = []
def connect(self):
self.connected = True
self.last_update = time.monotonic()
print("模拟设备连接成功(未访问真实硬件)")
return True
def disconnect(self):
self.connected = False
print("模拟设备已断开")
def _advance(self):
now = time.monotonic()
dt = max(0.0, min(now - self.last_update, 0.5))
self.last_update = now
if not self.connected or dt == 0:
return
# 行程与阀门开度反向:行程越大,阀门开度越小。阀门开度减小
# 时系统压力升高;默认量程下行程 0/1000 分别对应 10/400 kPa。
travel_ratio = max(0.0, min(1.0, self.position / 1000.0))
target_pressure = 10.0 + (self.pressure_range - 10.0) * travel_ratio
response = min(1.0, dt / 8.0)
self.pressure += (target_pressure - self.pressure) * response
def get_pressure(self, channel=0):
self._advance()
return max(0.0, self.pressure)
def get_flow(self, channel=0):
self._advance()
opening = max(0.0, min(1.0, 1.0 - self.position / 1000.0))
return self.flow * (0.25 + 0.75 * opening)
def set_motor_position(self, position, channel=0):
self._advance()
position = float(position)
if not 0.0 <= position <= 1000.0:
return False
self.position = position
self.command_log.append({"position": position, "channel": channel,
"time": time.monotonic()})
return True
# Compatibility methods used by the legacy GUI and standalone helpers.
def get_current_p(self):
return self.get_pressure(0)
def read_current_position(self):
return self.position
def set_position(self, position):
return self.set_motor_position(position)
def init(self):
return True
def start_control(self):
return True
def stop_control(self):
return True