opentrons 8.3.1a1__py2.py3-none-any.whl → 8.4.0a1__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- opentrons/calibration_storage/ot2/mark_bad_calibration.py +2 -0
- opentrons/calibration_storage/ot2/tip_length.py +6 -6
- opentrons/config/advanced_settings.py +9 -11
- opentrons/config/feature_flags.py +0 -4
- opentrons/config/reset.py +7 -2
- opentrons/drivers/asyncio/communication/__init__.py +2 -0
- opentrons/drivers/asyncio/communication/async_serial.py +4 -0
- opentrons/drivers/asyncio/communication/errors.py +41 -8
- opentrons/drivers/asyncio/communication/serial_connection.py +36 -10
- opentrons/drivers/flex_stacker/__init__.py +9 -3
- opentrons/drivers/flex_stacker/abstract.py +140 -15
- opentrons/drivers/flex_stacker/driver.py +593 -47
- opentrons/drivers/flex_stacker/errors.py +64 -0
- opentrons/drivers/flex_stacker/simulator.py +222 -24
- opentrons/drivers/flex_stacker/types.py +211 -15
- opentrons/drivers/flex_stacker/utils.py +19 -0
- opentrons/execute.py +4 -2
- opentrons/hardware_control/api.py +5 -0
- opentrons/hardware_control/backends/flex_protocol.py +4 -0
- opentrons/hardware_control/backends/ot3controller.py +12 -1
- opentrons/hardware_control/backends/ot3simulator.py +3 -0
- opentrons/hardware_control/backends/subsystem_manager.py +8 -4
- opentrons/hardware_control/instruments/ot2/instrument_calibration.py +10 -6
- opentrons/hardware_control/instruments/ot3/pipette_handler.py +59 -6
- opentrons/hardware_control/modules/__init__.py +12 -1
- opentrons/hardware_control/modules/absorbance_reader.py +11 -9
- opentrons/hardware_control/modules/flex_stacker.py +498 -0
- opentrons/hardware_control/modules/heater_shaker.py +12 -10
- opentrons/hardware_control/modules/magdeck.py +5 -1
- opentrons/hardware_control/modules/tempdeck.py +5 -1
- opentrons/hardware_control/modules/thermocycler.py +15 -14
- opentrons/hardware_control/modules/types.py +191 -1
- opentrons/hardware_control/modules/utils.py +3 -0
- opentrons/hardware_control/motion_utilities.py +20 -0
- opentrons/hardware_control/ot3api.py +145 -15
- opentrons/hardware_control/protocols/liquid_handler.py +47 -1
- opentrons/hardware_control/types.py +6 -0
- opentrons/legacy_commands/commands.py +19 -3
- opentrons/legacy_commands/helpers.py +15 -0
- opentrons/legacy_commands/types.py +3 -2
- opentrons/protocol_api/__init__.py +2 -0
- opentrons/protocol_api/_liquid.py +39 -8
- opentrons/protocol_api/_liquid_properties.py +20 -19
- opentrons/protocol_api/_transfer_liquid_validation.py +91 -0
- opentrons/protocol_api/core/common.py +3 -1
- opentrons/protocol_api/core/engine/deck_conflict.py +11 -1
- opentrons/protocol_api/core/engine/instrument.py +1233 -65
- opentrons/protocol_api/core/engine/labware.py +8 -4
- opentrons/protocol_api/core/engine/load_labware_params.py +68 -10
- opentrons/protocol_api/core/engine/module_core.py +118 -2
- opentrons/protocol_api/core/engine/protocol.py +253 -11
- opentrons/protocol_api/core/engine/stringify.py +19 -8
- opentrons/protocol_api/core/engine/transfer_components_executor.py +853 -0
- opentrons/protocol_api/core/engine/well.py +60 -5
- opentrons/protocol_api/core/instrument.py +65 -19
- opentrons/protocol_api/core/labware.py +6 -2
- opentrons/protocol_api/core/legacy/labware_offset_provider.py +7 -3
- opentrons/protocol_api/core/legacy/legacy_instrument_core.py +69 -21
- opentrons/protocol_api/core/legacy/legacy_labware_core.py +8 -4
- opentrons/protocol_api/core/legacy/legacy_protocol_core.py +36 -0
- opentrons/protocol_api/core/legacy/legacy_well_core.py +25 -1
- opentrons/protocol_api/core/legacy/load_info.py +4 -12
- opentrons/protocol_api/core/legacy/module_geometry.py +6 -1
- opentrons/protocol_api/core/legacy/well_geometry.py +3 -3
- opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py +67 -21
- opentrons/protocol_api/core/module.py +43 -0
- opentrons/protocol_api/core/protocol.py +33 -0
- opentrons/protocol_api/core/well.py +21 -1
- opentrons/protocol_api/instrument_context.py +246 -123
- opentrons/protocol_api/labware.py +75 -11
- opentrons/protocol_api/module_contexts.py +140 -0
- opentrons/protocol_api/protocol_context.py +156 -16
- opentrons/protocol_api/validation.py +51 -41
- opentrons/protocol_engine/__init__.py +21 -2
- opentrons/protocol_engine/actions/actions.py +5 -5
- opentrons/protocol_engine/clients/sync_client.py +6 -0
- opentrons/protocol_engine/commands/__init__.py +30 -0
- opentrons/protocol_engine/commands/absorbance_reader/__init__.py +0 -1
- opentrons/protocol_engine/commands/air_gap_in_place.py +3 -2
- opentrons/protocol_engine/commands/aspirate.py +6 -2
- opentrons/protocol_engine/commands/aspirate_in_place.py +3 -1
- opentrons/protocol_engine/commands/aspirate_while_tracking.py +237 -0
- opentrons/protocol_engine/commands/blow_out.py +2 -0
- opentrons/protocol_engine/commands/blow_out_in_place.py +4 -1
- opentrons/protocol_engine/commands/command_unions.py +69 -0
- opentrons/protocol_engine/commands/configure_for_volume.py +3 -0
- opentrons/protocol_engine/commands/dispense.py +3 -1
- opentrons/protocol_engine/commands/dispense_in_place.py +3 -0
- opentrons/protocol_engine/commands/dispense_while_tracking.py +240 -0
- opentrons/protocol_engine/commands/drop_tip.py +23 -1
- opentrons/protocol_engine/commands/evotip_dispense.py +6 -7
- opentrons/protocol_engine/commands/evotip_seal_pipette.py +24 -29
- opentrons/protocol_engine/commands/evotip_unseal_pipette.py +1 -7
- opentrons/protocol_engine/commands/flex_stacker/__init__.py +106 -0
- opentrons/protocol_engine/commands/flex_stacker/close_latch.py +72 -0
- opentrons/protocol_engine/commands/flex_stacker/common.py +15 -0
- opentrons/protocol_engine/commands/flex_stacker/empty.py +161 -0
- opentrons/protocol_engine/commands/flex_stacker/fill.py +164 -0
- opentrons/protocol_engine/commands/flex_stacker/open_latch.py +70 -0
- opentrons/protocol_engine/commands/flex_stacker/prepare_shuttle.py +112 -0
- opentrons/protocol_engine/commands/flex_stacker/retrieve.py +394 -0
- opentrons/protocol_engine/commands/flex_stacker/set_stored_labware.py +190 -0
- opentrons/protocol_engine/commands/flex_stacker/store.py +288 -0
- opentrons/protocol_engine/commands/generate_command_schema.py +31 -2
- opentrons/protocol_engine/commands/labware_handling_common.py +24 -0
- opentrons/protocol_engine/commands/liquid_probe.py +21 -12
- opentrons/protocol_engine/commands/load_labware.py +42 -39
- opentrons/protocol_engine/commands/load_lid.py +21 -13
- opentrons/protocol_engine/commands/load_lid_stack.py +130 -47
- opentrons/protocol_engine/commands/load_module.py +18 -17
- opentrons/protocol_engine/commands/load_pipette.py +3 -0
- opentrons/protocol_engine/commands/move_labware.py +139 -20
- opentrons/protocol_engine/commands/pick_up_tip.py +5 -2
- opentrons/protocol_engine/commands/pipetting_common.py +154 -7
- opentrons/protocol_engine/commands/prepare_to_aspirate.py +17 -2
- opentrons/protocol_engine/commands/reload_labware.py +6 -19
- opentrons/protocol_engine/commands/unsafe/unsafe_blow_out_in_place.py +3 -1
- opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py +6 -1
- opentrons/protocol_engine/errors/__init__.py +8 -0
- opentrons/protocol_engine/errors/exceptions.py +50 -0
- opentrons/protocol_engine/execution/equipment.py +123 -106
- opentrons/protocol_engine/execution/labware_movement.py +8 -6
- opentrons/protocol_engine/execution/pipetting.py +233 -26
- opentrons/protocol_engine/execution/tip_handler.py +14 -5
- opentrons/protocol_engine/labware_offset_standardization.py +173 -0
- opentrons/protocol_engine/protocol_engine.py +22 -13
- opentrons/protocol_engine/resources/deck_configuration_provider.py +94 -2
- opentrons/protocol_engine/resources/deck_data_provider.py +1 -1
- opentrons/protocol_engine/resources/labware_data_provider.py +32 -12
- opentrons/protocol_engine/resources/labware_validation.py +7 -5
- opentrons/protocol_engine/slot_standardization.py +11 -23
- opentrons/protocol_engine/state/addressable_areas.py +84 -46
- opentrons/protocol_engine/state/frustum_helpers.py +26 -10
- opentrons/protocol_engine/state/geometry.py +683 -100
- opentrons/protocol_engine/state/labware.py +252 -55
- opentrons/protocol_engine/state/module_substates/__init__.py +4 -0
- opentrons/protocol_engine/state/module_substates/flex_stacker_substate.py +68 -0
- opentrons/protocol_engine/state/module_substates/heater_shaker_module_substate.py +22 -0
- opentrons/protocol_engine/state/module_substates/temperature_module_substate.py +13 -0
- opentrons/protocol_engine/state/module_substates/thermocycler_module_substate.py +20 -0
- opentrons/protocol_engine/state/modules.py +178 -52
- opentrons/protocol_engine/state/pipettes.py +54 -0
- opentrons/protocol_engine/state/state.py +1 -1
- opentrons/protocol_engine/state/tips.py +14 -0
- opentrons/protocol_engine/state/update_types.py +180 -25
- opentrons/protocol_engine/state/wells.py +54 -8
- opentrons/protocol_engine/types/__init__.py +292 -0
- opentrons/protocol_engine/types/automatic_tip_selection.py +39 -0
- opentrons/protocol_engine/types/command_annotations.py +53 -0
- opentrons/protocol_engine/types/deck_configuration.py +72 -0
- opentrons/protocol_engine/types/execution.py +96 -0
- opentrons/protocol_engine/types/hardware_passthrough.py +25 -0
- opentrons/protocol_engine/types/instrument.py +47 -0
- opentrons/protocol_engine/types/instrument_sensors.py +47 -0
- opentrons/protocol_engine/types/labware.py +110 -0
- opentrons/protocol_engine/types/labware_movement.py +22 -0
- opentrons/protocol_engine/types/labware_offset_location.py +108 -0
- opentrons/protocol_engine/types/labware_offset_vector.py +33 -0
- opentrons/protocol_engine/types/liquid.py +40 -0
- opentrons/protocol_engine/types/liquid_class.py +59 -0
- opentrons/protocol_engine/types/liquid_handling.py +13 -0
- opentrons/protocol_engine/types/liquid_level_detection.py +137 -0
- opentrons/protocol_engine/types/location.py +193 -0
- opentrons/protocol_engine/types/module.py +269 -0
- opentrons/protocol_engine/types/partial_tip_configuration.py +76 -0
- opentrons/protocol_engine/types/run_time_parameters.py +133 -0
- opentrons/protocol_engine/types/tip.py +18 -0
- opentrons/protocol_engine/types/util.py +21 -0
- opentrons/protocol_engine/types/well_position.py +107 -0
- opentrons/protocol_reader/extract_labware_definitions.py +7 -3
- opentrons/protocol_reader/file_format_validator.py +5 -3
- opentrons/protocol_runner/json_translator.py +4 -2
- opentrons/protocol_runner/legacy_command_mapper.py +6 -2
- opentrons/protocol_runner/run_orchestrator.py +4 -1
- opentrons/protocols/advanced_control/transfers/common.py +48 -1
- opentrons/protocols/advanced_control/transfers/transfer_liquid_utils.py +204 -0
- opentrons/protocols/api_support/definitions.py +1 -1
- opentrons/protocols/api_support/instrument.py +16 -3
- opentrons/protocols/labware.py +5 -6
- opentrons/protocols/models/__init__.py +0 -21
- opentrons/simulate.py +4 -2
- opentrons/types.py +15 -6
- {opentrons-8.3.1a1.dist-info → opentrons-8.4.0a1.dist-info}/METADATA +4 -4
- {opentrons-8.3.1a1.dist-info → opentrons-8.4.0a1.dist-info}/RECORD +188 -148
- opentrons/calibration_storage/ot2/models/defaults.py +0 -0
- opentrons/calibration_storage/ot3/models/defaults.py +0 -0
- opentrons/protocol_api/core/legacy/legacy_robot_core.py +0 -0
- opentrons/protocol_engine/types.py +0 -1311
- {opentrons-8.3.1a1.dist-info → opentrons-8.4.0a1.dist-info}/LICENSE +0 -0
- {opentrons-8.3.1a1.dist-info → opentrons-8.4.0a1.dist-info}/WHEEL +0 -0
- {opentrons-8.3.1a1.dist-info → opentrons-8.4.0a1.dist-info}/entry_points.txt +0 -0
- {opentrons-8.3.1a1.dist-info → opentrons-8.4.0a1.dist-info}/top_level.txt +0 -0
|
@@ -7,8 +7,7 @@ from opentrons.types import MountType
|
|
|
7
7
|
from opentrons.protocol_engine.types import MotorAxis
|
|
8
8
|
from typing_extensions import Literal
|
|
9
9
|
|
|
10
|
-
from
|
|
11
|
-
from ..resources import ModelUtils, labware_validation
|
|
10
|
+
from ..resources import ModelUtils
|
|
12
11
|
from ..types import PickUpTipWellLocation, FluidKind, AspiratedFluid
|
|
13
12
|
from .pipetting_common import (
|
|
14
13
|
PipetteIdMixin,
|
|
@@ -41,10 +40,13 @@ if TYPE_CHECKING:
|
|
|
41
40
|
|
|
42
41
|
|
|
43
42
|
EvotipSealPipetteCommandType = Literal["evotipSealPipette"]
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
43
|
+
_CAM_PREP_DISTANCE_DEFAULT = 8.25
|
|
44
|
+
_CAM_PRESS_DISTANCE_DEFAULT = 3.5
|
|
45
|
+
_CAM_EJECTOR_PUSH_MM_DEFAULT = 7.0
|
|
46
|
+
_PRESS_FIT_PREP_DISTANCE_DEFAULT = 0
|
|
47
|
+
_PRESS_FIT_PRESS_DISTANCE_DEFAULT = -11.0
|
|
48
|
+
_PRESS_FIT_EJECTOR_PUSH_MM_DEFAULT = 0
|
|
49
|
+
_SAFE_TOP_VOLUME = 1000
|
|
48
50
|
|
|
49
51
|
|
|
50
52
|
class TipPickUpParams(BaseModel):
|
|
@@ -217,12 +219,6 @@ class EvotipSealPipetteImplementation(
|
|
|
217
219
|
labware_id = params.labwareId
|
|
218
220
|
well_name = params.wellName
|
|
219
221
|
|
|
220
|
-
labware_definition = self._state_view.labware.get_definition(params.labwareId)
|
|
221
|
-
if not labware_validation.is_evotips(labware_definition.parameters.loadName):
|
|
222
|
-
raise UnsupportedLabwareForActionError(
|
|
223
|
-
f"Cannot use command: `EvotipSealPipette` with labware: {labware_definition.parameters.loadName}"
|
|
224
|
-
)
|
|
225
|
-
|
|
226
222
|
well_location = self._state_view.geometry.convert_pick_up_tip_well_location(
|
|
227
223
|
well_location=params.wellLocation
|
|
228
224
|
)
|
|
@@ -251,29 +247,28 @@ class EvotipSealPipetteImplementation(
|
|
|
251
247
|
channels = self._state_view.tips.get_pipette_active_channels(pipette_id)
|
|
252
248
|
mount = self._state_view.pipettes.get_mount(pipette_id)
|
|
253
249
|
tip_pick_up_params = params.tipPickUpParams
|
|
254
|
-
if tip_pick_up_params is None:
|
|
255
|
-
tip_pick_up_params = TipPickUpParams(
|
|
256
|
-
prepDistance=_PREP_DISTANCE_DEFAULT,
|
|
257
|
-
pressDistance=_PRESS_DISTANCE_DEFAULT,
|
|
258
|
-
ejectorPushMm=_EJECTOR_PUSH_MM_DEFAULT,
|
|
259
|
-
)
|
|
260
250
|
|
|
261
|
-
if channels
|
|
262
|
-
|
|
263
|
-
tip_pick_up_params=
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
251
|
+
if channels == 96:
|
|
252
|
+
if tip_pick_up_params is None:
|
|
253
|
+
tip_pick_up_params = TipPickUpParams(
|
|
254
|
+
prepDistance=_CAM_PREP_DISTANCE_DEFAULT,
|
|
255
|
+
pressDistance=_CAM_PRESS_DISTANCE_DEFAULT,
|
|
256
|
+
ejectorPushMm=_CAM_EJECTOR_PUSH_MM_DEFAULT,
|
|
257
|
+
)
|
|
267
258
|
await self.cam_action_relative_pickup_tip(
|
|
268
259
|
tip_pick_up_params=tip_pick_up_params,
|
|
269
260
|
mount=mount,
|
|
270
261
|
)
|
|
271
262
|
else:
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
263
|
+
if tip_pick_up_params is None:
|
|
264
|
+
tip_pick_up_params = TipPickUpParams(
|
|
265
|
+
prepDistance=_PRESS_FIT_PREP_DISTANCE_DEFAULT,
|
|
266
|
+
pressDistance=_PRESS_FIT_PRESS_DISTANCE_DEFAULT,
|
|
267
|
+
ejectorPushMm=_PRESS_FIT_EJECTOR_PUSH_MM_DEFAULT,
|
|
268
|
+
)
|
|
269
|
+
await self.relative_pickup_tip(
|
|
270
|
+
tip_pick_up_params=tip_pick_up_params,
|
|
271
|
+
mount=mount,
|
|
277
272
|
)
|
|
278
273
|
|
|
279
274
|
# cache_tip
|
|
@@ -7,7 +7,6 @@ from typing import TYPE_CHECKING, Optional, Type
|
|
|
7
7
|
from typing_extensions import Literal
|
|
8
8
|
|
|
9
9
|
from opentrons.protocol_engine.resources.model_utils import ModelUtils
|
|
10
|
-
from opentrons.protocol_engine.errors import UnsupportedLabwareForActionError
|
|
11
10
|
from opentrons.protocol_engine.types import MotorAxis
|
|
12
11
|
from opentrons.types import MountType
|
|
13
12
|
|
|
@@ -27,7 +26,6 @@ from .command import (
|
|
|
27
26
|
DefinedErrorData,
|
|
28
27
|
SuccessData,
|
|
29
28
|
)
|
|
30
|
-
from ..resources import labware_validation
|
|
31
29
|
|
|
32
30
|
if TYPE_CHECKING:
|
|
33
31
|
from ..state.state import StateView
|
|
@@ -86,11 +84,7 @@ class EvotipUnsealPipetteImplementation(
|
|
|
86
84
|
well_name = params.wellName
|
|
87
85
|
|
|
88
86
|
well_location = params.wellLocation
|
|
89
|
-
|
|
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
|
-
)
|
|
87
|
+
|
|
94
88
|
is_partially_configured = self._state_view.pipettes.get_is_partially_configured(
|
|
95
89
|
pipette_id=pipette_id
|
|
96
90
|
)
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"""Command models for Flex Stacker commands."""
|
|
2
|
+
|
|
3
|
+
from .store import (
|
|
4
|
+
StoreCommandType,
|
|
5
|
+
StoreParams,
|
|
6
|
+
StoreResult,
|
|
7
|
+
Store,
|
|
8
|
+
StoreCreate,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
from .retrieve import (
|
|
12
|
+
RetrieveCommandType,
|
|
13
|
+
RetrieveParams,
|
|
14
|
+
RetrieveResult,
|
|
15
|
+
Retrieve,
|
|
16
|
+
RetrieveCreate,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
from .set_stored_labware import (
|
|
20
|
+
SetStoredLabwareCommandType,
|
|
21
|
+
SetStoredLabwareParams,
|
|
22
|
+
SetStoredLabwareResult,
|
|
23
|
+
SetStoredLabware,
|
|
24
|
+
SetStoredLabwareCreate,
|
|
25
|
+
StackerStoredLabwareDetails,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
from .fill import FillCommandType, FillParams, FillResult, Fill, FillCreate
|
|
29
|
+
|
|
30
|
+
from .empty import EmptyCommandType, EmptyParams, EmptyResult, Empty, EmptyCreate
|
|
31
|
+
|
|
32
|
+
from .close_latch import (
|
|
33
|
+
CloseLatchCommandType,
|
|
34
|
+
CloseLatchParams,
|
|
35
|
+
CloseLatchResult,
|
|
36
|
+
CloseLatch,
|
|
37
|
+
CloseLatchCreate,
|
|
38
|
+
)
|
|
39
|
+
from .open_latch import (
|
|
40
|
+
OpenLatchCommandType,
|
|
41
|
+
OpenLatchParams,
|
|
42
|
+
OpenLatchResult,
|
|
43
|
+
OpenLatch,
|
|
44
|
+
OpenLatchCreate,
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
from .prepare_shuttle import (
|
|
48
|
+
PrepareShuttleCommandType,
|
|
49
|
+
PrepareShuttleParams,
|
|
50
|
+
PrepareShuttleResult,
|
|
51
|
+
PrepareShuttle,
|
|
52
|
+
PrepareShuttleCreate,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
__all__ = [
|
|
57
|
+
# flexStacker/store
|
|
58
|
+
"StoreCommandType",
|
|
59
|
+
"StoreParams",
|
|
60
|
+
"StoreResult",
|
|
61
|
+
"Store",
|
|
62
|
+
"StoreCreate",
|
|
63
|
+
# flexStacker/retrieve
|
|
64
|
+
"RetrieveCommandType",
|
|
65
|
+
"RetrieveParams",
|
|
66
|
+
"RetrieveResult",
|
|
67
|
+
"Retrieve",
|
|
68
|
+
"RetrieveCreate",
|
|
69
|
+
# flexStacker/setStoredLabware
|
|
70
|
+
"SetStoredLabwareCommandType",
|
|
71
|
+
"SetStoredLabwareParams",
|
|
72
|
+
"SetStoredLabwareResult",
|
|
73
|
+
"SetStoredLabware",
|
|
74
|
+
"SetStoredLabwareCreate",
|
|
75
|
+
"StackerStoredLabwareDetails",
|
|
76
|
+
# flexStacker/fill
|
|
77
|
+
"FillCommandType",
|
|
78
|
+
"FillParams",
|
|
79
|
+
"FillResult",
|
|
80
|
+
"Fill",
|
|
81
|
+
"FillCreate",
|
|
82
|
+
# flexStacker/empty
|
|
83
|
+
"EmptyCommandType",
|
|
84
|
+
"EmptyParams",
|
|
85
|
+
"EmptyResult",
|
|
86
|
+
"Empty",
|
|
87
|
+
"EmptyCreate",
|
|
88
|
+
# flexStacker/closeLatch
|
|
89
|
+
"CloseLatchCommandType",
|
|
90
|
+
"CloseLatchParams",
|
|
91
|
+
"CloseLatchResult",
|
|
92
|
+
"CloseLatch",
|
|
93
|
+
"CloseLatchCreate",
|
|
94
|
+
# flexStacker/openLatch
|
|
95
|
+
"OpenLatchCommandType",
|
|
96
|
+
"OpenLatchParams",
|
|
97
|
+
"OpenLatchResult",
|
|
98
|
+
"OpenLatch",
|
|
99
|
+
"OpenLatchCreate",
|
|
100
|
+
# flexStacker/prepareShuttle
|
|
101
|
+
"PrepareShuttleCommandType",
|
|
102
|
+
"PrepareShuttleParams",
|
|
103
|
+
"PrepareShuttleResult",
|
|
104
|
+
"PrepareShuttle",
|
|
105
|
+
"PrepareShuttleCreate",
|
|
106
|
+
]
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"""Command models to close the latch of a Flex Stacker."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
from typing import Optional, Literal, TYPE_CHECKING
|
|
7
|
+
from typing_extensions import Type
|
|
8
|
+
|
|
9
|
+
from pydantic import BaseModel, Field
|
|
10
|
+
|
|
11
|
+
from ..command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, SuccessData
|
|
12
|
+
from ...errors import (
|
|
13
|
+
ErrorOccurrence,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from ...state.state import StateView
|
|
18
|
+
from opentrons.protocol_engine.execution import EquipmentHandler
|
|
19
|
+
|
|
20
|
+
CloseLatchCommandType = Literal["flexStacker/closeLatch"]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class CloseLatchParams(BaseModel):
|
|
24
|
+
"""The parameters defining how a stacker should close its latch."""
|
|
25
|
+
|
|
26
|
+
moduleId: str = Field(..., description="Unique ID of the Flex Stacker")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class CloseLatchResult(BaseModel):
|
|
30
|
+
"""Result data from a stacker CloseLatch command."""
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class CloseLatchImpl(
|
|
34
|
+
AbstractCommandImpl[CloseLatchParams, SuccessData[CloseLatchResult]]
|
|
35
|
+
):
|
|
36
|
+
"""Implementation of a stacker CloseLatch command."""
|
|
37
|
+
|
|
38
|
+
def __init__(
|
|
39
|
+
self, state_view: StateView, equipment: EquipmentHandler, **kwargs: object
|
|
40
|
+
) -> None:
|
|
41
|
+
self._state_view = state_view
|
|
42
|
+
self._equipment = equipment
|
|
43
|
+
|
|
44
|
+
async def execute(self, params: CloseLatchParams) -> SuccessData[CloseLatchResult]:
|
|
45
|
+
"""Execute the stacker CloseLatch command."""
|
|
46
|
+
stacker_state = self._state_view.modules.get_flex_stacker_substate(
|
|
47
|
+
params.moduleId
|
|
48
|
+
)
|
|
49
|
+
stacker_hw = self._equipment.get_module_hardware_api(stacker_state.module_id)
|
|
50
|
+
|
|
51
|
+
if stacker_hw is not None:
|
|
52
|
+
await stacker_hw.close_latch()
|
|
53
|
+
return SuccessData(public=CloseLatchResult())
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class CloseLatch(BaseCommand[CloseLatchParams, CloseLatchResult, ErrorOccurrence]):
|
|
57
|
+
"""A command to CloseLatch the Flex Stacker of labware."""
|
|
58
|
+
|
|
59
|
+
commandType: CloseLatchCommandType = "flexStacker/closeLatch"
|
|
60
|
+
params: CloseLatchParams
|
|
61
|
+
result: Optional[CloseLatchResult] = None
|
|
62
|
+
|
|
63
|
+
_ImplementationCls: Type[CloseLatchImpl] = CloseLatchImpl
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class CloseLatchCreate(BaseCommandCreate[CloseLatchParams]):
|
|
67
|
+
"""A request to execute a Flex Stacker CloseLatch command."""
|
|
68
|
+
|
|
69
|
+
commandType: CloseLatchCommandType = "flexStacker/closeLatch"
|
|
70
|
+
params: CloseLatchParams
|
|
71
|
+
|
|
72
|
+
_CommandCls: Type[CloseLatch] = CloseLatch
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""Common flex stacker base models."""
|
|
2
|
+
from typing import Literal
|
|
3
|
+
|
|
4
|
+
from ...errors import ErrorOccurrence
|
|
5
|
+
from opentrons_shared_data.errors import ErrorCodes
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class FlexStackerStallOrCollisionError(ErrorOccurrence):
|
|
9
|
+
"""Returned when the motor driver detects a stall."""
|
|
10
|
+
|
|
11
|
+
isDefined: bool = True
|
|
12
|
+
errorType: Literal["flexStackerStallOrCollision"] = "flexStackerStallOrCollision"
|
|
13
|
+
|
|
14
|
+
errorCode: str = ErrorCodes.FLEX_STACKER_STALL_OR_COLLISION_DETECTED.value.code
|
|
15
|
+
detail: str = ErrorCodes.FLEX_STACKER_STALL_OR_COLLISION_DETECTED.value.detail
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"""Command models to engage a user to empty a Flex Stacker."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
from typing import Optional, Literal, TYPE_CHECKING
|
|
7
|
+
from typing_extensions import Type
|
|
8
|
+
|
|
9
|
+
from pydantic import BaseModel, Field
|
|
10
|
+
|
|
11
|
+
from ..command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, SuccessData
|
|
12
|
+
from ...errors import (
|
|
13
|
+
ErrorOccurrence,
|
|
14
|
+
)
|
|
15
|
+
from ...errors.exceptions import FlexStackerLabwarePoolNotYetDefinedError
|
|
16
|
+
from ...state import update_types
|
|
17
|
+
from ...types import StackerFillEmptyStrategy
|
|
18
|
+
from opentrons.calibration_storage.helpers import uri_from_details
|
|
19
|
+
|
|
20
|
+
if TYPE_CHECKING:
|
|
21
|
+
from ...state.state import StateView
|
|
22
|
+
from ...execution import RunControlHandler
|
|
23
|
+
|
|
24
|
+
EmptyCommandType = Literal["flexStacker/empty"]
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class EmptyParams(BaseModel):
|
|
28
|
+
"""The parameters defining how a stacker should be emptied."""
|
|
29
|
+
|
|
30
|
+
moduleId: str = Field(..., description="Unique ID of the Flex Stacker")
|
|
31
|
+
|
|
32
|
+
strategy: StackerFillEmptyStrategy = Field(
|
|
33
|
+
...,
|
|
34
|
+
description=(
|
|
35
|
+
"How to empty the stacker. "
|
|
36
|
+
"If manualWithPause, pause the protocol until the client sends an interaction, and mark "
|
|
37
|
+
"the labware pool as empty thereafter. If logical, do not pause but immediately apply the "
|
|
38
|
+
"specified count."
|
|
39
|
+
),
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
message: str | None = Field(
|
|
43
|
+
None,
|
|
44
|
+
description="The message to display on connected clients during a manualWithPause strategy empty.",
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
count: int | None = Field(
|
|
48
|
+
None,
|
|
49
|
+
description=(
|
|
50
|
+
"The new count of labware in the pool. If None, default to an empty pool. If this number is "
|
|
51
|
+
"larger than the amount of labware currently in the pool, default to the smaller amount. "
|
|
52
|
+
"Do not use the value in the parameters as an outside observer; instead, use the count value "
|
|
53
|
+
"from the results."
|
|
54
|
+
),
|
|
55
|
+
ge=0,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class EmptyResult(BaseModel):
|
|
60
|
+
"""Result data from a stacker empty command."""
|
|
61
|
+
|
|
62
|
+
count: int = Field(
|
|
63
|
+
..., description="The new amount of labware stored in the stacker labware pool."
|
|
64
|
+
)
|
|
65
|
+
primaryLabwareURI: str = Field(
|
|
66
|
+
...,
|
|
67
|
+
description="The labware definition URI of the primary labware.",
|
|
68
|
+
)
|
|
69
|
+
adapterLabwareURI: str | None = Field(
|
|
70
|
+
None,
|
|
71
|
+
description="The labware definition URI of the adapter labware.",
|
|
72
|
+
)
|
|
73
|
+
lidLabwareURI: str | None = Field(
|
|
74
|
+
None,
|
|
75
|
+
description="The labware definition URI of the lid labware.",
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class EmptyImpl(AbstractCommandImpl[EmptyParams, SuccessData[EmptyResult]]):
|
|
80
|
+
"""Implementation of a stacker empty command."""
|
|
81
|
+
|
|
82
|
+
def __init__(
|
|
83
|
+
self, state_view: StateView, run_control: RunControlHandler, **kwargs: object
|
|
84
|
+
) -> None:
|
|
85
|
+
self._state_view = state_view
|
|
86
|
+
self._run_control = run_control
|
|
87
|
+
|
|
88
|
+
async def execute(self, params: EmptyParams) -> SuccessData[EmptyResult]:
|
|
89
|
+
"""Execute the stacker empty command."""
|
|
90
|
+
stacker_state = self._state_view.modules.get_flex_stacker_substate(
|
|
91
|
+
params.moduleId
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
if stacker_state.pool_primary_definition is None:
|
|
95
|
+
location = self._state_view.modules.get_location(params.moduleId)
|
|
96
|
+
raise FlexStackerLabwarePoolNotYetDefinedError(
|
|
97
|
+
message=f"The Flex Stacker in {location} has not been configured yet and cannot be emptied."
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
count = params.count if params.count is not None else 0
|
|
101
|
+
|
|
102
|
+
new_count = min(stacker_state.pool_count, count)
|
|
103
|
+
|
|
104
|
+
state_update = (
|
|
105
|
+
update_types.StateUpdate().update_flex_stacker_labware_pool_count(
|
|
106
|
+
params.moduleId, new_count
|
|
107
|
+
)
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
if params.strategy == StackerFillEmptyStrategy.MANUAL_WITH_PAUSE:
|
|
111
|
+
await self._run_control.wait_for_resume()
|
|
112
|
+
|
|
113
|
+
if stacker_state.pool_primary_definition is None:
|
|
114
|
+
raise FlexStackerLabwarePoolNotYetDefinedError(
|
|
115
|
+
"The Primary Labware must be defined in the stacker pool."
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
return SuccessData(
|
|
119
|
+
public=EmptyResult(
|
|
120
|
+
count=new_count,
|
|
121
|
+
primaryLabwareURI=uri_from_details(
|
|
122
|
+
stacker_state.pool_primary_definition.namespace,
|
|
123
|
+
stacker_state.pool_primary_definition.parameters.loadName,
|
|
124
|
+
stacker_state.pool_primary_definition.version,
|
|
125
|
+
),
|
|
126
|
+
adapterLabwareURI=uri_from_details(
|
|
127
|
+
stacker_state.pool_adapter_definition.namespace,
|
|
128
|
+
stacker_state.pool_adapter_definition.parameters.loadName,
|
|
129
|
+
stacker_state.pool_adapter_definition.version,
|
|
130
|
+
)
|
|
131
|
+
if stacker_state.pool_adapter_definition is not None
|
|
132
|
+
else None,
|
|
133
|
+
lidLabwareURI=uri_from_details(
|
|
134
|
+
stacker_state.pool_lid_definition.namespace,
|
|
135
|
+
stacker_state.pool_lid_definition.parameters.loadName,
|
|
136
|
+
stacker_state.pool_lid_definition.version,
|
|
137
|
+
)
|
|
138
|
+
if stacker_state.pool_lid_definition is not None
|
|
139
|
+
else None,
|
|
140
|
+
),
|
|
141
|
+
state_update=state_update,
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
class Empty(BaseCommand[EmptyParams, EmptyResult, ErrorOccurrence]):
|
|
146
|
+
"""A command to empty the Flex Stacker of labware."""
|
|
147
|
+
|
|
148
|
+
commandType: EmptyCommandType = "flexStacker/empty"
|
|
149
|
+
params: EmptyParams
|
|
150
|
+
result: Optional[EmptyResult] = None
|
|
151
|
+
|
|
152
|
+
_ImplementationCls: Type[EmptyImpl] = EmptyImpl
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
class EmptyCreate(BaseCommandCreate[EmptyParams]):
|
|
156
|
+
"""A request to execute a Flex Stacker empty command."""
|
|
157
|
+
|
|
158
|
+
commandType: EmptyCommandType = "flexStacker/empty"
|
|
159
|
+
params: EmptyParams
|
|
160
|
+
|
|
161
|
+
_CommandCls: Type[Empty] = Empty
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"""Command models to engage a user to empty a Flex Stacker."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from typing import Optional, Literal, TYPE_CHECKING
|
|
5
|
+
from typing_extensions import Type
|
|
6
|
+
|
|
7
|
+
from pydantic import BaseModel, Field
|
|
8
|
+
|
|
9
|
+
from ..command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, SuccessData
|
|
10
|
+
from ...errors import (
|
|
11
|
+
ErrorOccurrence,
|
|
12
|
+
)
|
|
13
|
+
from ...errors.exceptions import FlexStackerLabwarePoolNotYetDefinedError
|
|
14
|
+
from ...state import update_types
|
|
15
|
+
from ...types import StackerFillEmptyStrategy
|
|
16
|
+
from opentrons.calibration_storage.helpers import uri_from_details
|
|
17
|
+
|
|
18
|
+
if TYPE_CHECKING:
|
|
19
|
+
from ...state.state import StateView
|
|
20
|
+
from ...execution import RunControlHandler
|
|
21
|
+
|
|
22
|
+
FillCommandType = Literal["flexStacker/fill"]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class FillParams(BaseModel):
|
|
26
|
+
"""The parameters defining how a stacker should be filled."""
|
|
27
|
+
|
|
28
|
+
moduleId: str = Field(..., description="Unique ID of the Flex Stacker")
|
|
29
|
+
|
|
30
|
+
strategy: StackerFillEmptyStrategy = Field(
|
|
31
|
+
...,
|
|
32
|
+
description=(
|
|
33
|
+
"How to fill the stacker. "
|
|
34
|
+
"If manualWithPause, pause the protocol until the client sends an interaction, and apply "
|
|
35
|
+
"the new specified count thereafter. If logical, do not pause but immediately apply the "
|
|
36
|
+
"specified count."
|
|
37
|
+
),
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
message: str | None = Field(
|
|
41
|
+
None,
|
|
42
|
+
description="The message to display on connected clients during a manualWithPause strategy fill.",
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
count: int | None = Field(
|
|
46
|
+
None,
|
|
47
|
+
description=(
|
|
48
|
+
"How full the labware pool should now be. If None, default to the maximum amount "
|
|
49
|
+
"of the currently-configured labware the pool can hold. "
|
|
50
|
+
"If this number is larger than the maximum the pool can hold, it will be clamped to "
|
|
51
|
+
"the maximum. If this number is smaller than the current amount of labware the pool "
|
|
52
|
+
"holds, it will be clamped to that minimum. Do not use the value in the parameters as "
|
|
53
|
+
"an outside observer; instead, use the count value from the results."
|
|
54
|
+
),
|
|
55
|
+
ge=1,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class FillResult(BaseModel):
|
|
60
|
+
"""Result data from a stacker fill command."""
|
|
61
|
+
|
|
62
|
+
count: int = Field(
|
|
63
|
+
..., description="The new amount of labware stored in the stacker labware pool."
|
|
64
|
+
)
|
|
65
|
+
primaryLabwareURI: str = Field(
|
|
66
|
+
...,
|
|
67
|
+
description="The labware definition URI of the primary labware.",
|
|
68
|
+
)
|
|
69
|
+
adapterLabwareURI: str | None = Field(
|
|
70
|
+
None,
|
|
71
|
+
description="The labware definition URI of the adapter labware.",
|
|
72
|
+
)
|
|
73
|
+
lidLabwareURI: str | None = Field(
|
|
74
|
+
None,
|
|
75
|
+
description="The labware definition URI of the lid labware.",
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class FillImpl(AbstractCommandImpl[FillParams, SuccessData[FillResult]]):
|
|
80
|
+
"""Implementation of a stacker fill command."""
|
|
81
|
+
|
|
82
|
+
def __init__(
|
|
83
|
+
self, state_view: StateView, run_control: RunControlHandler, **kwargs: object
|
|
84
|
+
) -> None:
|
|
85
|
+
self._state_view = state_view
|
|
86
|
+
self._run_control = run_control
|
|
87
|
+
|
|
88
|
+
async def execute(self, params: FillParams) -> SuccessData[FillResult]:
|
|
89
|
+
"""Execute the stacker fill command."""
|
|
90
|
+
stacker_state = self._state_view.modules.get_flex_stacker_substate(
|
|
91
|
+
params.moduleId
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
if stacker_state.pool_primary_definition is None:
|
|
95
|
+
location = self._state_view.modules.get_location(params.moduleId)
|
|
96
|
+
raise FlexStackerLabwarePoolNotYetDefinedError(
|
|
97
|
+
message=f"The Flex Stacker in {location} has not been configured yet and cannot be filled."
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
count = (
|
|
101
|
+
params.count if params.count is not None else stacker_state.max_pool_count
|
|
102
|
+
)
|
|
103
|
+
new_count = min(
|
|
104
|
+
stacker_state.max_pool_count, max(stacker_state.pool_count, count)
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
state_update = (
|
|
108
|
+
update_types.StateUpdate().update_flex_stacker_labware_pool_count(
|
|
109
|
+
params.moduleId, new_count
|
|
110
|
+
)
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
if params.strategy == StackerFillEmptyStrategy.MANUAL_WITH_PAUSE:
|
|
114
|
+
await self._run_control.wait_for_resume()
|
|
115
|
+
|
|
116
|
+
if stacker_state.pool_primary_definition is None:
|
|
117
|
+
raise FlexStackerLabwarePoolNotYetDefinedError(
|
|
118
|
+
"The Primary Labware must be defined in the stacker pool."
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
return SuccessData(
|
|
122
|
+
public=FillResult(
|
|
123
|
+
count=new_count,
|
|
124
|
+
primaryLabwareURI=uri_from_details(
|
|
125
|
+
stacker_state.pool_primary_definition.namespace,
|
|
126
|
+
stacker_state.pool_primary_definition.parameters.loadName,
|
|
127
|
+
stacker_state.pool_primary_definition.version,
|
|
128
|
+
),
|
|
129
|
+
adapterLabwareURI=uri_from_details(
|
|
130
|
+
stacker_state.pool_adapter_definition.namespace,
|
|
131
|
+
stacker_state.pool_adapter_definition.parameters.loadName,
|
|
132
|
+
stacker_state.pool_adapter_definition.version,
|
|
133
|
+
)
|
|
134
|
+
if stacker_state.pool_adapter_definition is not None
|
|
135
|
+
else None,
|
|
136
|
+
lidLabwareURI=uri_from_details(
|
|
137
|
+
stacker_state.pool_lid_definition.namespace,
|
|
138
|
+
stacker_state.pool_lid_definition.parameters.loadName,
|
|
139
|
+
stacker_state.pool_lid_definition.version,
|
|
140
|
+
)
|
|
141
|
+
if stacker_state.pool_lid_definition is not None
|
|
142
|
+
else None,
|
|
143
|
+
),
|
|
144
|
+
state_update=state_update,
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
class Fill(BaseCommand[FillParams, FillResult, ErrorOccurrence]):
|
|
149
|
+
"""A command to fill the Flex Stacker with labware."""
|
|
150
|
+
|
|
151
|
+
commandType: FillCommandType = "flexStacker/fill"
|
|
152
|
+
params: FillParams
|
|
153
|
+
result: Optional[FillResult] = None
|
|
154
|
+
|
|
155
|
+
_ImplementationCls: Type[FillImpl] = FillImpl
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
class FillCreate(BaseCommandCreate[FillParams]):
|
|
159
|
+
"""A request to execute a Flex Stacker fill command."""
|
|
160
|
+
|
|
161
|
+
commandType: FillCommandType = "flexStacker/fill"
|
|
162
|
+
params: FillParams
|
|
163
|
+
|
|
164
|
+
_CommandCls: Type[Fill] = Fill
|