opentrons 8.3.0a1__py2.py3-none-any.whl → 8.3.0a4__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- opentrons/hardware_control/api.py +5 -1
- opentrons/hardware_control/ot3api.py +18 -8
- opentrons/hardware_control/protocols/liquid_handler.py +4 -1
- opentrons/hardware_control/protocols/motion_controller.py +1 -0
- opentrons/legacy_commands/commands.py +37 -0
- opentrons/legacy_commands/types.py +39 -0
- opentrons/protocol_api/core/engine/instrument.py +109 -0
- opentrons/protocol_api/core/instrument.py +27 -0
- opentrons/protocol_api/core/legacy/legacy_instrument_core.py +50 -0
- opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py +24 -0
- opentrons/protocol_api/instrument_context.py +141 -0
- opentrons/protocol_engine/commands/__init__.py +40 -0
- opentrons/protocol_engine/commands/absorbance_reader/close_lid.py +1 -1
- opentrons/protocol_engine/commands/absorbance_reader/initialize.py +1 -1
- opentrons/protocol_engine/commands/absorbance_reader/open_lid.py +1 -1
- opentrons/protocol_engine/commands/absorbance_reader/read.py +4 -1
- opentrons/protocol_engine/commands/air_gap_in_place.py +1 -1
- opentrons/protocol_engine/commands/command_unions.py +39 -0
- opentrons/protocol_engine/commands/evotip_dispense.py +156 -0
- opentrons/protocol_engine/commands/evotip_seal_pipette.py +331 -0
- opentrons/protocol_engine/commands/evotip_unseal_pipette.py +160 -0
- opentrons/protocol_engine/commands/get_next_tip.py +1 -1
- opentrons/protocol_engine/commands/liquid_probe.py +63 -12
- opentrons/protocol_engine/commands/load_labware.py +5 -0
- opentrons/protocol_engine/commands/load_lid.py +1 -1
- opentrons/protocol_engine/commands/load_lid_stack.py +1 -1
- opentrons/protocol_engine/commands/load_liquid_class.py +1 -1
- opentrons/protocol_engine/commands/move_labware.py +9 -0
- opentrons/protocol_engine/commands/robot/close_gripper_jaw.py +1 -1
- opentrons/protocol_engine/commands/robot/move_axes_relative.py +1 -1
- opentrons/protocol_engine/commands/robot/move_axes_to.py +1 -1
- opentrons/protocol_engine/commands/robot/move_to.py +1 -1
- opentrons/protocol_engine/commands/robot/open_gripper_jaw.py +1 -1
- opentrons/protocol_engine/commands/thermocycler/run_extended_profile.py +1 -1
- opentrons/protocol_engine/commands/unsafe/unsafe_blow_out_in_place.py +1 -1
- opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py +1 -1
- opentrons/protocol_engine/commands/unsafe/unsafe_engage_axes.py +1 -1
- opentrons/protocol_engine/commands/unsafe/unsafe_place_labware.py +1 -1
- opentrons/protocol_engine/commands/unsafe/unsafe_ungrip_labware.py +1 -1
- opentrons/protocol_engine/commands/unsafe/update_position_estimators.py +1 -1
- opentrons/protocol_engine/errors/__init__.py +4 -0
- opentrons/protocol_engine/errors/exceptions.py +26 -0
- opentrons/protocol_engine/execution/gantry_mover.py +5 -0
- opentrons/protocol_engine/execution/hardware_stopper.py +7 -7
- opentrons/protocol_engine/execution/tip_handler.py +30 -9
- opentrons/protocol_engine/resources/labware_validation.py +13 -0
- opentrons/protocol_engine/state/commands.py +6 -2
- opentrons/protocol_engine/state/frustum_helpers.py +13 -44
- opentrons/protocol_engine/state/labware.py +13 -1
- opentrons/protocol_engine/state/pipettes.py +5 -0
- opentrons/protocols/labware.py +37 -8
- opentrons/util/entrypoint_util.py +2 -5
- {opentrons-8.3.0a1.dist-info → opentrons-8.3.0a4.dist-info}/METADATA +4 -4
- {opentrons-8.3.0a1.dist-info → opentrons-8.3.0a4.dist-info}/RECORD +58 -55
- {opentrons-8.3.0a1.dist-info → opentrons-8.3.0a4.dist-info}/LICENSE +0 -0
- {opentrons-8.3.0a1.dist-info → opentrons-8.3.0a4.dist-info}/WHEEL +0 -0
- {opentrons-8.3.0a1.dist-info → opentrons-8.3.0a4.dist-info}/entry_points.txt +0 -0
- {opentrons-8.3.0a1.dist-info → opentrons-8.3.0a4.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"""Unseal evotip resin tip command request, result, and implementation models."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pydantic import Field
|
|
6
|
+
from typing import TYPE_CHECKING, Optional, Type
|
|
7
|
+
from typing_extensions import Literal
|
|
8
|
+
|
|
9
|
+
from opentrons.protocol_engine.resources.model_utils import ModelUtils
|
|
10
|
+
from opentrons.protocol_engine.errors import UnsupportedLabwareForActionError
|
|
11
|
+
from opentrons.protocol_engine.types import MotorAxis
|
|
12
|
+
from opentrons.types import MountType
|
|
13
|
+
|
|
14
|
+
from ..types import DropTipWellLocation
|
|
15
|
+
from .pipetting_common import (
|
|
16
|
+
PipetteIdMixin,
|
|
17
|
+
)
|
|
18
|
+
from .movement_common import (
|
|
19
|
+
DestinationPositionResult,
|
|
20
|
+
move_to_well,
|
|
21
|
+
StallOrCollisionError,
|
|
22
|
+
)
|
|
23
|
+
from .command import (
|
|
24
|
+
AbstractCommandImpl,
|
|
25
|
+
BaseCommand,
|
|
26
|
+
BaseCommandCreate,
|
|
27
|
+
DefinedErrorData,
|
|
28
|
+
SuccessData,
|
|
29
|
+
)
|
|
30
|
+
from ..resources import labware_validation
|
|
31
|
+
|
|
32
|
+
if TYPE_CHECKING:
|
|
33
|
+
from ..state.state import StateView
|
|
34
|
+
from ..execution import MovementHandler, TipHandler, GantryMover
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
EvotipUnsealPipetteCommandType = Literal["evotipUnsealPipette"]
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class EvotipUnsealPipetteParams(PipetteIdMixin):
|
|
41
|
+
"""Payload required to drop a tip in a specific well."""
|
|
42
|
+
|
|
43
|
+
labwareId: str = Field(..., description="Identifier of labware to use.")
|
|
44
|
+
wellName: str = Field(..., description="Name of well to use in labware.")
|
|
45
|
+
wellLocation: DropTipWellLocation = Field(
|
|
46
|
+
default_factory=DropTipWellLocation,
|
|
47
|
+
description="Relative well location at which to drop the tip.",
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class EvotipUnsealPipetteResult(DestinationPositionResult):
|
|
52
|
+
"""Result data from the execution of a DropTip command."""
|
|
53
|
+
|
|
54
|
+
pass
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
_ExecuteReturn = (
|
|
58
|
+
SuccessData[EvotipUnsealPipetteResult] | DefinedErrorData[StallOrCollisionError]
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class EvotipUnsealPipetteImplementation(
|
|
63
|
+
AbstractCommandImpl[EvotipUnsealPipetteParams, _ExecuteReturn]
|
|
64
|
+
):
|
|
65
|
+
"""Drop tip command implementation."""
|
|
66
|
+
|
|
67
|
+
def __init__(
|
|
68
|
+
self,
|
|
69
|
+
state_view: StateView,
|
|
70
|
+
tip_handler: TipHandler,
|
|
71
|
+
movement: MovementHandler,
|
|
72
|
+
model_utils: ModelUtils,
|
|
73
|
+
gantry_mover: GantryMover,
|
|
74
|
+
**kwargs: object,
|
|
75
|
+
) -> None:
|
|
76
|
+
self._state_view = state_view
|
|
77
|
+
self._tip_handler = tip_handler
|
|
78
|
+
self._movement_handler = movement
|
|
79
|
+
self._model_utils = model_utils
|
|
80
|
+
self._gantry_mover = gantry_mover
|
|
81
|
+
|
|
82
|
+
async def execute(self, params: EvotipUnsealPipetteParams) -> _ExecuteReturn:
|
|
83
|
+
"""Move to and drop a tip using the requested pipette."""
|
|
84
|
+
pipette_id = params.pipetteId
|
|
85
|
+
labware_id = params.labwareId
|
|
86
|
+
well_name = params.wellName
|
|
87
|
+
|
|
88
|
+
well_location = params.wellLocation
|
|
89
|
+
labware_definition = self._state_view.labware.get_definition(params.labwareId)
|
|
90
|
+
if not labware_validation.is_evotips(labware_definition.parameters.loadName):
|
|
91
|
+
raise UnsupportedLabwareForActionError(
|
|
92
|
+
f"Cannot use command: `EvotipUnsealPipette` with labware: {labware_definition.parameters.loadName}"
|
|
93
|
+
)
|
|
94
|
+
is_partially_configured = self._state_view.pipettes.get_is_partially_configured(
|
|
95
|
+
pipette_id=pipette_id
|
|
96
|
+
)
|
|
97
|
+
tip_drop_location = self._state_view.geometry.get_checked_tip_drop_location(
|
|
98
|
+
pipette_id=pipette_id,
|
|
99
|
+
labware_id=labware_id,
|
|
100
|
+
well_location=well_location,
|
|
101
|
+
partially_configured=is_partially_configured,
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
move_result = await move_to_well(
|
|
105
|
+
movement=self._movement_handler,
|
|
106
|
+
model_utils=self._model_utils,
|
|
107
|
+
pipette_id=pipette_id,
|
|
108
|
+
labware_id=labware_id,
|
|
109
|
+
well_name=well_name,
|
|
110
|
+
well_location=tip_drop_location,
|
|
111
|
+
)
|
|
112
|
+
if isinstance(move_result, DefinedErrorData):
|
|
113
|
+
return move_result
|
|
114
|
+
|
|
115
|
+
# Move to an appropriate position
|
|
116
|
+
mount = self._state_view.pipettes.get_mount(pipette_id)
|
|
117
|
+
|
|
118
|
+
mount_axis = MotorAxis.LEFT_Z if mount == MountType.LEFT else MotorAxis.RIGHT_Z
|
|
119
|
+
await self._gantry_mover.move_axes(
|
|
120
|
+
axis_map={mount_axis: -14}, speed=10, relative_move=True
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
await self._tip_handler.drop_tip(
|
|
124
|
+
pipette_id=pipette_id,
|
|
125
|
+
home_after=None,
|
|
126
|
+
do_not_ignore_tip_presence=False,
|
|
127
|
+
ignore_plunger=True,
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
return SuccessData(
|
|
131
|
+
public=EvotipUnsealPipetteResult(position=move_result.public.position),
|
|
132
|
+
state_update=move_result.state_update.set_fluid_unknown(
|
|
133
|
+
pipette_id=pipette_id
|
|
134
|
+
).update_pipette_tip_state(pipette_id=params.pipetteId, tip_geometry=None),
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class EvotipUnsealPipette(
|
|
139
|
+
BaseCommand[
|
|
140
|
+
EvotipUnsealPipetteParams, EvotipUnsealPipetteResult, StallOrCollisionError
|
|
141
|
+
]
|
|
142
|
+
):
|
|
143
|
+
"""Evotip unseal command model."""
|
|
144
|
+
|
|
145
|
+
commandType: EvotipUnsealPipetteCommandType = "evotipUnsealPipette"
|
|
146
|
+
params: EvotipUnsealPipetteParams
|
|
147
|
+
result: Optional[EvotipUnsealPipetteResult] = None
|
|
148
|
+
|
|
149
|
+
_ImplementationCls: Type[
|
|
150
|
+
EvotipUnsealPipetteImplementation
|
|
151
|
+
] = EvotipUnsealPipetteImplementation
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
class EvotipUnsealPipetteCreate(BaseCommandCreate[EvotipUnsealPipetteParams]):
|
|
155
|
+
"""Evotip unseal command creation request model."""
|
|
156
|
+
|
|
157
|
+
commandType: EvotipUnsealPipetteCommandType = "evotipUnsealPipette"
|
|
158
|
+
params: EvotipUnsealPipetteParams
|
|
159
|
+
|
|
160
|
+
_CommandCls: Type[EvotipUnsealPipette] = EvotipUnsealPipette
|
|
@@ -120,7 +120,7 @@ class GetNextTip(BaseCommand[GetNextTipParams, GetNextTipResult, ErrorOccurrence
|
|
|
120
120
|
|
|
121
121
|
commandType: GetNextTipCommandType = "getNextTip"
|
|
122
122
|
params: GetNextTipParams
|
|
123
|
-
result: Optional[GetNextTipResult]
|
|
123
|
+
result: Optional[GetNextTipResult] = None
|
|
124
124
|
|
|
125
125
|
_ImplementationCls: Type[GetNextTipImplementation] = GetNextTipImplementation
|
|
126
126
|
|
|
@@ -19,12 +19,14 @@ from opentrons.types import MountType
|
|
|
19
19
|
from opentrons_shared_data.errors.exceptions import (
|
|
20
20
|
PipetteLiquidNotFoundError,
|
|
21
21
|
UnsupportedHardwareCommand,
|
|
22
|
+
PipetteOverpressureError,
|
|
22
23
|
)
|
|
23
24
|
|
|
24
25
|
from ..types import DeckPoint
|
|
25
26
|
from .pipetting_common import (
|
|
26
27
|
LiquidNotFoundError,
|
|
27
28
|
PipetteIdMixin,
|
|
29
|
+
OverpressureError,
|
|
28
30
|
)
|
|
29
31
|
from .movement_common import (
|
|
30
32
|
WellLocationMixin,
|
|
@@ -43,7 +45,7 @@ from .command import (
|
|
|
43
45
|
from ..errors.error_occurrence import ErrorOccurrence
|
|
44
46
|
|
|
45
47
|
if TYPE_CHECKING:
|
|
46
|
-
from ..execution import MovementHandler, PipettingHandler
|
|
48
|
+
from ..execution import MovementHandler, PipettingHandler, GantryMover
|
|
47
49
|
from ..resources import ModelUtils
|
|
48
50
|
from ..state.state import StateView
|
|
49
51
|
|
|
@@ -99,10 +101,14 @@ class TryLiquidProbeResult(DestinationPositionResult):
|
|
|
99
101
|
|
|
100
102
|
_LiquidProbeExecuteReturn = Union[
|
|
101
103
|
SuccessData[LiquidProbeResult],
|
|
102
|
-
DefinedErrorData[LiquidNotFoundError]
|
|
104
|
+
DefinedErrorData[LiquidNotFoundError]
|
|
105
|
+
| DefinedErrorData[StallOrCollisionError]
|
|
106
|
+
| DefinedErrorData[OverpressureError],
|
|
103
107
|
]
|
|
104
108
|
_TryLiquidProbeExecuteReturn = (
|
|
105
|
-
SuccessData[TryLiquidProbeResult]
|
|
109
|
+
SuccessData[TryLiquidProbeResult]
|
|
110
|
+
| DefinedErrorData[StallOrCollisionError]
|
|
111
|
+
| DefinedErrorData[OverpressureError]
|
|
106
112
|
)
|
|
107
113
|
|
|
108
114
|
|
|
@@ -110,19 +116,22 @@ class _ExecuteCommonResult(NamedTuple):
|
|
|
110
116
|
# If the probe succeeded, the z_pos that it returned.
|
|
111
117
|
# Or, if the probe found no liquid, the error representing that,
|
|
112
118
|
# so calling code can propagate those details up.
|
|
113
|
-
z_pos_or_error: float | PipetteLiquidNotFoundError
|
|
119
|
+
z_pos_or_error: float | PipetteLiquidNotFoundError | PipetteOverpressureError
|
|
114
120
|
|
|
115
121
|
state_update: update_types.StateUpdate
|
|
116
122
|
deck_point: DeckPoint
|
|
117
123
|
|
|
118
124
|
|
|
119
|
-
async def _execute_common(
|
|
125
|
+
async def _execute_common( # noqa: C901
|
|
120
126
|
state_view: StateView,
|
|
121
127
|
movement: MovementHandler,
|
|
128
|
+
gantry_mover: GantryMover,
|
|
122
129
|
pipetting: PipettingHandler,
|
|
123
130
|
model_utils: ModelUtils,
|
|
124
131
|
params: _CommonParams,
|
|
125
|
-
) -> _ExecuteCommonResult | DefinedErrorData[StallOrCollisionError]
|
|
132
|
+
) -> _ExecuteCommonResult | DefinedErrorData[StallOrCollisionError] | DefinedErrorData[
|
|
133
|
+
OverpressureError
|
|
134
|
+
]:
|
|
126
135
|
pipette_id = params.pipetteId
|
|
127
136
|
labware_id = params.labwareId
|
|
128
137
|
well_name = params.wellName
|
|
@@ -173,6 +182,7 @@ async def _execute_common(
|
|
|
173
182
|
if isinstance(move_result, DefinedErrorData):
|
|
174
183
|
return move_result
|
|
175
184
|
try:
|
|
185
|
+
current_position = await gantry_mover.get_position(params.pipetteId)
|
|
176
186
|
z_pos = await pipetting.liquid_probe_in_place(
|
|
177
187
|
pipette_id=pipette_id,
|
|
178
188
|
labware_id=labware_id,
|
|
@@ -185,6 +195,33 @@ async def _execute_common(
|
|
|
185
195
|
state_update=move_result.state_update,
|
|
186
196
|
deck_point=move_result.public.position,
|
|
187
197
|
)
|
|
198
|
+
except PipetteOverpressureError as e:
|
|
199
|
+
return DefinedErrorData(
|
|
200
|
+
public=OverpressureError(
|
|
201
|
+
id=model_utils.generate_id(),
|
|
202
|
+
createdAt=model_utils.get_timestamp(),
|
|
203
|
+
wrappedErrors=[
|
|
204
|
+
ErrorOccurrence.from_failed(
|
|
205
|
+
id=model_utils.generate_id(),
|
|
206
|
+
createdAt=model_utils.get_timestamp(),
|
|
207
|
+
error=e,
|
|
208
|
+
)
|
|
209
|
+
],
|
|
210
|
+
errorInfo=(
|
|
211
|
+
{
|
|
212
|
+
# This is here bc its not optional in the type but we are not using the retry location for this case
|
|
213
|
+
"retryLocation": (
|
|
214
|
+
current_position.x,
|
|
215
|
+
current_position.y,
|
|
216
|
+
current_position.z,
|
|
217
|
+
)
|
|
218
|
+
}
|
|
219
|
+
),
|
|
220
|
+
),
|
|
221
|
+
state_update=move_result.state_update.set_fluid_unknown(
|
|
222
|
+
pipette_id=pipette_id
|
|
223
|
+
),
|
|
224
|
+
)
|
|
188
225
|
else:
|
|
189
226
|
return _ExecuteCommonResult(
|
|
190
227
|
z_pos_or_error=z_pos,
|
|
@@ -202,12 +239,14 @@ class LiquidProbeImplementation(
|
|
|
202
239
|
self,
|
|
203
240
|
state_view: StateView,
|
|
204
241
|
movement: MovementHandler,
|
|
242
|
+
gantry_mover: GantryMover,
|
|
205
243
|
pipetting: PipettingHandler,
|
|
206
244
|
model_utils: ModelUtils,
|
|
207
245
|
**kwargs: object,
|
|
208
246
|
) -> None:
|
|
209
247
|
self._state_view = state_view
|
|
210
248
|
self._movement = movement
|
|
249
|
+
self._gantry_mover = gantry_mover
|
|
211
250
|
self._pipetting = pipetting
|
|
212
251
|
self._model_utils = model_utils
|
|
213
252
|
|
|
@@ -230,6 +269,7 @@ class LiquidProbeImplementation(
|
|
|
230
269
|
result = await _execute_common(
|
|
231
270
|
state_view=self._state_view,
|
|
232
271
|
movement=self._movement,
|
|
272
|
+
gantry_mover=self._gantry_mover,
|
|
233
273
|
pipetting=self._pipetting,
|
|
234
274
|
model_utils=self._model_utils,
|
|
235
275
|
params=params,
|
|
@@ -237,7 +277,9 @@ class LiquidProbeImplementation(
|
|
|
237
277
|
if isinstance(result, DefinedErrorData):
|
|
238
278
|
return result
|
|
239
279
|
z_pos_or_error, state_update, deck_point = result
|
|
240
|
-
if isinstance(
|
|
280
|
+
if isinstance(
|
|
281
|
+
z_pos_or_error, (PipetteLiquidNotFoundError, PipetteOverpressureError)
|
|
282
|
+
):
|
|
241
283
|
state_update.set_liquid_probed(
|
|
242
284
|
labware_id=params.labwareId,
|
|
243
285
|
well_name=params.wellName,
|
|
@@ -294,12 +336,14 @@ class TryLiquidProbeImplementation(
|
|
|
294
336
|
self,
|
|
295
337
|
state_view: StateView,
|
|
296
338
|
movement: MovementHandler,
|
|
339
|
+
gantry_mover: GantryMover,
|
|
297
340
|
pipetting: PipettingHandler,
|
|
298
341
|
model_utils: ModelUtils,
|
|
299
342
|
**kwargs: object,
|
|
300
343
|
) -> None:
|
|
301
344
|
self._state_view = state_view
|
|
302
345
|
self._movement = movement
|
|
346
|
+
self._gantry_mover = gantry_mover
|
|
303
347
|
self._pipetting = pipetting
|
|
304
348
|
self._model_utils = model_utils
|
|
305
349
|
|
|
@@ -313,6 +357,7 @@ class TryLiquidProbeImplementation(
|
|
|
313
357
|
result = await _execute_common(
|
|
314
358
|
state_view=self._state_view,
|
|
315
359
|
movement=self._movement,
|
|
360
|
+
gantry_mover=self._gantry_mover,
|
|
316
361
|
pipetting=self._pipetting,
|
|
317
362
|
model_utils=self._model_utils,
|
|
318
363
|
params=params,
|
|
@@ -321,7 +366,9 @@ class TryLiquidProbeImplementation(
|
|
|
321
366
|
return result
|
|
322
367
|
z_pos_or_error, state_update, deck_point = result
|
|
323
368
|
|
|
324
|
-
if isinstance(
|
|
369
|
+
if isinstance(
|
|
370
|
+
z_pos_or_error, (PipetteLiquidNotFoundError, PipetteOverpressureError)
|
|
371
|
+
):
|
|
325
372
|
z_pos = None
|
|
326
373
|
well_volume: float | update_types.ClearType = update_types.CLEAR
|
|
327
374
|
else:
|
|
@@ -354,26 +401,30 @@ class LiquidProbe(
|
|
|
354
401
|
BaseCommand[
|
|
355
402
|
LiquidProbeParams,
|
|
356
403
|
LiquidProbeResult,
|
|
357
|
-
LiquidNotFoundError | StallOrCollisionError,
|
|
404
|
+
LiquidNotFoundError | StallOrCollisionError | OverpressureError,
|
|
358
405
|
]
|
|
359
406
|
):
|
|
360
407
|
"""The model for a full `liquidProbe` command."""
|
|
361
408
|
|
|
362
409
|
commandType: LiquidProbeCommandType = "liquidProbe"
|
|
363
410
|
params: LiquidProbeParams
|
|
364
|
-
result: Optional[LiquidProbeResult]
|
|
411
|
+
result: Optional[LiquidProbeResult] = None
|
|
365
412
|
|
|
366
413
|
_ImplementationCls: Type[LiquidProbeImplementation] = LiquidProbeImplementation
|
|
367
414
|
|
|
368
415
|
|
|
369
416
|
class TryLiquidProbe(
|
|
370
|
-
BaseCommand[
|
|
417
|
+
BaseCommand[
|
|
418
|
+
TryLiquidProbeParams,
|
|
419
|
+
TryLiquidProbeResult,
|
|
420
|
+
StallOrCollisionError | OverpressureError,
|
|
421
|
+
]
|
|
371
422
|
):
|
|
372
423
|
"""The model for a full `tryLiquidProbe` command."""
|
|
373
424
|
|
|
374
425
|
commandType: TryLiquidProbeCommandType = "tryLiquidProbe"
|
|
375
426
|
params: TryLiquidProbeParams
|
|
376
|
-
result: Optional[TryLiquidProbeResult]
|
|
427
|
+
result: Optional[TryLiquidProbeResult] = None
|
|
377
428
|
|
|
378
429
|
_ImplementationCls: Type[
|
|
379
430
|
TryLiquidProbeImplementation
|
|
@@ -192,6 +192,11 @@ class LoadLabwareImplementation(
|
|
|
192
192
|
self._state_view.labware.raise_if_labware_incompatible_with_plate_reader(
|
|
193
193
|
loaded_labware.definition
|
|
194
194
|
)
|
|
195
|
+
|
|
196
|
+
self._state_view.labware.raise_if_labware_cannot_be_ondeck(
|
|
197
|
+
location=params.location, labware_definition=loaded_labware.definition
|
|
198
|
+
)
|
|
199
|
+
|
|
195
200
|
return SuccessData(
|
|
196
201
|
public=LoadLabwareResult(
|
|
197
202
|
labwareId=loaded_labware.labware_id,
|
|
@@ -132,7 +132,7 @@ class LoadLid(BaseCommand[LoadLidParams, LoadLidResult, ErrorOccurrence]):
|
|
|
132
132
|
|
|
133
133
|
commandType: LoadLidCommandType = "loadLid"
|
|
134
134
|
params: LoadLidParams
|
|
135
|
-
result: Optional[LoadLidResult]
|
|
135
|
+
result: Optional[LoadLidResult] = None
|
|
136
136
|
|
|
137
137
|
_ImplementationCls: Type[LoadLidImplementation] = LoadLidImplementation
|
|
138
138
|
|
|
@@ -175,7 +175,7 @@ class LoadLidStack(
|
|
|
175
175
|
|
|
176
176
|
commandType: LoadLidStackCommandType = "loadLidStack"
|
|
177
177
|
params: LoadLidStackParams
|
|
178
|
-
result: Optional[LoadLidStackResult]
|
|
178
|
+
result: Optional[LoadLidStackResult] = None
|
|
179
179
|
|
|
180
180
|
_ImplementationCls: Type[LoadLidStackImplementation] = LoadLidStackImplementation
|
|
181
181
|
|
|
@@ -128,7 +128,7 @@ class LoadLiquidClass(
|
|
|
128
128
|
|
|
129
129
|
commandType: LoadLiquidClassCommandType = "loadLiquidClass"
|
|
130
130
|
params: LoadLiquidClassParams
|
|
131
|
-
result: Optional[LoadLiquidClassResult]
|
|
131
|
+
result: Optional[LoadLiquidClassResult] = None
|
|
132
132
|
|
|
133
133
|
_ImplementationCls: Type[
|
|
134
134
|
LoadLiquidClassImplementation
|
|
@@ -223,6 +223,15 @@ class MoveLabwareImplementation(AbstractCommandImpl[MoveLabwareParams, _ExecuteR
|
|
|
223
223
|
self._state_view.labware.raise_if_labware_has_labware_on_top(
|
|
224
224
|
labware_id=params.labwareId
|
|
225
225
|
)
|
|
226
|
+
|
|
227
|
+
if isinstance(available_new_location, DeckSlotLocation):
|
|
228
|
+
self._state_view.labware.raise_if_labware_cannot_be_ondeck(
|
|
229
|
+
location=available_new_location,
|
|
230
|
+
labware_definition=self._state_view.labware.get_definition(
|
|
231
|
+
params.labwareId
|
|
232
|
+
),
|
|
233
|
+
)
|
|
234
|
+
|
|
226
235
|
if isinstance(available_new_location, OnLabwareLocation):
|
|
227
236
|
self._state_view.labware.raise_if_labware_has_labware_on_top(
|
|
228
237
|
available_new_location.labwareId
|
|
@@ -70,7 +70,7 @@ class closeGripperJaw(
|
|
|
70
70
|
|
|
71
71
|
commandType: closeGripperJawCommandType = "robot/closeGripperJaw"
|
|
72
72
|
params: closeGripperJawParams
|
|
73
|
-
result: Optional[closeGripperJawResult]
|
|
73
|
+
result: Optional[closeGripperJawResult] = None
|
|
74
74
|
|
|
75
75
|
_ImplementationCls: Type[
|
|
76
76
|
closeGripperJawImplementation
|
|
@@ -85,7 +85,7 @@ class MoveAxesRelative(
|
|
|
85
85
|
|
|
86
86
|
commandType: MoveAxesRelativeCommandType = "robot/moveAxesRelative"
|
|
87
87
|
params: MoveAxesRelativeParams
|
|
88
|
-
result: Optional[MoveAxesRelativeResult]
|
|
88
|
+
result: Optional[MoveAxesRelativeResult] = None
|
|
89
89
|
|
|
90
90
|
_ImplementationCls: Type[
|
|
91
91
|
MoveAxesRelativeImplementation
|
|
@@ -86,7 +86,7 @@ class MoveAxesTo(BaseCommand[MoveAxesToParams, MoveAxesToResult, ErrorOccurrence
|
|
|
86
86
|
|
|
87
87
|
commandType: MoveAxesToCommandType = "robot/moveAxesTo"
|
|
88
88
|
params: MoveAxesToParams
|
|
89
|
-
result: Optional[MoveAxesToResult]
|
|
89
|
+
result: Optional[MoveAxesToResult] = None
|
|
90
90
|
|
|
91
91
|
_ImplementationCls: Type[MoveAxesToImplementation] = MoveAxesToImplementation
|
|
92
92
|
|
|
@@ -80,7 +80,7 @@ class MoveTo(BaseCommand[MoveToParams, MoveToResult, ErrorOccurrence]):
|
|
|
80
80
|
|
|
81
81
|
commandType: MoveToCommandType = "robot/moveTo"
|
|
82
82
|
params: MoveToParams
|
|
83
|
-
result: Optional[MoveToResult]
|
|
83
|
+
result: Optional[MoveToResult] = None
|
|
84
84
|
|
|
85
85
|
_ImplementationCls: Type[MoveToImplementation] = MoveToImplementation
|
|
86
86
|
|
|
@@ -61,7 +61,7 @@ class openGripperJaw(
|
|
|
61
61
|
|
|
62
62
|
commandType: openGripperJawCommandType = "robot/openGripperJaw"
|
|
63
63
|
params: openGripperJawParams
|
|
64
|
-
result: Optional[openGripperJawResult]
|
|
64
|
+
result: Optional[openGripperJawResult] = None
|
|
65
65
|
|
|
66
66
|
_ImplementationCls: Type[
|
|
67
67
|
openGripperJawImplementation
|
|
@@ -157,7 +157,7 @@ class RunExtendedProfile(
|
|
|
157
157
|
|
|
158
158
|
commandType: RunExtendedProfileCommandType = "thermocycler/runExtendedProfile"
|
|
159
159
|
params: RunExtendedProfileParams
|
|
160
|
-
result: Optional[RunExtendedProfileResult]
|
|
160
|
+
result: Optional[RunExtendedProfileResult] = None
|
|
161
161
|
|
|
162
162
|
_ImplementationCls: Type[RunExtendedProfileImpl] = RunExtendedProfileImpl
|
|
163
163
|
|
|
@@ -82,7 +82,7 @@ class UnsafeBlowOutInPlace(
|
|
|
82
82
|
|
|
83
83
|
commandType: UnsafeBlowOutInPlaceCommandType = "unsafe/blowOutInPlace"
|
|
84
84
|
params: UnsafeBlowOutInPlaceParams
|
|
85
|
-
result: Optional[UnsafeBlowOutInPlaceResult]
|
|
85
|
+
result: Optional[UnsafeBlowOutInPlaceResult] = None
|
|
86
86
|
|
|
87
87
|
_ImplementationCls: Type[
|
|
88
88
|
UnsafeBlowOutInPlaceImplementation
|
|
@@ -99,7 +99,7 @@ class UnsafeDropTipInPlace(
|
|
|
99
99
|
|
|
100
100
|
commandType: UnsafeDropTipInPlaceCommandType = "unsafe/dropTipInPlace"
|
|
101
101
|
params: UnsafeDropTipInPlaceParams
|
|
102
|
-
result: Optional[UnsafeDropTipInPlaceResult]
|
|
102
|
+
result: Optional[UnsafeDropTipInPlaceResult] = None
|
|
103
103
|
|
|
104
104
|
_ImplementationCls: Type[
|
|
105
105
|
UnsafeDropTipInPlaceImplementation
|
|
@@ -66,7 +66,7 @@ class UnsafeEngageAxes(
|
|
|
66
66
|
|
|
67
67
|
commandType: UnsafeEngageAxesCommandType = "unsafe/engageAxes"
|
|
68
68
|
params: UnsafeEngageAxesParams
|
|
69
|
-
result: Optional[UnsafeEngageAxesResult]
|
|
69
|
+
result: Optional[UnsafeEngageAxesResult] = None
|
|
70
70
|
|
|
71
71
|
_ImplementationCls: Type[
|
|
72
72
|
UnsafeEngageAxesImplementation
|
|
@@ -192,7 +192,7 @@ class UnsafePlaceLabware(
|
|
|
192
192
|
|
|
193
193
|
commandType: UnsafePlaceLabwareCommandType = "unsafe/placeLabware"
|
|
194
194
|
params: UnsafePlaceLabwareParams
|
|
195
|
-
result: Optional[UnsafePlaceLabwareResult]
|
|
195
|
+
result: Optional[UnsafePlaceLabwareResult] = None
|
|
196
196
|
|
|
197
197
|
_ImplementationCls: Type[
|
|
198
198
|
UnsafePlaceLabwareImplementation
|
|
@@ -61,7 +61,7 @@ class UnsafeUngripLabware(
|
|
|
61
61
|
|
|
62
62
|
commandType: UnsafeUngripLabwareCommandType = "unsafe/ungripLabware"
|
|
63
63
|
params: UnsafeUngripLabwareParams
|
|
64
|
-
result: Optional[UnsafeUngripLabwareResult]
|
|
64
|
+
result: Optional[UnsafeUngripLabwareResult] = None
|
|
65
65
|
|
|
66
66
|
_ImplementationCls: Type[
|
|
67
67
|
UnsafeUngripLabwareImplementation
|
|
@@ -74,7 +74,7 @@ class UpdatePositionEstimators(
|
|
|
74
74
|
|
|
75
75
|
commandType: UpdatePositionEstimatorsCommandType = "unsafe/updatePositionEstimators"
|
|
76
76
|
params: UpdatePositionEstimatorsParams
|
|
77
|
-
result: Optional[UpdatePositionEstimatorsResult]
|
|
77
|
+
result: Optional[UpdatePositionEstimatorsResult] = None
|
|
78
78
|
|
|
79
79
|
_ImplementationCls: Type[
|
|
80
80
|
UpdatePositionEstimatorsImplementation
|
|
@@ -11,6 +11,7 @@ from .exceptions import (
|
|
|
11
11
|
PickUpTipTipNotAttachedError,
|
|
12
12
|
TipAttachedError,
|
|
13
13
|
CommandDoesNotExistError,
|
|
14
|
+
UnsupportedLabwareForActionError,
|
|
14
15
|
LabwareNotLoadedError,
|
|
15
16
|
LabwareNotLoadedOnModuleError,
|
|
16
17
|
LabwareNotLoadedOnLabwareError,
|
|
@@ -18,6 +19,7 @@ from .exceptions import (
|
|
|
18
19
|
LiquidDoesNotExistError,
|
|
19
20
|
LabwareDefinitionDoesNotExistError,
|
|
20
21
|
LabwareCannotBeStackedError,
|
|
22
|
+
LabwareCannotSitOnDeckError,
|
|
21
23
|
LabwareIsInStackError,
|
|
22
24
|
LabwareOffsetDoesNotExistError,
|
|
23
25
|
LabwareIsNotTipRackError,
|
|
@@ -103,8 +105,10 @@ __all__ = [
|
|
|
103
105
|
"LabwareNotLoadedOnLabwareError",
|
|
104
106
|
"LabwareNotOnDeckError",
|
|
105
107
|
"LiquidDoesNotExistError",
|
|
108
|
+
"UnsupportedLabwareForActionError",
|
|
106
109
|
"LabwareDefinitionDoesNotExistError",
|
|
107
110
|
"LabwareCannotBeStackedError",
|
|
111
|
+
"LabwareCannotSitOnDeckError",
|
|
108
112
|
"LabwareIsInStackError",
|
|
109
113
|
"LabwareOffsetDoesNotExistError",
|
|
110
114
|
"LabwareIsNotTipRackError",
|
|
@@ -283,6 +283,19 @@ class LabwareCannotBeStackedError(ProtocolEngineError):
|
|
|
283
283
|
super().__init__(ErrorCodes.GENERAL_ERROR, message, details, wrapping)
|
|
284
284
|
|
|
285
285
|
|
|
286
|
+
class LabwareCannotSitOnDeckError(ProtocolEngineError):
|
|
287
|
+
"""Raised when a labware is incompatible with a deck slot."""
|
|
288
|
+
|
|
289
|
+
def __init__(
|
|
290
|
+
self,
|
|
291
|
+
message: Optional[str] = None,
|
|
292
|
+
details: Optional[Dict[str, Any]] = None,
|
|
293
|
+
wrapping: Optional[Sequence[EnumeratedError]] = None,
|
|
294
|
+
) -> None:
|
|
295
|
+
"""Build a LabwareCannotSitOnDeckError."""
|
|
296
|
+
super().__init__(ErrorCodes.GENERAL_ERROR, message, details, wrapping)
|
|
297
|
+
|
|
298
|
+
|
|
286
299
|
class LabwareIsInStackError(ProtocolEngineError):
|
|
287
300
|
"""Raised when trying to move to or physically interact with a labware that has another labware on top."""
|
|
288
301
|
|
|
@@ -374,6 +387,19 @@ class TouchTipIncompatibleArgumentsError(ProtocolEngineError):
|
|
|
374
387
|
super().__init__(ErrorCodes.GENERAL_ERROR, message, details, wrapping)
|
|
375
388
|
|
|
376
389
|
|
|
390
|
+
class UnsupportedLabwareForActionError(ProtocolEngineError):
|
|
391
|
+
"""Raised when trying to use an unsupported labware for a command."""
|
|
392
|
+
|
|
393
|
+
def __init__(
|
|
394
|
+
self,
|
|
395
|
+
message: Optional[str] = None,
|
|
396
|
+
details: Optional[Dict[str, Any]] = None,
|
|
397
|
+
wrapping: Optional[Sequence[EnumeratedError]] = None,
|
|
398
|
+
) -> None:
|
|
399
|
+
"""Build a UnsupportedLabwareForActionError."""
|
|
400
|
+
super().__init__(ErrorCodes.GENERAL_ERROR, message, details, wrapping)
|
|
401
|
+
|
|
402
|
+
|
|
377
403
|
class WellDoesNotExistError(ProtocolEngineError):
|
|
378
404
|
"""Raised when referencing a well that does not exist."""
|
|
379
405
|
|
|
@@ -114,6 +114,7 @@ class GantryMover(TypingProtocol):
|
|
|
114
114
|
critical_point: Optional[Dict[MotorAxis, float]] = None,
|
|
115
115
|
speed: Optional[float] = None,
|
|
116
116
|
relative_move: bool = False,
|
|
117
|
+
expect_stalls: bool = False,
|
|
117
118
|
) -> Dict[MotorAxis, float]:
|
|
118
119
|
"""Move a set of axes a given distance."""
|
|
119
120
|
...
|
|
@@ -341,6 +342,7 @@ class HardwareGantryMover(GantryMover):
|
|
|
341
342
|
critical_point: Optional[Dict[MotorAxis, float]] = None,
|
|
342
343
|
speed: Optional[float] = None,
|
|
343
344
|
relative_move: bool = False,
|
|
345
|
+
expect_stalls: bool = False,
|
|
344
346
|
) -> Dict[MotorAxis, float]:
|
|
345
347
|
"""Move a set of axes a given distance.
|
|
346
348
|
|
|
@@ -349,6 +351,7 @@ class HardwareGantryMover(GantryMover):
|
|
|
349
351
|
critical_point: A critical point override for axes
|
|
350
352
|
speed: Optional speed parameter for the move.
|
|
351
353
|
relative_move: Whether the axis map needs to be converted from a relative to absolute move.
|
|
354
|
+
expect_stalls: Whether it is expected that the move triggers a stall error.
|
|
352
355
|
"""
|
|
353
356
|
try:
|
|
354
357
|
pos_hw = self._convert_axis_map_for_hw(axis_map)
|
|
@@ -385,6 +388,7 @@ class HardwareGantryMover(GantryMover):
|
|
|
385
388
|
await self._hardware_api.move_axes(
|
|
386
389
|
position=absolute_pos,
|
|
387
390
|
speed=speed,
|
|
391
|
+
expect_stalls=expect_stalls,
|
|
388
392
|
)
|
|
389
393
|
|
|
390
394
|
except PositionUnknownError as e:
|
|
@@ -588,6 +592,7 @@ class VirtualGantryMover(GantryMover):
|
|
|
588
592
|
critical_point: Optional[Dict[MotorAxis, float]] = None,
|
|
589
593
|
speed: Optional[float] = None,
|
|
590
594
|
relative_move: bool = False,
|
|
595
|
+
expect_stalls: bool = False,
|
|
591
596
|
) -> Dict[MotorAxis, float]:
|
|
592
597
|
"""Move the give axes map. No-op in virtual implementation."""
|
|
593
598
|
mount = self.pick_mount_from_axis_map(axis_map)
|