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
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
|
|
4
4
|
from __future__ import annotations
|
|
5
5
|
|
|
6
|
+
import dataclasses
|
|
6
7
|
from abc import ABC, abstractmethod
|
|
7
|
-
from dataclasses import dataclass
|
|
8
8
|
from datetime import datetime
|
|
9
9
|
from enum import Enum
|
|
10
10
|
from typing import (
|
|
@@ -21,6 +21,7 @@ from pydantic import BaseModel, Field
|
|
|
21
21
|
from pydantic.generics import GenericModel
|
|
22
22
|
|
|
23
23
|
from opentrons.hardware_control import HardwareControlAPI
|
|
24
|
+
from opentrons.protocol_engine.state.update_types import StateUpdate
|
|
24
25
|
|
|
25
26
|
from ..resources import ModelUtils
|
|
26
27
|
from ..errors import ErrorOccurrence
|
|
@@ -29,7 +30,7 @@ from ..notes import CommandNote, CommandNoteAdder
|
|
|
29
30
|
# Work around type-only circular dependencies.
|
|
30
31
|
if TYPE_CHECKING:
|
|
31
32
|
from .. import execution
|
|
32
|
-
from ..state import StateView
|
|
33
|
+
from ..state.state import StateView
|
|
33
34
|
|
|
34
35
|
|
|
35
36
|
_ParamsT = TypeVar("_ParamsT", bound=BaseModel)
|
|
@@ -38,7 +39,6 @@ _ResultT = TypeVar("_ResultT", bound=BaseModel)
|
|
|
38
39
|
_ResultT_co = TypeVar("_ResultT_co", bound=BaseModel, covariant=True)
|
|
39
40
|
_ErrorT = TypeVar("_ErrorT", bound=ErrorOccurrence)
|
|
40
41
|
_ErrorT_co = TypeVar("_ErrorT_co", bound=ErrorOccurrence, covariant=True)
|
|
41
|
-
_PrivateResultT_co = TypeVar("_PrivateResultT_co", covariant=True)
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
class CommandStatus(str, Enum):
|
|
@@ -106,19 +106,23 @@ class BaseCommandCreate(
|
|
|
106
106
|
)
|
|
107
107
|
|
|
108
108
|
|
|
109
|
-
@dataclass(frozen=True)
|
|
110
|
-
class SuccessData(Generic[_ResultT_co
|
|
109
|
+
@dataclasses.dataclass(frozen=True)
|
|
110
|
+
class SuccessData(Generic[_ResultT_co]):
|
|
111
111
|
"""Data from the successful completion of a command."""
|
|
112
112
|
|
|
113
113
|
public: _ResultT_co
|
|
114
114
|
"""Public result data. Exposed over HTTP and stored in databases."""
|
|
115
115
|
|
|
116
|
-
|
|
117
|
-
|
|
116
|
+
state_update: StateUpdate = dataclasses.field(
|
|
117
|
+
# todo(mm, 2024-08-22): Remove the default once all command implementations
|
|
118
|
+
# use this, to make it harder to forget in new command implementations.
|
|
119
|
+
default_factory=StateUpdate
|
|
120
|
+
)
|
|
121
|
+
"""How the engine state should be updated to reflect this command success."""
|
|
118
122
|
|
|
119
123
|
|
|
120
|
-
@dataclass(frozen=True)
|
|
121
|
-
class DefinedErrorData(Generic[_ErrorT_co
|
|
124
|
+
@dataclasses.dataclass(frozen=True)
|
|
125
|
+
class DefinedErrorData(Generic[_ErrorT_co]):
|
|
122
126
|
"""Data from a command that failed with a defined error.
|
|
123
127
|
|
|
124
128
|
This should only be used for "defined" errors, not any error.
|
|
@@ -128,8 +132,16 @@ class DefinedErrorData(Generic[_ErrorT_co, _PrivateResultT_co]):
|
|
|
128
132
|
public: _ErrorT_co
|
|
129
133
|
"""Public error data. Exposed over HTTP and stored in databases."""
|
|
130
134
|
|
|
131
|
-
|
|
132
|
-
|
|
135
|
+
state_update: StateUpdate = dataclasses.field(
|
|
136
|
+
# todo(mm, 2024-08-22): Remove the default once all command implementations
|
|
137
|
+
# use this, to make it harder to forget in new command implementations.
|
|
138
|
+
default_factory=StateUpdate
|
|
139
|
+
)
|
|
140
|
+
"""How the engine state should be updated to reflect this command failure."""
|
|
141
|
+
|
|
142
|
+
state_update_if_false_positive: StateUpdate = dataclasses.field(
|
|
143
|
+
default_factory=StateUpdate
|
|
144
|
+
)
|
|
133
145
|
|
|
134
146
|
|
|
135
147
|
class BaseCommand(
|
|
@@ -173,7 +185,9 @@ class BaseCommand(
|
|
|
173
185
|
)
|
|
174
186
|
error: Union[
|
|
175
187
|
_ErrorT,
|
|
176
|
-
# ErrorOccurrence here is for undefined errors not captured by
|
|
188
|
+
# ErrorOccurrence here is a catch-all for undefined errors not captured by
|
|
189
|
+
# _ErrorT, or defined errors that don't parse into _ErrorT because, for example,
|
|
190
|
+
# they are from an older software version that was missing some fields.
|
|
177
191
|
ErrorOccurrence,
|
|
178
192
|
None,
|
|
179
193
|
] = Field(
|
|
@@ -219,13 +233,11 @@ class BaseCommand(
|
|
|
219
233
|
# Our _ImplementationCls must return public result data that can fit
|
|
220
234
|
# in our `result` field:
|
|
221
235
|
_ResultT,
|
|
222
|
-
# But we don't care (here) what kind of private result data it returns:
|
|
223
|
-
object,
|
|
224
236
|
],
|
|
225
237
|
DefinedErrorData[
|
|
226
|
-
#
|
|
238
|
+
# Our _ImplementationCls must return public error data that can fit
|
|
239
|
+
# in our `error` field:
|
|
227
240
|
_ErrorT,
|
|
228
|
-
object,
|
|
229
241
|
],
|
|
230
242
|
],
|
|
231
243
|
]
|
|
@@ -235,8 +247,8 @@ class BaseCommand(
|
|
|
235
247
|
_ExecuteReturnT_co = TypeVar(
|
|
236
248
|
"_ExecuteReturnT_co",
|
|
237
249
|
bound=Union[
|
|
238
|
-
SuccessData[BaseModel
|
|
239
|
-
DefinedErrorData[ErrorOccurrence
|
|
250
|
+
SuccessData[BaseModel],
|
|
251
|
+
DefinedErrorData[ErrorOccurrence],
|
|
240
252
|
],
|
|
241
253
|
covariant=True,
|
|
242
254
|
)
|
|
@@ -258,6 +270,7 @@ class AbstractCommandImpl(
|
|
|
258
270
|
state_view: StateView,
|
|
259
271
|
hardware_api: HardwareControlAPI,
|
|
260
272
|
equipment: execution.EquipmentHandler,
|
|
273
|
+
file_provider: execution.FileProvider,
|
|
261
274
|
movement: execution.MovementHandler,
|
|
262
275
|
gantry_mover: execution.GantryMover,
|
|
263
276
|
labware_movement: execution.LabwareMovementHandler,
|
|
@@ -10,9 +10,8 @@ from opentrons.util.get_union_elements import get_union_elements
|
|
|
10
10
|
from .command import DefinedErrorData
|
|
11
11
|
from .pipetting_common import (
|
|
12
12
|
OverpressureError,
|
|
13
|
-
OverpressureErrorInternalData,
|
|
14
13
|
LiquidNotFoundError,
|
|
15
|
-
|
|
14
|
+
TipPhysicallyAttachedError,
|
|
16
15
|
)
|
|
17
16
|
|
|
18
17
|
from . import absorbance_reader
|
|
@@ -142,10 +141,10 @@ from .load_pipette import (
|
|
|
142
141
|
LoadPipetteCreate,
|
|
143
142
|
LoadPipetteResult,
|
|
144
143
|
LoadPipetteCommandType,
|
|
145
|
-
LoadPipettePrivateResult,
|
|
146
144
|
)
|
|
147
145
|
|
|
148
146
|
from .move_labware import (
|
|
147
|
+
GripperMovementError,
|
|
149
148
|
MoveLabware,
|
|
150
149
|
MoveLabwareParams,
|
|
151
150
|
MoveLabwareCreate,
|
|
@@ -216,7 +215,6 @@ from .pick_up_tip import (
|
|
|
216
215
|
PickUpTipResult,
|
|
217
216
|
PickUpTipCommandType,
|
|
218
217
|
TipPhysicallyMissingError,
|
|
219
|
-
TipPhysicallyMissingErrorInternalData,
|
|
220
218
|
)
|
|
221
219
|
|
|
222
220
|
from .touch_tip import (
|
|
@@ -273,7 +271,6 @@ from .configure_for_volume import (
|
|
|
273
271
|
ConfigureForVolumeCreate,
|
|
274
272
|
ConfigureForVolumeResult,
|
|
275
273
|
ConfigureForVolumeCommandType,
|
|
276
|
-
ConfigureForVolumePrivateResult,
|
|
277
274
|
)
|
|
278
275
|
|
|
279
276
|
from .prepare_to_aspirate import (
|
|
@@ -290,7 +287,6 @@ from .configure_nozzle_layout import (
|
|
|
290
287
|
ConfigureNozzleLayoutParams,
|
|
291
288
|
ConfigureNozzleLayoutResult,
|
|
292
289
|
ConfigureNozzleLayoutCommandType,
|
|
293
|
-
ConfigureNozzleLayoutPrivateResult,
|
|
294
290
|
)
|
|
295
291
|
|
|
296
292
|
from .verify_tip_presence import (
|
|
@@ -382,8 +378,11 @@ Command = Annotated[
|
|
|
382
378
|
thermocycler.OpenLid,
|
|
383
379
|
thermocycler.CloseLid,
|
|
384
380
|
thermocycler.RunProfile,
|
|
381
|
+
thermocycler.RunExtendedProfile,
|
|
382
|
+
absorbance_reader.CloseLid,
|
|
383
|
+
absorbance_reader.OpenLid,
|
|
385
384
|
absorbance_reader.Initialize,
|
|
386
|
-
absorbance_reader.
|
|
385
|
+
absorbance_reader.ReadAbsorbance,
|
|
387
386
|
calibration.CalibrateGripper,
|
|
388
387
|
calibration.CalibratePipette,
|
|
389
388
|
calibration.CalibrateModule,
|
|
@@ -392,6 +391,8 @@ Command = Annotated[
|
|
|
392
391
|
unsafe.UnsafeDropTipInPlace,
|
|
393
392
|
unsafe.UpdatePositionEstimators,
|
|
394
393
|
unsafe.UnsafeEngageAxes,
|
|
394
|
+
unsafe.UnsafeUngripLabware,
|
|
395
|
+
unsafe.UnsafePlaceLabware,
|
|
395
396
|
],
|
|
396
397
|
Field(discriminator="commandType"),
|
|
397
398
|
]
|
|
@@ -455,8 +456,11 @@ CommandParams = Union[
|
|
|
455
456
|
thermocycler.OpenLidParams,
|
|
456
457
|
thermocycler.CloseLidParams,
|
|
457
458
|
thermocycler.RunProfileParams,
|
|
459
|
+
thermocycler.RunExtendedProfileParams,
|
|
460
|
+
absorbance_reader.CloseLidParams,
|
|
461
|
+
absorbance_reader.OpenLidParams,
|
|
458
462
|
absorbance_reader.InitializeParams,
|
|
459
|
-
absorbance_reader.
|
|
463
|
+
absorbance_reader.ReadAbsorbanceParams,
|
|
460
464
|
calibration.CalibrateGripperParams,
|
|
461
465
|
calibration.CalibratePipetteParams,
|
|
462
466
|
calibration.CalibrateModuleParams,
|
|
@@ -465,6 +469,8 @@ CommandParams = Union[
|
|
|
465
469
|
unsafe.UnsafeDropTipInPlaceParams,
|
|
466
470
|
unsafe.UpdatePositionEstimatorsParams,
|
|
467
471
|
unsafe.UnsafeEngageAxesParams,
|
|
472
|
+
unsafe.UnsafeUngripLabwareParams,
|
|
473
|
+
unsafe.UnsafePlaceLabwareParams,
|
|
468
474
|
]
|
|
469
475
|
|
|
470
476
|
CommandType = Union[
|
|
@@ -526,8 +532,11 @@ CommandType = Union[
|
|
|
526
532
|
thermocycler.OpenLidCommandType,
|
|
527
533
|
thermocycler.CloseLidCommandType,
|
|
528
534
|
thermocycler.RunProfileCommandType,
|
|
535
|
+
thermocycler.RunExtendedProfileCommandType,
|
|
536
|
+
absorbance_reader.CloseLidCommandType,
|
|
537
|
+
absorbance_reader.OpenLidCommandType,
|
|
529
538
|
absorbance_reader.InitializeCommandType,
|
|
530
|
-
absorbance_reader.
|
|
539
|
+
absorbance_reader.ReadAbsorbanceCommandType,
|
|
531
540
|
calibration.CalibrateGripperCommandType,
|
|
532
541
|
calibration.CalibratePipetteCommandType,
|
|
533
542
|
calibration.CalibrateModuleCommandType,
|
|
@@ -536,6 +545,8 @@ CommandType = Union[
|
|
|
536
545
|
unsafe.UnsafeDropTipInPlaceCommandType,
|
|
537
546
|
unsafe.UpdatePositionEstimatorsCommandType,
|
|
538
547
|
unsafe.UnsafeEngageAxesCommandType,
|
|
548
|
+
unsafe.UnsafeUngripLabwareCommandType,
|
|
549
|
+
unsafe.UnsafePlaceLabwareCommandType,
|
|
539
550
|
]
|
|
540
551
|
|
|
541
552
|
CommandCreate = Annotated[
|
|
@@ -598,8 +609,11 @@ CommandCreate = Annotated[
|
|
|
598
609
|
thermocycler.OpenLidCreate,
|
|
599
610
|
thermocycler.CloseLidCreate,
|
|
600
611
|
thermocycler.RunProfileCreate,
|
|
612
|
+
thermocycler.RunExtendedProfileCreate,
|
|
613
|
+
absorbance_reader.CloseLidCreate,
|
|
614
|
+
absorbance_reader.OpenLidCreate,
|
|
601
615
|
absorbance_reader.InitializeCreate,
|
|
602
|
-
absorbance_reader.
|
|
616
|
+
absorbance_reader.ReadAbsorbanceCreate,
|
|
603
617
|
calibration.CalibrateGripperCreate,
|
|
604
618
|
calibration.CalibratePipetteCreate,
|
|
605
619
|
calibration.CalibrateModuleCreate,
|
|
@@ -608,6 +622,8 @@ CommandCreate = Annotated[
|
|
|
608
622
|
unsafe.UnsafeDropTipInPlaceCreate,
|
|
609
623
|
unsafe.UpdatePositionEstimatorsCreate,
|
|
610
624
|
unsafe.UnsafeEngageAxesCreate,
|
|
625
|
+
unsafe.UnsafeUngripLabwareCreate,
|
|
626
|
+
unsafe.UnsafePlaceLabwareCreate,
|
|
611
627
|
],
|
|
612
628
|
Field(discriminator="commandType"),
|
|
613
629
|
]
|
|
@@ -671,8 +687,11 @@ CommandResult = Union[
|
|
|
671
687
|
thermocycler.OpenLidResult,
|
|
672
688
|
thermocycler.CloseLidResult,
|
|
673
689
|
thermocycler.RunProfileResult,
|
|
690
|
+
thermocycler.RunExtendedProfileResult,
|
|
691
|
+
absorbance_reader.CloseLidResult,
|
|
692
|
+
absorbance_reader.OpenLidResult,
|
|
674
693
|
absorbance_reader.InitializeResult,
|
|
675
|
-
absorbance_reader.
|
|
694
|
+
absorbance_reader.ReadAbsorbanceResult,
|
|
676
695
|
calibration.CalibrateGripperResult,
|
|
677
696
|
calibration.CalibratePipetteResult,
|
|
678
697
|
calibration.CalibrateModuleResult,
|
|
@@ -681,24 +700,18 @@ CommandResult = Union[
|
|
|
681
700
|
unsafe.UnsafeDropTipInPlaceResult,
|
|
682
701
|
unsafe.UpdatePositionEstimatorsResult,
|
|
683
702
|
unsafe.UnsafeEngageAxesResult,
|
|
703
|
+
unsafe.UnsafeUngripLabwareResult,
|
|
704
|
+
unsafe.UnsafePlaceLabwareResult,
|
|
684
705
|
]
|
|
685
706
|
|
|
686
|
-
# todo(mm, 2024-06-12): Ideally, command return types would have specific
|
|
687
|
-
# CommandPrivateResults paired with specific CommandResults. For example,
|
|
688
|
-
# a TouchTipResult can never be paired with a LoadPipettePrivateResult in practice,
|
|
689
|
-
# and ideally our types would reflect that.
|
|
690
|
-
CommandPrivateResult = Union[
|
|
691
|
-
None,
|
|
692
|
-
LoadPipettePrivateResult,
|
|
693
|
-
ConfigureForVolumePrivateResult,
|
|
694
|
-
ConfigureNozzleLayoutPrivateResult,
|
|
695
|
-
]
|
|
696
707
|
|
|
697
708
|
# All `DefinedErrorData`s that implementations will actually return in practice.
|
|
698
709
|
CommandDefinedErrorData = Union[
|
|
699
|
-
DefinedErrorData[TipPhysicallyMissingError
|
|
700
|
-
DefinedErrorData[
|
|
701
|
-
DefinedErrorData[
|
|
710
|
+
DefinedErrorData[TipPhysicallyMissingError],
|
|
711
|
+
DefinedErrorData[TipPhysicallyAttachedError],
|
|
712
|
+
DefinedErrorData[OverpressureError],
|
|
713
|
+
DefinedErrorData[LiquidNotFoundError],
|
|
714
|
+
DefinedErrorData[GripperMovementError],
|
|
702
715
|
]
|
|
703
716
|
|
|
704
717
|
|
|
@@ -24,16 +24,18 @@ class CommentResult(BaseModel):
|
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
class CommentImplementation(
|
|
27
|
-
AbstractCommandImpl[CommentParams, SuccessData[CommentResult
|
|
27
|
+
AbstractCommandImpl[CommentParams, SuccessData[CommentResult]]
|
|
28
28
|
):
|
|
29
29
|
"""Comment command implementation."""
|
|
30
30
|
|
|
31
31
|
def __init__(self, **kwargs: object) -> None:
|
|
32
32
|
pass
|
|
33
33
|
|
|
34
|
-
async def execute(self, params: CommentParams) -> SuccessData[CommentResult
|
|
34
|
+
async def execute(self, params: CommentParams) -> SuccessData[CommentResult]:
|
|
35
35
|
"""No operation taken other than capturing message in command."""
|
|
36
|
-
return SuccessData(
|
|
36
|
+
return SuccessData(
|
|
37
|
+
public=CommentResult(),
|
|
38
|
+
)
|
|
37
39
|
|
|
38
40
|
|
|
39
41
|
class Comment(BaseCommand[CommentParams, CommentResult, ErrorOccurrence]):
|
|
@@ -7,7 +7,7 @@ from typing_extensions import Literal
|
|
|
7
7
|
from .pipetting_common import PipetteIdMixin
|
|
8
8
|
from .command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, SuccessData
|
|
9
9
|
from ..errors.error_occurrence import ErrorOccurrence
|
|
10
|
-
from .
|
|
10
|
+
from ..state.update_types import StateUpdate
|
|
11
11
|
|
|
12
12
|
if TYPE_CHECKING:
|
|
13
13
|
from ..execution import EquipmentHandler
|
|
@@ -34,12 +34,6 @@ class ConfigureForVolumeParams(PipetteIdMixin):
|
|
|
34
34
|
)
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
class ConfigureForVolumePrivateResult(PipetteConfigUpdateResultMixin):
|
|
38
|
-
"""Result sent to the store but not serialized."""
|
|
39
|
-
|
|
40
|
-
pass
|
|
41
|
-
|
|
42
|
-
|
|
43
37
|
class ConfigureForVolumeResult(BaseModel):
|
|
44
38
|
"""Result data from execution of an ConfigureForVolume command."""
|
|
45
39
|
|
|
@@ -49,7 +43,7 @@ class ConfigureForVolumeResult(BaseModel):
|
|
|
49
43
|
class ConfigureForVolumeImplementation(
|
|
50
44
|
AbstractCommandImpl[
|
|
51
45
|
ConfigureForVolumeParams,
|
|
52
|
-
SuccessData[ConfigureForVolumeResult
|
|
46
|
+
SuccessData[ConfigureForVolumeResult],
|
|
53
47
|
]
|
|
54
48
|
):
|
|
55
49
|
"""Configure for volume command implementation."""
|
|
@@ -59,7 +53,7 @@ class ConfigureForVolumeImplementation(
|
|
|
59
53
|
|
|
60
54
|
async def execute(
|
|
61
55
|
self, params: ConfigureForVolumeParams
|
|
62
|
-
) -> SuccessData[ConfigureForVolumeResult
|
|
56
|
+
) -> SuccessData[ConfigureForVolumeResult]:
|
|
63
57
|
"""Check that requested pipette can be configured for the given volume."""
|
|
64
58
|
pipette_result = await self._equipment.configure_for_volume(
|
|
65
59
|
pipette_id=params.pipetteId,
|
|
@@ -67,13 +61,16 @@ class ConfigureForVolumeImplementation(
|
|
|
67
61
|
tip_overlap_version=params.tipOverlapNotAfterVersion,
|
|
68
62
|
)
|
|
69
63
|
|
|
64
|
+
state_update = StateUpdate()
|
|
65
|
+
state_update.update_pipette_config(
|
|
66
|
+
pipette_id=pipette_result.pipette_id,
|
|
67
|
+
config=pipette_result.static_config,
|
|
68
|
+
serial_number=pipette_result.serial_number,
|
|
69
|
+
)
|
|
70
|
+
|
|
70
71
|
return SuccessData(
|
|
71
72
|
public=ConfigureForVolumeResult(),
|
|
72
|
-
|
|
73
|
-
pipette_id=pipette_result.pipette_id,
|
|
74
|
-
serial_number=pipette_result.serial_number,
|
|
75
|
-
config=pipette_result.static_config,
|
|
76
|
-
),
|
|
73
|
+
state_update=state_update,
|
|
77
74
|
)
|
|
78
75
|
|
|
79
76
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""Configure nozzle layout command request, result, and implementation models."""
|
|
2
2
|
from __future__ import annotations
|
|
3
|
+
from opentrons.protocol_engine.state.update_types import StateUpdate
|
|
3
4
|
from pydantic import BaseModel
|
|
4
5
|
from typing import TYPE_CHECKING, Optional, Type, Union
|
|
5
6
|
from typing_extensions import Literal
|
|
@@ -9,9 +10,6 @@ from .pipetting_common import (
|
|
|
9
10
|
)
|
|
10
11
|
from .command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, SuccessData
|
|
11
12
|
from ..errors.error_occurrence import ErrorOccurrence
|
|
12
|
-
from .configuring_common import (
|
|
13
|
-
PipetteNozzleLayoutResultMixin,
|
|
14
|
-
)
|
|
15
13
|
from ..types import (
|
|
16
14
|
AllNozzleLayoutConfiguration,
|
|
17
15
|
SingleNozzleLayoutConfiguration,
|
|
@@ -39,12 +37,6 @@ class ConfigureNozzleLayoutParams(PipetteIdMixin):
|
|
|
39
37
|
]
|
|
40
38
|
|
|
41
39
|
|
|
42
|
-
class ConfigureNozzleLayoutPrivateResult(PipetteNozzleLayoutResultMixin):
|
|
43
|
-
"""Result sent to the store but not serialized."""
|
|
44
|
-
|
|
45
|
-
pass
|
|
46
|
-
|
|
47
|
-
|
|
48
40
|
class ConfigureNozzleLayoutResult(BaseModel):
|
|
49
41
|
"""Result data from execution of an configureNozzleLayout command."""
|
|
50
42
|
|
|
@@ -54,7 +46,7 @@ class ConfigureNozzleLayoutResult(BaseModel):
|
|
|
54
46
|
class ConfigureNozzleLayoutImplementation(
|
|
55
47
|
AbstractCommandImpl[
|
|
56
48
|
ConfigureNozzleLayoutParams,
|
|
57
|
-
SuccessData[ConfigureNozzleLayoutResult
|
|
49
|
+
SuccessData[ConfigureNozzleLayoutResult],
|
|
58
50
|
]
|
|
59
51
|
):
|
|
60
52
|
"""Configure nozzle layout command implementation."""
|
|
@@ -67,7 +59,7 @@ class ConfigureNozzleLayoutImplementation(
|
|
|
67
59
|
|
|
68
60
|
async def execute(
|
|
69
61
|
self, params: ConfigureNozzleLayoutParams
|
|
70
|
-
) -> SuccessData[ConfigureNozzleLayoutResult
|
|
62
|
+
) -> SuccessData[ConfigureNozzleLayoutResult]:
|
|
71
63
|
"""Check that requested pipette can support the requested nozzle layout."""
|
|
72
64
|
primary_nozzle = params.configurationParams.dict().get("primaryNozzle")
|
|
73
65
|
front_right_nozzle = params.configurationParams.dict().get("frontRightNozzle")
|
|
@@ -85,12 +77,14 @@ class ConfigureNozzleLayoutImplementation(
|
|
|
85
77
|
**nozzle_params,
|
|
86
78
|
)
|
|
87
79
|
|
|
80
|
+
update_state = StateUpdate()
|
|
81
|
+
update_state.update_pipette_nozzle(
|
|
82
|
+
pipette_id=params.pipetteId, nozzle_map=nozzle_map
|
|
83
|
+
)
|
|
84
|
+
|
|
88
85
|
return SuccessData(
|
|
89
86
|
public=ConfigureNozzleLayoutResult(),
|
|
90
|
-
|
|
91
|
-
pipette_id=params.pipetteId,
|
|
92
|
-
nozzle_map=nozzle_map,
|
|
93
|
-
),
|
|
87
|
+
state_update=update_state,
|
|
94
88
|
)
|
|
95
89
|
|
|
96
90
|
|
|
@@ -40,16 +40,18 @@ class CustomResult(BaseModel):
|
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
class CustomImplementation(
|
|
43
|
-
AbstractCommandImpl[CustomParams, SuccessData[CustomResult
|
|
43
|
+
AbstractCommandImpl[CustomParams, SuccessData[CustomResult]]
|
|
44
44
|
):
|
|
45
45
|
"""Custom command implementation."""
|
|
46
46
|
|
|
47
47
|
# TODO(mm, 2022-11-09): figure out how a plugin can specify a custom command
|
|
48
48
|
# implementation. For now, always no-op, so we can use custom commands as containers
|
|
49
49
|
# for legacy RPC (pre-ProtocolEngine) payloads.
|
|
50
|
-
async def execute(self, params: CustomParams) -> SuccessData[CustomResult
|
|
50
|
+
async def execute(self, params: CustomParams) -> SuccessData[CustomResult]:
|
|
51
51
|
"""A custom command does nothing when executed directly."""
|
|
52
|
-
return SuccessData(
|
|
52
|
+
return SuccessData(
|
|
53
|
+
public=CustomResult.construct(),
|
|
54
|
+
)
|
|
53
55
|
|
|
54
56
|
|
|
55
57
|
class Custom(BaseCommand[CustomParams, CustomResult, ErrorOccurrence]):
|
|
@@ -8,15 +8,15 @@ from opentrons_shared_data.errors.exceptions import PipetteOverpressureError
|
|
|
8
8
|
from pydantic import Field
|
|
9
9
|
|
|
10
10
|
from ..types import DeckPoint
|
|
11
|
+
from ..state.update_types import StateUpdate, CLEAR
|
|
11
12
|
from .pipetting_common import (
|
|
12
13
|
PipetteIdMixin,
|
|
13
14
|
DispenseVolumeMixin,
|
|
14
15
|
FlowRateMixin,
|
|
15
|
-
|
|
16
|
+
LiquidHandlingWellLocationMixin,
|
|
16
17
|
BaseLiquidHandlingResult,
|
|
17
18
|
DestinationPositionResult,
|
|
18
19
|
OverpressureError,
|
|
19
|
-
OverpressureErrorInternalData,
|
|
20
20
|
)
|
|
21
21
|
from .command import (
|
|
22
22
|
AbstractCommandImpl,
|
|
@@ -30,13 +30,14 @@ from ..errors.error_occurrence import ErrorOccurrence
|
|
|
30
30
|
if TYPE_CHECKING:
|
|
31
31
|
from ..execution import MovementHandler, PipettingHandler
|
|
32
32
|
from ..resources import ModelUtils
|
|
33
|
+
from ..state.state import StateView
|
|
33
34
|
|
|
34
35
|
|
|
35
36
|
DispenseCommandType = Literal["dispense"]
|
|
36
37
|
|
|
37
38
|
|
|
38
39
|
class DispenseParams(
|
|
39
|
-
PipetteIdMixin, DispenseVolumeMixin, FlowRateMixin,
|
|
40
|
+
PipetteIdMixin, DispenseVolumeMixin, FlowRateMixin, LiquidHandlingWellLocationMixin
|
|
40
41
|
):
|
|
41
42
|
"""Payload required to dispense to a specific well."""
|
|
42
43
|
|
|
@@ -53,8 +54,8 @@ class DispenseResult(BaseLiquidHandlingResult, DestinationPositionResult):
|
|
|
53
54
|
|
|
54
55
|
|
|
55
56
|
_ExecuteReturn = Union[
|
|
56
|
-
SuccessData[DispenseResult
|
|
57
|
-
DefinedErrorData[OverpressureError
|
|
57
|
+
SuccessData[DispenseResult],
|
|
58
|
+
DefinedErrorData[OverpressureError],
|
|
58
59
|
]
|
|
59
60
|
|
|
60
61
|
|
|
@@ -63,31 +64,54 @@ class DispenseImplementation(AbstractCommandImpl[DispenseParams, _ExecuteReturn]
|
|
|
63
64
|
|
|
64
65
|
def __init__(
|
|
65
66
|
self,
|
|
67
|
+
state_view: StateView,
|
|
66
68
|
movement: MovementHandler,
|
|
67
69
|
pipetting: PipettingHandler,
|
|
68
70
|
model_utils: ModelUtils,
|
|
69
71
|
**kwargs: object,
|
|
70
72
|
) -> None:
|
|
73
|
+
self._state_view = state_view
|
|
71
74
|
self._movement = movement
|
|
72
75
|
self._pipetting = pipetting
|
|
73
76
|
self._model_utils = model_utils
|
|
74
77
|
|
|
75
78
|
async def execute(self, params: DispenseParams) -> _ExecuteReturn:
|
|
76
79
|
"""Move to and dispense to the requested well."""
|
|
80
|
+
state_update = StateUpdate()
|
|
81
|
+
well_location = params.wellLocation
|
|
82
|
+
labware_id = params.labwareId
|
|
83
|
+
well_name = params.wellName
|
|
84
|
+
volume = params.volume
|
|
85
|
+
|
|
86
|
+
# TODO(pbm, 10-15-24): call self._state_view.geometry.validate_dispense_volume_into_well()
|
|
87
|
+
|
|
77
88
|
position = await self._movement.move_to_well(
|
|
78
89
|
pipette_id=params.pipetteId,
|
|
79
|
-
labware_id=
|
|
80
|
-
well_name=
|
|
81
|
-
well_location=
|
|
90
|
+
labware_id=labware_id,
|
|
91
|
+
well_name=well_name,
|
|
92
|
+
well_location=well_location,
|
|
82
93
|
)
|
|
94
|
+
deck_point = DeckPoint.construct(x=position.x, y=position.y, z=position.z)
|
|
95
|
+
state_update.set_pipette_location(
|
|
96
|
+
pipette_id=params.pipetteId,
|
|
97
|
+
new_labware_id=labware_id,
|
|
98
|
+
new_well_name=well_name,
|
|
99
|
+
new_deck_point=deck_point,
|
|
100
|
+
)
|
|
101
|
+
|
|
83
102
|
try:
|
|
84
103
|
volume = await self._pipetting.dispense_in_place(
|
|
85
104
|
pipette_id=params.pipetteId,
|
|
86
|
-
volume=
|
|
105
|
+
volume=volume,
|
|
87
106
|
flow_rate=params.flowRate,
|
|
88
107
|
push_out=params.pushOut,
|
|
89
108
|
)
|
|
90
109
|
except PipetteOverpressureError as e:
|
|
110
|
+
state_update.set_liquid_operated(
|
|
111
|
+
labware_id=labware_id,
|
|
112
|
+
well_name=well_name,
|
|
113
|
+
volume_added=CLEAR,
|
|
114
|
+
)
|
|
91
115
|
return DefinedErrorData(
|
|
92
116
|
public=OverpressureError(
|
|
93
117
|
id=self._model_utils.generate_id(),
|
|
@@ -101,23 +125,21 @@ class DispenseImplementation(AbstractCommandImpl[DispenseParams, _ExecuteReturn]
|
|
|
101
125
|
],
|
|
102
126
|
errorInfo={"retryLocation": (position.x, position.y, position.z)},
|
|
103
127
|
),
|
|
104
|
-
|
|
105
|
-
position=DeckPoint.construct(
|
|
106
|
-
x=position.x, y=position.y, z=position.z
|
|
107
|
-
)
|
|
108
|
-
),
|
|
128
|
+
state_update=state_update,
|
|
109
129
|
)
|
|
110
130
|
else:
|
|
131
|
+
state_update.set_liquid_operated(
|
|
132
|
+
labware_id=labware_id,
|
|
133
|
+
well_name=well_name,
|
|
134
|
+
volume_added=volume,
|
|
135
|
+
)
|
|
111
136
|
return SuccessData(
|
|
112
|
-
public=DispenseResult(
|
|
113
|
-
|
|
114
|
-
position=DeckPoint(x=position.x, y=position.y, z=position.z),
|
|
115
|
-
),
|
|
116
|
-
private=None,
|
|
137
|
+
public=DispenseResult(volume=volume, position=deck_point),
|
|
138
|
+
state_update=state_update,
|
|
117
139
|
)
|
|
118
140
|
|
|
119
141
|
|
|
120
|
-
class Dispense(BaseCommand[DispenseParams, DispenseResult,
|
|
142
|
+
class Dispense(BaseCommand[DispenseParams, DispenseResult, OverpressureError]):
|
|
121
143
|
"""Dispense command model."""
|
|
122
144
|
|
|
123
145
|
commandType: DispenseCommandType = "dispense"
|