From 2d4ecec1e1440638c5760345f8c9a106ccf26108 Mon Sep 17 00:00:00 2001 From: shiyubo0410 Date: Sun, 12 Oct 2025 22:56:39 +0800 Subject: [PATCH] Update prcxi driver & fix transfer_liquid mix_times (#90) * Update prcxi driver & fix transfer_liquid mix_times * fix: correct mix_times type * Update liquid_handler registry * test: prcxi.py --- test/experiments/prcxi_9320.json | 2 +- .../liquid_handler_abstract.py | 2 +- .../devices/liquid_handling/prcxi/prcxi.py | 38 +++++++++++++------ unilabos/registry/devices/liquid_handler.yaml | 33 ++++++---------- .../action/LiquidHandlerTransfer.action | 2 +- 5 files changed, 42 insertions(+), 35 deletions(-) diff --git a/test/experiments/prcxi_9320.json b/test/experiments/prcxi_9320.json index c838fe9f..fb81d64d 100644 --- a/test/experiments/prcxi_9320.json +++ b/test/experiments/prcxi_9320.json @@ -19,7 +19,7 @@ "host": "192.168.0.121", "port": 9999, "timeout": 10.0, - "axis": "Left", + "axis": "Right", "channel_num": 1, "setup": true, "debug": false, diff --git a/unilabos/devices/liquid_handling/liquid_handler_abstract.py b/unilabos/devices/liquid_handling/liquid_handler_abstract.py index 1963e417..69b757b5 100644 --- a/unilabos/devices/liquid_handling/liquid_handler_abstract.py +++ b/unilabos/devices/liquid_handling/liquid_handler_abstract.py @@ -923,7 +923,7 @@ class LiquidHandlerAbstract(LiquidHandlerMiddleware): spread: Literal["wide", "tight", "custom"] = "wide", is_96_well: bool = False, mix_stage: Optional[Literal["none", "before", "after", "both"]] = "none", - mix_times: Optional[List[int]] = None, + mix_times: Optional[int] = None, mix_vol: Optional[int] = None, mix_rate: Optional[int] = None, mix_liquid_height: Optional[float] = None, diff --git a/unilabos/devices/liquid_handling/prcxi/prcxi.py b/unilabos/devices/liquid_handling/prcxi/prcxi.py index 865c34cb..d9c04331 100644 --- a/unilabos/devices/liquid_handling/prcxi/prcxi.py +++ b/unilabos/devices/liquid_handling/prcxi/prcxi.py @@ -2,6 +2,7 @@ import asyncio import collections import contextlib import json +import os import socket import time from typing import Any, List, Dict, Optional, Tuple, TypedDict, Union, Sequence, Iterator, Literal @@ -548,7 +549,7 @@ class PRCXI9300Backend(LiquidHandlerBackend): blending_times=0, balance_height=0, plate_or_hole=f"H{hole_col}-8,T{PlateNo}", - hole_numbers="1,2,3,4,5,6,7,8", + hole_numbers=f"{(hole_col - 1) * 8 + hole_row}" if self._num_channels == 1 else "1,2,3,4,5", ) self.steps_todo_list.append(step) @@ -1618,24 +1619,39 @@ if __name__ == "__main__": host="192.168.0.121", port=9999, timeout=10.0, - setup=False, + setup=True, debug=False, matrix_id="5de524d0-3f95-406c-86dd-f83626ebc7cb", channel_num=1, - axis="Left", + axis="Right", simulator=False, is_9320=True, - ) # Initialize the handler with the deck and host settings + ) backend: PRCXI9300Backend = handler.backend - res = backend.api_client.get_all_materials() - handler.set_tiprack([plate8]) # Set the tip rack for the handler - asyncio.run(handler.setup()) # Initialize the handler and setup the connection from pylabrobot.resources import set_volume_tracking - - # from pylabrobot.resources import set_tip_tracking set_volume_tracking(enabled=True) + # res = backend.api_client.get_all_materials() + asyncio.run(handler.setup()) # Initialize the handler and setup the connection + handler.set_tiprack([plate1, plate5]) # Set the tip rack for the handler + handler.set_liquid([plate9.get_well("H12")], ["water"], [5]) + asyncio.run(handler.create_protocol(protocol_name="Test Protocol")) + asyncio.run(handler.pick_up_tips([plate5.get_item("C5")], [0])) + asyncio.run(handler.aspirate([plate9.get_item("H12")], [5], [0])) - + for well in plate13.get_all_items(): + # well_pos = well.name.split("_")[1] # 走一行 + # if well_pos.startswith("A"): + if well.name.startswith("PlateT13"): # 走整个Plate + asyncio.run(handler.dispense([well], [0.01], [0])) + + # asyncio.run(handler.dispense([plate10.get_item("H12")], [1], [0])) + # asyncio.run(handler.dispense([plate13.get_item("A1")], [1], [0])) + # asyncio.run(handler.dispense([plate14.get_item("C5")], [1], [0])) + asyncio.run(handler.mix([plate10.get_item("H12")], mix_time=3, mix_vol=5)) + asyncio.run(handler.discard_tips([0])) + asyncio.run(handler.run_protocol()) + time.sleep(5) + os._exit(0) # 第一种情景:一个孔往多个孔加液 # plate_2_liquids = handler.set_group("water", [plate2.children[0]], [300]) # plate5_liquids = handler.set_group("master_mix", plate5.children[:23], [100]*23) @@ -1652,7 +1668,7 @@ if __name__ == "__main__": # # json.dump(A, f, indent=4, ensure_ascii=False) # print(plate11.get_well(0).tracker.get_used_volume()) - asyncio.run(handler.create_protocol(protocol_name="Test Protocol")) # Initialize the backend and setup the connection + # Initialize the backend and setup the connection asyncio.run(handler.transfer_group("water", "master_mix", 10)) # Reset tip tracking diff --git a/unilabos/registry/devices/liquid_handler.yaml b/unilabos/registry/devices/liquid_handler.yaml index b21ccd7e..99c92333 100644 --- a/unilabos/registry/devices/liquid_handler.yaml +++ b/unilabos/registry/devices/liquid_handler.yaml @@ -3994,8 +3994,7 @@ liquid_handler: mix_liquid_height: 0.0 mix_rate: 0 mix_stage: '' - mix_times: - - 0 + mix_times: 0 mix_vol: 0 none_keys: - '' @@ -4151,11 +4150,9 @@ liquid_handler: mix_stage: type: string mix_times: - items: - maximum: 2147483647 - minimum: -2147483648 - type: integer - type: array + maximum: 2147483647 + minimum: -2147483648 + type: integer mix_vol: maximum: 2147483647 minimum: -2147483648 @@ -5015,8 +5012,7 @@ liquid_handler.biomek: mix_liquid_height: 0.0 mix_rate: 0 mix_stage: '' - mix_times: - - 0 + mix_times: 0 mix_vol: 0 none_keys: - '' @@ -5159,11 +5155,9 @@ liquid_handler.biomek: mix_stage: type: string mix_times: - items: - maximum: 2147483647 - minimum: -2147483648 - type: integer - type: array + maximum: 2147483647 + minimum: -2147483648 + type: integer mix_vol: maximum: 2147483647 minimum: -2147483648 @@ -7807,8 +7801,7 @@ liquid_handler.prcxi: mix_liquid_height: 0.0 mix_rate: 0 mix_stage: '' - mix_times: - - 0 + mix_times: 0 mix_vol: 0 none_keys: - '' @@ -7937,11 +7930,9 @@ liquid_handler.prcxi: mix_stage: type: string mix_times: - items: - maximum: 2147483647 - minimum: -2147483648 - type: integer - type: array + maximum: 2147483647 + minimum: -2147483648 + type: integer mix_vol: maximum: 2147483647 minimum: -2147483648 diff --git a/unilabos_msgs/action/LiquidHandlerTransfer.action b/unilabos_msgs/action/LiquidHandlerTransfer.action index 6130f20c..971fcba6 100644 --- a/unilabos_msgs/action/LiquidHandlerTransfer.action +++ b/unilabos_msgs/action/LiquidHandlerTransfer.action @@ -13,7 +13,7 @@ float64[] blow_out_air_volume string spread bool is_96_well string mix_stage -int32[] mix_times +int32 mix_times int32 mix_vol int32 mix_rate float64 mix_liquid_height