diff --git a/unilabos/registry/devices/balance.yaml b/unilabos/registry/devices/balance.yaml index 12d87264..0967ef42 100644 --- a/unilabos/registry/devices/balance.yaml +++ b/unilabos/registry/devices/balance.yaml @@ -1,256 +1 @@ -balance.mettler_toledo_xpr: - category: - - balance - class: - action_value_mappings: - disconnect: - feedback: {} - goal: {} - goal_default: {} - handles: {} - result: - success: success - schema: - description: Disconnect from balance - properties: - feedback: {} - goal: - properties: {} - required: [] - type: object - result: - properties: - success: - description: Whether disconnect was successful - type: boolean - required: - - success - type: object - required: - - goal - type: object - type: UniLabJsonCommand - get_weight: - feedback: {} - goal: {} - goal_default: {} - handles: {} - result: - unit: unit - weight: weight - schema: - description: Get current weight reading - properties: - feedback: {} - goal: - properties: {} - required: [] - type: object - result: - properties: - unit: - description: Weight unit (e.g., g, kg) - type: string - weight: - description: Weight value - type: number - required: - - weight - - unit - type: object - required: - - goal - type: object - type: UniLabJsonCommand - read_with_tare: - feedback: {} - goal: - immediate_tare: immediate_tare - goal_default: - immediate_tare: true - handles: {} - result: - unit: unit - weight: weight - schema: - description: Perform tare then read weight (standard read operation) - properties: - feedback: {} - goal: - properties: - immediate_tare: - default: true - description: Whether to use immediate tare - type: boolean - required: [] - type: object - result: - properties: - unit: - description: Weight unit (e.g., g, kg) - type: string - weight: - description: Weight value after tare - type: number - required: - - weight - - unit - type: object - required: - - goal - type: object - type: UniLabJsonCommand - send_cmd: - feedback: {} - goal: - command: command - goal_default: - command: '' - handles: {} - result: - return_info: return_info - success: success - schema: - description: '' - properties: - feedback: - properties: - status: - type: string - required: - - status - title: SendCmd_Feedback - type: object - goal: - properties: - command: - type: string - required: - - command - title: SendCmd_Goal - type: object - result: - properties: - return_info: - type: string - success: - type: boolean - required: - - return_info - - success - title: SendCmd_Result - type: object - required: - - goal - title: SendCmd - type: object - type: SendCmd - tare: - feedback: {} - goal: - immediate: immediate - goal_default: - immediate: false - handles: {} - result: - success: success - schema: - description: Tare operation for balance - properties: - feedback: {} - goal: - properties: - immediate: - default: false - description: Whether to perform immediate tare - type: boolean - required: [] - type: object - result: - properties: - success: - description: Whether tare operation was successful - type: boolean - required: - - success - type: object - required: - - goal - type: object - type: UniLabJsonCommand - zero: - feedback: {} - goal: - immediate: immediate - goal_default: - immediate: false - handles: {} - result: - success: success - schema: - description: Zero operation for balance - properties: - feedback: {} - goal: - properties: - immediate: - default: false - description: Whether to perform immediate zero - type: boolean - required: [] - type: object - result: - properties: - success: - description: Whether zero operation was successful - type: boolean - required: - - success - type: object - required: - - goal - type: object - type: UniLabJsonCommand - module: unilabos.devices.balance.mettler_toledo_xpr.mettler_toledo_xpr:MettlerToledoXPR - status_types: - error_message: str - is_stable: bool - status: str - unit: str - weight: float - type: python - config_info: [] - description: Mettler Toledo XPR/XSR Balance Driver - handles: [] - icon: '' - init_param_schema: - description: MettlerToledoXPR __init__ parameters - properties: - feedback: {} - goal: - description: Initialization parameters for Mettler Toledo XPR balance - properties: - ip: - default: 192.168.1.10 - description: Balance IP address - type: string - password: - default: '123456' - description: Balance password - type: string - port: - default: 81 - description: Balance port number - type: integer - timeout: - default: 10 - description: Connection timeout in seconds - type: integer - required: [] - type: object - result: {} - required: - - goal - title: __init__ command parameters - type: object - version: 1.0.0 +{} diff --git a/unilabos/registry/devices/liquid_handler.yaml b/unilabos/registry/devices/liquid_handler.yaml index 4452b5c4..50d24152 100644 --- a/unilabos/registry/devices/liquid_handler.yaml +++ b/unilabos/registry/devices/liquid_handler.yaml @@ -8375,6 +8375,9 @@ liquid_handler.prcxi: type: object host: type: string + is_9320: + default: false + type: string matrix_id: default: '' type: string diff --git a/unilabos/registry/devices/work_station.yaml b/unilabos/registry/devices/work_station.yaml index bdcf830f..3bc4dfa4 100644 --- a/unilabos/registry/devices/work_station.yaml +++ b/unilabos/registry/devices/work_station.yaml @@ -6112,7 +6112,7 @@ workstation: title: initialize_device参数 type: object type: UniLabJsonCommand - module: unilabos.ros.nodes.presets.protocol_node:ROS2ProtocolNode + module: unilabos.ros.nodes.presets.workstation:ROS2WorkstationNode status_types: {} type: ros2 config_info: [] @@ -6122,19 +6122,35 @@ workstation: init_param_schema: config: properties: + action_value_mappings: + type: object children: type: object device_id: type: string - protocol_type: + driver_instance: type: string + hardware_interface: + type: object + print_publish: + default: true + type: string + protocol_type: + items: + type: string + type: array resource_tracker: + type: string + status_types: type: object required: - - device_id - - children - protocol_type - - resource_tracker + - children + - driver_instance + - device_id + - status_types + - action_value_mappings + - hardware_interface type: object data: properties: {} @@ -6145,146 +6161,21 @@ workstation.example: category: - work_station class: - action_value_mappings: - auto-create_resource: - feedback: {} - goal: {} - goal_default: - bind_location: null - bind_parent_id: null - liquid_input_slot: null - liquid_type: null - liquid_volume: null - resource_tracker: null - resources: null - slot_on_deck: null - handles: {} - result: {} - schema: - description: '' - properties: - feedback: {} - goal: - properties: - bind_location: - type: object - bind_parent_id: - type: string - liquid_input_slot: - items: - type: integer - type: array - liquid_type: - items: - type: string - type: array - liquid_volume: - items: - type: integer - type: array - resource_tracker: - type: object - resources: - items: - type: object - type: array - slot_on_deck: - type: integer - required: - - resource_tracker - - resources - - bind_parent_id - - bind_location - - liquid_input_slot - - liquid_type - - liquid_volume - - slot_on_deck - type: object - result: {} - required: - - goal - title: create_resource参数 - type: object - type: UniLabJsonCommand - auto-transfer_bottle: - feedback: {} - goal: {} - goal_default: - base_plate: null - tip_rack: null - handles: {} - result: {} - schema: - description: '' - properties: - feedback: {} - goal: - properties: - base_plate: - type: object - tip_rack: - type: object - required: - - tip_rack - - base_plate - type: object - result: {} - required: - - goal - title: transfer_bottle参数 - type: object - type: UniLabJsonCommand - auto-trigger_resource_update: - feedback: {} - goal: {} - goal_default: - from_plate: null - to_base_plate: null - handles: {} - result: {} - schema: - description: '' - properties: - feedback: {} - goal: - properties: - from_plate: - type: object - to_base_plate: - type: object - required: - - from_plate - - to_base_plate - type: object - result: {} - required: - - goal - title: trigger_resource_update参数 - type: object - type: UniLabJsonCommand - module: unilabos.ros.nodes.presets.workstation:WorkStationExample + action_value_mappings: {} + module: unilabos.devices.workstation.workstation_base:WorkstationExample status_types: {} type: ros2 config_info: [] - description: '' + description: Example Workstation handles: [] icon: '' init_param_schema: config: properties: - children: - type: object - device_id: - type: string - protocol_type: - type: string - resource_tracker: + station_resource: type: object required: - - device_id - - children - - protocol_type - - resource_tracker + - station_resource type: object data: properties: {} diff --git a/unilabos/registry/devices/zhida_gcms.yaml b/unilabos/registry/devices/zhida_gcms.yaml index 921a0622..66f53822 100644 --- a/unilabos/registry/devices/zhida_gcms.yaml +++ b/unilabos/registry/devices/zhida_gcms.yaml @@ -52,7 +52,7 @@ zhida_gcms: result: {} required: - goal - title: close 参数 + title: close参数 type: object type: UniLabJsonCommand auto-connect: @@ -72,7 +72,31 @@ zhida_gcms: result: {} required: - goal - title: connect 参数 + title: connect参数 + type: object + type: UniLabJsonCommand + auto-post_init: + feedback: {} + goal: {} + goal_default: + ros_node: null + handles: {} + result: {} + schema: + description: '' + properties: + feedback: {} + goal: + properties: + ros_node: + type: string + required: + - ros_node + type: object + result: {} + required: + - goal + title: post_init参数 type: object type: UniLabJsonCommand get_methods: @@ -284,32 +308,40 @@ zhida_gcms: type: object type: StrSingleInput module: unilabos.devices.zhida_gcms.zhida:ZhidaClient - status_types: {} + status_types: + methods: dict + status: str + version: dict type: python config_info: [] description: 智达气相色谱-质谱联用(GC-MS)分析设备,通过 TCP 通信实现远程控制与状态监控,支持方法管理与任务启动等功能。 handles: [] icon: '' init_param_schema: - feedback: - properties: {} - required: [] - type: object - goal: + config: properties: host: default: 192.168.3.184 type: string port: default: 5792 - type: integer + type: string timeout: default: 10.0 - type: number + type: string required: [] type: object - result: - properties: {} - required: [] + data: + properties: + methods: + type: object + status: + type: string + version: + type: object + required: + - status + - methods + - version type: object version: 1.0.0 diff --git a/unilabos/resources/plr_additional_res_reg.py b/unilabos/resources/plr_additional_res_reg.py index 52ad3536..2b482d22 100644 --- a/unilabos/resources/plr_additional_res_reg.py +++ b/unilabos/resources/plr_additional_res_reg.py @@ -6,4 +6,4 @@ def register(): # noinspection PyUnresolvedReferences from unilabos.devices.liquid_handling.prcxi.prcxi import PRCXI9300Container # noinspection PyUnresolvedReferences - from unilabos.ros.nodes.presets.workstation import WorkStationContainer + from unilabos.devices.workstation.workstation_base import WorkStationContainer diff --git a/unilabos/ros/nodes/base_device_node.py b/unilabos/ros/nodes/base_device_node.py index e8b1717b..6213cd0b 100644 --- a/unilabos/ros/nodes/base_device_node.py +++ b/unilabos/ros/nodes/base_device_node.py @@ -51,7 +51,7 @@ from unilabos_msgs.msg import Resource # type: ignore from unilabos.ros.nodes.resource_tracker import DeviceNodeResourceTracker from unilabos.ros.x.rclpyx import get_event_loop -from unilabos.ros.utils.driver_creator import ProtocolNodeCreator, PyLabRobotCreator, DeviceClassCreator +from unilabos.ros.utils.driver_creator import WorkstationNodeCreator, PyLabRobotCreator, DeviceClassCreator from unilabos.utils.async_util import run_async_func from unilabos.utils.log import info, debug, warning, error, critical, logger, trace from unilabos.utils.type_check import get_type_class, TypeEncoder, serialize_result_info, get_result_info_str diff --git a/unilabos/ros/nodes/presets/workstation.py b/unilabos/ros/nodes/presets/workstation.py index 4e2dbef8..92d47cc9 100644 --- a/unilabos/ros/nodes/presets/workstation.py +++ b/unilabos/ros/nodes/presets/workstation.py @@ -29,6 +29,8 @@ from unilabos.utils.type_check import serialize_result_info if TYPE_CHECKING: from unilabos.devices.workstation.workstation_base import WorkstationBase +class ROS2WorkstationNodeTempError(Exception): + pass class ROS2WorkstationNode(BaseROS2DeviceNode): """ @@ -259,11 +261,14 @@ class ROS2WorkstationNode(BaseROS2DeviceNode): time.sleep(action["action_kwargs"]["time"]) step_results.append({"step": i + 1, "action": "wait", "result": "completed"}) else: - result = await self.execute_single_action(**action) - step_results.append({"step": i + 1, "action": action["action_name"], "result": result}) - ret_info = json.loads(getattr(result, "return_info", "{}")) - if not ret_info.get("suc", False): - raise RuntimeError(f"Step {i + 1} failed.") + try: + result = await self.execute_single_action(**action) + step_results.append({"step": i + 1, "action": action["action_name"], "result": result}) + ret_info = json.loads(getattr(result, "return_info", "{}")) + if not ret_info.get("suc", False): + raise RuntimeError(f"Step {i + 1} failed.") + except ROS2WorkstationNodeTempError as ex: + step_results.append({"step": i + 1, "action": action["action_name"], "result": ex.args[0]}) elif isinstance(action, list): # 如果是并行动作,同时执行 actions = action @@ -340,6 +345,9 @@ class ROS2WorkstationNode(BaseROS2DeviceNode): async def execute_single_action(self, device_id, action_name, action_kwargs): """执行单个动作""" # 构建动作ID + if action_name == "log_message": + self.lab_logger().info(f"[Protocol Log] {action_kwargs}") + raise ROS2WorkstationNodeTempError(f"[Protocol Log] {action_kwargs}") if device_id in ["", None, "self"]: action_id = f"/devices/{self.device_id}/{action_name}" else: