opentrons 8.2.0a4__py2.py3-none-any.whl → 8.3.0a1__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 +28 -20
- 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 +60 -23
- 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 +18 -0
- opentrons/hardware_control/protocols/motion_controller.py +6 -0
- opentrons/hardware_control/robot_calibration.py +1 -1
- opentrons/hardware_control/types.py +61 -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 +82 -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 +46 -4
- opentrons/protocol_api/core/labware.py +13 -4
- opentrons/protocol_api/core/legacy/legacy_instrument_core.py +37 -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 +37 -3
- opentrons/protocol_api/core/protocol.py +34 -1
- opentrons/protocol_api/core/robot.py +51 -0
- opentrons/protocol_api/instrument_context.py +158 -44
- opentrons/protocol_api/labware.py +231 -7
- 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 +81 -0
- opentrons/protocol_engine/commands/absorbance_reader/close_lid.py +0 -2
- opentrons/protocol_engine/commands/absorbance_reader/initialize.py +19 -5
- opentrons/protocol_engine/commands/absorbance_reader/open_lid.py +0 -1
- opentrons/protocol_engine/commands/absorbance_reader/read.py +32 -9
- 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 +101 -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 +13 -3
- 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 +67 -24
- opentrons/protocol_engine/commands/load_labware.py +29 -7
- 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 +19 -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 +8 -2
- 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 +4 -1
- opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py +12 -3
- opentrons/protocol_engine/commands/unsafe/unsafe_engage_axes.py +1 -4
- opentrons/protocol_engine/commands/unsafe/update_position_estimators.py +1 -4
- 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 +8 -0
- opentrons/protocol_engine/errors/error_occurrence.py +19 -20
- opentrons/protocol_engine/errors/exceptions.py +50 -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 +364 -8
- opentrons/protocol_engine/execution/movement.py +27 -0
- opentrons/protocol_engine/execution/pipetting.py +5 -1
- opentrons/protocol_engine/execution/tip_handler.py +4 -6
- 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 +5 -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 +17 -13
- opentrons/protocol_engine/state/files.py +10 -12
- opentrons/protocol_engine/state/fluid_stack.py +138 -0
- opentrons/protocol_engine/state/frustum_helpers.py +57 -32
- opentrons/protocol_engine/state/geometry.py +47 -1
- opentrons/protocol_engine/state/labware.py +79 -25
- 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 +144 -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 +39 -6
- opentrons/protocols/models/json_protocol.py +5 -9
- opentrons/simulate.py +3 -1
- opentrons/types.py +162 -2
- opentrons/util/logging_config.py +1 -1
- {opentrons-8.2.0a4.dist-info → opentrons-8.3.0a1.dist-info}/METADATA +16 -15
- {opentrons-8.2.0a4.dist-info → opentrons-8.3.0a1.dist-info}/RECORD +229 -202
- {opentrons-8.2.0a4.dist-info → opentrons-8.3.0a1.dist-info}/WHEEL +1 -1
- {opentrons-8.2.0a4.dist-info → opentrons-8.3.0a1.dist-info}/LICENSE +0 -0
- {opentrons-8.2.0a4.dist-info → opentrons-8.3.0a1.dist-info}/entry_points.txt +0 -0
- {opentrons-8.2.0a4.dist-info → opentrons-8.3.0a1.dist-info}/top_level.txt +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Aspirate command request, result, and implementation models."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
4
|
from typing import TYPE_CHECKING, Optional, Type, Union
|
|
4
|
-
from opentrons_shared_data.errors.exceptions import PipetteOverpressureError
|
|
5
5
|
from typing_extensions import Literal
|
|
6
6
|
|
|
7
7
|
from .pipetting_common import (
|
|
@@ -9,9 +9,15 @@ from .pipetting_common import (
|
|
|
9
9
|
PipetteIdMixin,
|
|
10
10
|
AspirateVolumeMixin,
|
|
11
11
|
FlowRateMixin,
|
|
12
|
-
LiquidHandlingWellLocationMixin,
|
|
13
12
|
BaseLiquidHandlingResult,
|
|
13
|
+
aspirate_in_place,
|
|
14
|
+
prepare_for_aspirate,
|
|
15
|
+
)
|
|
16
|
+
from .movement_common import (
|
|
17
|
+
LiquidHandlingWellLocationMixin,
|
|
14
18
|
DestinationPositionResult,
|
|
19
|
+
StallOrCollisionError,
|
|
20
|
+
move_to_well,
|
|
15
21
|
)
|
|
16
22
|
from .command import (
|
|
17
23
|
AbstractCommandImpl,
|
|
@@ -20,12 +26,15 @@ from .command import (
|
|
|
20
26
|
DefinedErrorData,
|
|
21
27
|
SuccessData,
|
|
22
28
|
)
|
|
23
|
-
from ..errors.error_occurrence import ErrorOccurrence
|
|
24
29
|
|
|
25
30
|
from opentrons.hardware_control import HardwareControlAPI
|
|
26
31
|
|
|
27
32
|
from ..state.update_types import StateUpdate, CLEAR
|
|
28
|
-
from ..types import
|
|
33
|
+
from ..types import (
|
|
34
|
+
WellLocation,
|
|
35
|
+
WellOrigin,
|
|
36
|
+
CurrentWell,
|
|
37
|
+
)
|
|
29
38
|
|
|
30
39
|
if TYPE_CHECKING:
|
|
31
40
|
from ..execution import MovementHandler, PipettingHandler
|
|
@@ -53,7 +62,7 @@ class AspirateResult(BaseLiquidHandlingResult, DestinationPositionResult):
|
|
|
53
62
|
|
|
54
63
|
_ExecuteReturn = Union[
|
|
55
64
|
SuccessData[AspirateResult],
|
|
56
|
-
DefinedErrorData[OverpressureError],
|
|
65
|
+
DefinedErrorData[OverpressureError] | DefinedErrorData[StallOrCollisionError],
|
|
57
66
|
]
|
|
58
67
|
|
|
59
68
|
|
|
@@ -86,23 +95,51 @@ class AspirateImplementation(AbstractCommandImpl[AspirateParams, _ExecuteReturn]
|
|
|
86
95
|
pipette_id = params.pipetteId
|
|
87
96
|
labware_id = params.labwareId
|
|
88
97
|
well_name = params.wellName
|
|
98
|
+
well_location = params.wellLocation
|
|
99
|
+
|
|
100
|
+
state_update = StateUpdate()
|
|
101
|
+
|
|
102
|
+
final_location = self._state_view.geometry.get_well_position(
|
|
103
|
+
labware_id=labware_id,
|
|
104
|
+
well_name=well_name,
|
|
105
|
+
well_location=well_location,
|
|
106
|
+
operation_volume=-params.volume,
|
|
107
|
+
pipette_id=pipette_id,
|
|
108
|
+
)
|
|
89
109
|
|
|
90
110
|
ready_to_aspirate = self._pipetting.get_is_ready_to_aspirate(
|
|
91
111
|
pipette_id=pipette_id
|
|
92
112
|
)
|
|
93
113
|
|
|
94
114
|
current_well = None
|
|
95
|
-
state_update = StateUpdate()
|
|
96
115
|
|
|
97
116
|
if not ready_to_aspirate:
|
|
98
|
-
await
|
|
117
|
+
move_result = await move_to_well(
|
|
118
|
+
movement=self._movement,
|
|
119
|
+
model_utils=self._model_utils,
|
|
99
120
|
pipette_id=pipette_id,
|
|
100
121
|
labware_id=labware_id,
|
|
101
122
|
well_name=well_name,
|
|
102
123
|
well_location=WellLocation(origin=WellOrigin.TOP),
|
|
103
124
|
)
|
|
125
|
+
state_update.append(move_result.state_update)
|
|
126
|
+
if isinstance(move_result, DefinedErrorData):
|
|
127
|
+
return DefinedErrorData(move_result.public, state_update=state_update)
|
|
104
128
|
|
|
105
|
-
await
|
|
129
|
+
prepare_result = await prepare_for_aspirate(
|
|
130
|
+
pipette_id=pipette_id,
|
|
131
|
+
pipetting=self._pipetting,
|
|
132
|
+
model_utils=self._model_utils,
|
|
133
|
+
# Note that the retryLocation is the final location, inside the liquid,
|
|
134
|
+
# because that's where we'd want the client to try re-aspirating if this
|
|
135
|
+
# command fails and the run enters error recovery.
|
|
136
|
+
location_if_error={"retryLocation": final_location},
|
|
137
|
+
)
|
|
138
|
+
state_update.append(prepare_result.state_update)
|
|
139
|
+
if isinstance(prepare_result, DefinedErrorData):
|
|
140
|
+
return DefinedErrorData(
|
|
141
|
+
public=prepare_result.public, state_update=state_update
|
|
142
|
+
)
|
|
106
143
|
|
|
107
144
|
# set our current deck location to the well now that we've made
|
|
108
145
|
# an intermediate move for the "prepare for aspirate" step
|
|
@@ -112,71 +149,84 @@ class AspirateImplementation(AbstractCommandImpl[AspirateParams, _ExecuteReturn]
|
|
|
112
149
|
well_name=well_name,
|
|
113
150
|
)
|
|
114
151
|
|
|
115
|
-
|
|
152
|
+
move_result = await move_to_well(
|
|
153
|
+
movement=self._movement,
|
|
154
|
+
model_utils=self._model_utils,
|
|
116
155
|
pipette_id=pipette_id,
|
|
117
156
|
labware_id=labware_id,
|
|
118
157
|
well_name=well_name,
|
|
119
|
-
well_location=
|
|
158
|
+
well_location=well_location,
|
|
120
159
|
current_well=current_well,
|
|
121
160
|
operation_volume=-params.volume,
|
|
122
161
|
)
|
|
123
|
-
|
|
124
|
-
|
|
162
|
+
state_update.append(move_result.state_update)
|
|
163
|
+
if isinstance(move_result, DefinedErrorData):
|
|
164
|
+
return DefinedErrorData(
|
|
165
|
+
public=move_result.public, state_update=state_update
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
aspirate_result = await aspirate_in_place(
|
|
125
169
|
pipette_id=pipette_id,
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
170
|
+
volume=params.volume,
|
|
171
|
+
flow_rate=params.flowRate,
|
|
172
|
+
location_if_error={
|
|
173
|
+
"retryLocation": (
|
|
174
|
+
move_result.public.position.x,
|
|
175
|
+
move_result.public.position.y,
|
|
176
|
+
move_result.public.position.z,
|
|
177
|
+
)
|
|
178
|
+
},
|
|
179
|
+
command_note_adder=self._command_note_adder,
|
|
180
|
+
pipetting=self._pipetting,
|
|
181
|
+
model_utils=self._model_utils,
|
|
129
182
|
)
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
volume_aspirated = await self._pipetting.aspirate_in_place(
|
|
133
|
-
pipette_id=pipette_id,
|
|
134
|
-
volume=params.volume,
|
|
135
|
-
flow_rate=params.flowRate,
|
|
136
|
-
command_note_adder=self._command_note_adder,
|
|
137
|
-
)
|
|
138
|
-
except PipetteOverpressureError as e:
|
|
183
|
+
state_update.append(aspirate_result.state_update)
|
|
184
|
+
if isinstance(aspirate_result, DefinedErrorData):
|
|
139
185
|
state_update.set_liquid_operated(
|
|
140
186
|
labware_id=labware_id,
|
|
141
|
-
|
|
187
|
+
well_names=self._state_view.geometry.get_wells_covered_by_pipette_with_active_well(
|
|
188
|
+
labware_id,
|
|
189
|
+
well_name,
|
|
190
|
+
params.pipetteId,
|
|
191
|
+
),
|
|
142
192
|
volume_added=CLEAR,
|
|
143
193
|
)
|
|
144
194
|
return DefinedErrorData(
|
|
145
|
-
public=
|
|
146
|
-
id=self._model_utils.generate_id(),
|
|
147
|
-
createdAt=self._model_utils.get_timestamp(),
|
|
148
|
-
wrappedErrors=[
|
|
149
|
-
ErrorOccurrence.from_failed(
|
|
150
|
-
id=self._model_utils.generate_id(),
|
|
151
|
-
createdAt=self._model_utils.get_timestamp(),
|
|
152
|
-
error=e,
|
|
153
|
-
)
|
|
154
|
-
],
|
|
155
|
-
errorInfo={"retryLocation": (position.x, position.y, position.z)},
|
|
156
|
-
),
|
|
157
|
-
state_update=state_update,
|
|
158
|
-
)
|
|
159
|
-
else:
|
|
160
|
-
state_update.set_liquid_operated(
|
|
161
|
-
labware_id=labware_id,
|
|
162
|
-
well_name=well_name,
|
|
163
|
-
volume_added=-volume_aspirated,
|
|
164
|
-
)
|
|
165
|
-
return SuccessData(
|
|
166
|
-
public=AspirateResult(
|
|
167
|
-
volume=volume_aspirated,
|
|
168
|
-
position=deck_point,
|
|
169
|
-
),
|
|
170
|
-
state_update=state_update,
|
|
195
|
+
public=aspirate_result.public, state_update=state_update
|
|
171
196
|
)
|
|
172
197
|
|
|
198
|
+
state_update.set_liquid_operated(
|
|
199
|
+
labware_id=labware_id,
|
|
200
|
+
well_names=self._state_view.geometry.get_wells_covered_by_pipette_with_active_well(
|
|
201
|
+
labware_id, well_name, pipette_id
|
|
202
|
+
),
|
|
203
|
+
volume_added=-aspirate_result.public.volume
|
|
204
|
+
* self._state_view.geometry.get_nozzles_per_well(
|
|
205
|
+
labware_id,
|
|
206
|
+
well_name,
|
|
207
|
+
params.pipetteId,
|
|
208
|
+
),
|
|
209
|
+
)
|
|
173
210
|
|
|
174
|
-
|
|
211
|
+
return SuccessData(
|
|
212
|
+
public=AspirateResult(
|
|
213
|
+
volume=aspirate_result.public.volume,
|
|
214
|
+
position=move_result.public.position,
|
|
215
|
+
),
|
|
216
|
+
state_update=state_update,
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
class Aspirate(
|
|
221
|
+
BaseCommand[
|
|
222
|
+
AspirateParams, AspirateResult, OverpressureError | StallOrCollisionError
|
|
223
|
+
]
|
|
224
|
+
):
|
|
175
225
|
"""Aspirate command model."""
|
|
176
226
|
|
|
177
227
|
commandType: AspirateCommandType = "aspirate"
|
|
178
228
|
params: AspirateParams
|
|
179
|
-
result: Optional[AspirateResult]
|
|
229
|
+
result: Optional[AspirateResult] = None
|
|
180
230
|
|
|
181
231
|
_ImplementationCls: Type[AspirateImplementation] = AspirateImplementation
|
|
182
232
|
|
|
@@ -4,8 +4,6 @@ from __future__ import annotations
|
|
|
4
4
|
from typing import TYPE_CHECKING, Optional, Type, Union
|
|
5
5
|
from typing_extensions import Literal
|
|
6
6
|
|
|
7
|
-
from opentrons_shared_data.errors.exceptions import PipetteOverpressureError
|
|
8
|
-
|
|
9
7
|
from opentrons.hardware_control import HardwareControlAPI
|
|
10
8
|
|
|
11
9
|
from .pipetting_common import (
|
|
@@ -14,6 +12,7 @@ from .pipetting_common import (
|
|
|
14
12
|
FlowRateMixin,
|
|
15
13
|
BaseLiquidHandlingResult,
|
|
16
14
|
OverpressureError,
|
|
15
|
+
aspirate_in_place,
|
|
17
16
|
)
|
|
18
17
|
from .command import (
|
|
19
18
|
AbstractCommandImpl,
|
|
@@ -22,9 +21,8 @@ from .command import (
|
|
|
22
21
|
SuccessData,
|
|
23
22
|
DefinedErrorData,
|
|
24
23
|
)
|
|
25
|
-
from ..errors.error_occurrence import ErrorOccurrence
|
|
26
24
|
from ..errors.exceptions import PipetteNotReadyToAspirateError
|
|
27
|
-
from ..state.update_types import
|
|
25
|
+
from ..state.update_types import CLEAR
|
|
28
26
|
from ..types import CurrentWell
|
|
29
27
|
|
|
30
28
|
if TYPE_CHECKING:
|
|
@@ -83,8 +81,6 @@ class AspirateInPlaceImplementation(
|
|
|
83
81
|
TipNotAttachedError: if no tip is attached to the pipette.
|
|
84
82
|
PipetteNotReadyToAspirateError: pipette plunger is not ready.
|
|
85
83
|
"""
|
|
86
|
-
state_update = StateUpdate()
|
|
87
|
-
|
|
88
84
|
ready_to_aspirate = self._pipetting.get_is_ready_to_aspirate(
|
|
89
85
|
pipette_id=params.pipetteId,
|
|
90
86
|
)
|
|
@@ -95,63 +91,71 @@ class AspirateInPlaceImplementation(
|
|
|
95
91
|
" so the plunger can be reset in a known safe position."
|
|
96
92
|
)
|
|
97
93
|
|
|
98
|
-
current_location = self._state_view.pipettes.get_current_location()
|
|
99
94
|
current_position = await self._gantry_mover.get_position(params.pipetteId)
|
|
95
|
+
current_location = self._state_view.pipettes.get_current_location()
|
|
100
96
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
97
|
+
result = await aspirate_in_place(
|
|
98
|
+
pipette_id=params.pipetteId,
|
|
99
|
+
volume=params.volume,
|
|
100
|
+
flow_rate=params.flowRate,
|
|
101
|
+
location_if_error={
|
|
102
|
+
"retryLocation": (
|
|
103
|
+
current_position.x,
|
|
104
|
+
current_position.y,
|
|
105
|
+
current_position.z,
|
|
106
|
+
)
|
|
107
|
+
},
|
|
108
|
+
command_note_adder=self._command_note_adder,
|
|
109
|
+
pipetting=self._pipetting,
|
|
110
|
+
model_utils=self._model_utils,
|
|
111
|
+
)
|
|
112
|
+
if isinstance(result, DefinedErrorData):
|
|
109
113
|
if (
|
|
110
114
|
isinstance(current_location, CurrentWell)
|
|
111
115
|
and current_location.pipette_id == params.pipetteId
|
|
112
116
|
):
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
ErrorOccurrence.from_failed(
|
|
124
|
-
id=self._model_utils.generate_id(),
|
|
125
|
-
createdAt=self._model_utils.get_timestamp(),
|
|
126
|
-
error=e,
|
|
127
|
-
)
|
|
128
|
-
],
|
|
129
|
-
errorInfo=(
|
|
130
|
-
{
|
|
131
|
-
"retryLocation": (
|
|
132
|
-
current_position.x,
|
|
133
|
-
current_position.y,
|
|
134
|
-
current_position.z,
|
|
135
|
-
)
|
|
136
|
-
}
|
|
117
|
+
return DefinedErrorData(
|
|
118
|
+
public=result.public,
|
|
119
|
+
state_update=result.state_update.set_liquid_operated(
|
|
120
|
+
labware_id=current_location.labware_id,
|
|
121
|
+
well_names=self._state_view.geometry.get_wells_covered_by_pipette_with_active_well(
|
|
122
|
+
current_location.labware_id,
|
|
123
|
+
current_location.well_name,
|
|
124
|
+
params.pipetteId,
|
|
125
|
+
),
|
|
126
|
+
volume_added=CLEAR,
|
|
137
127
|
),
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
128
|
+
state_update_if_false_positive=result.state_update_if_false_positive,
|
|
129
|
+
)
|
|
130
|
+
else:
|
|
131
|
+
return result
|
|
141
132
|
else:
|
|
142
133
|
if (
|
|
143
134
|
isinstance(current_location, CurrentWell)
|
|
144
135
|
and current_location.pipette_id == params.pipetteId
|
|
145
136
|
):
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
137
|
+
return SuccessData(
|
|
138
|
+
public=AspirateInPlaceResult(volume=result.public.volume),
|
|
139
|
+
state_update=result.state_update.set_liquid_operated(
|
|
140
|
+
labware_id=current_location.labware_id,
|
|
141
|
+
well_names=self._state_view.geometry.get_wells_covered_by_pipette_with_active_well(
|
|
142
|
+
current_location.labware_id,
|
|
143
|
+
current_location.well_name,
|
|
144
|
+
params.pipetteId,
|
|
145
|
+
),
|
|
146
|
+
volume_added=-result.public.volume
|
|
147
|
+
* self._state_view.geometry.get_nozzles_per_well(
|
|
148
|
+
current_location.labware_id,
|
|
149
|
+
current_location.well_name,
|
|
150
|
+
params.pipetteId,
|
|
151
|
+
),
|
|
152
|
+
),
|
|
153
|
+
)
|
|
154
|
+
else:
|
|
155
|
+
return SuccessData(
|
|
156
|
+
public=AspirateInPlaceResult(volume=result.public.volume),
|
|
157
|
+
state_update=result.state_update,
|
|
150
158
|
)
|
|
151
|
-
return SuccessData(
|
|
152
|
-
public=AspirateInPlaceResult(volume=volume),
|
|
153
|
-
state_update=state_update,
|
|
154
|
-
)
|
|
155
159
|
|
|
156
160
|
|
|
157
161
|
class AspirateInPlace(
|
|
@@ -161,7 +165,7 @@ class AspirateInPlace(
|
|
|
161
165
|
|
|
162
166
|
commandType: AspirateInPlaceCommandType = "aspirateInPlace"
|
|
163
167
|
params: AspirateInPlaceParams
|
|
164
|
-
result: Optional[AspirateInPlaceResult]
|
|
168
|
+
result: Optional[AspirateInPlaceResult] = None
|
|
165
169
|
|
|
166
170
|
_ImplementationCls: Type[
|
|
167
171
|
AspirateInPlaceImplementation
|
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
"""Blow-out command request, result, and implementation models."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
4
|
from typing import TYPE_CHECKING, Optional, Type, Union
|
|
4
|
-
from opentrons_shared_data.errors.exceptions import PipetteOverpressureError
|
|
5
5
|
from typing_extensions import Literal
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
from ..state.update_types import StateUpdate
|
|
9
|
-
from ..types import DeckPoint
|
|
10
8
|
from .pipetting_common import (
|
|
11
9
|
OverpressureError,
|
|
12
10
|
PipetteIdMixin,
|
|
13
11
|
FlowRateMixin,
|
|
12
|
+
blow_out_in_place,
|
|
13
|
+
)
|
|
14
|
+
from .movement_common import (
|
|
14
15
|
WellLocationMixin,
|
|
15
16
|
DestinationPositionResult,
|
|
17
|
+
move_to_well,
|
|
18
|
+
StallOrCollisionError,
|
|
16
19
|
)
|
|
17
20
|
from .command import (
|
|
18
21
|
AbstractCommandImpl,
|
|
@@ -21,7 +24,7 @@ from .command import (
|
|
|
21
24
|
DefinedErrorData,
|
|
22
25
|
SuccessData,
|
|
23
26
|
)
|
|
24
|
-
from ..
|
|
27
|
+
from ..state.update_types import StateUpdate
|
|
25
28
|
|
|
26
29
|
from opentrons.hardware_control import HardwareControlAPI
|
|
27
30
|
|
|
@@ -49,7 +52,7 @@ class BlowOutResult(DestinationPositionResult):
|
|
|
49
52
|
|
|
50
53
|
_ExecuteReturn = Union[
|
|
51
54
|
SuccessData[BlowOutResult],
|
|
52
|
-
DefinedErrorData[OverpressureError],
|
|
55
|
+
DefinedErrorData[OverpressureError] | DefinedErrorData[StallOrCollisionError],
|
|
53
56
|
]
|
|
54
57
|
|
|
55
58
|
|
|
@@ -73,59 +76,61 @@ class BlowOutImplementation(AbstractCommandImpl[BlowOutParams, _ExecuteReturn]):
|
|
|
73
76
|
|
|
74
77
|
async def execute(self, params: BlowOutParams) -> _ExecuteReturn:
|
|
75
78
|
"""Move to and blow-out the requested well."""
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
+
move_result = await move_to_well(
|
|
80
|
+
movement=self._movement,
|
|
81
|
+
model_utils=self._model_utils,
|
|
79
82
|
pipette_id=params.pipetteId,
|
|
80
83
|
labware_id=params.labwareId,
|
|
81
84
|
well_name=params.wellName,
|
|
82
85
|
well_location=params.wellLocation,
|
|
83
86
|
)
|
|
84
|
-
|
|
85
|
-
|
|
87
|
+
if isinstance(move_result, DefinedErrorData):
|
|
88
|
+
return move_result
|
|
89
|
+
blow_out_result = await blow_out_in_place(
|
|
86
90
|
pipette_id=params.pipetteId,
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
91
|
+
flow_rate=params.flowRate,
|
|
92
|
+
location_if_error={
|
|
93
|
+
"retryLocation": (
|
|
94
|
+
move_result.public.position.x,
|
|
95
|
+
move_result.public.position.y,
|
|
96
|
+
move_result.public.position.z,
|
|
97
|
+
)
|
|
98
|
+
},
|
|
99
|
+
pipetting=self._pipetting,
|
|
100
|
+
model_utils=self._model_utils,
|
|
90
101
|
)
|
|
91
|
-
|
|
92
|
-
await self._pipetting.blow_out_in_place(
|
|
93
|
-
pipette_id=params.pipetteId, flow_rate=params.flowRate
|
|
94
|
-
)
|
|
95
|
-
except PipetteOverpressureError as e:
|
|
102
|
+
if isinstance(blow_out_result, DefinedErrorData):
|
|
96
103
|
return DefinedErrorData(
|
|
97
|
-
public=
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
error=e,
|
|
105
|
-
)
|
|
106
|
-
],
|
|
107
|
-
errorInfo={
|
|
108
|
-
"retryLocation": (
|
|
109
|
-
x,
|
|
110
|
-
y,
|
|
111
|
-
z,
|
|
112
|
-
)
|
|
113
|
-
},
|
|
104
|
+
public=blow_out_result.public,
|
|
105
|
+
state_update=StateUpdate.reduce(
|
|
106
|
+
move_result.state_update, blow_out_result.state_update
|
|
107
|
+
),
|
|
108
|
+
state_update_if_false_positive=StateUpdate.reduce(
|
|
109
|
+
move_result.state_update,
|
|
110
|
+
blow_out_result.state_update_if_false_positive,
|
|
114
111
|
),
|
|
115
112
|
)
|
|
116
113
|
else:
|
|
117
114
|
return SuccessData(
|
|
118
|
-
public=BlowOutResult(position=
|
|
119
|
-
state_update=
|
|
115
|
+
public=BlowOutResult(position=move_result.public.position),
|
|
116
|
+
state_update=StateUpdate.reduce(
|
|
117
|
+
move_result.state_update, blow_out_result.state_update
|
|
118
|
+
),
|
|
120
119
|
)
|
|
121
120
|
|
|
122
121
|
|
|
123
|
-
class BlowOut(
|
|
122
|
+
class BlowOut(
|
|
123
|
+
BaseCommand[
|
|
124
|
+
BlowOutParams,
|
|
125
|
+
BlowOutResult,
|
|
126
|
+
OverpressureError | StallOrCollisionError,
|
|
127
|
+
]
|
|
128
|
+
):
|
|
124
129
|
"""Blow-out command model."""
|
|
125
130
|
|
|
126
131
|
commandType: BlowOutCommandType = "blowout"
|
|
127
132
|
params: BlowOutParams
|
|
128
|
-
result: Optional[BlowOutResult]
|
|
133
|
+
result: Optional[BlowOutResult] = None
|
|
129
134
|
|
|
130
135
|
_ImplementationCls: Type[BlowOutImplementation] = BlowOutImplementation
|
|
131
136
|
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
from typing import TYPE_CHECKING, Optional, Type, Union
|
|
5
|
-
from opentrons_shared_data.errors.exceptions import PipetteOverpressureError
|
|
6
5
|
from typing_extensions import Literal
|
|
7
6
|
from pydantic import BaseModel
|
|
8
7
|
|
|
@@ -10,6 +9,7 @@ from .pipetting_common import (
|
|
|
10
9
|
OverpressureError,
|
|
11
10
|
PipetteIdMixin,
|
|
12
11
|
FlowRateMixin,
|
|
12
|
+
blow_out_in_place,
|
|
13
13
|
)
|
|
14
14
|
from .command import (
|
|
15
15
|
AbstractCommandImpl,
|
|
@@ -72,36 +72,25 @@ class BlowOutInPlaceImplementation(
|
|
|
72
72
|
|
|
73
73
|
async def execute(self, params: BlowOutInPlaceParams) -> _ExecuteReturn:
|
|
74
74
|
"""Blow-out without moving the pipette."""
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
current_position.x,
|
|
95
|
-
current_position.y,
|
|
96
|
-
current_position.z,
|
|
97
|
-
)
|
|
98
|
-
},
|
|
99
|
-
),
|
|
100
|
-
)
|
|
101
|
-
else:
|
|
102
|
-
return SuccessData(
|
|
103
|
-
public=BlowOutInPlaceResult(),
|
|
104
|
-
)
|
|
75
|
+
current_position = await self._gantry_mover.get_position(params.pipetteId)
|
|
76
|
+
result = await blow_out_in_place(
|
|
77
|
+
pipette_id=params.pipetteId,
|
|
78
|
+
flow_rate=params.flowRate,
|
|
79
|
+
location_if_error={
|
|
80
|
+
"retryLocation": (
|
|
81
|
+
current_position.x,
|
|
82
|
+
current_position.y,
|
|
83
|
+
current_position.z,
|
|
84
|
+
)
|
|
85
|
+
},
|
|
86
|
+
pipetting=self._pipetting,
|
|
87
|
+
model_utils=self._model_utils,
|
|
88
|
+
)
|
|
89
|
+
if isinstance(result, DefinedErrorData):
|
|
90
|
+
return result
|
|
91
|
+
return SuccessData(
|
|
92
|
+
public=BlowOutInPlaceResult(), state_update=result.state_update
|
|
93
|
+
)
|
|
105
94
|
|
|
106
95
|
|
|
107
96
|
class BlowOutInPlace(
|
|
@@ -111,7 +100,7 @@ class BlowOutInPlace(
|
|
|
111
100
|
|
|
112
101
|
commandType: BlowOutInPlaceCommandType = "blowOutInPlace"
|
|
113
102
|
params: BlowOutInPlaceParams
|
|
114
|
-
result: Optional[BlowOutInPlaceResult]
|
|
103
|
+
result: Optional[BlowOutInPlaceResult] = None
|
|
115
104
|
|
|
116
105
|
_ImplementationCls: Type[
|
|
117
106
|
BlowOutInPlaceImplementation
|