opentrons 8.3.1a1__py2.py3-none-any.whl → 8.4.0a0__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.
Potentially problematic release.
This version of opentrons might be problematic. Click here for more details.
- 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 +7 -2
- 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 +245 -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 +2 -9
- 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 +3 -1
- 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/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.0a0.dist-info}/METADATA +4 -4
- {opentrons-8.3.1a1.dist-info → opentrons-8.4.0a0.dist-info}/RECORD +187 -147
- 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.0a0.dist-info}/LICENSE +0 -0
- {opentrons-8.3.1a1.dist-info → opentrons-8.4.0a0.dist-info}/WHEEL +0 -0
- {opentrons-8.3.1a1.dist-info → opentrons-8.4.0a0.dist-info}/entry_points.txt +0 -0
- {opentrons-8.3.1a1.dist-info → opentrons-8.4.0a0.dist-info}/top_level.txt +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Load lid command request, result, and implementation models."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
4
|
from pydantic import BaseModel, Field
|
|
4
5
|
from typing import TYPE_CHECKING, Optional, Type
|
|
@@ -9,10 +10,12 @@ from opentrons_shared_data.labware.labware_definition import LabwareDefinition
|
|
|
9
10
|
from ..errors import LabwareCannotBeStackedError, LabwareIsNotAllowedInLocationError
|
|
10
11
|
from ..resources import labware_validation
|
|
11
12
|
from ..types import (
|
|
12
|
-
|
|
13
|
+
LoadableLabwareLocation,
|
|
13
14
|
OnLabwareLocation,
|
|
15
|
+
OnLabwareLocationSequenceComponent,
|
|
14
16
|
)
|
|
15
17
|
|
|
18
|
+
from .labware_handling_common import LabwareHandlingResultMixin
|
|
16
19
|
from .command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, SuccessData
|
|
17
20
|
from ..errors.error_occurrence import ErrorOccurrence
|
|
18
21
|
from ..state.update_types import StateUpdate
|
|
@@ -28,7 +31,7 @@ LoadLidCommandType = Literal["loadLid"]
|
|
|
28
31
|
class LoadLidParams(BaseModel):
|
|
29
32
|
"""Payload required to load a lid onto a labware."""
|
|
30
33
|
|
|
31
|
-
location:
|
|
34
|
+
location: LoadableLabwareLocation = Field(
|
|
32
35
|
...,
|
|
33
36
|
description="Labware the lid should be loaded onto.",
|
|
34
37
|
)
|
|
@@ -46,13 +49,9 @@ class LoadLidParams(BaseModel):
|
|
|
46
49
|
)
|
|
47
50
|
|
|
48
51
|
|
|
49
|
-
class LoadLidResult(
|
|
52
|
+
class LoadLidResult(LabwareHandlingResultMixin):
|
|
50
53
|
"""Result data from the execution of a LoadLabware command."""
|
|
51
54
|
|
|
52
|
-
labwareId: str = Field(
|
|
53
|
-
...,
|
|
54
|
-
description="An ID to reference this lid labware in subsequent commands.",
|
|
55
|
-
)
|
|
56
55
|
definition: LabwareDefinition = Field(
|
|
57
56
|
...,
|
|
58
57
|
description="The full definition data for this lid labware.",
|
|
@@ -88,9 +87,6 @@ class LoadLidImplementation(
|
|
|
88
87
|
labware_id=None,
|
|
89
88
|
)
|
|
90
89
|
|
|
91
|
-
# TODO(chb 2024-12-12) these validation checks happen after the labware is loaded, because they rely on
|
|
92
|
-
# on the definition. In practice this will not cause any issues since they will raise protocol ending
|
|
93
|
-
# exception, but for correctness should be refactored to do this check beforehand.
|
|
94
90
|
if not labware_validation.validate_definition_is_lid(loaded_labware.definition):
|
|
95
91
|
raise LabwareCannotBeStackedError(
|
|
96
92
|
f"Labware {params.loadName} is not a Lid and cannot be loaded onto {self._state_view.labware.get_display_name(params.location.labwareId)}."
|
|
@@ -99,9 +95,9 @@ class LoadLidImplementation(
|
|
|
99
95
|
state_update = StateUpdate()
|
|
100
96
|
|
|
101
97
|
# In the case of lids being loaded on top of other labware, set the parent labware's lid
|
|
102
|
-
state_update.
|
|
103
|
-
|
|
104
|
-
|
|
98
|
+
state_update.set_lids(
|
|
99
|
+
parent_labware_ids=[params.location.labwareId],
|
|
100
|
+
lid_ids=[loaded_labware.labware_id],
|
|
105
101
|
)
|
|
106
102
|
|
|
107
103
|
state_update.set_loaded_labware(
|
|
@@ -122,6 +118,18 @@ class LoadLidImplementation(
|
|
|
122
118
|
public=LoadLidResult(
|
|
123
119
|
labwareId=loaded_labware.labware_id,
|
|
124
120
|
definition=loaded_labware.definition,
|
|
121
|
+
# Note: the lid is not yet loaded and therefore won't be found as the lid id for the
|
|
122
|
+
# labware onto which we're loading it, so build that part of the location sequence
|
|
123
|
+
# here and then build the rest of the sequence from the parent labware
|
|
124
|
+
locationSequence=[
|
|
125
|
+
OnLabwareLocationSequenceComponent(
|
|
126
|
+
labwareId=params.location.labwareId,
|
|
127
|
+
lidId=loaded_labware.labware_id,
|
|
128
|
+
)
|
|
129
|
+
]
|
|
130
|
+
+ self._state_view.geometry.get_location_sequence(
|
|
131
|
+
params.location.labwareId
|
|
132
|
+
),
|
|
125
133
|
),
|
|
126
134
|
state_update=state_update,
|
|
127
135
|
)
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"""Load lid stack command request, result, and implementation models."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
4
|
from pydantic import BaseModel, Field
|
|
4
|
-
from typing import TYPE_CHECKING, Optional, Type, List
|
|
5
|
+
from typing import TYPE_CHECKING, Optional, Type, List, Any
|
|
6
|
+
from pydantic.json_schema import SkipJsonSchema
|
|
5
7
|
from typing_extensions import Literal
|
|
6
8
|
|
|
7
9
|
from opentrons_shared_data.labware.labware_definition import LabwareDefinition
|
|
@@ -9,10 +11,13 @@ from opentrons_shared_data.labware.labware_definition import LabwareDefinition
|
|
|
9
11
|
from ..errors import LabwareIsNotAllowedInLocationError, ProtocolEngineError
|
|
10
12
|
from ..resources import fixture_validation, labware_validation
|
|
11
13
|
from ..types import (
|
|
12
|
-
|
|
14
|
+
LoadableLabwareLocation,
|
|
15
|
+
SYSTEM_LOCATION,
|
|
13
16
|
OnLabwareLocation,
|
|
14
17
|
DeckSlotLocation,
|
|
15
18
|
AddressableAreaLocation,
|
|
19
|
+
LabwareLocationSequence,
|
|
20
|
+
OnLabwareLocationSequenceComponent,
|
|
16
21
|
)
|
|
17
22
|
|
|
18
23
|
from .command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, SuccessData
|
|
@@ -21,11 +26,16 @@ from ..state.update_types import StateUpdate
|
|
|
21
26
|
|
|
22
27
|
if TYPE_CHECKING:
|
|
23
28
|
from ..state.state import StateView
|
|
24
|
-
from ..execution import EquipmentHandler
|
|
29
|
+
from ..execution import LoadedLabwareData, EquipmentHandler
|
|
25
30
|
|
|
26
31
|
|
|
27
32
|
LoadLidStackCommandType = Literal["loadLidStack"]
|
|
28
33
|
|
|
34
|
+
|
|
35
|
+
def _remove_default(s: dict[str, Any]) -> None:
|
|
36
|
+
s.pop("default", None)
|
|
37
|
+
|
|
38
|
+
|
|
29
39
|
_LID_STACK_PE_LABWARE = "protocol_engine_lid_stack_object"
|
|
30
40
|
_LID_STACK_PE_NAMESPACE = "opentrons"
|
|
31
41
|
_LID_STACK_PE_VERSION = 1
|
|
@@ -34,7 +44,7 @@ _LID_STACK_PE_VERSION = 1
|
|
|
34
44
|
class LoadLidStackParams(BaseModel):
|
|
35
45
|
"""Payload required to load a lid stack onto a location."""
|
|
36
46
|
|
|
37
|
-
location:
|
|
47
|
+
location: LoadableLabwareLocation = Field(
|
|
38
48
|
...,
|
|
39
49
|
description="Location the lid stack should be loaded into.",
|
|
40
50
|
)
|
|
@@ -50,6 +60,18 @@ class LoadLidStackParams(BaseModel):
|
|
|
50
60
|
...,
|
|
51
61
|
description="The lid labware definition version.",
|
|
52
62
|
)
|
|
63
|
+
stackLabwareId: str | SkipJsonSchema[None] = Field(
|
|
64
|
+
None,
|
|
65
|
+
description="An optional ID to assign to the lid stack labware object created."
|
|
66
|
+
"If None, an ID will be generated.",
|
|
67
|
+
json_schema_extra=_remove_default,
|
|
68
|
+
)
|
|
69
|
+
labwareIds: List[str] | SkipJsonSchema[None] = Field(
|
|
70
|
+
None,
|
|
71
|
+
description="An optional list of IDs to assign to the lids in the stack."
|
|
72
|
+
"If None, an ID will be generated.",
|
|
73
|
+
json_schema_extra=_remove_default,
|
|
74
|
+
)
|
|
53
75
|
quantity: int = Field(
|
|
54
76
|
...,
|
|
55
77
|
description="The quantity of lids to load.",
|
|
@@ -61,19 +83,31 @@ class LoadLidStackResult(BaseModel):
|
|
|
61
83
|
|
|
62
84
|
stackLabwareId: str = Field(
|
|
63
85
|
...,
|
|
64
|
-
description="An ID to reference the
|
|
86
|
+
description="An ID to reference the lid stack labware object created.",
|
|
65
87
|
)
|
|
66
88
|
labwareIds: List[str] = Field(
|
|
67
89
|
...,
|
|
68
90
|
description="A list of lid labware IDs to reference the lids in this stack by. The first ID is the bottom of the stack.",
|
|
69
91
|
)
|
|
70
|
-
definition: LabwareDefinition = Field(
|
|
92
|
+
definition: LabwareDefinition | None = Field(
|
|
71
93
|
...,
|
|
72
94
|
description="The full definition data for this lid labware.",
|
|
73
95
|
)
|
|
74
|
-
location:
|
|
96
|
+
location: LoadableLabwareLocation = Field(
|
|
75
97
|
..., description="The Location that the stack of lid labware has been loaded."
|
|
76
98
|
)
|
|
99
|
+
lidStackDefinition: LabwareDefinition | None = Field(
|
|
100
|
+
None,
|
|
101
|
+
description="The definition of the lid stack object. Optional for backwards-compatibility.",
|
|
102
|
+
)
|
|
103
|
+
stackLocationSequence: LabwareLocationSequence | None = Field(
|
|
104
|
+
None,
|
|
105
|
+
description="The location sequence for the lid stack labware object created.",
|
|
106
|
+
)
|
|
107
|
+
locationSequences: List[LabwareLocationSequence] | None = Field(
|
|
108
|
+
None,
|
|
109
|
+
description="The location sequences for the lids just loaded into the stack. These are in the same order as labwareIds.",
|
|
110
|
+
)
|
|
77
111
|
|
|
78
112
|
|
|
79
113
|
class LoadLidStackImplementation(
|
|
@@ -87,10 +121,7 @@ class LoadLidStackImplementation(
|
|
|
87
121
|
self._equipment = equipment
|
|
88
122
|
self._state_view = state_view
|
|
89
123
|
|
|
90
|
-
|
|
91
|
-
self, params: LoadLidStackParams
|
|
92
|
-
) -> SuccessData[LoadLidStackResult]:
|
|
93
|
-
"""Load definition and calibration data necessary for a lid stack."""
|
|
124
|
+
def _validate_location(self, params: LoadLidStackParams) -> LoadableLabwareLocation:
|
|
94
125
|
if isinstance(params.location, AddressableAreaLocation):
|
|
95
126
|
area_name = params.location.addressableAreaName
|
|
96
127
|
if not (
|
|
@@ -107,36 +138,47 @@ class LoadLidStackImplementation(
|
|
|
107
138
|
self._state_view.addressable_areas.raise_if_area_not_in_deck_configuration(
|
|
108
139
|
params.location.slotName.id
|
|
109
140
|
)
|
|
110
|
-
|
|
111
|
-
verified_location = self._state_view.geometry.ensure_location_not_occupied(
|
|
112
|
-
params.location
|
|
113
|
-
)
|
|
114
|
-
|
|
115
|
-
lid_stack_object = await self._equipment.load_labware(
|
|
116
|
-
load_name=_LID_STACK_PE_LABWARE,
|
|
117
|
-
namespace=_LID_STACK_PE_NAMESPACE,
|
|
118
|
-
version=_LID_STACK_PE_VERSION,
|
|
119
|
-
location=verified_location,
|
|
120
|
-
labware_id=None,
|
|
121
|
-
)
|
|
122
|
-
if not labware_validation.validate_definition_is_system(
|
|
123
|
-
lid_stack_object.definition
|
|
124
|
-
):
|
|
141
|
+
if params.quantity <= 0 and params.location != SYSTEM_LOCATION:
|
|
125
142
|
raise ProtocolEngineError(
|
|
126
|
-
message="Lid Stack Labware Object
|
|
143
|
+
message="Lid Stack Labware Object with quantity 0 must be loaded onto System Location."
|
|
127
144
|
)
|
|
145
|
+
return self._state_view.geometry.ensure_location_not_occupied(params.location)
|
|
128
146
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
147
|
+
def _format_results(
|
|
148
|
+
self,
|
|
149
|
+
verified_location: LoadableLabwareLocation,
|
|
150
|
+
lid_stack_object: LoadedLabwareData,
|
|
151
|
+
loaded_lid_labwares: list[LoadedLabwareData],
|
|
152
|
+
lid_labware_definition: LabwareDefinition | None,
|
|
153
|
+
) -> SuccessData[LoadLidStackResult]:
|
|
154
|
+
stack_location_sequence = (
|
|
155
|
+
self._state_view.geometry.get_predicted_location_sequence(verified_location)
|
|
135
156
|
)
|
|
136
|
-
loaded_lid_locations_by_id = {}
|
|
157
|
+
loaded_lid_locations_by_id: dict[str, OnLabwareLocation] = {}
|
|
158
|
+
loaded_lid_ids_ordered: list[str] = []
|
|
159
|
+
loaded_lid_location_sequences_ordered: list[LabwareLocationSequence] = []
|
|
160
|
+
lid_location_sequence_accumulated: LabwareLocationSequence = [
|
|
161
|
+
OnLabwareLocationSequenceComponent(
|
|
162
|
+
labwareId=lid_stack_object.labware_id, lidId=None
|
|
163
|
+
)
|
|
164
|
+
] + stack_location_sequence
|
|
137
165
|
load_location = OnLabwareLocation(labwareId=lid_stack_object.labware_id)
|
|
166
|
+
last_lid_id: str | None = None
|
|
138
167
|
for loaded_lid in loaded_lid_labwares:
|
|
139
168
|
loaded_lid_locations_by_id[loaded_lid.labware_id] = load_location
|
|
169
|
+
loaded_lid_ids_ordered.append(loaded_lid.labware_id)
|
|
170
|
+
if last_lid_id is None:
|
|
171
|
+
last_lid_id = loaded_lid.labware_id
|
|
172
|
+
else:
|
|
173
|
+
lid_location_sequence_accumulated = [
|
|
174
|
+
OnLabwareLocationSequenceComponent(
|
|
175
|
+
labwareId=last_lid_id, lidId=None
|
|
176
|
+
)
|
|
177
|
+
] + lid_location_sequence_accumulated
|
|
178
|
+
last_lid_id = loaded_lid.labware_id
|
|
179
|
+
loaded_lid_location_sequences_ordered.append(
|
|
180
|
+
[loc for loc in lid_location_sequence_accumulated]
|
|
181
|
+
)
|
|
140
182
|
load_location = OnLabwareLocation(labwareId=loaded_lid.labware_id)
|
|
141
183
|
|
|
142
184
|
state_update = StateUpdate()
|
|
@@ -144,29 +186,70 @@ class LoadLidStackImplementation(
|
|
|
144
186
|
stack_id=lid_stack_object.labware_id,
|
|
145
187
|
stack_object_definition=lid_stack_object.definition,
|
|
146
188
|
stack_location=verified_location,
|
|
147
|
-
labware_ids=list(loaded_lid_locations_by_id.keys()),
|
|
148
|
-
labware_definition=loaded_lid_labwares[0].definition,
|
|
149
189
|
locations=loaded_lid_locations_by_id,
|
|
190
|
+
labware_definition=lid_labware_definition,
|
|
150
191
|
)
|
|
151
192
|
|
|
152
|
-
if isinstance(verified_location, OnLabwareLocation):
|
|
153
|
-
self._state_view.labware.raise_if_labware_cannot_be_stacked(
|
|
154
|
-
top_labware_definition=loaded_lid_labwares[
|
|
155
|
-
params.quantity - 1
|
|
156
|
-
].definition,
|
|
157
|
-
bottom_labware_id=verified_location.labwareId,
|
|
158
|
-
)
|
|
159
|
-
|
|
160
193
|
return SuccessData(
|
|
161
194
|
public=LoadLidStackResult(
|
|
162
195
|
stackLabwareId=lid_stack_object.labware_id,
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
196
|
+
lidStackDefinition=lid_stack_object.definition,
|
|
197
|
+
labwareIds=loaded_lid_ids_ordered,
|
|
198
|
+
definition=lid_labware_definition,
|
|
199
|
+
location=verified_location,
|
|
200
|
+
stackLocationSequence=stack_location_sequence,
|
|
201
|
+
locationSequences=loaded_lid_location_sequences_ordered,
|
|
166
202
|
),
|
|
167
203
|
state_update=state_update,
|
|
168
204
|
)
|
|
169
205
|
|
|
206
|
+
async def execute(
|
|
207
|
+
self, params: LoadLidStackParams
|
|
208
|
+
) -> SuccessData[LoadLidStackResult]:
|
|
209
|
+
"""Load definition and calibration data necessary for a lid stack."""
|
|
210
|
+
verified_location = self._validate_location(params)
|
|
211
|
+
|
|
212
|
+
lid_stack_object = await self._equipment.load_labware(
|
|
213
|
+
load_name=_LID_STACK_PE_LABWARE,
|
|
214
|
+
namespace=_LID_STACK_PE_NAMESPACE,
|
|
215
|
+
version=_LID_STACK_PE_VERSION,
|
|
216
|
+
location=verified_location,
|
|
217
|
+
labware_id=params.stackLabwareId,
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
if not labware_validation.validate_definition_is_system(
|
|
221
|
+
lid_stack_object.definition
|
|
222
|
+
):
|
|
223
|
+
raise ProtocolEngineError(
|
|
224
|
+
message="Lid Stack Labware Object Labware Definition does not contain required allowed role 'system'."
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
loaded_lid_labwares: list[LoadedLabwareData] = []
|
|
228
|
+
lid_labware_definition: LabwareDefinition | None = None
|
|
229
|
+
|
|
230
|
+
if params.quantity > 0:
|
|
231
|
+
loaded_lid_labwares = await self._equipment.load_lids(
|
|
232
|
+
load_name=params.loadName,
|
|
233
|
+
namespace=params.namespace,
|
|
234
|
+
version=params.version,
|
|
235
|
+
location=OnLabwareLocation(labwareId=lid_stack_object.labware_id),
|
|
236
|
+
quantity=params.quantity,
|
|
237
|
+
labware_ids=params.labwareIds,
|
|
238
|
+
)
|
|
239
|
+
lid_labware_definition = loaded_lid_labwares[-1].definition
|
|
240
|
+
if isinstance(verified_location, OnLabwareLocation):
|
|
241
|
+
self._state_view.labware.raise_if_labware_cannot_be_stacked(
|
|
242
|
+
top_labware_definition=lid_labware_definition,
|
|
243
|
+
bottom_labware_id=verified_location.labwareId,
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
return self._format_results(
|
|
247
|
+
verified_location,
|
|
248
|
+
lid_stack_object,
|
|
249
|
+
loaded_lid_labwares,
|
|
250
|
+
lid_labware_definition,
|
|
251
|
+
)
|
|
252
|
+
|
|
170
253
|
|
|
171
254
|
class LoadLidStack(
|
|
172
255
|
BaseCommand[LoadLidStackParams, LoadLidStackResult, ErrorOccurrence]
|
|
@@ -11,6 +11,7 @@ from .command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, Succes
|
|
|
11
11
|
from ..errors.error_occurrence import ErrorOccurrence
|
|
12
12
|
from ..types import (
|
|
13
13
|
DeckSlotLocation,
|
|
14
|
+
AddressableAreaLocation,
|
|
14
15
|
ModuleType,
|
|
15
16
|
ModuleModel,
|
|
16
17
|
ModuleDefinition,
|
|
@@ -129,41 +130,41 @@ class LoadModuleImplementation(
|
|
|
129
130
|
module_type = params.model.as_type()
|
|
130
131
|
self._ensure_module_location(params.location.slotName, module_type)
|
|
131
132
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
# Can this be simplified?
|
|
135
|
-
if self._state_view.config.robot_type == "OT-2 Standard":
|
|
136
|
-
self._state_view.addressable_areas.raise_if_area_not_in_deck_configuration(
|
|
137
|
-
params.location.slotName.id
|
|
138
|
-
)
|
|
139
|
-
else:
|
|
140
|
-
addressable_area_provided_by_module = (
|
|
133
|
+
if self._state_view.modules.get_deck_supports_module_fixtures():
|
|
134
|
+
addressable_area_module_reference = (
|
|
141
135
|
self._state_view.modules.ensure_and_convert_module_fixture_location(
|
|
142
136
|
deck_slot=params.location.slotName,
|
|
143
137
|
model=params.model,
|
|
144
138
|
)
|
|
145
139
|
)
|
|
146
|
-
|
|
147
|
-
|
|
140
|
+
else:
|
|
141
|
+
addressable_area_module_reference = params.location.slotName.id
|
|
142
|
+
state_update.set_addressable_area_used(
|
|
143
|
+
addressable_area_name=addressable_area_module_reference
|
|
148
144
|
)
|
|
149
145
|
|
|
150
|
-
|
|
151
|
-
|
|
146
|
+
self._state_view.addressable_areas.raise_if_area_not_in_deck_configuration(
|
|
147
|
+
addressable_area_module_reference
|
|
152
148
|
)
|
|
153
|
-
|
|
154
|
-
|
|
149
|
+
|
|
150
|
+
self._state_view.geometry.ensure_location_not_occupied(
|
|
151
|
+
params.location, addressable_area_module_reference
|
|
155
152
|
)
|
|
156
153
|
|
|
157
154
|
if params.model == ModuleModel.MAGNETIC_BLOCK_V1:
|
|
158
155
|
loaded_module = await self._equipment.load_magnetic_block(
|
|
159
156
|
model=params.model,
|
|
160
|
-
location=
|
|
157
|
+
location=AddressableAreaLocation(
|
|
158
|
+
addressableAreaName=addressable_area_module_reference
|
|
159
|
+
),
|
|
161
160
|
module_id=params.moduleId,
|
|
162
161
|
)
|
|
163
162
|
else:
|
|
164
163
|
loaded_module = await self._equipment.load_module(
|
|
165
164
|
model=params.model,
|
|
166
|
-
location=
|
|
165
|
+
location=AddressableAreaLocation(
|
|
166
|
+
addressableAreaName=addressable_area_module_reference
|
|
167
|
+
),
|
|
167
168
|
module_id=params.moduleId,
|
|
168
169
|
)
|
|
169
170
|
|
|
@@ -138,6 +138,9 @@ class LoadPipetteImplementation(
|
|
|
138
138
|
config=loaded_pipette.static_config,
|
|
139
139
|
)
|
|
140
140
|
state_update.set_fluid_unknown(pipette_id=loaded_pipette.pipette_id)
|
|
141
|
+
state_update.set_pipette_ready_to_aspirate(
|
|
142
|
+
pipette_id=loaded_pipette.pipette_id, ready_to_aspirate=False
|
|
143
|
+
),
|
|
141
144
|
|
|
142
145
|
return SuccessData(
|
|
143
146
|
public=LoadPipetteResult(pipetteId=loaded_pipette.pipette_id),
|