opentrons 8.1.0__py2.py3-none-any.whl → 8.2.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/cli/analyze.py +71 -7
- opentrons/config/__init__.py +9 -0
- opentrons/config/advanced_settings.py +22 -0
- opentrons/config/defaults_ot3.py +14 -36
- opentrons/config/feature_flags.py +4 -0
- opentrons/config/types.py +6 -17
- opentrons/drivers/absorbance_reader/abstract.py +27 -3
- opentrons/drivers/absorbance_reader/async_byonoy.py +208 -154
- opentrons/drivers/absorbance_reader/driver.py +24 -15
- opentrons/drivers/absorbance_reader/hid_protocol.py +79 -50
- opentrons/drivers/absorbance_reader/simulator.py +32 -6
- opentrons/drivers/types.py +23 -1
- opentrons/execute.py +2 -2
- opentrons/hardware_control/api.py +18 -10
- opentrons/hardware_control/backends/controller.py +3 -2
- opentrons/hardware_control/backends/flex_protocol.py +11 -5
- opentrons/hardware_control/backends/ot3controller.py +18 -50
- opentrons/hardware_control/backends/ot3simulator.py +7 -6
- opentrons/hardware_control/backends/ot3utils.py +1 -0
- opentrons/hardware_control/instruments/ot2/pipette_handler.py +22 -82
- opentrons/hardware_control/instruments/ot3/pipette_handler.py +10 -2
- opentrons/hardware_control/module_control.py +43 -2
- opentrons/hardware_control/modules/__init__.py +7 -1
- opentrons/hardware_control/modules/absorbance_reader.py +232 -83
- opentrons/hardware_control/modules/errors.py +7 -0
- opentrons/hardware_control/modules/heater_shaker.py +8 -3
- opentrons/hardware_control/modules/magdeck.py +12 -3
- opentrons/hardware_control/modules/mod_abc.py +27 -2
- opentrons/hardware_control/modules/tempdeck.py +15 -7
- opentrons/hardware_control/modules/thermocycler.py +69 -3
- opentrons/hardware_control/modules/types.py +11 -5
- opentrons/hardware_control/modules/update.py +11 -5
- opentrons/hardware_control/modules/utils.py +3 -1
- opentrons/hardware_control/ot3_calibration.py +6 -6
- opentrons/hardware_control/ot3api.py +131 -94
- opentrons/hardware_control/poller.py +15 -11
- opentrons/hardware_control/protocols/__init__.py +1 -7
- opentrons/hardware_control/protocols/instrument_configurer.py +14 -2
- opentrons/hardware_control/protocols/liquid_handler.py +5 -0
- opentrons/hardware_control/protocols/position_estimator.py +3 -1
- opentrons/hardware_control/types.py +2 -0
- opentrons/legacy_commands/helpers.py +8 -2
- opentrons/motion_planning/__init__.py +2 -0
- opentrons/motion_planning/waypoints.py +32 -0
- opentrons/protocol_api/__init__.py +2 -1
- opentrons/protocol_api/_liquid.py +87 -1
- opentrons/protocol_api/_parameter_context.py +10 -1
- opentrons/protocol_api/core/engine/deck_conflict.py +0 -297
- opentrons/protocol_api/core/engine/instrument.py +29 -25
- opentrons/protocol_api/core/engine/labware.py +20 -4
- opentrons/protocol_api/core/engine/module_core.py +166 -17
- opentrons/protocol_api/core/engine/pipette_movement_conflict.py +362 -0
- opentrons/protocol_api/core/engine/protocol.py +30 -2
- opentrons/protocol_api/core/instrument.py +2 -0
- opentrons/protocol_api/core/labware.py +4 -0
- opentrons/protocol_api/core/legacy/legacy_instrument_core.py +2 -0
- opentrons/protocol_api/core/legacy/legacy_labware_core.py +5 -0
- opentrons/protocol_api/core/legacy/legacy_protocol_core.py +6 -2
- opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py +2 -0
- opentrons/protocol_api/core/module.py +22 -4
- opentrons/protocol_api/core/protocol.py +6 -2
- opentrons/protocol_api/instrument_context.py +52 -20
- opentrons/protocol_api/labware.py +13 -1
- opentrons/protocol_api/module_contexts.py +115 -17
- opentrons/protocol_api/protocol_context.py +49 -5
- opentrons/protocol_api/validation.py +5 -3
- opentrons/protocol_engine/__init__.py +10 -9
- opentrons/protocol_engine/actions/__init__.py +3 -0
- opentrons/protocol_engine/actions/actions.py +30 -25
- opentrons/protocol_engine/actions/get_state_update.py +38 -0
- opentrons/protocol_engine/clients/sync_client.py +1 -1
- opentrons/protocol_engine/clients/transports.py +1 -1
- opentrons/protocol_engine/commands/__init__.py +0 -4
- opentrons/protocol_engine/commands/absorbance_reader/__init__.py +41 -11
- opentrons/protocol_engine/commands/absorbance_reader/close_lid.py +148 -0
- opentrons/protocol_engine/commands/absorbance_reader/initialize.py +65 -9
- opentrons/protocol_engine/commands/absorbance_reader/open_lid.py +148 -0
- opentrons/protocol_engine/commands/absorbance_reader/read.py +200 -0
- opentrons/protocol_engine/commands/aspirate.py +29 -16
- opentrons/protocol_engine/commands/aspirate_in_place.py +33 -16
- opentrons/protocol_engine/commands/blow_out.py +63 -14
- opentrons/protocol_engine/commands/blow_out_in_place.py +55 -13
- opentrons/protocol_engine/commands/calibration/calibrate_gripper.py +2 -5
- opentrons/protocol_engine/commands/calibration/calibrate_module.py +3 -4
- opentrons/protocol_engine/commands/calibration/calibrate_pipette.py +2 -5
- opentrons/protocol_engine/commands/calibration/move_to_maintenance_position.py +6 -4
- opentrons/protocol_engine/commands/command.py +31 -18
- opentrons/protocol_engine/commands/command_unions.py +37 -24
- opentrons/protocol_engine/commands/comment.py +5 -3
- opentrons/protocol_engine/commands/configure_for_volume.py +11 -14
- opentrons/protocol_engine/commands/configure_nozzle_layout.py +9 -15
- opentrons/protocol_engine/commands/custom.py +5 -3
- opentrons/protocol_engine/commands/dispense.py +42 -20
- opentrons/protocol_engine/commands/dispense_in_place.py +32 -14
- opentrons/protocol_engine/commands/drop_tip.py +70 -16
- opentrons/protocol_engine/commands/drop_tip_in_place.py +59 -13
- opentrons/protocol_engine/commands/get_tip_presence.py +5 -3
- opentrons/protocol_engine/commands/heater_shaker/close_labware_latch.py +6 -6
- opentrons/protocol_engine/commands/heater_shaker/deactivate_heater.py +6 -6
- opentrons/protocol_engine/commands/heater_shaker/deactivate_shaker.py +6 -6
- opentrons/protocol_engine/commands/heater_shaker/open_labware_latch.py +8 -6
- opentrons/protocol_engine/commands/heater_shaker/set_and_wait_for_shake_speed.py +8 -4
- opentrons/protocol_engine/commands/heater_shaker/set_target_temperature.py +6 -4
- opentrons/protocol_engine/commands/heater_shaker/wait_for_temperature.py +6 -6
- opentrons/protocol_engine/commands/home.py +11 -5
- opentrons/protocol_engine/commands/liquid_probe.py +146 -88
- opentrons/protocol_engine/commands/load_labware.py +28 -5
- opentrons/protocol_engine/commands/load_liquid.py +18 -7
- opentrons/protocol_engine/commands/load_module.py +4 -6
- opentrons/protocol_engine/commands/load_pipette.py +18 -17
- opentrons/protocol_engine/commands/magnetic_module/disengage.py +6 -6
- opentrons/protocol_engine/commands/magnetic_module/engage.py +6 -4
- opentrons/protocol_engine/commands/move_labware.py +155 -23
- opentrons/protocol_engine/commands/move_relative.py +15 -3
- opentrons/protocol_engine/commands/move_to_addressable_area.py +29 -4
- opentrons/protocol_engine/commands/move_to_addressable_area_for_drop_tip.py +13 -4
- opentrons/protocol_engine/commands/move_to_coordinates.py +11 -5
- opentrons/protocol_engine/commands/move_to_well.py +37 -10
- opentrons/protocol_engine/commands/pick_up_tip.py +51 -30
- opentrons/protocol_engine/commands/pipetting_common.py +47 -16
- opentrons/protocol_engine/commands/prepare_to_aspirate.py +62 -15
- opentrons/protocol_engine/commands/reload_labware.py +13 -4
- opentrons/protocol_engine/commands/retract_axis.py +6 -3
- opentrons/protocol_engine/commands/save_position.py +2 -3
- opentrons/protocol_engine/commands/set_rail_lights.py +5 -3
- opentrons/protocol_engine/commands/set_status_bar.py +5 -3
- opentrons/protocol_engine/commands/temperature_module/deactivate.py +6 -4
- opentrons/protocol_engine/commands/temperature_module/set_target_temperature.py +3 -4
- opentrons/protocol_engine/commands/temperature_module/wait_for_temperature.py +6 -6
- opentrons/protocol_engine/commands/thermocycler/__init__.py +19 -0
- opentrons/protocol_engine/commands/thermocycler/close_lid.py +8 -8
- opentrons/protocol_engine/commands/thermocycler/deactivate_block.py +6 -4
- opentrons/protocol_engine/commands/thermocycler/deactivate_lid.py +6 -4
- opentrons/protocol_engine/commands/thermocycler/open_lid.py +8 -4
- opentrons/protocol_engine/commands/thermocycler/run_extended_profile.py +165 -0
- opentrons/protocol_engine/commands/thermocycler/run_profile.py +6 -6
- opentrons/protocol_engine/commands/thermocycler/set_target_block_temperature.py +3 -4
- opentrons/protocol_engine/commands/thermocycler/set_target_lid_temperature.py +3 -4
- opentrons/protocol_engine/commands/thermocycler/wait_for_block_temperature.py +6 -4
- opentrons/protocol_engine/commands/thermocycler/wait_for_lid_temperature.py +6 -4
- opentrons/protocol_engine/commands/touch_tip.py +19 -7
- opentrons/protocol_engine/commands/unsafe/__init__.py +30 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_blow_out_in_place.py +6 -4
- opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py +12 -4
- opentrons/protocol_engine/commands/unsafe/unsafe_engage_axes.py +5 -3
- opentrons/protocol_engine/commands/unsafe/unsafe_place_labware.py +208 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_ungrip_labware.py +77 -0
- opentrons/protocol_engine/commands/unsafe/update_position_estimators.py +10 -4
- opentrons/protocol_engine/commands/verify_tip_presence.py +5 -5
- opentrons/protocol_engine/commands/wait_for_duration.py +5 -3
- opentrons/protocol_engine/commands/wait_for_resume.py +5 -3
- opentrons/protocol_engine/create_protocol_engine.py +60 -10
- opentrons/protocol_engine/engine_support.py +2 -1
- opentrons/protocol_engine/error_recovery_policy.py +14 -3
- opentrons/protocol_engine/errors/__init__.py +20 -0
- opentrons/protocol_engine/errors/error_occurrence.py +8 -3
- opentrons/protocol_engine/errors/exceptions.py +127 -2
- opentrons/protocol_engine/execution/__init__.py +2 -0
- opentrons/protocol_engine/execution/command_executor.py +22 -13
- opentrons/protocol_engine/execution/create_queue_worker.py +5 -1
- opentrons/protocol_engine/execution/door_watcher.py +1 -1
- opentrons/protocol_engine/execution/equipment.py +2 -1
- opentrons/protocol_engine/execution/error_recovery_hardware_state_synchronizer.py +101 -0
- opentrons/protocol_engine/execution/gantry_mover.py +4 -2
- opentrons/protocol_engine/execution/hardware_stopper.py +3 -3
- opentrons/protocol_engine/execution/heater_shaker_movement_flagger.py +1 -4
- opentrons/protocol_engine/execution/labware_movement.py +73 -22
- opentrons/protocol_engine/execution/movement.py +17 -7
- opentrons/protocol_engine/execution/pipetting.py +7 -4
- opentrons/protocol_engine/execution/queue_worker.py +6 -2
- opentrons/protocol_engine/execution/run_control.py +1 -1
- opentrons/protocol_engine/execution/thermocycler_movement_flagger.py +1 -1
- opentrons/protocol_engine/execution/thermocycler_plate_lifter.py +2 -1
- opentrons/protocol_engine/execution/tip_handler.py +77 -43
- opentrons/protocol_engine/notes/__init__.py +14 -2
- opentrons/protocol_engine/notes/notes.py +18 -1
- opentrons/protocol_engine/plugins.py +1 -1
- opentrons/protocol_engine/protocol_engine.py +47 -31
- opentrons/protocol_engine/resources/__init__.py +2 -0
- opentrons/protocol_engine/resources/deck_data_provider.py +19 -5
- opentrons/protocol_engine/resources/file_provider.py +161 -0
- opentrons/protocol_engine/resources/fixture_validation.py +11 -1
- opentrons/protocol_engine/resources/labware_validation.py +10 -0
- opentrons/protocol_engine/state/__init__.py +0 -70
- opentrons/protocol_engine/state/addressable_areas.py +1 -1
- opentrons/protocol_engine/state/command_history.py +21 -2
- opentrons/protocol_engine/state/commands.py +110 -31
- opentrons/protocol_engine/state/files.py +59 -0
- opentrons/protocol_engine/state/frustum_helpers.py +440 -0
- opentrons/protocol_engine/state/geometry.py +445 -59
- opentrons/protocol_engine/state/labware.py +264 -84
- opentrons/protocol_engine/state/liquids.py +1 -1
- opentrons/protocol_engine/state/module_substates/absorbance_reader_substate.py +21 -3
- opentrons/protocol_engine/state/modules.py +145 -90
- opentrons/protocol_engine/state/motion.py +33 -14
- opentrons/protocol_engine/state/pipettes.py +157 -317
- opentrons/protocol_engine/state/state.py +30 -1
- opentrons/protocol_engine/state/state_summary.py +3 -0
- opentrons/protocol_engine/state/tips.py +69 -114
- opentrons/protocol_engine/state/update_types.py +424 -0
- opentrons/protocol_engine/state/wells.py +236 -0
- opentrons/protocol_engine/types.py +90 -0
- opentrons/protocol_reader/file_format_validator.py +83 -15
- opentrons/protocol_runner/json_translator.py +21 -5
- opentrons/protocol_runner/legacy_command_mapper.py +27 -6
- opentrons/protocol_runner/legacy_context_plugin.py +27 -71
- opentrons/protocol_runner/protocol_runner.py +6 -3
- opentrons/protocol_runner/run_orchestrator.py +41 -6
- opentrons/protocols/advanced_control/mix.py +3 -5
- opentrons/protocols/advanced_control/transfers.py +125 -56
- opentrons/protocols/api_support/constants.py +1 -1
- opentrons/protocols/api_support/definitions.py +1 -1
- opentrons/protocols/api_support/labware_like.py +4 -4
- opentrons/protocols/api_support/tip_tracker.py +2 -2
- opentrons/protocols/api_support/types.py +15 -2
- opentrons/protocols/api_support/util.py +30 -42
- opentrons/protocols/duration/errors.py +1 -1
- opentrons/protocols/duration/estimator.py +50 -29
- opentrons/protocols/execution/dev_types.py +2 -2
- opentrons/protocols/execution/execute_json_v4.py +15 -10
- opentrons/protocols/execution/execute_python.py +8 -3
- opentrons/protocols/geometry/planning.py +12 -12
- opentrons/protocols/labware.py +17 -33
- opentrons/protocols/parameters/csv_parameter_interface.py +3 -1
- opentrons/simulate.py +3 -3
- opentrons/types.py +30 -3
- opentrons/util/logging_config.py +34 -0
- {opentrons-8.1.0.dist-info → opentrons-8.2.0.dist-info}/METADATA +5 -4
- {opentrons-8.1.0.dist-info → opentrons-8.2.0.dist-info}/RECORD +235 -223
- opentrons/protocol_engine/commands/absorbance_reader/measure.py +0 -94
- opentrons/protocol_engine/commands/configuring_common.py +0 -26
- opentrons/protocol_runner/thread_async_queue.py +0 -174
- /opentrons/protocol_engine/state/{abstract_store.py → _abstract_store.py} +0 -0
- /opentrons/protocol_engine/state/{move_types.py → _move_types.py} +0 -0
- {opentrons-8.1.0.dist-info → opentrons-8.2.0.dist-info}/LICENSE +0 -0
- {opentrons-8.1.0.dist-info → opentrons-8.2.0.dist-info}/WHEEL +0 -0
- {opentrons-8.1.0.dist-info → opentrons-8.2.0.dist-info}/entry_points.txt +0 -0
- {opentrons-8.1.0.dist-info → opentrons-8.2.0.dist-info}/top_level.txt +0 -0
|
@@ -6,11 +6,10 @@ from typing_extensions import Literal
|
|
|
6
6
|
|
|
7
7
|
from .pipetting_common import (
|
|
8
8
|
OverpressureError,
|
|
9
|
-
OverpressureErrorInternalData,
|
|
10
9
|
PipetteIdMixin,
|
|
11
10
|
AspirateVolumeMixin,
|
|
12
11
|
FlowRateMixin,
|
|
13
|
-
|
|
12
|
+
LiquidHandlingWellLocationMixin,
|
|
14
13
|
BaseLiquidHandlingResult,
|
|
15
14
|
DestinationPositionResult,
|
|
16
15
|
)
|
|
@@ -25,12 +24,13 @@ from ..errors.error_occurrence import ErrorOccurrence
|
|
|
25
24
|
|
|
26
25
|
from opentrons.hardware_control import HardwareControlAPI
|
|
27
26
|
|
|
27
|
+
from ..state.update_types import StateUpdate, CLEAR
|
|
28
28
|
from ..types import WellLocation, WellOrigin, CurrentWell, DeckPoint
|
|
29
29
|
|
|
30
30
|
if TYPE_CHECKING:
|
|
31
31
|
from ..execution import MovementHandler, PipettingHandler
|
|
32
32
|
from ..resources import ModelUtils
|
|
33
|
-
from ..state import StateView
|
|
33
|
+
from ..state.state import StateView
|
|
34
34
|
from ..notes import CommandNoteAdder
|
|
35
35
|
|
|
36
36
|
|
|
@@ -38,7 +38,7 @@ AspirateCommandType = Literal["aspirate"]
|
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
class AspirateParams(
|
|
41
|
-
PipetteIdMixin, AspirateVolumeMixin, FlowRateMixin,
|
|
41
|
+
PipetteIdMixin, AspirateVolumeMixin, FlowRateMixin, LiquidHandlingWellLocationMixin
|
|
42
42
|
):
|
|
43
43
|
"""Parameters required to aspirate from a specific well."""
|
|
44
44
|
|
|
@@ -52,8 +52,8 @@ class AspirateResult(BaseLiquidHandlingResult, DestinationPositionResult):
|
|
|
52
52
|
|
|
53
53
|
|
|
54
54
|
_ExecuteReturn = Union[
|
|
55
|
-
SuccessData[AspirateResult
|
|
56
|
-
DefinedErrorData[OverpressureError
|
|
55
|
+
SuccessData[AspirateResult],
|
|
56
|
+
DefinedErrorData[OverpressureError],
|
|
57
57
|
]
|
|
58
58
|
|
|
59
59
|
|
|
@@ -92,6 +92,7 @@ class AspirateImplementation(AbstractCommandImpl[AspirateParams, _ExecuteReturn]
|
|
|
92
92
|
)
|
|
93
93
|
|
|
94
94
|
current_well = None
|
|
95
|
+
state_update = StateUpdate()
|
|
95
96
|
|
|
96
97
|
if not ready_to_aspirate:
|
|
97
98
|
await self._movement.move_to_well(
|
|
@@ -117,6 +118,14 @@ class AspirateImplementation(AbstractCommandImpl[AspirateParams, _ExecuteReturn]
|
|
|
117
118
|
well_name=well_name,
|
|
118
119
|
well_location=params.wellLocation,
|
|
119
120
|
current_well=current_well,
|
|
121
|
+
operation_volume=-params.volume,
|
|
122
|
+
)
|
|
123
|
+
deck_point = DeckPoint.construct(x=position.x, y=position.y, z=position.z)
|
|
124
|
+
state_update.set_pipette_location(
|
|
125
|
+
pipette_id=pipette_id,
|
|
126
|
+
new_labware_id=labware_id,
|
|
127
|
+
new_well_name=well_name,
|
|
128
|
+
new_deck_point=deck_point,
|
|
120
129
|
)
|
|
121
130
|
|
|
122
131
|
try:
|
|
@@ -127,6 +136,11 @@ class AspirateImplementation(AbstractCommandImpl[AspirateParams, _ExecuteReturn]
|
|
|
127
136
|
command_note_adder=self._command_note_adder,
|
|
128
137
|
)
|
|
129
138
|
except PipetteOverpressureError as e:
|
|
139
|
+
state_update.set_liquid_operated(
|
|
140
|
+
labware_id=labware_id,
|
|
141
|
+
well_name=well_name,
|
|
142
|
+
volume_added=CLEAR,
|
|
143
|
+
)
|
|
130
144
|
return DefinedErrorData(
|
|
131
145
|
public=OverpressureError(
|
|
132
146
|
id=self._model_utils.generate_id(),
|
|
@@ -140,25 +154,24 @@ class AspirateImplementation(AbstractCommandImpl[AspirateParams, _ExecuteReturn]
|
|
|
140
154
|
],
|
|
141
155
|
errorInfo={"retryLocation": (position.x, position.y, position.z)},
|
|
142
156
|
),
|
|
143
|
-
|
|
144
|
-
position=DeckPoint.construct(
|
|
145
|
-
x=position.x, y=position.y, z=position.z
|
|
146
|
-
)
|
|
147
|
-
),
|
|
157
|
+
state_update=state_update,
|
|
148
158
|
)
|
|
149
159
|
else:
|
|
160
|
+
state_update.set_liquid_operated(
|
|
161
|
+
labware_id=labware_id,
|
|
162
|
+
well_name=well_name,
|
|
163
|
+
volume_added=-volume_aspirated,
|
|
164
|
+
)
|
|
150
165
|
return SuccessData(
|
|
151
166
|
public=AspirateResult(
|
|
152
167
|
volume=volume_aspirated,
|
|
153
|
-
position=
|
|
154
|
-
x=position.x, y=position.y, z=position.z
|
|
155
|
-
),
|
|
168
|
+
position=deck_point,
|
|
156
169
|
),
|
|
157
|
-
|
|
170
|
+
state_update=state_update,
|
|
158
171
|
)
|
|
159
172
|
|
|
160
173
|
|
|
161
|
-
class Aspirate(BaseCommand[AspirateParams, AspirateResult,
|
|
174
|
+
class Aspirate(BaseCommand[AspirateParams, AspirateResult, OverpressureError]):
|
|
162
175
|
"""Aspirate command model."""
|
|
163
176
|
|
|
164
177
|
commandType: AspirateCommandType = "aspirate"
|
|
@@ -14,7 +14,6 @@ from .pipetting_common import (
|
|
|
14
14
|
FlowRateMixin,
|
|
15
15
|
BaseLiquidHandlingResult,
|
|
16
16
|
OverpressureError,
|
|
17
|
-
OverpressureErrorInternalData,
|
|
18
17
|
)
|
|
19
18
|
from .command import (
|
|
20
19
|
AbstractCommandImpl,
|
|
@@ -25,12 +24,13 @@ from .command import (
|
|
|
25
24
|
)
|
|
26
25
|
from ..errors.error_occurrence import ErrorOccurrence
|
|
27
26
|
from ..errors.exceptions import PipetteNotReadyToAspirateError
|
|
28
|
-
from ..
|
|
27
|
+
from ..state.update_types import StateUpdate, CLEAR
|
|
28
|
+
from ..types import CurrentWell
|
|
29
29
|
|
|
30
30
|
if TYPE_CHECKING:
|
|
31
31
|
from ..execution import PipettingHandler, GantryMover
|
|
32
32
|
from ..resources import ModelUtils
|
|
33
|
-
from ..state import StateView
|
|
33
|
+
from ..state.state import StateView
|
|
34
34
|
from ..notes import CommandNoteAdder
|
|
35
35
|
|
|
36
36
|
AspirateInPlaceCommandType = Literal["aspirateInPlace"]
|
|
@@ -49,8 +49,8 @@ class AspirateInPlaceResult(BaseLiquidHandlingResult):
|
|
|
49
49
|
|
|
50
50
|
|
|
51
51
|
_ExecuteReturn = Union[
|
|
52
|
-
SuccessData[AspirateInPlaceResult
|
|
53
|
-
DefinedErrorData[OverpressureError
|
|
52
|
+
SuccessData[AspirateInPlaceResult],
|
|
53
|
+
DefinedErrorData[OverpressureError],
|
|
54
54
|
]
|
|
55
55
|
|
|
56
56
|
|
|
@@ -83,16 +83,21 @@ class AspirateInPlaceImplementation(
|
|
|
83
83
|
TipNotAttachedError: if no tip is attached to the pipette.
|
|
84
84
|
PipetteNotReadyToAspirateError: pipette plunger is not ready.
|
|
85
85
|
"""
|
|
86
|
+
state_update = StateUpdate()
|
|
87
|
+
|
|
86
88
|
ready_to_aspirate = self._pipetting.get_is_ready_to_aspirate(
|
|
87
89
|
pipette_id=params.pipetteId,
|
|
88
90
|
)
|
|
89
|
-
|
|
90
91
|
if not ready_to_aspirate:
|
|
91
92
|
raise PipetteNotReadyToAspirateError(
|
|
92
93
|
"Pipette cannot aspirate in place because of a previous blow out."
|
|
93
94
|
" The first aspirate following a blow-out must be from a specific well"
|
|
94
95
|
" so the plunger can be reset in a known safe position."
|
|
95
96
|
)
|
|
97
|
+
|
|
98
|
+
current_location = self._state_view.pipettes.get_current_location()
|
|
99
|
+
current_position = await self._gantry_mover.get_position(params.pipetteId)
|
|
100
|
+
|
|
96
101
|
try:
|
|
97
102
|
volume = await self._pipetting.aspirate_in_place(
|
|
98
103
|
pipette_id=params.pipetteId,
|
|
@@ -101,7 +106,15 @@ class AspirateInPlaceImplementation(
|
|
|
101
106
|
command_note_adder=self._command_note_adder,
|
|
102
107
|
)
|
|
103
108
|
except PipetteOverpressureError as e:
|
|
104
|
-
|
|
109
|
+
if (
|
|
110
|
+
isinstance(current_location, CurrentWell)
|
|
111
|
+
and current_location.pipette_id == params.pipetteId
|
|
112
|
+
):
|
|
113
|
+
state_update.set_liquid_operated(
|
|
114
|
+
labware_id=current_location.labware_id,
|
|
115
|
+
well_name=current_location.well_name,
|
|
116
|
+
volume_added=CLEAR,
|
|
117
|
+
)
|
|
105
118
|
return DefinedErrorData(
|
|
106
119
|
public=OverpressureError(
|
|
107
120
|
id=self._model_utils.generate_id(),
|
|
@@ -123,22 +136,26 @@ class AspirateInPlaceImplementation(
|
|
|
123
136
|
}
|
|
124
137
|
),
|
|
125
138
|
),
|
|
126
|
-
|
|
127
|
-
position=DeckPoint(
|
|
128
|
-
x=current_position.x,
|
|
129
|
-
y=current_position.y,
|
|
130
|
-
z=current_position.z,
|
|
131
|
-
),
|
|
132
|
-
),
|
|
139
|
+
state_update=state_update,
|
|
133
140
|
)
|
|
134
141
|
else:
|
|
142
|
+
if (
|
|
143
|
+
isinstance(current_location, CurrentWell)
|
|
144
|
+
and current_location.pipette_id == params.pipetteId
|
|
145
|
+
):
|
|
146
|
+
state_update.set_liquid_operated(
|
|
147
|
+
labware_id=current_location.labware_id,
|
|
148
|
+
well_name=current_location.well_name,
|
|
149
|
+
volume_added=-volume,
|
|
150
|
+
)
|
|
135
151
|
return SuccessData(
|
|
136
|
-
public=AspirateInPlaceResult(volume=volume),
|
|
152
|
+
public=AspirateInPlaceResult(volume=volume),
|
|
153
|
+
state_update=state_update,
|
|
137
154
|
)
|
|
138
155
|
|
|
139
156
|
|
|
140
157
|
class AspirateInPlace(
|
|
141
|
-
BaseCommand[AspirateInPlaceParams, AspirateInPlaceResult,
|
|
158
|
+
BaseCommand[AspirateInPlaceParams, AspirateInPlaceResult, OverpressureError]
|
|
142
159
|
):
|
|
143
160
|
"""AspirateInPlace command model."""
|
|
144
161
|
|
|
@@ -1,16 +1,26 @@
|
|
|
1
1
|
"""Blow-out command request, result, and implementation models."""
|
|
2
2
|
from __future__ import annotations
|
|
3
|
-
from typing import TYPE_CHECKING, Optional, Type
|
|
3
|
+
from typing import TYPE_CHECKING, Optional, Type, Union
|
|
4
|
+
from opentrons_shared_data.errors.exceptions import PipetteOverpressureError
|
|
4
5
|
from typing_extensions import Literal
|
|
5
6
|
|
|
7
|
+
|
|
8
|
+
from ..state.update_types import StateUpdate
|
|
6
9
|
from ..types import DeckPoint
|
|
7
10
|
from .pipetting_common import (
|
|
11
|
+
OverpressureError,
|
|
8
12
|
PipetteIdMixin,
|
|
9
13
|
FlowRateMixin,
|
|
10
14
|
WellLocationMixin,
|
|
11
15
|
DestinationPositionResult,
|
|
12
16
|
)
|
|
13
|
-
from .command import
|
|
17
|
+
from .command import (
|
|
18
|
+
AbstractCommandImpl,
|
|
19
|
+
BaseCommand,
|
|
20
|
+
BaseCommandCreate,
|
|
21
|
+
DefinedErrorData,
|
|
22
|
+
SuccessData,
|
|
23
|
+
)
|
|
14
24
|
from ..errors.error_occurrence import ErrorOccurrence
|
|
15
25
|
|
|
16
26
|
from opentrons.hardware_control import HardwareControlAPI
|
|
@@ -18,7 +28,9 @@ from opentrons.hardware_control import HardwareControlAPI
|
|
|
18
28
|
|
|
19
29
|
if TYPE_CHECKING:
|
|
20
30
|
from ..execution import MovementHandler, PipettingHandler
|
|
21
|
-
from ..state import StateView
|
|
31
|
+
from ..state.state import StateView
|
|
32
|
+
from ..resources import ModelUtils
|
|
33
|
+
|
|
22
34
|
|
|
23
35
|
BlowOutCommandType = Literal["blowout"]
|
|
24
36
|
|
|
@@ -35,9 +47,13 @@ class BlowOutResult(DestinationPositionResult):
|
|
|
35
47
|
pass
|
|
36
48
|
|
|
37
49
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
50
|
+
_ExecuteReturn = Union[
|
|
51
|
+
SuccessData[BlowOutResult],
|
|
52
|
+
DefinedErrorData[OverpressureError],
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class BlowOutImplementation(AbstractCommandImpl[BlowOutParams, _ExecuteReturn]):
|
|
41
57
|
"""BlowOut command implementation."""
|
|
42
58
|
|
|
43
59
|
def __init__(
|
|
@@ -46,29 +62,62 @@ class BlowOutImplementation(
|
|
|
46
62
|
pipetting: PipettingHandler,
|
|
47
63
|
state_view: StateView,
|
|
48
64
|
hardware_api: HardwareControlAPI,
|
|
65
|
+
model_utils: ModelUtils,
|
|
49
66
|
**kwargs: object,
|
|
50
67
|
) -> None:
|
|
51
68
|
self._movement = movement
|
|
52
69
|
self._pipetting = pipetting
|
|
53
70
|
self._state_view = state_view
|
|
54
71
|
self._hardware_api = hardware_api
|
|
72
|
+
self._model_utils = model_utils
|
|
55
73
|
|
|
56
|
-
async def execute(self, params: BlowOutParams) ->
|
|
74
|
+
async def execute(self, params: BlowOutParams) -> _ExecuteReturn:
|
|
57
75
|
"""Move to and blow-out the requested well."""
|
|
76
|
+
state_update = StateUpdate()
|
|
77
|
+
|
|
58
78
|
x, y, z = await self._movement.move_to_well(
|
|
59
79
|
pipette_id=params.pipetteId,
|
|
60
80
|
labware_id=params.labwareId,
|
|
61
81
|
well_name=params.wellName,
|
|
62
82
|
well_location=params.wellLocation,
|
|
63
83
|
)
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
pipette_id=params.pipetteId,
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
public=BlowOutResult(position=DeckPoint(x=x, y=y, z=z)), private=None
|
|
84
|
+
deck_point = DeckPoint.construct(x=x, y=y, z=z)
|
|
85
|
+
state_update.set_pipette_location(
|
|
86
|
+
pipette_id=params.pipetteId,
|
|
87
|
+
new_labware_id=params.labwareId,
|
|
88
|
+
new_well_name=params.wellName,
|
|
89
|
+
new_deck_point=deck_point,
|
|
71
90
|
)
|
|
91
|
+
try:
|
|
92
|
+
await self._pipetting.blow_out_in_place(
|
|
93
|
+
pipette_id=params.pipetteId, flow_rate=params.flowRate
|
|
94
|
+
)
|
|
95
|
+
except PipetteOverpressureError as e:
|
|
96
|
+
return DefinedErrorData(
|
|
97
|
+
public=OverpressureError(
|
|
98
|
+
id=self._model_utils.generate_id(),
|
|
99
|
+
createdAt=self._model_utils.get_timestamp(),
|
|
100
|
+
wrappedErrors=[
|
|
101
|
+
ErrorOccurrence.from_failed(
|
|
102
|
+
id=self._model_utils.generate_id(),
|
|
103
|
+
createdAt=self._model_utils.get_timestamp(),
|
|
104
|
+
error=e,
|
|
105
|
+
)
|
|
106
|
+
],
|
|
107
|
+
errorInfo={
|
|
108
|
+
"retryLocation": (
|
|
109
|
+
x,
|
|
110
|
+
y,
|
|
111
|
+
z,
|
|
112
|
+
)
|
|
113
|
+
},
|
|
114
|
+
),
|
|
115
|
+
)
|
|
116
|
+
else:
|
|
117
|
+
return SuccessData(
|
|
118
|
+
public=BlowOutResult(position=deck_point),
|
|
119
|
+
state_update=state_update,
|
|
120
|
+
)
|
|
72
121
|
|
|
73
122
|
|
|
74
123
|
class BlowOut(BaseCommand[BlowOutParams, BlowOutResult, ErrorOccurrence]):
|
|
@@ -1,23 +1,32 @@
|
|
|
1
1
|
"""Blow-out in place command request, result, and implementation models."""
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
|
-
from typing import TYPE_CHECKING, Optional, Type
|
|
4
|
+
from typing import TYPE_CHECKING, Optional, Type, Union
|
|
5
|
+
from opentrons_shared_data.errors.exceptions import PipetteOverpressureError
|
|
5
6
|
from typing_extensions import Literal
|
|
6
7
|
from pydantic import BaseModel
|
|
7
8
|
|
|
8
9
|
from .pipetting_common import (
|
|
10
|
+
OverpressureError,
|
|
9
11
|
PipetteIdMixin,
|
|
10
12
|
FlowRateMixin,
|
|
11
13
|
)
|
|
12
|
-
from .command import
|
|
14
|
+
from .command import (
|
|
15
|
+
AbstractCommandImpl,
|
|
16
|
+
BaseCommand,
|
|
17
|
+
BaseCommandCreate,
|
|
18
|
+
DefinedErrorData,
|
|
19
|
+
SuccessData,
|
|
20
|
+
)
|
|
13
21
|
from ..errors.error_occurrence import ErrorOccurrence
|
|
14
22
|
|
|
15
23
|
from opentrons.hardware_control import HardwareControlAPI
|
|
16
24
|
|
|
17
25
|
|
|
18
26
|
if TYPE_CHECKING:
|
|
19
|
-
from ..execution import PipettingHandler
|
|
20
|
-
from ..state import StateView
|
|
27
|
+
from ..execution import PipettingHandler, GantryMover
|
|
28
|
+
from ..state.state import StateView
|
|
29
|
+
from ..resources import ModelUtils
|
|
21
30
|
|
|
22
31
|
|
|
23
32
|
BlowOutInPlaceCommandType = Literal["blowOutInPlace"]
|
|
@@ -35,8 +44,14 @@ class BlowOutInPlaceResult(BaseModel):
|
|
|
35
44
|
pass
|
|
36
45
|
|
|
37
46
|
|
|
47
|
+
_ExecuteReturn = Union[
|
|
48
|
+
SuccessData[BlowOutInPlaceResult],
|
|
49
|
+
DefinedErrorData[OverpressureError],
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
|
|
38
53
|
class BlowOutInPlaceImplementation(
|
|
39
|
-
AbstractCommandImpl[BlowOutInPlaceParams,
|
|
54
|
+
AbstractCommandImpl[BlowOutInPlaceParams, _ExecuteReturn]
|
|
40
55
|
):
|
|
41
56
|
"""BlowOutInPlace command implementation."""
|
|
42
57
|
|
|
@@ -45,21 +60,48 @@ class BlowOutInPlaceImplementation(
|
|
|
45
60
|
pipetting: PipettingHandler,
|
|
46
61
|
state_view: StateView,
|
|
47
62
|
hardware_api: HardwareControlAPI,
|
|
63
|
+
model_utils: ModelUtils,
|
|
64
|
+
gantry_mover: GantryMover,
|
|
48
65
|
**kwargs: object,
|
|
49
66
|
) -> None:
|
|
50
67
|
self._pipetting = pipetting
|
|
51
68
|
self._state_view = state_view
|
|
52
69
|
self._hardware_api = hardware_api
|
|
70
|
+
self._model_utils = model_utils
|
|
71
|
+
self._gantry_mover = gantry_mover
|
|
53
72
|
|
|
54
|
-
async def execute(
|
|
55
|
-
self, params: BlowOutInPlaceParams
|
|
56
|
-
) -> SuccessData[BlowOutInPlaceResult, None]:
|
|
73
|
+
async def execute(self, params: BlowOutInPlaceParams) -> _ExecuteReturn:
|
|
57
74
|
"""Blow-out without moving the pipette."""
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
75
|
+
try:
|
|
76
|
+
current_position = await self._gantry_mover.get_position(params.pipetteId)
|
|
77
|
+
await self._pipetting.blow_out_in_place(
|
|
78
|
+
pipette_id=params.pipetteId, flow_rate=params.flowRate
|
|
79
|
+
)
|
|
80
|
+
except PipetteOverpressureError as e:
|
|
81
|
+
return DefinedErrorData(
|
|
82
|
+
public=OverpressureError(
|
|
83
|
+
id=self._model_utils.generate_id(),
|
|
84
|
+
createdAt=self._model_utils.get_timestamp(),
|
|
85
|
+
wrappedErrors=[
|
|
86
|
+
ErrorOccurrence.from_failed(
|
|
87
|
+
id=self._model_utils.generate_id(),
|
|
88
|
+
createdAt=self._model_utils.get_timestamp(),
|
|
89
|
+
error=e,
|
|
90
|
+
)
|
|
91
|
+
],
|
|
92
|
+
errorInfo={
|
|
93
|
+
"retryLocation": (
|
|
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
|
+
)
|
|
63
105
|
|
|
64
106
|
|
|
65
107
|
class BlowOutInPlace(
|
|
@@ -71,9 +71,7 @@ class CalibrateGripperResult(BaseModel):
|
|
|
71
71
|
|
|
72
72
|
|
|
73
73
|
class CalibrateGripperImplementation(
|
|
74
|
-
AbstractCommandImpl[
|
|
75
|
-
CalibrateGripperParams, SuccessData[CalibrateGripperResult, None]
|
|
76
|
-
]
|
|
74
|
+
AbstractCommandImpl[CalibrateGripperParams, SuccessData[CalibrateGripperResult]]
|
|
77
75
|
):
|
|
78
76
|
"""The implementation of a `calibrateGripper` command."""
|
|
79
77
|
|
|
@@ -87,7 +85,7 @@ class CalibrateGripperImplementation(
|
|
|
87
85
|
|
|
88
86
|
async def execute(
|
|
89
87
|
self, params: CalibrateGripperParams
|
|
90
|
-
) -> SuccessData[CalibrateGripperResult
|
|
88
|
+
) -> SuccessData[CalibrateGripperResult]:
|
|
91
89
|
"""Execute a `calibrateGripper` command.
|
|
92
90
|
|
|
93
91
|
1. Move from the current location to the calibration area on the deck.
|
|
@@ -126,7 +124,6 @@ class CalibrateGripperImplementation(
|
|
|
126
124
|
),
|
|
127
125
|
savedCalibration=calibration_data,
|
|
128
126
|
),
|
|
129
|
-
private=None,
|
|
130
127
|
)
|
|
131
128
|
|
|
132
129
|
@staticmethod
|
|
@@ -12,7 +12,7 @@ from ...errors.error_occurrence import ErrorOccurrence
|
|
|
12
12
|
|
|
13
13
|
# Work around type-only circular dependencies.
|
|
14
14
|
if TYPE_CHECKING:
|
|
15
|
-
from ...state import StateView
|
|
15
|
+
from ...state.state import StateView
|
|
16
16
|
|
|
17
17
|
from ...types import ModuleOffsetVector, DeckSlotLocation
|
|
18
18
|
|
|
@@ -49,7 +49,7 @@ class CalibrateModuleResult(BaseModel):
|
|
|
49
49
|
|
|
50
50
|
|
|
51
51
|
class CalibrateModuleImplementation(
|
|
52
|
-
AbstractCommandImpl[CalibrateModuleParams, SuccessData[CalibrateModuleResult
|
|
52
|
+
AbstractCommandImpl[CalibrateModuleParams, SuccessData[CalibrateModuleResult]]
|
|
53
53
|
):
|
|
54
54
|
"""CalibrateModule command implementation."""
|
|
55
55
|
|
|
@@ -64,7 +64,7 @@ class CalibrateModuleImplementation(
|
|
|
64
64
|
|
|
65
65
|
async def execute(
|
|
66
66
|
self, params: CalibrateModuleParams
|
|
67
|
-
) -> SuccessData[CalibrateModuleResult
|
|
67
|
+
) -> SuccessData[CalibrateModuleResult]:
|
|
68
68
|
"""Execute calibrate-module command."""
|
|
69
69
|
ot3_api = ensure_ot3_hardware(
|
|
70
70
|
self._hardware_api,
|
|
@@ -91,7 +91,6 @@ class CalibrateModuleImplementation(
|
|
|
91
91
|
),
|
|
92
92
|
location=slot,
|
|
93
93
|
),
|
|
94
|
-
private=None,
|
|
95
94
|
)
|
|
96
95
|
|
|
97
96
|
|
|
@@ -34,9 +34,7 @@ class CalibratePipetteResult(BaseModel):
|
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
class CalibratePipetteImplementation(
|
|
37
|
-
AbstractCommandImpl[
|
|
38
|
-
CalibratePipetteParams, SuccessData[CalibratePipetteResult, None]
|
|
39
|
-
]
|
|
37
|
+
AbstractCommandImpl[CalibratePipetteParams, SuccessData[CalibratePipetteResult]]
|
|
40
38
|
):
|
|
41
39
|
"""CalibratePipette command implementation."""
|
|
42
40
|
|
|
@@ -49,7 +47,7 @@ class CalibratePipetteImplementation(
|
|
|
49
47
|
|
|
50
48
|
async def execute(
|
|
51
49
|
self, params: CalibratePipetteParams
|
|
52
|
-
) -> SuccessData[CalibratePipetteResult
|
|
50
|
+
) -> SuccessData[CalibratePipetteResult]:
|
|
53
51
|
"""Execute calibrate-pipette command."""
|
|
54
52
|
# TODO (tz, 20-9-22): Add a better solution to determine if a command can be executed on an OT-3/OT-2
|
|
55
53
|
ot3_api = ensure_ot3_hardware(
|
|
@@ -72,7 +70,6 @@ class CalibratePipetteImplementation(
|
|
|
72
70
|
x=pipette_offset.x, y=pipette_offset.y, z=pipette_offset.z
|
|
73
71
|
)
|
|
74
72
|
),
|
|
75
|
-
private=None,
|
|
76
73
|
)
|
|
77
74
|
|
|
78
75
|
|
|
@@ -15,7 +15,7 @@ from opentrons.protocol_engine.resources.ot3_validation import ensure_ot3_hardwa
|
|
|
15
15
|
|
|
16
16
|
if TYPE_CHECKING:
|
|
17
17
|
from opentrons.hardware_control import HardwareControlAPI
|
|
18
|
-
from ...state import StateView
|
|
18
|
+
from ...state.state import StateView
|
|
19
19
|
|
|
20
20
|
# These offsets supplied from HW
|
|
21
21
|
_ATTACH_POINT = Point(x=0, y=110)
|
|
@@ -57,7 +57,7 @@ class MoveToMaintenancePositionResult(BaseModel):
|
|
|
57
57
|
class MoveToMaintenancePositionImplementation(
|
|
58
58
|
AbstractCommandImpl[
|
|
59
59
|
MoveToMaintenancePositionParams,
|
|
60
|
-
SuccessData[MoveToMaintenancePositionResult
|
|
60
|
+
SuccessData[MoveToMaintenancePositionResult],
|
|
61
61
|
]
|
|
62
62
|
):
|
|
63
63
|
"""Calibration set up position command implementation."""
|
|
@@ -73,7 +73,7 @@ class MoveToMaintenancePositionImplementation(
|
|
|
73
73
|
|
|
74
74
|
async def execute(
|
|
75
75
|
self, params: MoveToMaintenancePositionParams
|
|
76
|
-
) -> SuccessData[MoveToMaintenancePositionResult
|
|
76
|
+
) -> SuccessData[MoveToMaintenancePositionResult]:
|
|
77
77
|
"""Move the requested mount to a maintenance deck slot."""
|
|
78
78
|
ot3_api = ensure_ot3_hardware(
|
|
79
79
|
self._hardware_api,
|
|
@@ -118,7 +118,9 @@ class MoveToMaintenancePositionImplementation(
|
|
|
118
118
|
)
|
|
119
119
|
await ot3_api.disengage_axes([Axis.Z_R])
|
|
120
120
|
|
|
121
|
-
return SuccessData(
|
|
121
|
+
return SuccessData(
|
|
122
|
+
public=MoveToMaintenancePositionResult(),
|
|
123
|
+
)
|
|
122
124
|
|
|
123
125
|
|
|
124
126
|
class MoveToMaintenancePosition(
|