opentrons 8.3.0a1__py2.py3-none-any.whl → 8.3.0a4__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of opentrons might be problematic. Click here for more details.
- opentrons/hardware_control/api.py +5 -1
- opentrons/hardware_control/ot3api.py +18 -8
- opentrons/hardware_control/protocols/liquid_handler.py +4 -1
- opentrons/hardware_control/protocols/motion_controller.py +1 -0
- opentrons/legacy_commands/commands.py +37 -0
- opentrons/legacy_commands/types.py +39 -0
- opentrons/protocol_api/core/engine/instrument.py +109 -0
- opentrons/protocol_api/core/instrument.py +27 -0
- opentrons/protocol_api/core/legacy/legacy_instrument_core.py +50 -0
- opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py +24 -0
- opentrons/protocol_api/instrument_context.py +141 -0
- opentrons/protocol_engine/commands/__init__.py +40 -0
- opentrons/protocol_engine/commands/absorbance_reader/close_lid.py +1 -1
- opentrons/protocol_engine/commands/absorbance_reader/initialize.py +1 -1
- opentrons/protocol_engine/commands/absorbance_reader/open_lid.py +1 -1
- opentrons/protocol_engine/commands/absorbance_reader/read.py +4 -1
- opentrons/protocol_engine/commands/air_gap_in_place.py +1 -1
- opentrons/protocol_engine/commands/command_unions.py +39 -0
- opentrons/protocol_engine/commands/evotip_dispense.py +156 -0
- opentrons/protocol_engine/commands/evotip_seal_pipette.py +331 -0
- opentrons/protocol_engine/commands/evotip_unseal_pipette.py +160 -0
- opentrons/protocol_engine/commands/get_next_tip.py +1 -1
- opentrons/protocol_engine/commands/liquid_probe.py +63 -12
- opentrons/protocol_engine/commands/load_labware.py +5 -0
- opentrons/protocol_engine/commands/load_lid.py +1 -1
- opentrons/protocol_engine/commands/load_lid_stack.py +1 -1
- opentrons/protocol_engine/commands/load_liquid_class.py +1 -1
- opentrons/protocol_engine/commands/move_labware.py +9 -0
- opentrons/protocol_engine/commands/robot/close_gripper_jaw.py +1 -1
- opentrons/protocol_engine/commands/robot/move_axes_relative.py +1 -1
- opentrons/protocol_engine/commands/robot/move_axes_to.py +1 -1
- opentrons/protocol_engine/commands/robot/move_to.py +1 -1
- opentrons/protocol_engine/commands/robot/open_gripper_jaw.py +1 -1
- opentrons/protocol_engine/commands/thermocycler/run_extended_profile.py +1 -1
- opentrons/protocol_engine/commands/unsafe/unsafe_blow_out_in_place.py +1 -1
- opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py +1 -1
- opentrons/protocol_engine/commands/unsafe/unsafe_engage_axes.py +1 -1
- opentrons/protocol_engine/commands/unsafe/unsafe_place_labware.py +1 -1
- opentrons/protocol_engine/commands/unsafe/unsafe_ungrip_labware.py +1 -1
- opentrons/protocol_engine/commands/unsafe/update_position_estimators.py +1 -1
- opentrons/protocol_engine/errors/__init__.py +4 -0
- opentrons/protocol_engine/errors/exceptions.py +26 -0
- opentrons/protocol_engine/execution/gantry_mover.py +5 -0
- opentrons/protocol_engine/execution/hardware_stopper.py +7 -7
- opentrons/protocol_engine/execution/tip_handler.py +30 -9
- opentrons/protocol_engine/resources/labware_validation.py +13 -0
- opentrons/protocol_engine/state/commands.py +6 -2
- opentrons/protocol_engine/state/frustum_helpers.py +13 -44
- opentrons/protocol_engine/state/labware.py +13 -1
- opentrons/protocol_engine/state/pipettes.py +5 -0
- opentrons/protocols/labware.py +37 -8
- opentrons/util/entrypoint_util.py +2 -5
- {opentrons-8.3.0a1.dist-info → opentrons-8.3.0a4.dist-info}/METADATA +4 -4
- {opentrons-8.3.0a1.dist-info → opentrons-8.3.0a4.dist-info}/RECORD +58 -55
- {opentrons-8.3.0a1.dist-info → opentrons-8.3.0a4.dist-info}/LICENSE +0 -0
- {opentrons-8.3.0a1.dist-info → opentrons-8.3.0a4.dist-info}/WHEEL +0 -0
- {opentrons-8.3.0a1.dist-info → opentrons-8.3.0a4.dist-info}/entry_points.txt +0 -0
- {opentrons-8.3.0a1.dist-info → opentrons-8.3.0a4.dist-info}/top_level.txt +0 -0
|
@@ -778,6 +778,7 @@ class API(
|
|
|
778
778
|
position: Mapping[Axis, float],
|
|
779
779
|
speed: Optional[float] = None,
|
|
780
780
|
max_speeds: Optional[Dict[Axis, float]] = None,
|
|
781
|
+
expect_stalls: bool = False,
|
|
781
782
|
) -> None:
|
|
782
783
|
"""Moves the effectors of the specified axis to the specified position.
|
|
783
784
|
The effector of the x,y axis is the center of the carriage.
|
|
@@ -1248,7 +1249,10 @@ class API(
|
|
|
1248
1249
|
await self.prepare_for_aspirate(mount)
|
|
1249
1250
|
|
|
1250
1251
|
async def tip_drop_moves(
|
|
1251
|
-
self,
|
|
1252
|
+
self,
|
|
1253
|
+
mount: top_types.Mount,
|
|
1254
|
+
home_after: bool = True,
|
|
1255
|
+
ignore_plunger: bool = False,
|
|
1252
1256
|
) -> None:
|
|
1253
1257
|
spec, _ = self.plan_check_drop_tip(mount, home_after)
|
|
1254
1258
|
|
|
@@ -1189,7 +1189,7 @@ class OT3API(
|
|
|
1189
1189
|
speed: Optional[float] = None,
|
|
1190
1190
|
critical_point: Optional[CriticalPoint] = None,
|
|
1191
1191
|
max_speeds: Union[None, Dict[Axis, float], OT3AxisMap[float]] = None,
|
|
1192
|
-
|
|
1192
|
+
expect_stalls: bool = False,
|
|
1193
1193
|
) -> None:
|
|
1194
1194
|
"""Move the critical point of the specified mount to a location
|
|
1195
1195
|
relative to the deck, at the specified speed."""
|
|
@@ -1233,7 +1233,7 @@ class OT3API(
|
|
|
1233
1233
|
target_position,
|
|
1234
1234
|
speed=speed,
|
|
1235
1235
|
max_speeds=checked_max,
|
|
1236
|
-
expect_stalls=
|
|
1236
|
+
expect_stalls=expect_stalls,
|
|
1237
1237
|
)
|
|
1238
1238
|
|
|
1239
1239
|
async def move_axes( # noqa: C901
|
|
@@ -1241,6 +1241,7 @@ class OT3API(
|
|
|
1241
1241
|
position: Mapping[Axis, float],
|
|
1242
1242
|
speed: Optional[float] = None,
|
|
1243
1243
|
max_speeds: Optional[Dict[Axis, float]] = None,
|
|
1244
|
+
expect_stalls: bool = False,
|
|
1244
1245
|
) -> None:
|
|
1245
1246
|
"""Moves the effectors of the specified axis to the specified position.
|
|
1246
1247
|
The effector of the x,y axis is the center of the carriage.
|
|
@@ -1296,7 +1297,11 @@ class OT3API(
|
|
|
1296
1297
|
if axis not in absolute_positions:
|
|
1297
1298
|
absolute_positions[axis] = position_value
|
|
1298
1299
|
|
|
1299
|
-
await self._move(
|
|
1300
|
+
await self._move(
|
|
1301
|
+
target_position=absolute_positions,
|
|
1302
|
+
speed=speed,
|
|
1303
|
+
expect_stalls=expect_stalls,
|
|
1304
|
+
)
|
|
1300
1305
|
|
|
1301
1306
|
async def move_rel(
|
|
1302
1307
|
self,
|
|
@@ -1306,7 +1311,7 @@ class OT3API(
|
|
|
1306
1311
|
max_speeds: Union[None, Dict[Axis, float], OT3AxisMap[float]] = None,
|
|
1307
1312
|
check_bounds: MotionChecks = MotionChecks.NONE,
|
|
1308
1313
|
fail_on_not_homed: bool = False,
|
|
1309
|
-
|
|
1314
|
+
expect_stalls: bool = False,
|
|
1310
1315
|
) -> None:
|
|
1311
1316
|
"""Move the critical point of the specified mount by a specified
|
|
1312
1317
|
displacement in a specified direction, at the specified speed."""
|
|
@@ -1348,7 +1353,7 @@ class OT3API(
|
|
|
1348
1353
|
speed=speed,
|
|
1349
1354
|
max_speeds=checked_max,
|
|
1350
1355
|
check_bounds=check_bounds,
|
|
1351
|
-
expect_stalls=
|
|
1356
|
+
expect_stalls=expect_stalls,
|
|
1352
1357
|
)
|
|
1353
1358
|
|
|
1354
1359
|
async def _cache_and_maybe_retract_mount(self, mount: OT3Mount) -> None:
|
|
@@ -2320,11 +2325,16 @@ class OT3API(
|
|
|
2320
2325
|
instrument.working_volume = tip_volume
|
|
2321
2326
|
|
|
2322
2327
|
async def tip_drop_moves(
|
|
2323
|
-
self,
|
|
2328
|
+
self,
|
|
2329
|
+
mount: Union[top_types.Mount, OT3Mount],
|
|
2330
|
+
home_after: bool = False,
|
|
2331
|
+
ignore_plunger: bool = False,
|
|
2324
2332
|
) -> None:
|
|
2325
2333
|
realmount = OT3Mount.from_mount(mount)
|
|
2326
|
-
|
|
2327
|
-
|
|
2334
|
+
if ignore_plunger is False:
|
|
2335
|
+
await self._move_to_plunger_bottom(
|
|
2336
|
+
realmount, rate=1.0, check_current_vol=False
|
|
2337
|
+
)
|
|
2328
2338
|
|
|
2329
2339
|
if self.gantry_load == GantryLoad.HIGH_THROUGHPUT:
|
|
2330
2340
|
spec = self._pipette_handler.plan_ht_drop_tip()
|
|
@@ -171,6 +171,7 @@ class MotionController(Protocol[MountArgType]):
|
|
|
171
171
|
position: Mapping[Axis, float],
|
|
172
172
|
speed: Optional[float] = None,
|
|
173
173
|
max_speeds: Optional[Dict[Axis, float]] = None,
|
|
174
|
+
expect_stalls: bool = False,
|
|
174
175
|
) -> None:
|
|
175
176
|
"""Moves the effectors of the specified axis to the specified position.
|
|
176
177
|
The effector of the x,y axis is the center of the carriage.
|
|
@@ -299,3 +299,40 @@ def move_to_disposal_location(
|
|
|
299
299
|
"name": command_types.MOVE_TO_DISPOSAL_LOCATION,
|
|
300
300
|
"payload": {"instrument": instrument, "location": location, "text": text},
|
|
301
301
|
}
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
def seal(
|
|
305
|
+
instrument: InstrumentContext,
|
|
306
|
+
location: Well,
|
|
307
|
+
) -> command_types.SealCommand:
|
|
308
|
+
location_text = stringify_location(location)
|
|
309
|
+
text = f"Sealing to {location_text}"
|
|
310
|
+
return {
|
|
311
|
+
"name": command_types.SEAL,
|
|
312
|
+
"payload": {"instrument": instrument, "location": location, "text": text},
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
def unseal(
|
|
317
|
+
instrument: InstrumentContext,
|
|
318
|
+
location: Well,
|
|
319
|
+
) -> command_types.UnsealCommand:
|
|
320
|
+
location_text = stringify_location(location)
|
|
321
|
+
text = f"Unsealing from {location_text}"
|
|
322
|
+
return {
|
|
323
|
+
"name": command_types.UNSEAL,
|
|
324
|
+
"payload": {"instrument": instrument, "location": location, "text": text},
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
def resin_tip_dispense(
|
|
329
|
+
instrument: InstrumentContext,
|
|
330
|
+
flow_rate: float | None,
|
|
331
|
+
) -> command_types.PressurizeCommand:
|
|
332
|
+
if flow_rate is None:
|
|
333
|
+
flow_rate = 10 # The Protocol Engine default for Resin Tip Dispense
|
|
334
|
+
text = f"Pressurize pipette to dispense from resin tip at {flow_rate}uL/s."
|
|
335
|
+
return {
|
|
336
|
+
"name": command_types.PRESSURIZE,
|
|
337
|
+
"payload": {"instrument": instrument, "text": text},
|
|
338
|
+
}
|
|
@@ -43,6 +43,10 @@ TOUCH_TIP: Final = "command.TOUCH_TIP"
|
|
|
43
43
|
RETURN_TIP: Final = "command.RETURN_TIP"
|
|
44
44
|
MOVE_TO: Final = "command.MOVE_TO"
|
|
45
45
|
MOVE_TO_DISPOSAL_LOCATION: Final = "command.MOVE_TO_DISPOSAL_LOCATION"
|
|
46
|
+
SEAL: Final = "command.SEAL"
|
|
47
|
+
UNSEAL: Final = "command.UNSEAL"
|
|
48
|
+
PRESSURIZE: Final = "command.PRESSURIZE"
|
|
49
|
+
|
|
46
50
|
|
|
47
51
|
# Modules #
|
|
48
52
|
|
|
@@ -535,11 +539,40 @@ class MoveLabwareCommandPayload(TextOnlyPayload):
|
|
|
535
539
|
pass
|
|
536
540
|
|
|
537
541
|
|
|
542
|
+
class SealCommandPayload(TextOnlyPayload):
|
|
543
|
+
instrument: InstrumentContext
|
|
544
|
+
location: Union[None, Location, Well]
|
|
545
|
+
|
|
546
|
+
|
|
547
|
+
class UnsealCommandPayload(TextOnlyPayload):
|
|
548
|
+
instrument: InstrumentContext
|
|
549
|
+
location: Union[None, Location, Well]
|
|
550
|
+
|
|
551
|
+
|
|
552
|
+
class PressurizeCommandPayload(TextOnlyPayload):
|
|
553
|
+
instrument: InstrumentContext
|
|
554
|
+
|
|
555
|
+
|
|
538
556
|
class MoveLabwareCommand(TypedDict):
|
|
539
557
|
name: Literal["command.MOVE_LABWARE"]
|
|
540
558
|
payload: MoveLabwareCommandPayload
|
|
541
559
|
|
|
542
560
|
|
|
561
|
+
class SealCommand(TypedDict):
|
|
562
|
+
name: Literal["command.SEAL"]
|
|
563
|
+
payload: SealCommandPayload
|
|
564
|
+
|
|
565
|
+
|
|
566
|
+
class UnsealCommand(TypedDict):
|
|
567
|
+
name: Literal["command.UNSEAL"]
|
|
568
|
+
payload: UnsealCommandPayload
|
|
569
|
+
|
|
570
|
+
|
|
571
|
+
class PressurizeCommand(TypedDict):
|
|
572
|
+
name: Literal["command.PRESSURIZE"]
|
|
573
|
+
payload: PressurizeCommandPayload
|
|
574
|
+
|
|
575
|
+
|
|
543
576
|
Command = Union[
|
|
544
577
|
DropTipCommand,
|
|
545
578
|
DropTipInDisposalLocationCommand,
|
|
@@ -588,6 +621,9 @@ Command = Union[
|
|
|
588
621
|
MoveToCommand,
|
|
589
622
|
MoveToDisposalLocationCommand,
|
|
590
623
|
MoveLabwareCommand,
|
|
624
|
+
SealCommand,
|
|
625
|
+
UnsealCommand,
|
|
626
|
+
PressurizeCommand,
|
|
591
627
|
]
|
|
592
628
|
|
|
593
629
|
|
|
@@ -637,6 +673,9 @@ CommandPayload = Union[
|
|
|
637
673
|
MoveToCommandPayload,
|
|
638
674
|
MoveToDisposalLocationCommandPayload,
|
|
639
675
|
MoveLabwareCommandPayload,
|
|
676
|
+
SealCommandPayload,
|
|
677
|
+
UnsealCommandPayload,
|
|
678
|
+
PressurizeCommandPayload,
|
|
640
679
|
]
|
|
641
680
|
|
|
642
681
|
|
|
@@ -48,6 +48,8 @@ if TYPE_CHECKING:
|
|
|
48
48
|
from opentrons.protocol_api._liquid import LiquidClass
|
|
49
49
|
|
|
50
50
|
_DISPENSE_VOLUME_VALIDATION_ADDED_IN = APIVersion(2, 17)
|
|
51
|
+
_RESIN_TIP_DEFAULT_VOLUME = 400
|
|
52
|
+
_RESIN_TIP_DEFAULT_FLOW_RATE = 10.0
|
|
51
53
|
|
|
52
54
|
|
|
53
55
|
class InstrumentCore(AbstractInstrument[WellCore]):
|
|
@@ -678,6 +680,113 @@ class InstrumentCore(AbstractInstrument[WellCore]):
|
|
|
678
680
|
location=location, mount=self.get_mount()
|
|
679
681
|
)
|
|
680
682
|
|
|
683
|
+
def resin_tip_seal(
|
|
684
|
+
self, location: Location, well_core: WellCore, in_place: Optional[bool] = False
|
|
685
|
+
) -> None:
|
|
686
|
+
labware_id = well_core.labware_id
|
|
687
|
+
well_name = well_core.get_name()
|
|
688
|
+
well_location = (
|
|
689
|
+
self._engine_client.state.geometry.get_relative_pick_up_tip_well_location(
|
|
690
|
+
labware_id=labware_id,
|
|
691
|
+
well_name=well_name,
|
|
692
|
+
absolute_point=location.point,
|
|
693
|
+
)
|
|
694
|
+
)
|
|
695
|
+
|
|
696
|
+
self._engine_client.execute_command(
|
|
697
|
+
cmd.EvotipSealPipetteParams(
|
|
698
|
+
pipetteId=self._pipette_id,
|
|
699
|
+
labwareId=labware_id,
|
|
700
|
+
wellName=well_name,
|
|
701
|
+
wellLocation=well_location,
|
|
702
|
+
)
|
|
703
|
+
)
|
|
704
|
+
|
|
705
|
+
def resin_tip_unseal(self, location: Location, well_core: WellCore) -> None:
|
|
706
|
+
well_name = well_core.get_name()
|
|
707
|
+
labware_id = well_core.labware_id
|
|
708
|
+
|
|
709
|
+
if location is not None:
|
|
710
|
+
relative_well_location = (
|
|
711
|
+
self._engine_client.state.geometry.get_relative_well_location(
|
|
712
|
+
labware_id=labware_id,
|
|
713
|
+
well_name=well_name,
|
|
714
|
+
absolute_point=location.point,
|
|
715
|
+
)
|
|
716
|
+
)
|
|
717
|
+
|
|
718
|
+
well_location = DropTipWellLocation(
|
|
719
|
+
origin=DropTipWellOrigin(relative_well_location.origin.value),
|
|
720
|
+
offset=relative_well_location.offset,
|
|
721
|
+
)
|
|
722
|
+
else:
|
|
723
|
+
well_location = DropTipWellLocation()
|
|
724
|
+
|
|
725
|
+
pipette_movement_conflict.check_safe_for_pipette_movement(
|
|
726
|
+
engine_state=self._engine_client.state,
|
|
727
|
+
pipette_id=self._pipette_id,
|
|
728
|
+
labware_id=labware_id,
|
|
729
|
+
well_name=well_name,
|
|
730
|
+
well_location=well_location,
|
|
731
|
+
)
|
|
732
|
+
self._engine_client.execute_command(
|
|
733
|
+
cmd.EvotipUnsealPipetteParams(
|
|
734
|
+
pipetteId=self._pipette_id,
|
|
735
|
+
labwareId=labware_id,
|
|
736
|
+
wellName=well_name,
|
|
737
|
+
wellLocation=well_location,
|
|
738
|
+
)
|
|
739
|
+
)
|
|
740
|
+
|
|
741
|
+
self._protocol_core.set_last_location(location=location, mount=self.get_mount())
|
|
742
|
+
|
|
743
|
+
def resin_tip_dispense(
|
|
744
|
+
self,
|
|
745
|
+
location: Location,
|
|
746
|
+
well_core: WellCore,
|
|
747
|
+
volume: Optional[float] = None,
|
|
748
|
+
flow_rate: Optional[float] = None,
|
|
749
|
+
) -> None:
|
|
750
|
+
"""
|
|
751
|
+
Args:
|
|
752
|
+
volume: The volume of liquid to dispense, in microliters. Defaults to 400uL.
|
|
753
|
+
location: The exact location to dispense to.
|
|
754
|
+
well_core: The well to dispense to, if applicable.
|
|
755
|
+
flow_rate: The flow rate in µL/s to dispense at. Defaults to 10.0uL/S.
|
|
756
|
+
"""
|
|
757
|
+
if isinstance(location, (TrashBin, WasteChute)):
|
|
758
|
+
raise ValueError("Trash Bin and Waste Chute have no Wells.")
|
|
759
|
+
well_name = well_core.get_name()
|
|
760
|
+
labware_id = well_core.labware_id
|
|
761
|
+
if volume is None:
|
|
762
|
+
volume = _RESIN_TIP_DEFAULT_VOLUME
|
|
763
|
+
if flow_rate is None:
|
|
764
|
+
flow_rate = _RESIN_TIP_DEFAULT_FLOW_RATE
|
|
765
|
+
|
|
766
|
+
well_location = self._engine_client.state.geometry.get_relative_liquid_handling_well_location(
|
|
767
|
+
labware_id=labware_id,
|
|
768
|
+
well_name=well_name,
|
|
769
|
+
absolute_point=location.point,
|
|
770
|
+
is_meniscus=None,
|
|
771
|
+
)
|
|
772
|
+
pipette_movement_conflict.check_safe_for_pipette_movement(
|
|
773
|
+
engine_state=self._engine_client.state,
|
|
774
|
+
pipette_id=self._pipette_id,
|
|
775
|
+
labware_id=labware_id,
|
|
776
|
+
well_name=well_name,
|
|
777
|
+
well_location=well_location,
|
|
778
|
+
)
|
|
779
|
+
self._engine_client.execute_command(
|
|
780
|
+
cmd.EvotipDispenseParams(
|
|
781
|
+
pipetteId=self._pipette_id,
|
|
782
|
+
labwareId=labware_id,
|
|
783
|
+
wellName=well_name,
|
|
784
|
+
wellLocation=well_location,
|
|
785
|
+
volume=volume,
|
|
786
|
+
flowRate=flow_rate,
|
|
787
|
+
)
|
|
788
|
+
)
|
|
789
|
+
|
|
681
790
|
def get_mount(self) -> Mount:
|
|
682
791
|
"""Get the mount the pipette is attached to."""
|
|
683
792
|
return self._engine_client.state.pipettes.get(
|
|
@@ -180,6 +180,33 @@ class AbstractInstrument(ABC, Generic[WellCoreType]):
|
|
|
180
180
|
) -> None:
|
|
181
181
|
...
|
|
182
182
|
|
|
183
|
+
@abstractmethod
|
|
184
|
+
def resin_tip_seal(
|
|
185
|
+
self,
|
|
186
|
+
location: types.Location,
|
|
187
|
+
well_core: WellCoreType,
|
|
188
|
+
in_place: Optional[bool] = False,
|
|
189
|
+
) -> None:
|
|
190
|
+
...
|
|
191
|
+
|
|
192
|
+
@abstractmethod
|
|
193
|
+
def resin_tip_unseal(
|
|
194
|
+
self,
|
|
195
|
+
location: types.Location,
|
|
196
|
+
well_core: WellCoreType,
|
|
197
|
+
) -> None:
|
|
198
|
+
...
|
|
199
|
+
|
|
200
|
+
@abstractmethod
|
|
201
|
+
def resin_tip_dispense(
|
|
202
|
+
self,
|
|
203
|
+
location: types.Location,
|
|
204
|
+
well_core: WellCoreType,
|
|
205
|
+
volume: Optional[float] = None,
|
|
206
|
+
flow_rate: Optional[float] = None,
|
|
207
|
+
) -> None:
|
|
208
|
+
...
|
|
209
|
+
|
|
183
210
|
@abstractmethod
|
|
184
211
|
def get_mount(self) -> types.Mount:
|
|
185
212
|
...
|
|
@@ -308,6 +308,30 @@ class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore]):
|
|
|
308
308
|
) -> None:
|
|
309
309
|
raise APIVersionError(api_element="Dropping tips in a trash bin or waste chute")
|
|
310
310
|
|
|
311
|
+
def resin_tip_seal(
|
|
312
|
+
self,
|
|
313
|
+
location: types.Location,
|
|
314
|
+
well_core: WellCore,
|
|
315
|
+
in_place: Optional[bool] = False,
|
|
316
|
+
) -> None:
|
|
317
|
+
raise APIVersionError(api_element="Sealing resin tips.")
|
|
318
|
+
|
|
319
|
+
def resin_tip_unseal(
|
|
320
|
+
self,
|
|
321
|
+
location: types.Location,
|
|
322
|
+
well_core: WellCore,
|
|
323
|
+
) -> None:
|
|
324
|
+
raise APIVersionError(api_element="Unsealing resin tips.")
|
|
325
|
+
|
|
326
|
+
def resin_tip_dispense(
|
|
327
|
+
self,
|
|
328
|
+
location: types.Location,
|
|
329
|
+
well_core: WellCore,
|
|
330
|
+
volume: Optional[float] = None,
|
|
331
|
+
flow_rate: Optional[float] = None,
|
|
332
|
+
) -> None:
|
|
333
|
+
raise APIVersionError(api_element="Dispensing liquid from resin tips.")
|
|
334
|
+
|
|
311
335
|
def home(self) -> None:
|
|
312
336
|
"""Home the mount"""
|
|
313
337
|
self._protocol_interface.get_hardware().home_z(
|
|
@@ -400,6 +424,32 @@ class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore]):
|
|
|
400
424
|
location=location, mount=location_cache_mount
|
|
401
425
|
)
|
|
402
426
|
|
|
427
|
+
def evotip_seal(
|
|
428
|
+
self,
|
|
429
|
+
location: types.Location,
|
|
430
|
+
well_core: LegacyWellCore,
|
|
431
|
+
in_place: Optional[bool] = False,
|
|
432
|
+
) -> None:
|
|
433
|
+
"""This will never be called because it was added in API 2.22."""
|
|
434
|
+
assert False, "evotip_seal only supported in API 2.22 & later"
|
|
435
|
+
|
|
436
|
+
def evotip_unseal(
|
|
437
|
+
self, location: types.Location, well_core: WellCore, home_after: Optional[bool]
|
|
438
|
+
) -> None:
|
|
439
|
+
"""This will never be called because it was added in API 2.22."""
|
|
440
|
+
assert False, "evotip_unseal only supported in API 2.22 & later"
|
|
441
|
+
|
|
442
|
+
def evotip_dispense(
|
|
443
|
+
self,
|
|
444
|
+
location: types.Location,
|
|
445
|
+
well_core: WellCore,
|
|
446
|
+
volume: Optional[float] = None,
|
|
447
|
+
flow_rate: Optional[float] = None,
|
|
448
|
+
push_out: Optional[float] = None,
|
|
449
|
+
) -> None:
|
|
450
|
+
"""This will never be called because it was added in API 2.22."""
|
|
451
|
+
assert False, "evotip_dispense only supported in API 2.22 & later"
|
|
452
|
+
|
|
403
453
|
def get_mount(self) -> types.Mount:
|
|
404
454
|
"""Get the mount this pipette is attached to."""
|
|
405
455
|
return self._mount
|
|
@@ -276,6 +276,30 @@ class LegacyInstrumentCoreSimulator(AbstractInstrument[LegacyWellCore]):
|
|
|
276
276
|
) -> None:
|
|
277
277
|
raise APIVersionError(api_element="Dropping tips in a trash bin or waste chute")
|
|
278
278
|
|
|
279
|
+
def resin_tip_seal(
|
|
280
|
+
self,
|
|
281
|
+
location: types.Location,
|
|
282
|
+
well_core: WellCore,
|
|
283
|
+
in_place: Optional[bool] = False,
|
|
284
|
+
) -> None:
|
|
285
|
+
raise APIVersionError(api_element="Sealing resin tips.")
|
|
286
|
+
|
|
287
|
+
def resin_tip_unseal(
|
|
288
|
+
self,
|
|
289
|
+
location: types.Location,
|
|
290
|
+
well_core: WellCore,
|
|
291
|
+
) -> None:
|
|
292
|
+
raise APIVersionError(api_element="Unsealing resin tips.")
|
|
293
|
+
|
|
294
|
+
def resin_tip_dispense(
|
|
295
|
+
self,
|
|
296
|
+
location: types.Location,
|
|
297
|
+
well_core: WellCore,
|
|
298
|
+
volume: Optional[float] = None,
|
|
299
|
+
flow_rate: Optional[float] = None,
|
|
300
|
+
) -> None:
|
|
301
|
+
raise APIVersionError(api_element="Dispensing liquid from resin tips.")
|
|
302
|
+
|
|
279
303
|
def home(self) -> None:
|
|
280
304
|
self._protocol_interface.set_last_location(None)
|
|
281
305
|
|
|
@@ -1712,6 +1712,147 @@ class InstrumentContext(publisher.CommandPublisher):
|
|
|
1712
1712
|
|
|
1713
1713
|
return self
|
|
1714
1714
|
|
|
1715
|
+
@requires_version(2, 22)
|
|
1716
|
+
def resin_tip_seal(
|
|
1717
|
+
self,
|
|
1718
|
+
location: Union[labware.Well, labware.Labware],
|
|
1719
|
+
) -> InstrumentContext:
|
|
1720
|
+
"""Seal resin tips onto the pipette.
|
|
1721
|
+
|
|
1722
|
+
The location provided should contain resin tips. Sealing the
|
|
1723
|
+
tip will perform a `pick up` action but there will be no tip tracking
|
|
1724
|
+
associated with the pipette.
|
|
1725
|
+
|
|
1726
|
+
:param location: A location containing resin tips, must be a Labware or a Well.
|
|
1727
|
+
|
|
1728
|
+
:type location: :py:class:`~.types.Location`
|
|
1729
|
+
"""
|
|
1730
|
+
if isinstance(location, labware.Labware):
|
|
1731
|
+
well = location.wells()[0]
|
|
1732
|
+
else:
|
|
1733
|
+
well = location
|
|
1734
|
+
|
|
1735
|
+
with publisher.publish_context(
|
|
1736
|
+
broker=self.broker,
|
|
1737
|
+
command=cmds.seal(
|
|
1738
|
+
instrument=self,
|
|
1739
|
+
location=well,
|
|
1740
|
+
),
|
|
1741
|
+
):
|
|
1742
|
+
self._core.resin_tip_seal(
|
|
1743
|
+
location=well.top(), well_core=well._core, in_place=False
|
|
1744
|
+
)
|
|
1745
|
+
return self
|
|
1746
|
+
|
|
1747
|
+
@requires_version(2, 22)
|
|
1748
|
+
def resin_tip_unseal(
|
|
1749
|
+
self,
|
|
1750
|
+
location: Union[labware.Well, labware.Labware],
|
|
1751
|
+
) -> InstrumentContext:
|
|
1752
|
+
"""Release resin tips from the pipette.
|
|
1753
|
+
|
|
1754
|
+
The location provided should be a valid location to drop resin tips.
|
|
1755
|
+
|
|
1756
|
+
:param location: A location containing that can accept tips.
|
|
1757
|
+
|
|
1758
|
+
:type location: :py:class:`~.types.Location`
|
|
1759
|
+
|
|
1760
|
+
:param home_after:
|
|
1761
|
+
Whether to home the pipette after dropping the tip. If not specified
|
|
1762
|
+
defaults to ``True`` on a Flex. The plunger will not home on an unseal.
|
|
1763
|
+
|
|
1764
|
+
When ``False``, the pipette does not home its plunger. This can save a few
|
|
1765
|
+
seconds, but is not recommended. Homing helps the robot track the pipette's
|
|
1766
|
+
position.
|
|
1767
|
+
|
|
1768
|
+
"""
|
|
1769
|
+
if isinstance(location, labware.Labware):
|
|
1770
|
+
well = location.wells()[0]
|
|
1771
|
+
else:
|
|
1772
|
+
well = location
|
|
1773
|
+
|
|
1774
|
+
with publisher.publish_context(
|
|
1775
|
+
broker=self.broker,
|
|
1776
|
+
command=cmds.unseal(
|
|
1777
|
+
instrument=self,
|
|
1778
|
+
location=well,
|
|
1779
|
+
),
|
|
1780
|
+
):
|
|
1781
|
+
self._core.resin_tip_unseal(location=well.top(), well_core=well._core)
|
|
1782
|
+
|
|
1783
|
+
return self
|
|
1784
|
+
|
|
1785
|
+
@requires_version(2, 22)
|
|
1786
|
+
def resin_tip_dispense(
|
|
1787
|
+
self,
|
|
1788
|
+
location: types.Location,
|
|
1789
|
+
volume: Optional[float] = None,
|
|
1790
|
+
rate: Optional[float] = None,
|
|
1791
|
+
) -> InstrumentContext:
|
|
1792
|
+
"""Dispense a volume from resin tips into a labware.
|
|
1793
|
+
|
|
1794
|
+
The location provided should contain resin tips labware as well as a
|
|
1795
|
+
receptical for dispensed liquid. Dispensing from tip will perform a
|
|
1796
|
+
`dispense` action of the specified volume at a desired flow rate.
|
|
1797
|
+
|
|
1798
|
+
:param location: A location containing resin tips.
|
|
1799
|
+
:type location: :py:class:`~.types.Location`
|
|
1800
|
+
|
|
1801
|
+
:param volume: Will default to maximum, recommended to use the default.
|
|
1802
|
+
The volume, in µL, that the pipette will prepare to handle.
|
|
1803
|
+
:type volume: float
|
|
1804
|
+
|
|
1805
|
+
:param rate: Will default to 10.0, recommended to use the default. How quickly
|
|
1806
|
+
a pipette dispenses liquid. The speed in µL/s is calculated as
|
|
1807
|
+
``rate`` multiplied by :py:attr:`flow_rate.dispense<flow_rate>`.
|
|
1808
|
+
:type rate: float
|
|
1809
|
+
|
|
1810
|
+
"""
|
|
1811
|
+
well: Optional[labware.Well] = None
|
|
1812
|
+
last_location = self._get_last_location_by_api_version()
|
|
1813
|
+
|
|
1814
|
+
try:
|
|
1815
|
+
target = validation.validate_location(
|
|
1816
|
+
location=location, last_location=last_location
|
|
1817
|
+
)
|
|
1818
|
+
except validation.NoLocationError as e:
|
|
1819
|
+
raise RuntimeError(
|
|
1820
|
+
"If dispense is called without an explicit location, another"
|
|
1821
|
+
" method that moves to a location (such as move_to or "
|
|
1822
|
+
"aspirate) must previously have been called so the robot "
|
|
1823
|
+
"knows where it is."
|
|
1824
|
+
) from e
|
|
1825
|
+
|
|
1826
|
+
if isinstance(target, validation.WellTarget):
|
|
1827
|
+
well = target.well
|
|
1828
|
+
if target.location:
|
|
1829
|
+
move_to_location = target.location
|
|
1830
|
+
elif well.parent._core.is_fixed_trash():
|
|
1831
|
+
move_to_location = target.well.top()
|
|
1832
|
+
else:
|
|
1833
|
+
move_to_location = target.well.bottom(
|
|
1834
|
+
z=self._well_bottom_clearances.dispense
|
|
1835
|
+
)
|
|
1836
|
+
else:
|
|
1837
|
+
raise RuntimeError(
|
|
1838
|
+
"A well must be specified when using `resin_tip_dispense`."
|
|
1839
|
+
)
|
|
1840
|
+
|
|
1841
|
+
with publisher.publish_context(
|
|
1842
|
+
broker=self.broker,
|
|
1843
|
+
command=cmds.resin_tip_dispense(
|
|
1844
|
+
instrument=self,
|
|
1845
|
+
flow_rate=rate,
|
|
1846
|
+
),
|
|
1847
|
+
):
|
|
1848
|
+
self._core.resin_tip_dispense(
|
|
1849
|
+
move_to_location,
|
|
1850
|
+
well_core=well._core,
|
|
1851
|
+
volume=volume,
|
|
1852
|
+
flow_rate=rate,
|
|
1853
|
+
)
|
|
1854
|
+
return self
|
|
1855
|
+
|
|
1715
1856
|
@requires_version(2, 18)
|
|
1716
1857
|
def _retract(
|
|
1717
1858
|
self,
|
|
@@ -380,6 +380,28 @@ from .liquid_probe import (
|
|
|
380
380
|
TryLiquidProbeCommandType,
|
|
381
381
|
)
|
|
382
382
|
|
|
383
|
+
from .evotip_seal_pipette import (
|
|
384
|
+
EvotipSealPipette,
|
|
385
|
+
EvotipSealPipetteParams,
|
|
386
|
+
EvotipSealPipetteCreate,
|
|
387
|
+
EvotipSealPipetteResult,
|
|
388
|
+
EvotipSealPipetteCommandType,
|
|
389
|
+
)
|
|
390
|
+
from .evotip_unseal_pipette import (
|
|
391
|
+
EvotipUnsealPipette,
|
|
392
|
+
EvotipUnsealPipetteParams,
|
|
393
|
+
EvotipUnsealPipetteCreate,
|
|
394
|
+
EvotipUnsealPipetteResult,
|
|
395
|
+
EvotipUnsealPipetteCommandType,
|
|
396
|
+
)
|
|
397
|
+
from .evotip_dispense import (
|
|
398
|
+
EvotipDispense,
|
|
399
|
+
EvotipDispenseParams,
|
|
400
|
+
EvotipDispenseCreate,
|
|
401
|
+
EvotipDispenseResult,
|
|
402
|
+
EvotipDispenseCommandType,
|
|
403
|
+
)
|
|
404
|
+
|
|
383
405
|
__all__ = [
|
|
384
406
|
# command type unions
|
|
385
407
|
"Command",
|
|
@@ -670,4 +692,22 @@ __all__ = [
|
|
|
670
692
|
"TryLiquidProbeCreate",
|
|
671
693
|
"TryLiquidProbeResult",
|
|
672
694
|
"TryLiquidProbeCommandType",
|
|
695
|
+
# evotip seal command bundle
|
|
696
|
+
"EvotipSealPipette",
|
|
697
|
+
"EvotipSealPipetteParams",
|
|
698
|
+
"EvotipSealPipetteCreate",
|
|
699
|
+
"EvotipSealPipetteResult",
|
|
700
|
+
"EvotipSealPipetteCommandType",
|
|
701
|
+
# evotip unseal command bundle
|
|
702
|
+
"EvotipUnsealPipette",
|
|
703
|
+
"EvotipUnsealPipetteParams",
|
|
704
|
+
"EvotipUnsealPipetteCreate",
|
|
705
|
+
"EvotipUnsealPipetteResult",
|
|
706
|
+
"EvotipUnsealPipetteCommandType",
|
|
707
|
+
# evotip dispense command bundle
|
|
708
|
+
"EvotipDispense",
|
|
709
|
+
"EvotipDispenseParams",
|
|
710
|
+
"EvotipDispenseCreate",
|
|
711
|
+
"EvotipDispenseResult",
|
|
712
|
+
"EvotipDispenseCommandType",
|
|
673
713
|
]
|
|
@@ -132,7 +132,7 @@ class CloseLid(BaseCommand[CloseLidParams, CloseLidResult, ErrorOccurrence]):
|
|
|
132
132
|
|
|
133
133
|
commandType: CloseLidCommandType = "absorbanceReader/closeLid"
|
|
134
134
|
params: CloseLidParams
|
|
135
|
-
result: Optional[CloseLidResult]
|
|
135
|
+
result: Optional[CloseLidResult] = None
|
|
136
136
|
|
|
137
137
|
_ImplementationCls: Type[CloseLidImpl] = CloseLidImpl
|
|
138
138
|
|