opentrons 8.2.0a4__py2.py3-none-any.whl → 8.3.0__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.
- opentrons/calibration_storage/deck_configuration.py +3 -3
- opentrons/calibration_storage/file_operators.py +3 -3
- opentrons/calibration_storage/helpers.py +3 -1
- opentrons/calibration_storage/ot2/models/v1.py +16 -29
- opentrons/calibration_storage/ot2/tip_length.py +7 -4
- opentrons/calibration_storage/ot3/models/v1.py +14 -23
- opentrons/cli/analyze.py +18 -6
- opentrons/config/defaults_ot3.py +1 -0
- opentrons/drivers/asyncio/communication/__init__.py +2 -0
- opentrons/drivers/asyncio/communication/errors.py +16 -3
- opentrons/drivers/asyncio/communication/serial_connection.py +24 -9
- opentrons/drivers/command_builder.py +2 -2
- opentrons/drivers/flex_stacker/__init__.py +9 -0
- opentrons/drivers/flex_stacker/abstract.py +89 -0
- opentrons/drivers/flex_stacker/driver.py +260 -0
- opentrons/drivers/flex_stacker/simulator.py +109 -0
- opentrons/drivers/flex_stacker/types.py +138 -0
- opentrons/drivers/heater_shaker/driver.py +18 -3
- opentrons/drivers/temp_deck/driver.py +13 -3
- opentrons/drivers/thermocycler/driver.py +17 -3
- opentrons/execute.py +3 -1
- opentrons/hardware_control/__init__.py +1 -2
- opentrons/hardware_control/api.py +33 -21
- opentrons/hardware_control/backends/flex_protocol.py +17 -7
- opentrons/hardware_control/backends/ot3controller.py +213 -63
- opentrons/hardware_control/backends/ot3simulator.py +18 -9
- opentrons/hardware_control/backends/ot3utils.py +43 -15
- opentrons/hardware_control/dev_types.py +4 -0
- opentrons/hardware_control/emulation/heater_shaker.py +4 -0
- opentrons/hardware_control/emulation/module_server/client.py +1 -1
- opentrons/hardware_control/emulation/module_server/server.py +5 -3
- opentrons/hardware_control/emulation/settings.py +3 -4
- opentrons/hardware_control/instruments/ot2/instrument_calibration.py +2 -1
- opentrons/hardware_control/instruments/ot2/pipette.py +15 -22
- opentrons/hardware_control/instruments/ot2/pipette_handler.py +8 -1
- opentrons/hardware_control/instruments/ot3/gripper.py +2 -2
- opentrons/hardware_control/instruments/ot3/pipette.py +23 -22
- opentrons/hardware_control/instruments/ot3/pipette_handler.py +10 -1
- opentrons/hardware_control/modules/mod_abc.py +2 -2
- opentrons/hardware_control/motion_utilities.py +68 -0
- opentrons/hardware_control/nozzle_manager.py +39 -41
- opentrons/hardware_control/ot3_calibration.py +1 -1
- opentrons/hardware_control/ot3api.py +78 -31
- opentrons/hardware_control/protocols/gripper_controller.py +3 -0
- opentrons/hardware_control/protocols/hardware_manager.py +5 -1
- opentrons/hardware_control/protocols/liquid_handler.py +22 -1
- opentrons/hardware_control/protocols/motion_controller.py +7 -0
- opentrons/hardware_control/robot_calibration.py +1 -1
- opentrons/hardware_control/types.py +61 -0
- opentrons/legacy_commands/commands.py +37 -0
- opentrons/legacy_commands/types.py +39 -0
- opentrons/protocol_api/__init__.py +20 -1
- opentrons/protocol_api/_liquid.py +24 -49
- opentrons/protocol_api/_liquid_properties.py +754 -0
- opentrons/protocol_api/_types.py +24 -0
- opentrons/protocol_api/core/common.py +2 -0
- opentrons/protocol_api/core/engine/instrument.py +191 -10
- opentrons/protocol_api/core/engine/labware.py +29 -7
- opentrons/protocol_api/core/engine/protocol.py +130 -5
- opentrons/protocol_api/core/engine/robot.py +139 -0
- opentrons/protocol_api/core/engine/well.py +4 -1
- opentrons/protocol_api/core/instrument.py +73 -4
- opentrons/protocol_api/core/labware.py +13 -4
- opentrons/protocol_api/core/legacy/legacy_instrument_core.py +87 -3
- opentrons/protocol_api/core/legacy/legacy_labware_core.py +13 -4
- opentrons/protocol_api/core/legacy/legacy_protocol_core.py +32 -1
- opentrons/protocol_api/core/legacy/legacy_robot_core.py +0 -0
- opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py +61 -3
- opentrons/protocol_api/core/protocol.py +34 -1
- opentrons/protocol_api/core/robot.py +51 -0
- opentrons/protocol_api/instrument_context.py +299 -44
- opentrons/protocol_api/labware.py +248 -9
- opentrons/protocol_api/module_contexts.py +21 -17
- opentrons/protocol_api/protocol_context.py +125 -4
- opentrons/protocol_api/robot_context.py +204 -32
- opentrons/protocol_api/validation.py +262 -3
- opentrons/protocol_engine/__init__.py +4 -0
- opentrons/protocol_engine/actions/actions.py +2 -3
- opentrons/protocol_engine/clients/sync_client.py +18 -0
- opentrons/protocol_engine/commands/__init__.py +121 -0
- opentrons/protocol_engine/commands/absorbance_reader/close_lid.py +1 -3
- opentrons/protocol_engine/commands/absorbance_reader/initialize.py +20 -6
- opentrons/protocol_engine/commands/absorbance_reader/open_lid.py +1 -2
- opentrons/protocol_engine/commands/absorbance_reader/read.py +36 -10
- opentrons/protocol_engine/commands/air_gap_in_place.py +160 -0
- opentrons/protocol_engine/commands/aspirate.py +103 -53
- opentrons/protocol_engine/commands/aspirate_in_place.py +55 -51
- opentrons/protocol_engine/commands/blow_out.py +44 -39
- opentrons/protocol_engine/commands/blow_out_in_place.py +21 -32
- opentrons/protocol_engine/commands/calibration/calibrate_gripper.py +13 -6
- opentrons/protocol_engine/commands/calibration/calibrate_module.py +1 -1
- opentrons/protocol_engine/commands/calibration/calibrate_pipette.py +3 -3
- opentrons/protocol_engine/commands/calibration/move_to_maintenance_position.py +1 -1
- opentrons/protocol_engine/commands/command.py +73 -66
- opentrons/protocol_engine/commands/command_unions.py +140 -1
- opentrons/protocol_engine/commands/comment.py +1 -1
- opentrons/protocol_engine/commands/configure_for_volume.py +10 -3
- opentrons/protocol_engine/commands/configure_nozzle_layout.py +6 -4
- opentrons/protocol_engine/commands/custom.py +6 -12
- opentrons/protocol_engine/commands/dispense.py +82 -48
- opentrons/protocol_engine/commands/dispense_in_place.py +71 -51
- opentrons/protocol_engine/commands/drop_tip.py +52 -31
- opentrons/protocol_engine/commands/drop_tip_in_place.py +79 -8
- 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/generate_command_schema.py +4 -11
- opentrons/protocol_engine/commands/get_next_tip.py +134 -0
- opentrons/protocol_engine/commands/get_tip_presence.py +1 -1
- opentrons/protocol_engine/commands/heater_shaker/close_labware_latch.py +1 -1
- opentrons/protocol_engine/commands/heater_shaker/deactivate_heater.py +1 -1
- opentrons/protocol_engine/commands/heater_shaker/deactivate_shaker.py +1 -1
- opentrons/protocol_engine/commands/heater_shaker/open_labware_latch.py +1 -1
- opentrons/protocol_engine/commands/heater_shaker/set_and_wait_for_shake_speed.py +1 -1
- opentrons/protocol_engine/commands/heater_shaker/set_target_temperature.py +1 -1
- opentrons/protocol_engine/commands/heater_shaker/wait_for_temperature.py +10 -4
- opentrons/protocol_engine/commands/home.py +13 -4
- opentrons/protocol_engine/commands/liquid_probe.py +125 -31
- opentrons/protocol_engine/commands/load_labware.py +33 -6
- opentrons/protocol_engine/commands/load_lid.py +146 -0
- opentrons/protocol_engine/commands/load_lid_stack.py +189 -0
- opentrons/protocol_engine/commands/load_liquid.py +12 -4
- opentrons/protocol_engine/commands/load_liquid_class.py +144 -0
- opentrons/protocol_engine/commands/load_module.py +31 -10
- opentrons/protocol_engine/commands/load_pipette.py +19 -8
- opentrons/protocol_engine/commands/magnetic_module/disengage.py +1 -1
- opentrons/protocol_engine/commands/magnetic_module/engage.py +1 -1
- opentrons/protocol_engine/commands/move_labware.py +28 -6
- opentrons/protocol_engine/commands/move_relative.py +35 -25
- opentrons/protocol_engine/commands/move_to_addressable_area.py +40 -27
- opentrons/protocol_engine/commands/move_to_addressable_area_for_drop_tip.py +53 -32
- opentrons/protocol_engine/commands/move_to_coordinates.py +36 -22
- opentrons/protocol_engine/commands/move_to_well.py +40 -24
- opentrons/protocol_engine/commands/movement_common.py +338 -0
- opentrons/protocol_engine/commands/pick_up_tip.py +49 -27
- opentrons/protocol_engine/commands/pipetting_common.py +169 -87
- opentrons/protocol_engine/commands/prepare_to_aspirate.py +24 -33
- opentrons/protocol_engine/commands/reload_labware.py +1 -1
- opentrons/protocol_engine/commands/retract_axis.py +1 -1
- opentrons/protocol_engine/commands/robot/__init__.py +69 -0
- opentrons/protocol_engine/commands/robot/close_gripper_jaw.py +86 -0
- opentrons/protocol_engine/commands/robot/common.py +18 -0
- opentrons/protocol_engine/commands/robot/move_axes_relative.py +101 -0
- opentrons/protocol_engine/commands/robot/move_axes_to.py +100 -0
- opentrons/protocol_engine/commands/robot/move_to.py +94 -0
- opentrons/protocol_engine/commands/robot/open_gripper_jaw.py +77 -0
- opentrons/protocol_engine/commands/save_position.py +14 -5
- opentrons/protocol_engine/commands/set_rail_lights.py +1 -1
- opentrons/protocol_engine/commands/set_status_bar.py +1 -1
- opentrons/protocol_engine/commands/temperature_module/deactivate.py +1 -1
- opentrons/protocol_engine/commands/temperature_module/set_target_temperature.py +1 -1
- opentrons/protocol_engine/commands/temperature_module/wait_for_temperature.py +10 -4
- opentrons/protocol_engine/commands/thermocycler/close_lid.py +1 -1
- opentrons/protocol_engine/commands/thermocycler/deactivate_block.py +1 -1
- opentrons/protocol_engine/commands/thermocycler/deactivate_lid.py +1 -1
- opentrons/protocol_engine/commands/thermocycler/open_lid.py +1 -1
- opentrons/protocol_engine/commands/thermocycler/run_extended_profile.py +9 -3
- opentrons/protocol_engine/commands/thermocycler/run_profile.py +9 -3
- opentrons/protocol_engine/commands/thermocycler/set_target_block_temperature.py +11 -4
- opentrons/protocol_engine/commands/thermocycler/set_target_lid_temperature.py +1 -1
- opentrons/protocol_engine/commands/thermocycler/wait_for_block_temperature.py +1 -1
- opentrons/protocol_engine/commands/thermocycler/wait_for_lid_temperature.py +1 -1
- opentrons/protocol_engine/commands/touch_tip.py +65 -16
- opentrons/protocol_engine/commands/unsafe/unsafe_blow_out_in_place.py +5 -2
- opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py +13 -4
- opentrons/protocol_engine/commands/unsafe/unsafe_engage_axes.py +2 -5
- 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 +2 -5
- opentrons/protocol_engine/commands/verify_tip_presence.py +11 -4
- opentrons/protocol_engine/commands/wait_for_duration.py +10 -3
- opentrons/protocol_engine/commands/wait_for_resume.py +10 -3
- opentrons/protocol_engine/errors/__init__.py +12 -0
- opentrons/protocol_engine/errors/error_occurrence.py +19 -20
- opentrons/protocol_engine/errors/exceptions.py +76 -0
- opentrons/protocol_engine/execution/command_executor.py +1 -1
- opentrons/protocol_engine/execution/equipment.py +73 -5
- opentrons/protocol_engine/execution/gantry_mover.py +369 -8
- opentrons/protocol_engine/execution/hardware_stopper.py +7 -7
- opentrons/protocol_engine/execution/movement.py +27 -0
- opentrons/protocol_engine/execution/pipetting.py +5 -1
- opentrons/protocol_engine/execution/tip_handler.py +34 -15
- opentrons/protocol_engine/notes/notes.py +1 -1
- opentrons/protocol_engine/protocol_engine.py +7 -6
- opentrons/protocol_engine/resources/labware_data_provider.py +1 -1
- opentrons/protocol_engine/resources/labware_validation.py +18 -0
- opentrons/protocol_engine/resources/module_data_provider.py +1 -1
- opentrons/protocol_engine/resources/pipette_data_provider.py +26 -0
- opentrons/protocol_engine/slot_standardization.py +9 -9
- opentrons/protocol_engine/state/_move_types.py +9 -5
- opentrons/protocol_engine/state/_well_math.py +193 -0
- opentrons/protocol_engine/state/addressable_areas.py +25 -61
- opentrons/protocol_engine/state/command_history.py +12 -0
- opentrons/protocol_engine/state/commands.py +22 -14
- opentrons/protocol_engine/state/files.py +10 -12
- opentrons/protocol_engine/state/fluid_stack.py +138 -0
- opentrons/protocol_engine/state/frustum_helpers.py +63 -69
- opentrons/protocol_engine/state/geometry.py +47 -1
- opentrons/protocol_engine/state/labware.py +92 -26
- opentrons/protocol_engine/state/liquid_classes.py +82 -0
- opentrons/protocol_engine/state/liquids.py +16 -4
- opentrons/protocol_engine/state/modules.py +52 -70
- opentrons/protocol_engine/state/motion.py +6 -1
- opentrons/protocol_engine/state/pipettes.py +149 -58
- opentrons/protocol_engine/state/state.py +21 -2
- opentrons/protocol_engine/state/state_summary.py +4 -2
- opentrons/protocol_engine/state/tips.py +11 -44
- opentrons/protocol_engine/state/update_types.py +343 -48
- opentrons/protocol_engine/state/wells.py +19 -11
- opentrons/protocol_engine/types.py +176 -28
- opentrons/protocol_reader/extract_labware_definitions.py +5 -2
- opentrons/protocol_reader/file_format_validator.py +5 -5
- opentrons/protocol_runner/json_file_reader.py +9 -3
- opentrons/protocol_runner/json_translator.py +51 -25
- opentrons/protocol_runner/legacy_command_mapper.py +66 -64
- opentrons/protocol_runner/protocol_runner.py +35 -4
- opentrons/protocol_runner/python_protocol_wrappers.py +1 -1
- opentrons/protocol_runner/run_orchestrator.py +13 -3
- opentrons/protocols/advanced_control/common.py +38 -0
- opentrons/protocols/advanced_control/mix.py +1 -1
- opentrons/protocols/advanced_control/transfers/__init__.py +0 -0
- opentrons/protocols/advanced_control/transfers/common.py +56 -0
- opentrons/protocols/advanced_control/{transfers.py → transfers/transfer.py} +10 -85
- opentrons/protocols/api_support/definitions.py +1 -1
- opentrons/protocols/api_support/instrument.py +1 -1
- opentrons/protocols/api_support/util.py +10 -0
- opentrons/protocols/labware.py +70 -8
- opentrons/protocols/models/json_protocol.py +5 -9
- opentrons/simulate.py +3 -1
- opentrons/types.py +162 -2
- opentrons/util/entrypoint_util.py +2 -5
- opentrons/util/logging_config.py +1 -1
- {opentrons-8.2.0a4.dist-info → opentrons-8.3.0.dist-info}/METADATA +16 -15
- {opentrons-8.2.0a4.dist-info → opentrons-8.3.0.dist-info}/RECORD +238 -208
- {opentrons-8.2.0a4.dist-info → opentrons-8.3.0.dist-info}/WHEEL +1 -1
- {opentrons-8.2.0a4.dist-info → opentrons-8.3.0.dist-info}/LICENSE +0 -0
- {opentrons-8.2.0a4.dist-info → opentrons-8.3.0.dist-info}/entry_points.txt +0 -0
- {opentrons-8.2.0a4.dist-info → opentrons-8.3.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
from typing import Optional, Dict, Union
|
|
2
|
+
from opentrons.hardware_control import SyncHardwareAPI
|
|
3
|
+
|
|
4
|
+
from opentrons.types import Mount, MountType, Point, AxisType, AxisMapType
|
|
5
|
+
from opentrons_shared_data.pipette import types as pip_types
|
|
6
|
+
from opentrons.protocol_api._types import PipetteActionTypes, PlungerPositionTypes
|
|
7
|
+
from opentrons.protocol_engine import commands as cmd
|
|
8
|
+
from opentrons.protocol_engine.clients import SyncClient as EngineClient
|
|
9
|
+
from opentrons.protocol_engine.types import DeckPoint, MotorAxis
|
|
10
|
+
|
|
11
|
+
from opentrons.protocol_api.core.robot import AbstractRobot
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
_AXIS_TYPE_TO_MOTOR_AXIS = {
|
|
15
|
+
AxisType.X: MotorAxis.X,
|
|
16
|
+
AxisType.Y: MotorAxis.Y,
|
|
17
|
+
AxisType.P_L: MotorAxis.LEFT_PLUNGER,
|
|
18
|
+
AxisType.P_R: MotorAxis.RIGHT_PLUNGER,
|
|
19
|
+
AxisType.Z_L: MotorAxis.LEFT_Z,
|
|
20
|
+
AxisType.Z_R: MotorAxis.RIGHT_Z,
|
|
21
|
+
AxisType.Z_G: MotorAxis.EXTENSION_Z,
|
|
22
|
+
AxisType.G: MotorAxis.EXTENSION_JAW,
|
|
23
|
+
AxisType.Q: MotorAxis.AXIS_96_CHANNEL_CAM,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class RobotCore(AbstractRobot):
|
|
28
|
+
"""Robot API core using a ProtocolEngine.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
engine_client: A client to the ProtocolEngine that is executing the protocol.
|
|
32
|
+
api_version: The Python Protocol API versionat which this core is operating.
|
|
33
|
+
sync_hardware: A SynchronousAdapter-wrapped Hardware Control API.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
def __init__(
|
|
37
|
+
self, engine_client: EngineClient, sync_hardware_api: SyncHardwareAPI
|
|
38
|
+
) -> None:
|
|
39
|
+
self._engine_client = engine_client
|
|
40
|
+
self._sync_hardware_api = sync_hardware_api
|
|
41
|
+
|
|
42
|
+
def _convert_to_engine_mount(self, axis_map: AxisMapType) -> Dict[MotorAxis, float]:
|
|
43
|
+
return {_AXIS_TYPE_TO_MOTOR_AXIS[ax]: dist for ax, dist in axis_map.items()}
|
|
44
|
+
|
|
45
|
+
def get_pipette_type_from_engine(
|
|
46
|
+
self, mount: Union[Mount, str]
|
|
47
|
+
) -> Optional[pip_types.PipetteNameType]:
|
|
48
|
+
"""Get the pipette attached to the given mount."""
|
|
49
|
+
if isinstance(mount, Mount):
|
|
50
|
+
engine_mount = MountType[mount.name]
|
|
51
|
+
else:
|
|
52
|
+
if mount.lower() == "right":
|
|
53
|
+
engine_mount = MountType.RIGHT
|
|
54
|
+
else:
|
|
55
|
+
engine_mount = MountType.LEFT
|
|
56
|
+
maybe_pipette = self._engine_client.state.pipettes.get_by_mount(engine_mount)
|
|
57
|
+
return maybe_pipette.pipetteName if maybe_pipette else None
|
|
58
|
+
|
|
59
|
+
def get_plunger_position_from_name(
|
|
60
|
+
self, mount: Mount, position_name: PlungerPositionTypes
|
|
61
|
+
) -> float:
|
|
62
|
+
engine_mount = MountType[mount.name]
|
|
63
|
+
maybe_pipette = self._engine_client.state.pipettes.get_by_mount(engine_mount)
|
|
64
|
+
if not maybe_pipette:
|
|
65
|
+
return 0.0
|
|
66
|
+
return self._engine_client.state.pipettes.lookup_plunger_position_name(
|
|
67
|
+
maybe_pipette.id, position_name.value
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
def get_plunger_position_from_volume(
|
|
71
|
+
self, mount: Mount, volume: float, action: PipetteActionTypes, robot_type: str
|
|
72
|
+
) -> float:
|
|
73
|
+
engine_mount = MountType[mount.name]
|
|
74
|
+
maybe_pipette = self._engine_client.state.pipettes.get_by_mount(engine_mount)
|
|
75
|
+
if not maybe_pipette:
|
|
76
|
+
raise RuntimeError(
|
|
77
|
+
f"Cannot load plunger position as no pipette is attached to {mount}"
|
|
78
|
+
)
|
|
79
|
+
convert_volume = (
|
|
80
|
+
self._engine_client.state.pipettes.lookup_volume_to_mm_conversion(
|
|
81
|
+
maybe_pipette.id, volume, action.value
|
|
82
|
+
)
|
|
83
|
+
)
|
|
84
|
+
plunger_bottom = (
|
|
85
|
+
self._engine_client.state.pipettes.lookup_plunger_position_name(
|
|
86
|
+
maybe_pipette.id, "bottom"
|
|
87
|
+
)
|
|
88
|
+
)
|
|
89
|
+
mm = volume / convert_volume
|
|
90
|
+
if robot_type == "OT-2 Standard":
|
|
91
|
+
position = plunger_bottom + mm
|
|
92
|
+
else:
|
|
93
|
+
position = plunger_bottom - mm
|
|
94
|
+
return round(position, 6)
|
|
95
|
+
|
|
96
|
+
def move_to(self, mount: Mount, destination: Point, speed: Optional[float]) -> None:
|
|
97
|
+
engine_mount = MountType[mount.name]
|
|
98
|
+
engine_destination = DeckPoint(
|
|
99
|
+
x=destination.x, y=destination.y, z=destination.z
|
|
100
|
+
)
|
|
101
|
+
self._engine_client.execute_command(
|
|
102
|
+
cmd.robot.MoveToParams(
|
|
103
|
+
mount=engine_mount, destination=engine_destination, speed=speed
|
|
104
|
+
)
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
def move_axes_to(
|
|
108
|
+
self,
|
|
109
|
+
axis_map: AxisMapType,
|
|
110
|
+
critical_point: Optional[AxisMapType],
|
|
111
|
+
speed: Optional[float],
|
|
112
|
+
) -> None:
|
|
113
|
+
axis_engine_map = self._convert_to_engine_mount(axis_map)
|
|
114
|
+
if critical_point:
|
|
115
|
+
critical_point_engine = self._convert_to_engine_mount(critical_point)
|
|
116
|
+
else:
|
|
117
|
+
critical_point_engine = None
|
|
118
|
+
|
|
119
|
+
self._engine_client.execute_command(
|
|
120
|
+
cmd.robot.MoveAxesToParams(
|
|
121
|
+
axis_map=axis_engine_map,
|
|
122
|
+
critical_point=critical_point_engine,
|
|
123
|
+
speed=speed,
|
|
124
|
+
)
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
def move_axes_relative(self, axis_map: AxisMapType, speed: Optional[float]) -> None:
|
|
128
|
+
axis_engine_map = self._convert_to_engine_mount(axis_map)
|
|
129
|
+
self._engine_client.execute_command(
|
|
130
|
+
cmd.robot.MoveAxesRelativeParams(axis_map=axis_engine_map, speed=speed)
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
def release_grip(self) -> None:
|
|
134
|
+
self._engine_client.execute_command(cmd.robot.openGripperJawParams())
|
|
135
|
+
|
|
136
|
+
def close_gripper(self, force: Optional[float] = None) -> None:
|
|
137
|
+
self._engine_client.execute_command(
|
|
138
|
+
cmd.robot.closeGripperJawParams(force=force)
|
|
139
|
+
)
|
|
@@ -130,7 +130,10 @@ class WellCore(AbstractWellCore):
|
|
|
130
130
|
liquid: Liquid,
|
|
131
131
|
volume: float,
|
|
132
132
|
) -> None:
|
|
133
|
-
"""Load liquid into a well.
|
|
133
|
+
"""Load liquid into a well.
|
|
134
|
+
|
|
135
|
+
If the well is known to be empty, use ``load_empty()`` instead of calling this with a 0.0 volume.
|
|
136
|
+
"""
|
|
134
137
|
self._engine_client.execute_command(
|
|
135
138
|
cmd.LoadLiquidParams(
|
|
136
139
|
labwareId=self._labware_id,
|
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
from abc import abstractmethod, ABC
|
|
6
|
-
from typing import Any, Generic, Optional, TypeVar, Union
|
|
6
|
+
from typing import Any, Generic, Optional, TypeVar, Union, List
|
|
7
7
|
|
|
8
8
|
from opentrons import types
|
|
9
9
|
from opentrons.hardware_control.dev_types import PipetteDict
|
|
10
10
|
from opentrons.protocols.api_support.util import FlowRates
|
|
11
|
+
from opentrons.protocols.advanced_control.transfers.common import TransferTipPolicyV2
|
|
11
12
|
from opentrons.protocol_api._nozzle_layout import NozzleLayout
|
|
12
|
-
from opentrons.
|
|
13
|
-
|
|
13
|
+
from opentrons.protocol_api._liquid import LiquidClass
|
|
14
14
|
from ..disposal_locations import TrashBin, WasteChute
|
|
15
15
|
from .well import WellCoreType
|
|
16
16
|
|
|
@@ -24,6 +24,14 @@ class AbstractInstrument(ABC, Generic[WellCoreType]):
|
|
|
24
24
|
def set_default_speed(self, speed: float) -> None:
|
|
25
25
|
...
|
|
26
26
|
|
|
27
|
+
@abstractmethod
|
|
28
|
+
def air_gap_in_place(self, volume: float, flow_rate: float) -> None:
|
|
29
|
+
"""Aspirate a given volume of air from the current location of the pipette.
|
|
30
|
+
Args:
|
|
31
|
+
volume: The volume of air to aspirate, in microliters.
|
|
32
|
+
flow_rate: The flow rate of air into the pipette, in microliters.
|
|
33
|
+
"""
|
|
34
|
+
|
|
27
35
|
@abstractmethod
|
|
28
36
|
def aspirate(
|
|
29
37
|
self,
|
|
@@ -172,6 +180,33 @@ class AbstractInstrument(ABC, Generic[WellCoreType]):
|
|
|
172
180
|
) -> None:
|
|
173
181
|
...
|
|
174
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
|
+
|
|
175
210
|
@abstractmethod
|
|
176
211
|
def get_mount(self) -> types.Mount:
|
|
177
212
|
...
|
|
@@ -222,7 +257,7 @@ class AbstractInstrument(ABC, Generic[WellCoreType]):
|
|
|
222
257
|
...
|
|
223
258
|
|
|
224
259
|
@abstractmethod
|
|
225
|
-
def get_nozzle_map(self) ->
|
|
260
|
+
def get_nozzle_map(self) -> types.NozzleMapInterface:
|
|
226
261
|
...
|
|
227
262
|
|
|
228
263
|
@abstractmethod
|
|
@@ -253,6 +288,10 @@ class AbstractInstrument(ABC, Generic[WellCoreType]):
|
|
|
253
288
|
def get_liquid_presence_detection(self) -> bool:
|
|
254
289
|
...
|
|
255
290
|
|
|
291
|
+
@abstractmethod
|
|
292
|
+
def _pressure_supported_by_pipette(self) -> bool:
|
|
293
|
+
...
|
|
294
|
+
|
|
256
295
|
@abstractmethod
|
|
257
296
|
def set_liquid_presence_detection(self, enable: bool) -> None:
|
|
258
297
|
...
|
|
@@ -298,6 +337,32 @@ class AbstractInstrument(ABC, Generic[WellCoreType]):
|
|
|
298
337
|
"""
|
|
299
338
|
...
|
|
300
339
|
|
|
340
|
+
@abstractmethod
|
|
341
|
+
def load_liquid_class(
|
|
342
|
+
self,
|
|
343
|
+
liquid_class: LiquidClass,
|
|
344
|
+
pipette_load_name: str,
|
|
345
|
+
tiprack_uri: str,
|
|
346
|
+
) -> str:
|
|
347
|
+
"""Load the liquid class properties of given pipette and tiprack into the engine.
|
|
348
|
+
|
|
349
|
+
Returns: ID of the liquid class record
|
|
350
|
+
"""
|
|
351
|
+
...
|
|
352
|
+
|
|
353
|
+
@abstractmethod
|
|
354
|
+
def transfer_liquid(
|
|
355
|
+
self,
|
|
356
|
+
liquid_class_id: str,
|
|
357
|
+
volume: float,
|
|
358
|
+
source: List[WellCoreType],
|
|
359
|
+
dest: List[WellCoreType],
|
|
360
|
+
new_tip: TransferTipPolicyV2,
|
|
361
|
+
trash_location: Union[WellCoreType, types.Location, TrashBin, WasteChute],
|
|
362
|
+
) -> None:
|
|
363
|
+
"""Transfer a liquid from source to dest according to liquid class properties."""
|
|
364
|
+
...
|
|
365
|
+
|
|
301
366
|
@abstractmethod
|
|
302
367
|
def is_tip_tracking_available(self) -> bool:
|
|
303
368
|
"""Return whether auto tip tracking is available for the pipette's current nozzle configuration."""
|
|
@@ -327,5 +392,9 @@ class AbstractInstrument(ABC, Generic[WellCoreType]):
|
|
|
327
392
|
"""Do a liquid probe to find the level of the liquid in the well."""
|
|
328
393
|
...
|
|
329
394
|
|
|
395
|
+
@abstractmethod
|
|
396
|
+
def nozzle_configuration_valid_for_lld(self) -> bool:
|
|
397
|
+
"""Check if the nozzle configuration currently supports LLD."""
|
|
398
|
+
|
|
330
399
|
|
|
331
400
|
InstrumentCoreType = TypeVar("InstrumentCoreType", bound=AbstractInstrument[Any])
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"""The interface that implements InstrumentContext."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
4
|
|
|
4
5
|
from abc import ABC, abstractmethod
|
|
5
|
-
from typing import Any, Generic, List, NamedTuple, Optional, TypeVar
|
|
6
|
+
from typing import Any, Generic, List, NamedTuple, Optional, TypeVar, Dict
|
|
6
7
|
|
|
7
8
|
from opentrons_shared_data.labware.types import (
|
|
8
9
|
LabwareUri,
|
|
@@ -10,8 +11,8 @@ from opentrons_shared_data.labware.types import (
|
|
|
10
11
|
LabwareDefinition as LabwareDefinitionDict,
|
|
11
12
|
)
|
|
12
13
|
|
|
13
|
-
from opentrons.types import DeckSlotName, Point
|
|
14
|
-
from
|
|
14
|
+
from opentrons.types import DeckSlotName, Point, NozzleMapInterface
|
|
15
|
+
from .._liquid import Liquid
|
|
15
16
|
|
|
16
17
|
from .well import WellCoreType
|
|
17
18
|
|
|
@@ -118,7 +119,7 @@ class AbstractLabware(ABC, Generic[WellCoreType]):
|
|
|
118
119
|
self,
|
|
119
120
|
num_tips: int,
|
|
120
121
|
starting_tip: Optional[WellCoreType],
|
|
121
|
-
nozzle_map: Optional[
|
|
122
|
+
nozzle_map: Optional[NozzleMapInterface],
|
|
122
123
|
) -> Optional[str]:
|
|
123
124
|
"""Get the name of the next available tip(s) in the rack, if available."""
|
|
124
125
|
|
|
@@ -134,5 +135,13 @@ class AbstractLabware(ABC, Generic[WellCoreType]):
|
|
|
134
135
|
def get_deck_slot(self) -> Optional[DeckSlotName]:
|
|
135
136
|
"""Get the deck slot the labware or its parent is in, if any."""
|
|
136
137
|
|
|
138
|
+
@abstractmethod
|
|
139
|
+
def load_liquid(self, volumes: Dict[str, float], liquid: Liquid) -> None:
|
|
140
|
+
"""Load liquid into wells of the labware."""
|
|
141
|
+
|
|
142
|
+
@abstractmethod
|
|
143
|
+
def load_empty(self, wells: List[str]) -> None:
|
|
144
|
+
"""Mark wells of the labware as empty."""
|
|
145
|
+
|
|
137
146
|
|
|
138
147
|
LabwareCoreType = TypeVar("LabwareCoreType", bound=AbstractLabware[Any])
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
-
from typing import TYPE_CHECKING, Optional, Union
|
|
4
|
+
from typing import TYPE_CHECKING, Optional, Union, List
|
|
5
5
|
|
|
6
6
|
from opentrons import types
|
|
7
7
|
from opentrons.hardware_control import CriticalPoint
|
|
8
8
|
from opentrons.hardware_control.dev_types import PipetteDict
|
|
9
9
|
from opentrons.protocol_api.core.common import WellCore
|
|
10
|
+
from opentrons.protocols.advanced_control.transfers.common import TransferTipPolicyV2
|
|
10
11
|
from opentrons.protocols.api_support import instrument as instrument_support
|
|
11
12
|
from opentrons.protocols.api_support.definitions import MAX_SUPPORTED_VERSION
|
|
12
13
|
from opentrons.protocols.api_support.labware_like import LabwareLike
|
|
@@ -19,7 +20,7 @@ from opentrons.protocols.api_support.util import (
|
|
|
19
20
|
)
|
|
20
21
|
from opentrons.protocols.geometry import planning
|
|
21
22
|
from opentrons.protocol_api._nozzle_layout import NozzleLayout
|
|
22
|
-
from opentrons.
|
|
23
|
+
from opentrons.protocol_api._liquid import LiquidClass
|
|
23
24
|
|
|
24
25
|
from ...disposal_locations import TrashBin, WasteChute
|
|
25
26
|
from ..instrument import AbstractInstrument
|
|
@@ -72,6 +73,9 @@ class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore]):
|
|
|
72
73
|
"""Sets the speed at which the robot's gantry moves."""
|
|
73
74
|
self._default_speed = speed
|
|
74
75
|
|
|
76
|
+
def air_gap_in_place(self, volume: float, flow_rate: float) -> None:
|
|
77
|
+
assert False, "Air gap tracking only available in API version 2.22 and later"
|
|
78
|
+
|
|
75
79
|
def aspirate(
|
|
76
80
|
self,
|
|
77
81
|
location: types.Location,
|
|
@@ -304,6 +308,30 @@ class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore]):
|
|
|
304
308
|
) -> None:
|
|
305
309
|
raise APIVersionError(api_element="Dropping tips in a trash bin or waste chute")
|
|
306
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
|
+
|
|
307
335
|
def home(self) -> None:
|
|
308
336
|
"""Home the mount"""
|
|
309
337
|
self._protocol_interface.get_hardware().home_z(
|
|
@@ -396,6 +424,32 @@ class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore]):
|
|
|
396
424
|
location=location, mount=location_cache_mount
|
|
397
425
|
)
|
|
398
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
|
+
|
|
399
453
|
def get_mount(self) -> types.Mount:
|
|
400
454
|
"""Get the mount this pipette is attached to."""
|
|
401
455
|
return self._mount
|
|
@@ -552,11 +606,34 @@ class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore]):
|
|
|
552
606
|
"""This will never be called because it was added in API 2.16."""
|
|
553
607
|
pass
|
|
554
608
|
|
|
609
|
+
def load_liquid_class(
|
|
610
|
+
self,
|
|
611
|
+
liquid_class: LiquidClass,
|
|
612
|
+
pipette_load_name: str,
|
|
613
|
+
tiprack_uri: str,
|
|
614
|
+
) -> str:
|
|
615
|
+
"""This will never be called because it was added in .."""
|
|
616
|
+
# TODO(spp, 2024-11-20): update the docstring and error to include API version
|
|
617
|
+
assert False, "load_liquid_class is not supported in legacy context"
|
|
618
|
+
|
|
619
|
+
def transfer_liquid(
|
|
620
|
+
self,
|
|
621
|
+
liquid_class_id: str,
|
|
622
|
+
volume: float,
|
|
623
|
+
source: List[LegacyWellCore],
|
|
624
|
+
dest: List[LegacyWellCore],
|
|
625
|
+
new_tip: TransferTipPolicyV2,
|
|
626
|
+
trash_location: Union[LegacyWellCore, types.Location, TrashBin, WasteChute],
|
|
627
|
+
) -> None:
|
|
628
|
+
"""This will never be called because it was added in .."""
|
|
629
|
+
# TODO(spp, 2024-11-20): update the docstring and error to include API version
|
|
630
|
+
assert False, "transfer_liquid is not supported in legacy context"
|
|
631
|
+
|
|
555
632
|
def get_active_channels(self) -> int:
|
|
556
633
|
"""This will never be called because it was added in API 2.16."""
|
|
557
634
|
assert False, "get_active_channels only supported in API 2.16 & later"
|
|
558
635
|
|
|
559
|
-
def get_nozzle_map(self) ->
|
|
636
|
+
def get_nozzle_map(self) -> types.NozzleMapInterface:
|
|
560
637
|
"""This will never be called because it was added in API 2.18."""
|
|
561
638
|
assert False, "get_nozzle_map only supported in API 2.18 & later"
|
|
562
639
|
|
|
@@ -583,3 +660,10 @@ class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore]):
|
|
|
583
660
|
) -> float:
|
|
584
661
|
"""This will never be called because it was added in API 2.20."""
|
|
585
662
|
assert False, "liquid_probe_without_recovery only supported in API 2.20 & later"
|
|
663
|
+
|
|
664
|
+
def _pressure_supported_by_pipette(self) -> bool:
|
|
665
|
+
return False
|
|
666
|
+
|
|
667
|
+
def nozzle_configuration_valid_for_lld(self) -> bool:
|
|
668
|
+
"""Check if the nozzle configuration currently supports LLD."""
|
|
669
|
+
return False
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
from typing import List, Optional
|
|
1
|
+
from typing import List, Optional, Dict
|
|
2
2
|
|
|
3
3
|
from opentrons.calibration_storage import helpers
|
|
4
4
|
from opentrons.protocols.geometry.labware_geometry import LabwareGeometry
|
|
5
5
|
from opentrons.protocols.api_support.tip_tracker import TipTracker
|
|
6
6
|
|
|
7
|
-
from opentrons.types import DeckSlotName, Location, Point
|
|
8
|
-
|
|
7
|
+
from opentrons.types import DeckSlotName, Location, Point, NozzleMapInterface
|
|
8
|
+
|
|
9
9
|
from opentrons_shared_data.labware.types import LabwareParameters, LabwareDefinition
|
|
10
10
|
|
|
11
|
+
from ..._liquid import Liquid
|
|
11
12
|
from ..labware import AbstractLabware, LabwareLoadParams
|
|
12
13
|
from .legacy_well_core import LegacyWellCore
|
|
13
14
|
from .well_geometry import WellGeometry
|
|
@@ -162,7 +163,7 @@ class LegacyLabwareCore(AbstractLabware[LegacyWellCore]):
|
|
|
162
163
|
self,
|
|
163
164
|
num_tips: int,
|
|
164
165
|
starting_tip: Optional[LegacyWellCore],
|
|
165
|
-
nozzle_map: Optional[
|
|
166
|
+
nozzle_map: Optional[NozzleMapInterface],
|
|
166
167
|
) -> Optional[str]:
|
|
167
168
|
if nozzle_map is not None:
|
|
168
169
|
raise ValueError(
|
|
@@ -220,3 +221,11 @@ class LegacyLabwareCore(AbstractLabware[LegacyWellCore]):
|
|
|
220
221
|
"""Get the deck slot the labware is in, if in a deck slot."""
|
|
221
222
|
slot = self._geometry.parent.labware.first_parent()
|
|
222
223
|
return DeckSlotName.from_primitive(slot) if slot is not None else None
|
|
224
|
+
|
|
225
|
+
def load_liquid(self, volumes: Dict[str, float], liquid: Liquid) -> None:
|
|
226
|
+
"""Load liquid into wells of the labware."""
|
|
227
|
+
assert False, "load_liquid only supported in API version 2.22 & later"
|
|
228
|
+
|
|
229
|
+
def load_empty(self, wells: List[str]) -> None:
|
|
230
|
+
"""Mark wells of the labware as empty."""
|
|
231
|
+
assert False, "load_empty only supported in API version 2.22 & later"
|
|
@@ -6,7 +6,13 @@ from opentrons_shared_data.labware.types import LabwareDefinition
|
|
|
6
6
|
from opentrons_shared_data.pipette.types import PipetteNameType
|
|
7
7
|
from opentrons_shared_data.robot.types import RobotType
|
|
8
8
|
|
|
9
|
-
from opentrons.types import
|
|
9
|
+
from opentrons.types import (
|
|
10
|
+
DeckSlotName,
|
|
11
|
+
StagingSlotName,
|
|
12
|
+
Location,
|
|
13
|
+
Mount,
|
|
14
|
+
Point,
|
|
15
|
+
)
|
|
10
16
|
from opentrons.util.broker import Broker
|
|
11
17
|
from opentrons.hardware_control import SyncHardwareAPI
|
|
12
18
|
from opentrons.hardware_control.modules import AbstractModule, ModuleModel, ModuleType
|
|
@@ -267,6 +273,20 @@ class LegacyProtocolCore(
|
|
|
267
273
|
"""Load an adapter using its identifying parameters"""
|
|
268
274
|
raise APIVersionError(api_element="Loading adapter")
|
|
269
275
|
|
|
276
|
+
def load_lid(
|
|
277
|
+
self,
|
|
278
|
+
load_name: str,
|
|
279
|
+
location: LegacyLabwareCore,
|
|
280
|
+
namespace: Optional[str],
|
|
281
|
+
version: Optional[int],
|
|
282
|
+
) -> LegacyLabwareCore:
|
|
283
|
+
"""Load an individual lid labware using its identifying parameters. Must be loaded on a labware."""
|
|
284
|
+
raise APIVersionError(api_element="Loading lid")
|
|
285
|
+
|
|
286
|
+
def load_robot(self) -> None: # type: ignore
|
|
287
|
+
"""Load an adapter using its identifying parameters"""
|
|
288
|
+
raise APIVersionError(api_element="Loading robot")
|
|
289
|
+
|
|
270
290
|
def move_labware(
|
|
271
291
|
self,
|
|
272
292
|
labware_core: LegacyLabwareCore,
|
|
@@ -474,6 +494,17 @@ class LegacyProtocolCore(
|
|
|
474
494
|
self._last_location = location
|
|
475
495
|
self._last_mount = mount
|
|
476
496
|
|
|
497
|
+
def load_lid_stack(
|
|
498
|
+
self,
|
|
499
|
+
load_name: str,
|
|
500
|
+
location: Union[DeckSlotName, StagingSlotName, LegacyLabwareCore],
|
|
501
|
+
quantity: int,
|
|
502
|
+
namespace: Optional[str],
|
|
503
|
+
version: Optional[int],
|
|
504
|
+
) -> LegacyLabwareCore:
|
|
505
|
+
"""Load a Stack of Lids to a given location, creating a Lid Stack."""
|
|
506
|
+
raise APIVersionError(api_element="Lid stack")
|
|
507
|
+
|
|
477
508
|
def get_module_cores(self) -> List[legacy_module_core.LegacyModuleCore]:
|
|
478
509
|
"""Get loaded module cores."""
|
|
479
510
|
return self._module_cores
|
|
File without changes
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
-
from typing import TYPE_CHECKING, Optional, Union
|
|
4
|
+
from typing import TYPE_CHECKING, Optional, Union, List
|
|
5
5
|
|
|
6
6
|
from opentrons import types
|
|
7
7
|
from opentrons.hardware_control.dev_types import PipetteDict
|
|
8
8
|
from opentrons.hardware_control.types import HardwareAction
|
|
9
9
|
from opentrons.protocol_api.core.common import WellCore
|
|
10
|
+
from opentrons.protocols.advanced_control.transfers.common import TransferTipPolicyV2
|
|
10
11
|
from opentrons.protocols.api_support import instrument as instrument_support
|
|
11
12
|
from opentrons.protocols.api_support.labware_like import LabwareLike
|
|
12
13
|
from opentrons.protocols.api_support.types import APIVersion
|
|
@@ -24,7 +25,7 @@ from opentrons_shared_data.errors.exceptions import (
|
|
|
24
25
|
|
|
25
26
|
from ...disposal_locations import TrashBin, WasteChute
|
|
26
27
|
from opentrons.protocol_api._nozzle_layout import NozzleLayout
|
|
27
|
-
from opentrons.
|
|
28
|
+
from opentrons.protocol_api._liquid import LiquidClass
|
|
28
29
|
|
|
29
30
|
from ..instrument import AbstractInstrument
|
|
30
31
|
|
|
@@ -83,6 +84,9 @@ class LegacyInstrumentCoreSimulator(AbstractInstrument[LegacyWellCore]):
|
|
|
83
84
|
def set_default_speed(self, speed: float) -> None:
|
|
84
85
|
self._default_speed = speed
|
|
85
86
|
|
|
87
|
+
def air_gap_in_place(self, volume: float, flow_rate: float) -> None:
|
|
88
|
+
assert False, "Air gap tracking only available in API version 2.22 and later"
|
|
89
|
+
|
|
86
90
|
def aspirate(
|
|
87
91
|
self,
|
|
88
92
|
location: types.Location,
|
|
@@ -272,6 +276,30 @@ class LegacyInstrumentCoreSimulator(AbstractInstrument[LegacyWellCore]):
|
|
|
272
276
|
) -> None:
|
|
273
277
|
raise APIVersionError(api_element="Dropping tips in a trash bin or waste chute")
|
|
274
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
|
+
|
|
275
303
|
def home(self) -> None:
|
|
276
304
|
self._protocol_interface.set_last_location(None)
|
|
277
305
|
|
|
@@ -470,11 +498,34 @@ class LegacyInstrumentCoreSimulator(AbstractInstrument[LegacyWellCore]):
|
|
|
470
498
|
"""This will never be called because it was added in API 2.15."""
|
|
471
499
|
pass
|
|
472
500
|
|
|
501
|
+
def load_liquid_class(
|
|
502
|
+
self,
|
|
503
|
+
liquid_class: LiquidClass,
|
|
504
|
+
pipette_load_name: str,
|
|
505
|
+
tiprack_uri: str,
|
|
506
|
+
) -> str:
|
|
507
|
+
"""This will never be called because it was added in .."""
|
|
508
|
+
# TODO(spp, 2024-11-20): update the docstring and error to include API version
|
|
509
|
+
assert False, "load_liquid_class is not supported in legacy context"
|
|
510
|
+
|
|
511
|
+
def transfer_liquid(
|
|
512
|
+
self,
|
|
513
|
+
liquid_class_id: str,
|
|
514
|
+
volume: float,
|
|
515
|
+
source: List[LegacyWellCore],
|
|
516
|
+
dest: List[LegacyWellCore],
|
|
517
|
+
new_tip: TransferTipPolicyV2,
|
|
518
|
+
trash_location: Union[LegacyWellCore, types.Location, TrashBin, WasteChute],
|
|
519
|
+
) -> None:
|
|
520
|
+
"""Transfer a liquid from source to dest according to liquid class properties."""
|
|
521
|
+
# TODO(spp, 2024-11-20): update the docstring and error to include API version
|
|
522
|
+
assert False, "transfer_liquid is not supported in legacy context"
|
|
523
|
+
|
|
473
524
|
def get_active_channels(self) -> int:
|
|
474
525
|
"""This will never be called because it was added in API 2.16."""
|
|
475
526
|
assert False, "get_active_channels only supported in API 2.16 & later"
|
|
476
527
|
|
|
477
|
-
def get_nozzle_map(self) ->
|
|
528
|
+
def get_nozzle_map(self) -> types.NozzleMapInterface:
|
|
478
529
|
"""This will never be called because it was added in API 2.18."""
|
|
479
530
|
assert False, "get_nozzle_map only supported in API 2.18 & later"
|
|
480
531
|
|
|
@@ -501,3 +552,10 @@ class LegacyInstrumentCoreSimulator(AbstractInstrument[LegacyWellCore]):
|
|
|
501
552
|
) -> float:
|
|
502
553
|
"""This will never be called because it was added in API 2.20."""
|
|
503
554
|
assert False, "liquid_probe_without_recovery only supported in API 2.20 & later"
|
|
555
|
+
|
|
556
|
+
def _pressure_supported_by_pipette(self) -> bool:
|
|
557
|
+
return False
|
|
558
|
+
|
|
559
|
+
def nozzle_configuration_valid_for_lld(self) -> bool:
|
|
560
|
+
"""Check if the nozzle configuration currently supports LLD."""
|
|
561
|
+
return False
|