diff --git a/unilabos/compile/heatchill_protocol.py b/unilabos/compile/heatchill_protocol.py index 6b0e3e38..bc5a15db 100644 --- a/unilabos/compile/heatchill_protocol.py +++ b/unilabos/compile/heatchill_protocol.py @@ -220,6 +220,7 @@ def generate_heat_chill_protocol( "device_id": heatchill_id, "action_name": "heat_chill", "action_kwargs": { + "vessel": vessel, "temp": float(final_temp), "time": float(final_time), "stir": bool(stir), diff --git a/unilabos/compile/recrystallize_protocol.py b/unilabos/compile/recrystallize_protocol.py index 61653e23..f5e8e75d 100644 --- a/unilabos/compile/recrystallize_protocol.py +++ b/unilabos/compile/recrystallize_protocol.py @@ -2,7 +2,7 @@ import networkx as nx import re import logging from typing import List, Dict, Any, Tuple, Union -from .utils.vessel_parser import get_vessel +from .utils.vessel_parser import get_vessel, find_solvent_vessel from .utils.unit_parser import parse_volume_input from .pump_protocol import generate_pump_protocol_with_rinsing diff --git a/unilabos/devices/virtual/virtual_heatchill.py b/unilabos/devices/virtual/virtual_heatchill.py index 71023320..2f7e555b 100644 --- a/unilabos/devices/virtual/virtual_heatchill.py +++ b/unilabos/devices/virtual/virtual_heatchill.py @@ -68,7 +68,7 @@ class VirtualHeatChill: return True async def heat_chill(self, temp: float, time, stir: bool, - stir_speed: float, purpose: str) -> bool: + stir_speed: float, purpose: str, vessel: dict = {}) -> bool: """Execute heat chill action - 🔧 修复:确保参数类型正确""" # 🔧 关键修复:确保所有参数类型正确 @@ -201,7 +201,7 @@ class VirtualHeatChill: return True - async def heat_chill_start(self, temp: float, purpose: str) -> bool: + async def heat_chill_start(self, temp: float, purpose: str, vessel: dict = {}) -> bool: """Start continuous heat chill 🔄""" # 🔧 添加类型转换 @@ -257,7 +257,7 @@ class VirtualHeatChill: self.logger.info(f"✅ 持续温控已启动! {temp_emoji} {status_action}模式 🚀") return True - async def heat_chill_stop(self) -> bool: + async def heat_chill_stop(self, vessel: dict = {}) -> bool: """Stop heat chill 🛑""" self.logger.info(f"🛑 停止温控:") diff --git a/unilabos/devices/virtual/virtual_multiway_valve.py b/unilabos/devices/virtual/virtual_multiway_valve.py index 3cd68a16..1d9904e6 100644 --- a/unilabos/devices/virtual/virtual_multiway_valve.py +++ b/unilabos/devices/virtual/virtual_multiway_valve.py @@ -253,24 +253,6 @@ class VirtualMultiwayValve: # 删除debug日志:self.logger.debug(f"🌊 当前流路: {flow_path}") return flow_path - def get_info(self) -> dict: - """获取阀门详细信息 📊""" - info = { - "port": self.port, - "max_positions": self.max_positions, - "total_positions": self.total_positions, - "current_position": self._current_position, - "current_port": self.get_current_port(), - "target_position": self._target_position, - "status": self._status, - "valve_state": self._valve_state, - "flow_path": self.get_flow_path(), - "position_map": self.position_map - } - - # 删除debug日志:self.logger.debug(f"📊 阀门信息: 位置={self._current_position}, 状态={self._status}, 端口={self.get_current_port()}") - return info - def __str__(self): current_port = self.get_current_port() status_emoji = "✅" if self._status == "Idle" else "🔄" if self._status == "Busy" else "❌" @@ -313,9 +295,6 @@ if __name__ == "__main__": print(f"\n📋 可用位置: {valve.get_available_positions()}") print(f"🗺️ 端口映射: {valve.get_available_ports()}") - # 获取详细信息 - print(f"\n📊 详细信息: {valve.get_info()}") - # 测试切换功能 print(f"\n🔄 智能切换测试:") print(f"当前位置: {valve._current_position}") diff --git a/unilabos/devices/virtual/virtual_solid_dispenser.py b/unilabos/devices/virtual/virtual_solid_dispenser.py index 54a93ec3..4d914df9 100644 --- a/unilabos/devices/virtual/virtual_solid_dispenser.py +++ b/unilabos/devices/virtual/virtual_solid_dispenser.py @@ -319,21 +319,6 @@ class VirtualSolidDispenser: def total_operations(self) -> int: return self._total_operations - def get_device_info(self) -> Dict[str, Any]: - """获取设备状态信息 📊""" - info = { - "device_id": self.device_id, - "status": self._status, - "current_reagent": self._current_reagent, - "last_dispensed_amount": self._dispensed_amount, - "total_operations": self._total_operations, - "max_capacity": self.max_capacity, - "precision": self.precision - } - - # self.logger.debug(f"📊 设备信息: 状态={self._status}, 试剂={self._current_reagent}, 加样量={self._dispensed_amount:.6f}g") - return info - def __str__(self): status_emoji = "✅" if self._status == "Ready" else "🔄" if self._status == "Dispensing" else "❌" if self._status == "Error" else "🏠" return f"⚗️ VirtualSolidDispenser({status_emoji} {self.device_id}: {self._status}, 最后加样 {self._dispensed_amount:.3f}g)" @@ -380,8 +365,6 @@ async def test_solid_dispenser(): mass="150 g" # 超过100g限制 ) print(f"📊 测试4结果: {result4}") - - print(f"\n📊 最终设备信息: {dispenser.get_device_info()}") print(f"✅ === 测试完成 === 🎉") diff --git a/unilabos/devices/virtual/virtual_transferpump.py b/unilabos/devices/virtual/virtual_transferpump.py index 7d80744c..1187db5f 100644 --- a/unilabos/devices/virtual/virtual_transferpump.py +++ b/unilabos/devices/virtual/virtual_transferpump.py @@ -380,22 +380,6 @@ class VirtualTransferPump: """检查是否已满""" return self._current_volume >= (self.max_volume - 0.01) # 允许小量误差 - # 调试和状态信息 - def get_pump_info(self) -> dict: - """获取泵的详细信息""" - return { - "device_id": self.device_id, - "status": self._status, - "position": self._position, - "current_volume": self._current_volume, - "max_volume": self.max_volume, - "max_velocity": self._max_velocity, - "mode": self.mode.name, - "is_empty": self.is_empty(), - "is_full": self.is_full(), - "remaining_capacity": self.get_remaining_capacity() - } - def __str__(self): return f"VirtualTransferPump({self.device_id}: {self._current_volume:.2f}/{self.max_volume} ml, {self._status})" @@ -425,8 +409,6 @@ async def demo(): result = await pump.set_position(0.0) print(f"Empty result: {result}") print(f"After emptying: {pump}") - - print("\nPump info:", pump.get_pump_info()) if __name__ == "__main__": diff --git a/unilabos/registry/devices/solid_dispenser.yaml b/unilabos/registry/devices/solid_dispenser.yaml index 9c8cafb5..31af41d0 100644 --- a/unilabos/registry/devices/solid_dispenser.yaml +++ b/unilabos/registry/devices/solid_dispenser.yaml @@ -353,7 +353,7 @@ solid_dispenser.laiyu: title: EmptyIn type: object type: EmptyIn - module: unilabos.devices.laiyu_add_solid.laiyu:Laiyu + module: unilabos.devices.powder_dispense.laiyu:Laiyu status_types: status: str type: python diff --git a/unilabos/registry/devices/virtual_device.yaml b/unilabos/registry/devices/virtual_device.yaml index 55859f9c..af2ccf3e 100644 --- a/unilabos/registry/devices/virtual_device.yaml +++ b/unilabos/registry/devices/virtual_device.yaml @@ -2166,7 +2166,6 @@ virtual_multiway_valve: current_port: str current_position: int flow_path: str - info: dict status: str target_position: int valve_position: int @@ -2279,8 +2278,6 @@ virtual_multiway_valve: type: integer flow_path: type: string - info: - type: object status: type: string target_position: @@ -2299,529 +2296,6 @@ virtual_multiway_valve: - available_positions - available_ports - flow_path - - info - type: object - version: 1.0.0 -virtual_pump: - category: - - virtual_device - class: - action_value_mappings: - auto-clean_vessel: - feedback: {} - goal: {} - goal_default: - repeats: 1 - solvent: null - temp: null - vessel: null - volume: null - handles: [] - result: {} - schema: - description: clean_vessel的参数schema - properties: - feedback: {} - goal: - properties: - repeats: - default: 1 - type: integer - solvent: - type: string - temp: - type: number - vessel: - type: string - volume: - type: number - required: - - vessel - - solvent - - volume - - temp - type: object - result: {} - required: - - goal - title: clean_vessel参数 - type: object - type: UniLabJsonCommandAsync - auto-cleanup: - feedback: {} - goal: {} - goal_default: {} - handles: [] - result: {} - schema: - description: cleanup的参数schema - properties: - feedback: {} - goal: - properties: {} - required: [] - type: object - result: {} - required: - - goal - title: cleanup参数 - type: object - type: UniLabJsonCommandAsync - auto-initialize: - feedback: {} - goal: {} - goal_default: {} - handles: [] - result: {} - schema: - description: initialize的参数schema - properties: - feedback: {} - goal: - properties: {} - required: [] - type: object - result: {} - required: - - goal - title: initialize参数 - type: object - type: UniLabJsonCommandAsync - set_valve_position: - feedback: - status: status - goal: - float_in: valve_position - goal_default: - float_in: 0.0 - handles: [] - result: - success: success - schema: - description: '' - properties: - feedback: - properties: {} - required: [] - title: FloatSingleInput_Feedback - type: object - goal: - properties: - float_in: - type: number - required: - - float_in - title: FloatSingleInput_Goal - type: object - result: - properties: - return_info: - type: string - success: - type: boolean - required: - - return_info - - success - title: FloatSingleInput_Result - type: object - required: - - goal - title: FloatSingleInput - type: object - type: FloatSingleInput - transfer: - feedback: - status: status - goal: - amount: amount - from_vessel: from_vessel - rinsing_repeats: rinsing_repeats - rinsing_solvent: rinsing_solvent - rinsing_volume: rinsing_volume - solid: solid - time: time - to_vessel: to_vessel - viscous: viscous - volume: volume - goal_default: - amount: '' - event: '' - flowrate: 0.0 - from_vessel: - category: '' - children: [] - config: '' - data: '' - id: '' - name: '' - parent: '' - pose: - orientation: - w: 1.0 - x: 0.0 - y: 0.0 - z: 0.0 - position: - x: 0.0 - y: 0.0 - z: 0.0 - sample_id: '' - type: '' - rate_spec: '' - rinsing_repeats: 0 - rinsing_solvent: '' - rinsing_volume: 0.0 - solid: false - through: '' - time: 0.0 - to_vessel: - category: '' - children: [] - config: '' - data: '' - id: '' - name: '' - parent: '' - pose: - orientation: - w: 1.0 - x: 0.0 - y: 0.0 - z: 0.0 - position: - x: 0.0 - y: 0.0 - z: 0.0 - sample_id: '' - type: '' - transfer_flowrate: 0.0 - viscous: false - volume: 0.0 - handles: [] - result: - success: success - schema: - description: '' - properties: - feedback: - properties: - current_device: - type: string - status: - type: string - time_remaining: - properties: - nanosec: - maximum: 4294967295 - minimum: 0 - type: integer - sec: - maximum: 2147483647 - minimum: -2147483648 - type: integer - required: - - sec - - nanosec - title: Duration - type: object - time_spent: - properties: - nanosec: - maximum: 4294967295 - minimum: 0 - type: integer - sec: - maximum: 2147483647 - minimum: -2147483648 - type: integer - required: - - sec - - nanosec - title: Duration - type: object - required: - - status - - current_device - - time_spent - - time_remaining - title: PumpTransfer_Feedback - type: object - goal: - properties: - amount: - type: string - event: - type: string - flowrate: - type: number - from_vessel: - properties: - category: - type: string - children: - items: - type: string - type: array - config: - type: string - data: - type: string - id: - type: string - name: - type: string - parent: - type: string - pose: - properties: - orientation: - properties: - w: - type: number - x: - type: number - y: - type: number - z: - type: number - required: - - x - - y - - z - - w - title: Quaternion - type: object - position: - properties: - x: - type: number - y: - type: number - z: - type: number - required: - - x - - y - - z - title: Point - type: object - required: - - position - - orientation - title: Pose - type: object - sample_id: - type: string - type: - type: string - required: - - id - - name - - sample_id - - children - - parent - - type - - category - - pose - - config - - data - title: Resource - type: object - rate_spec: - type: string - rinsing_repeats: - maximum: 2147483647 - minimum: -2147483648 - type: integer - rinsing_solvent: - type: string - rinsing_volume: - type: number - solid: - type: boolean - through: - type: string - time: - type: number - to_vessel: - properties: - category: - type: string - children: - items: - type: string - type: array - config: - type: string - data: - type: string - id: - type: string - name: - type: string - parent: - type: string - pose: - properties: - orientation: - properties: - w: - type: number - x: - type: number - y: - type: number - z: - type: number - required: - - x - - y - - z - - w - title: Quaternion - type: object - position: - properties: - x: - type: number - y: - type: number - z: - type: number - required: - - x - - y - - z - title: Point - type: object - required: - - position - - orientation - title: Pose - type: object - sample_id: - type: string - type: - type: string - required: - - id - - name - - sample_id - - children - - parent - - type - - category - - pose - - config - - data - title: Resource - type: object - transfer_flowrate: - type: number - viscous: - type: boolean - volume: - type: number - required: - - from_vessel - - to_vessel - - volume - - amount - - time - - viscous - - rinsing_solvent - - rinsing_volume - - rinsing_repeats - - solid - - flowrate - - transfer_flowrate - - rate_spec - - event - - through - title: PumpTransfer_Goal - type: object - result: - properties: - return_info: - type: string - success: - type: boolean - required: - - return_info - - success - title: PumpTransfer_Result - type: object - required: - - goal - title: PumpTransfer - type: object - type: PumpTransfer - module: unilabos.devices.virtual.virtual_pump:VirtualPump - status_types: - current_status: str - current_volume: float - from_vessel: str - max_volume: float - progress: float - status: str - to_vessel: str - transfer_rate: float - transferred_volume: float - valve_position: int - type: python - config_info: [] - description: Virtual Pump for PumpTransferProtocol Testing - handles: - - data_key: fluid_in - data_source: handle - data_type: fluid - description: 泵的输出口 - handler_key: pumpio - io_type: source - label: pumpio - icon: '' - init_param_schema: - config: - properties: - config: - type: object - device_id: - type: string - required: [] - type: object - data: - properties: - current_status: - type: string - current_volume: - type: number - from_vessel: - type: string - max_volume: - type: number - progress: - type: number - status: - type: string - to_vessel: - type: string - transfer_rate: - type: number - transferred_volume: - type: number - valve_position: - type: integer - required: - - status - - valve_position - - current_volume - - max_volume - - transfer_rate - - from_vessel - - to_vessel - - progress - - transferred_volume - - current_status type: object version: 1.0.0 virtual_rotavap: @@ -4683,7 +4157,6 @@ virtual_solid_dispenser: module: unilabos.devices.virtual.virtual_solid_dispenser:VirtualSolidDispenser status_types: current_reagent: str - device_info: dict dispensed_amount: float status: str total_operations: int @@ -4722,8 +4195,6 @@ virtual_solid_dispenser: properties: current_reagent: type: string - device_info: - type: object dispensed_amount: type: number status: @@ -4735,7 +4206,6 @@ virtual_solid_dispenser: - current_reagent - dispensed_amount - total_operations - - device_info type: object version: 1.0.0 virtual_stirrer: @@ -5246,7 +4716,6 @@ virtual_stirrer: status_types: current_speed: float current_vessel: str - device_info: dict is_stirring: bool max_speed: float min_speed: float @@ -5281,8 +4750,6 @@ virtual_stirrer: type: number current_vessel: type: string - device_info: - type: object is_stirring: type: boolean max_speed: @@ -5304,7 +4771,6 @@ virtual_stirrer: - remaining_time - max_speed - min_speed - - device_info type: object version: 1.0.0 virtual_transfer_pump: @@ -5761,7 +5227,6 @@ virtual_transfer_pump: current_volume: float max_velocity: float position: float - pump_info: dict remaining_capacity: float status: str transfer_rate: float @@ -5795,8 +5260,6 @@ virtual_transfer_pump: type: number position: type: number - pump_info: - type: object remaining_capacity: type: number status: @@ -5810,7 +5273,6 @@ virtual_transfer_pump: - max_velocity - transfer_rate - remaining_capacity - - pump_info type: object version: 1.0.0 virtual_vacuum_pump: diff --git a/unilabos/registry/devices/work_station.yaml b/unilabos/registry/devices/work_station.yaml index 0ec9d079..d8bb21ac 100644 --- a/unilabos/registry/devices/work_station.yaml +++ b/unilabos/registry/devices/work_station.yaml @@ -1805,6 +1805,11 @@ workstation: data_type: resource handler_key: Vessel label: Evaporation Vessel + - data_key: solvent + data_source: handle + data_type: resource + handler_key: solvent + label: Eluting Solvent output: - data_key: vessel data_source: handle diff --git a/unilabos/ros/nodes/presets/protocol_node.py b/unilabos/ros/nodes/presets/protocol_node.py index a0420130..cb8f8d2a 100644 --- a/unilabos/ros/nodes/presets/protocol_node.py +++ b/unilabos/ros/nodes/presets/protocol_node.py @@ -217,7 +217,6 @@ class ROS2ProtocolNode(BaseROS2DeviceNode): [convert_from_ros_msg(rs) for rs in response.resources] ) - self.lab_logger().info(f"🔍 最终传递给协议的 protocol_kwargs: {protocol_kwargs}") self.lab_logger().info(f"🔍 最终的 vessel: {protocol_kwargs.get('vessel', 'NOT_FOUND')}") from unilabos.resources.graphio import physical_setup_graph