mirror of
https://github.com/dptech-corp/Uni-Lab-OS.git
synced 2026-02-04 13:25:13 +00:00
* Add Device MockChiller Add device MockChiller * Add Device MockFilter * Add Device MockPump * Add Device MockRotavap * Add Device MockSeparator * Add Device MockStirrer * Add Device MockHeater * Add Device MockVacuum * Add Device MockSolenoidValve * Add Device Mock \_init_.py * 规范模拟设备代码与注册表信息 * 更改Mock大写文件夹名 * 删除大写目录 * Edited Mock device json * Match mock device with action * Edit mock device yaml * Add new action * Add Virtual Device, Action, YAML, Protocol for Organic Syn * 单独分类测试的protocol文件夹 * 更名Action --------- Co-authored-by: Xuwznln <18435084+Xuwznln@users.noreply.github.com>
158 lines
5.5 KiB
Python
158 lines
5.5 KiB
Python
import asyncio
|
||
import logging
|
||
from typing import Dict, Any
|
||
|
||
class VirtualCentrifuge:
|
||
"""Virtual centrifuge device for CentrifugeProtocol testing"""
|
||
|
||
def __init__(self, device_id: str = None, config: Dict[str, Any] = None, **kwargs):
|
||
# 处理可能的不同调用方式
|
||
if device_id is None and 'id' in kwargs:
|
||
device_id = kwargs.pop('id')
|
||
if config is None and 'config' in kwargs:
|
||
config = kwargs.pop('config')
|
||
|
||
# 设置默认值
|
||
self.device_id = device_id or "unknown_centrifuge"
|
||
self.config = config or {}
|
||
|
||
self.logger = logging.getLogger(f"VirtualCentrifuge.{self.device_id}")
|
||
self.data = {}
|
||
|
||
# 添加调试信息
|
||
print(f"=== VirtualCentrifuge {self.device_id} is being created! ===")
|
||
print(f"=== Config: {self.config} ===")
|
||
print(f"=== Kwargs: {kwargs} ===")
|
||
|
||
# 从config或kwargs中获取配置参数
|
||
self.port = self.config.get('port') or kwargs.get('port', 'VIRTUAL')
|
||
self._max_speed = self.config.get('max_speed') or kwargs.get('max_speed', 15000.0)
|
||
self._max_temp = self.config.get('max_temp') or kwargs.get('max_temp', 40.0)
|
||
self._min_temp = self.config.get('min_temp') or kwargs.get('min_temp', 4.0)
|
||
|
||
# 处理其他kwargs参数,但跳过已知的配置参数
|
||
skip_keys = {'port', 'max_speed', 'max_temp', 'min_temp'}
|
||
for key, value in kwargs.items():
|
||
if key not in skip_keys and not hasattr(self, key):
|
||
setattr(self, key, value)
|
||
|
||
async def initialize(self) -> bool:
|
||
"""Initialize virtual centrifuge"""
|
||
print(f"=== VirtualCentrifuge {self.device_id} initialize() called! ===")
|
||
self.logger.info(f"Initializing virtual centrifuge {self.device_id}")
|
||
self.data.update({
|
||
"status": "Idle",
|
||
"current_speed": 0.0,
|
||
"target_speed": 0.0,
|
||
"current_temp": 25.0,
|
||
"target_temp": 25.0,
|
||
"max_speed": self._max_speed,
|
||
"max_temp": self._max_temp,
|
||
"min_temp": self._min_temp,
|
||
"centrifuge_state": "Stopped",
|
||
"time_remaining": 0.0,
|
||
"progress": 0.0,
|
||
"message": ""
|
||
})
|
||
return True
|
||
|
||
async def cleanup(self) -> bool:
|
||
"""Cleanup virtual centrifuge"""
|
||
self.logger.info(f"Cleaning up virtual centrifuge {self.device_id}")
|
||
return True
|
||
|
||
async def centrifuge(self, vessel: str, speed: float, time: float, temp: float = 25.0) -> bool:
|
||
"""Execute centrifuge action - matches Centrifuge action"""
|
||
self.logger.info(f"Centrifuge: vessel={vessel}, speed={speed} RPM, time={time}s, temp={temp}°C")
|
||
|
||
# 验证参数
|
||
if speed > self._max_speed:
|
||
self.logger.error(f"Speed {speed} exceeds maximum {self._max_speed}")
|
||
self.data["message"] = f"速度 {speed} 超过最大值 {self._max_speed}"
|
||
return False
|
||
|
||
if temp > self._max_temp or temp < self._min_temp:
|
||
self.logger.error(f"Temperature {temp} outside range {self._min_temp}-{self._max_temp}")
|
||
self.data["message"] = f"温度 {temp} 超出范围 {self._min_temp}-{self._max_temp}"
|
||
return False
|
||
|
||
# 开始离心
|
||
self.data.update({
|
||
"status": "Running",
|
||
"centrifuge_state": "Centrifuging",
|
||
"target_speed": speed,
|
||
"current_speed": speed,
|
||
"target_temp": temp,
|
||
"current_temp": temp,
|
||
"time_remaining": time,
|
||
"vessel": vessel,
|
||
"progress": 0.0,
|
||
"message": f"离心中: {vessel} at {speed} RPM"
|
||
})
|
||
|
||
# 模拟离心过程
|
||
simulation_time = min(time, 5.0) # 最多等待5秒用于测试
|
||
await asyncio.sleep(simulation_time)
|
||
|
||
# 离心完成
|
||
self.data.update({
|
||
"status": "Idle",
|
||
"centrifuge_state": "Stopped",
|
||
"current_speed": 0.0,
|
||
"target_speed": 0.0,
|
||
"time_remaining": 0.0,
|
||
"progress": 100.0,
|
||
"message": f"离心完成: {vessel}"
|
||
})
|
||
|
||
self.logger.info(f"Centrifuge completed for vessel {vessel}")
|
||
return True
|
||
|
||
# 状态属性
|
||
@property
|
||
def status(self) -> str:
|
||
return self.data.get("status", "Unknown")
|
||
|
||
@property
|
||
def current_speed(self) -> float:
|
||
return self.data.get("current_speed", 0.0)
|
||
|
||
@property
|
||
def target_speed(self) -> float:
|
||
return self.data.get("target_speed", 0.0)
|
||
|
||
@property
|
||
def current_temp(self) -> float:
|
||
return self.data.get("current_temp", 25.0)
|
||
|
||
@property
|
||
def target_temp(self) -> float:
|
||
return self.data.get("target_temp", 25.0)
|
||
|
||
@property
|
||
def max_speed(self) -> float:
|
||
return self.data.get("max_speed", self._max_speed)
|
||
|
||
@property
|
||
def max_temp(self) -> float:
|
||
return self.data.get("max_temp", self._max_temp)
|
||
|
||
@property
|
||
def min_temp(self) -> float:
|
||
return self.data.get("min_temp", self._min_temp)
|
||
|
||
@property
|
||
def centrifuge_state(self) -> str:
|
||
return self.data.get("centrifuge_state", "Unknown")
|
||
|
||
@property
|
||
def time_remaining(self) -> float:
|
||
return self.data.get("time_remaining", 0.0)
|
||
|
||
@property
|
||
def progress(self) -> float:
|
||
return self.data.get("progress", 0.0)
|
||
|
||
@property
|
||
def message(self) -> str:
|
||
return self.data.get("message", "") |