opentrons 8.2.0a3__py2.py3-none-any.whl → 8.3.0__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of opentrons might be problematic. Click here for more details.
- opentrons/calibration_storage/deck_configuration.py +3 -3
- opentrons/calibration_storage/file_operators.py +3 -3
- opentrons/calibration_storage/helpers.py +3 -1
- opentrons/calibration_storage/ot2/models/v1.py +16 -29
- opentrons/calibration_storage/ot2/tip_length.py +7 -4
- opentrons/calibration_storage/ot3/models/v1.py +14 -23
- opentrons/cli/analyze.py +18 -6
- opentrons/config/defaults_ot3.py +1 -0
- opentrons/drivers/asyncio/communication/__init__.py +2 -0
- opentrons/drivers/asyncio/communication/errors.py +16 -3
- opentrons/drivers/asyncio/communication/serial_connection.py +24 -9
- opentrons/drivers/command_builder.py +2 -2
- opentrons/drivers/flex_stacker/__init__.py +9 -0
- opentrons/drivers/flex_stacker/abstract.py +89 -0
- opentrons/drivers/flex_stacker/driver.py +260 -0
- opentrons/drivers/flex_stacker/simulator.py +109 -0
- opentrons/drivers/flex_stacker/types.py +138 -0
- opentrons/drivers/heater_shaker/driver.py +18 -3
- opentrons/drivers/temp_deck/driver.py +13 -3
- opentrons/drivers/thermocycler/driver.py +17 -3
- opentrons/execute.py +3 -1
- opentrons/hardware_control/__init__.py +1 -2
- opentrons/hardware_control/api.py +33 -21
- opentrons/hardware_control/backends/flex_protocol.py +17 -7
- opentrons/hardware_control/backends/ot3controller.py +213 -63
- opentrons/hardware_control/backends/ot3simulator.py +18 -9
- opentrons/hardware_control/backends/ot3utils.py +43 -15
- opentrons/hardware_control/dev_types.py +4 -0
- opentrons/hardware_control/emulation/heater_shaker.py +4 -0
- opentrons/hardware_control/emulation/module_server/client.py +1 -1
- opentrons/hardware_control/emulation/module_server/server.py +5 -3
- opentrons/hardware_control/emulation/settings.py +3 -4
- opentrons/hardware_control/instruments/ot2/instrument_calibration.py +2 -1
- opentrons/hardware_control/instruments/ot2/pipette.py +15 -22
- opentrons/hardware_control/instruments/ot2/pipette_handler.py +8 -1
- opentrons/hardware_control/instruments/ot3/gripper.py +2 -2
- opentrons/hardware_control/instruments/ot3/pipette.py +23 -22
- opentrons/hardware_control/instruments/ot3/pipette_handler.py +10 -1
- opentrons/hardware_control/modules/mod_abc.py +2 -2
- opentrons/hardware_control/motion_utilities.py +68 -0
- opentrons/hardware_control/nozzle_manager.py +39 -41
- opentrons/hardware_control/ot3_calibration.py +1 -1
- opentrons/hardware_control/ot3api.py +78 -31
- opentrons/hardware_control/protocols/gripper_controller.py +3 -0
- opentrons/hardware_control/protocols/hardware_manager.py +5 -1
- opentrons/hardware_control/protocols/liquid_handler.py +22 -1
- opentrons/hardware_control/protocols/motion_controller.py +7 -0
- opentrons/hardware_control/robot_calibration.py +1 -1
- opentrons/hardware_control/types.py +61 -0
- opentrons/legacy_commands/commands.py +37 -0
- opentrons/legacy_commands/types.py +39 -0
- opentrons/protocol_api/__init__.py +20 -1
- opentrons/protocol_api/_liquid.py +24 -49
- opentrons/protocol_api/_liquid_properties.py +754 -0
- opentrons/protocol_api/_types.py +24 -0
- opentrons/protocol_api/core/common.py +2 -0
- opentrons/protocol_api/core/engine/instrument.py +191 -10
- opentrons/protocol_api/core/engine/labware.py +29 -7
- opentrons/protocol_api/core/engine/protocol.py +130 -5
- opentrons/protocol_api/core/engine/robot.py +139 -0
- opentrons/protocol_api/core/engine/well.py +4 -1
- opentrons/protocol_api/core/instrument.py +73 -4
- opentrons/protocol_api/core/labware.py +13 -4
- opentrons/protocol_api/core/legacy/legacy_instrument_core.py +87 -3
- opentrons/protocol_api/core/legacy/legacy_labware_core.py +13 -4
- opentrons/protocol_api/core/legacy/legacy_protocol_core.py +32 -1
- opentrons/protocol_api/core/legacy/legacy_robot_core.py +0 -0
- opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py +61 -3
- opentrons/protocol_api/core/protocol.py +34 -1
- opentrons/protocol_api/core/robot.py +51 -0
- opentrons/protocol_api/instrument_context.py +299 -44
- opentrons/protocol_api/labware.py +248 -9
- opentrons/protocol_api/module_contexts.py +21 -17
- opentrons/protocol_api/protocol_context.py +125 -4
- opentrons/protocol_api/robot_context.py +204 -32
- opentrons/protocol_api/validation.py +262 -3
- opentrons/protocol_engine/__init__.py +4 -0
- opentrons/protocol_engine/actions/actions.py +2 -3
- opentrons/protocol_engine/clients/sync_client.py +18 -0
- opentrons/protocol_engine/commands/__init__.py +121 -0
- opentrons/protocol_engine/commands/absorbance_reader/close_lid.py +1 -3
- opentrons/protocol_engine/commands/absorbance_reader/initialize.py +20 -6
- opentrons/protocol_engine/commands/absorbance_reader/open_lid.py +1 -2
- opentrons/protocol_engine/commands/absorbance_reader/read.py +40 -10
- opentrons/protocol_engine/commands/air_gap_in_place.py +160 -0
- opentrons/protocol_engine/commands/aspirate.py +103 -53
- opentrons/protocol_engine/commands/aspirate_in_place.py +55 -51
- opentrons/protocol_engine/commands/blow_out.py +44 -39
- opentrons/protocol_engine/commands/blow_out_in_place.py +21 -32
- opentrons/protocol_engine/commands/calibration/calibrate_gripper.py +13 -6
- opentrons/protocol_engine/commands/calibration/calibrate_module.py +1 -1
- opentrons/protocol_engine/commands/calibration/calibrate_pipette.py +3 -3
- opentrons/protocol_engine/commands/calibration/move_to_maintenance_position.py +1 -1
- opentrons/protocol_engine/commands/command.py +73 -66
- opentrons/protocol_engine/commands/command_unions.py +140 -1
- opentrons/protocol_engine/commands/comment.py +1 -1
- opentrons/protocol_engine/commands/configure_for_volume.py +10 -3
- opentrons/protocol_engine/commands/configure_nozzle_layout.py +6 -4
- opentrons/protocol_engine/commands/custom.py +6 -12
- opentrons/protocol_engine/commands/dispense.py +82 -48
- opentrons/protocol_engine/commands/dispense_in_place.py +71 -51
- opentrons/protocol_engine/commands/drop_tip.py +52 -31
- opentrons/protocol_engine/commands/drop_tip_in_place.py +79 -8
- 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/generate_command_schema.py +4 -11
- opentrons/protocol_engine/commands/get_next_tip.py +134 -0
- opentrons/protocol_engine/commands/get_tip_presence.py +1 -1
- opentrons/protocol_engine/commands/heater_shaker/close_labware_latch.py +1 -1
- opentrons/protocol_engine/commands/heater_shaker/deactivate_heater.py +1 -1
- opentrons/protocol_engine/commands/heater_shaker/deactivate_shaker.py +1 -1
- opentrons/protocol_engine/commands/heater_shaker/open_labware_latch.py +1 -1
- opentrons/protocol_engine/commands/heater_shaker/set_and_wait_for_shake_speed.py +1 -1
- opentrons/protocol_engine/commands/heater_shaker/set_target_temperature.py +1 -1
- opentrons/protocol_engine/commands/heater_shaker/wait_for_temperature.py +10 -4
- opentrons/protocol_engine/commands/home.py +13 -4
- opentrons/protocol_engine/commands/liquid_probe.py +125 -31
- opentrons/protocol_engine/commands/load_labware.py +33 -6
- opentrons/protocol_engine/commands/load_lid.py +146 -0
- opentrons/protocol_engine/commands/load_lid_stack.py +189 -0
- opentrons/protocol_engine/commands/load_liquid.py +12 -4
- opentrons/protocol_engine/commands/load_liquid_class.py +144 -0
- opentrons/protocol_engine/commands/load_module.py +31 -10
- opentrons/protocol_engine/commands/load_pipette.py +19 -8
- opentrons/protocol_engine/commands/magnetic_module/disengage.py +1 -1
- opentrons/protocol_engine/commands/magnetic_module/engage.py +1 -1
- opentrons/protocol_engine/commands/move_labware.py +28 -6
- opentrons/protocol_engine/commands/move_relative.py +35 -25
- opentrons/protocol_engine/commands/move_to_addressable_area.py +40 -27
- opentrons/protocol_engine/commands/move_to_addressable_area_for_drop_tip.py +53 -32
- opentrons/protocol_engine/commands/move_to_coordinates.py +36 -22
- opentrons/protocol_engine/commands/move_to_well.py +40 -24
- opentrons/protocol_engine/commands/movement_common.py +338 -0
- opentrons/protocol_engine/commands/pick_up_tip.py +49 -27
- opentrons/protocol_engine/commands/pipetting_common.py +169 -87
- opentrons/protocol_engine/commands/prepare_to_aspirate.py +24 -33
- opentrons/protocol_engine/commands/reload_labware.py +1 -1
- opentrons/protocol_engine/commands/retract_axis.py +1 -1
- opentrons/protocol_engine/commands/robot/__init__.py +69 -0
- opentrons/protocol_engine/commands/robot/close_gripper_jaw.py +86 -0
- opentrons/protocol_engine/commands/robot/common.py +18 -0
- opentrons/protocol_engine/commands/robot/move_axes_relative.py +101 -0
- opentrons/protocol_engine/commands/robot/move_axes_to.py +100 -0
- opentrons/protocol_engine/commands/robot/move_to.py +94 -0
- opentrons/protocol_engine/commands/robot/open_gripper_jaw.py +77 -0
- opentrons/protocol_engine/commands/save_position.py +14 -5
- opentrons/protocol_engine/commands/set_rail_lights.py +1 -1
- opentrons/protocol_engine/commands/set_status_bar.py +1 -1
- opentrons/protocol_engine/commands/temperature_module/deactivate.py +1 -1
- opentrons/protocol_engine/commands/temperature_module/set_target_temperature.py +1 -1
- opentrons/protocol_engine/commands/temperature_module/wait_for_temperature.py +10 -4
- opentrons/protocol_engine/commands/thermocycler/close_lid.py +1 -1
- opentrons/protocol_engine/commands/thermocycler/deactivate_block.py +1 -1
- opentrons/protocol_engine/commands/thermocycler/deactivate_lid.py +1 -1
- opentrons/protocol_engine/commands/thermocycler/open_lid.py +1 -1
- opentrons/protocol_engine/commands/thermocycler/run_extended_profile.py +9 -3
- opentrons/protocol_engine/commands/thermocycler/run_profile.py +9 -3
- opentrons/protocol_engine/commands/thermocycler/set_target_block_temperature.py +11 -4
- opentrons/protocol_engine/commands/thermocycler/set_target_lid_temperature.py +1 -1
- opentrons/protocol_engine/commands/thermocycler/wait_for_block_temperature.py +1 -1
- opentrons/protocol_engine/commands/thermocycler/wait_for_lid_temperature.py +1 -1
- opentrons/protocol_engine/commands/touch_tip.py +65 -16
- opentrons/protocol_engine/commands/unsafe/unsafe_blow_out_in_place.py +5 -2
- opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py +13 -4
- opentrons/protocol_engine/commands/unsafe/unsafe_engage_axes.py +2 -5
- opentrons/protocol_engine/commands/unsafe/unsafe_place_labware.py +1 -1
- opentrons/protocol_engine/commands/unsafe/unsafe_ungrip_labware.py +4 -2
- opentrons/protocol_engine/commands/unsafe/update_position_estimators.py +2 -5
- opentrons/protocol_engine/commands/verify_tip_presence.py +11 -4
- opentrons/protocol_engine/commands/wait_for_duration.py +10 -3
- opentrons/protocol_engine/commands/wait_for_resume.py +10 -3
- opentrons/protocol_engine/errors/__init__.py +12 -0
- opentrons/protocol_engine/errors/error_occurrence.py +19 -20
- opentrons/protocol_engine/errors/exceptions.py +76 -0
- opentrons/protocol_engine/execution/command_executor.py +1 -1
- opentrons/protocol_engine/execution/equipment.py +73 -5
- opentrons/protocol_engine/execution/gantry_mover.py +369 -8
- opentrons/protocol_engine/execution/hardware_stopper.py +7 -7
- opentrons/protocol_engine/execution/movement.py +27 -0
- opentrons/protocol_engine/execution/pipetting.py +5 -1
- opentrons/protocol_engine/execution/tip_handler.py +34 -15
- opentrons/protocol_engine/notes/notes.py +1 -1
- opentrons/protocol_engine/protocol_engine.py +7 -6
- opentrons/protocol_engine/resources/labware_data_provider.py +1 -1
- opentrons/protocol_engine/resources/labware_validation.py +18 -0
- opentrons/protocol_engine/resources/module_data_provider.py +1 -1
- opentrons/protocol_engine/resources/pipette_data_provider.py +26 -0
- opentrons/protocol_engine/slot_standardization.py +9 -9
- opentrons/protocol_engine/state/_move_types.py +9 -5
- opentrons/protocol_engine/state/_well_math.py +193 -0
- opentrons/protocol_engine/state/addressable_areas.py +25 -61
- opentrons/protocol_engine/state/command_history.py +12 -0
- opentrons/protocol_engine/state/commands.py +22 -14
- opentrons/protocol_engine/state/files.py +10 -12
- opentrons/protocol_engine/state/fluid_stack.py +138 -0
- opentrons/protocol_engine/state/frustum_helpers.py +63 -69
- opentrons/protocol_engine/state/geometry.py +47 -1
- opentrons/protocol_engine/state/labware.py +92 -26
- opentrons/protocol_engine/state/liquid_classes.py +82 -0
- opentrons/protocol_engine/state/liquids.py +16 -4
- opentrons/protocol_engine/state/modules.py +56 -71
- opentrons/protocol_engine/state/motion.py +6 -1
- opentrons/protocol_engine/state/pipettes.py +149 -58
- opentrons/protocol_engine/state/state.py +21 -2
- opentrons/protocol_engine/state/state_summary.py +4 -2
- opentrons/protocol_engine/state/tips.py +11 -44
- opentrons/protocol_engine/state/update_types.py +343 -48
- opentrons/protocol_engine/state/wells.py +19 -11
- opentrons/protocol_engine/types.py +176 -28
- opentrons/protocol_reader/extract_labware_definitions.py +5 -2
- opentrons/protocol_reader/file_format_validator.py +5 -5
- opentrons/protocol_runner/json_file_reader.py +9 -3
- opentrons/protocol_runner/json_translator.py +51 -25
- opentrons/protocol_runner/legacy_command_mapper.py +66 -64
- opentrons/protocol_runner/protocol_runner.py +35 -4
- opentrons/protocol_runner/python_protocol_wrappers.py +1 -1
- opentrons/protocol_runner/run_orchestrator.py +13 -3
- opentrons/protocols/advanced_control/common.py +38 -0
- opentrons/protocols/advanced_control/mix.py +1 -1
- opentrons/protocols/advanced_control/transfers/__init__.py +0 -0
- opentrons/protocols/advanced_control/transfers/common.py +56 -0
- opentrons/protocols/advanced_control/{transfers.py → transfers/transfer.py} +10 -85
- opentrons/protocols/api_support/definitions.py +1 -1
- opentrons/protocols/api_support/instrument.py +1 -1
- opentrons/protocols/api_support/util.py +10 -0
- opentrons/protocols/labware.py +70 -8
- opentrons/protocols/models/json_protocol.py +5 -9
- opentrons/simulate.py +3 -1
- opentrons/types.py +162 -2
- opentrons/util/entrypoint_util.py +2 -5
- opentrons/util/logging_config.py +1 -1
- {opentrons-8.2.0a3.dist-info → opentrons-8.3.0.dist-info}/METADATA +16 -15
- {opentrons-8.2.0a3.dist-info → opentrons-8.3.0.dist-info}/RECORD +238 -208
- {opentrons-8.2.0a3.dist-info → opentrons-8.3.0.dist-info}/WHEEL +1 -1
- {opentrons-8.2.0a3.dist-info → opentrons-8.3.0.dist-info}/LICENSE +0 -0
- {opentrons-8.2.0a3.dist-info → opentrons-8.3.0.dist-info}/entry_points.txt +0 -0
- {opentrons-8.2.0a3.dist-info → opentrons-8.3.0.dist-info}/top_level.txt +0 -0
|
@@ -4,7 +4,7 @@ from logging import getLogger
|
|
|
4
4
|
from datetime import datetime
|
|
5
5
|
from textwrap import dedent
|
|
6
6
|
from typing import Any, Dict, Mapping, List, Type, Union, Optional, Sequence
|
|
7
|
-
from pydantic import BaseModel, Field
|
|
7
|
+
from pydantic import BaseModel, Field, ConfigDict
|
|
8
8
|
from opentrons_shared_data.errors.codes import ErrorCodes
|
|
9
9
|
from .exceptions import ProtocolEngineError
|
|
10
10
|
from opentrons_shared_data.errors.exceptions import EnumeratedError
|
|
@@ -29,7 +29,7 @@ class ErrorOccurrence(BaseModel):
|
|
|
29
29
|
wrappedErrors = [
|
|
30
30
|
cls.from_failed(id, createdAt, err) for err in error.wrapping
|
|
31
31
|
]
|
|
32
|
-
return cls.
|
|
32
|
+
return cls.model_construct(
|
|
33
33
|
id=id,
|
|
34
34
|
createdAt=createdAt,
|
|
35
35
|
errorType=type(error).__name__,
|
|
@@ -39,6 +39,21 @@ class ErrorOccurrence(BaseModel):
|
|
|
39
39
|
wrappedErrors=wrappedErrors,
|
|
40
40
|
)
|
|
41
41
|
|
|
42
|
+
@staticmethod
|
|
43
|
+
def schema_extra(schema: Dict[str, Any], model: object) -> None:
|
|
44
|
+
"""Append the schema to make the errorCode appear required.
|
|
45
|
+
|
|
46
|
+
`errorCode`, `wrappedErrors`, and `errorInfo` have defaults because they are not included in earlier
|
|
47
|
+
versions of this model, _and_ this model is loaded directly from
|
|
48
|
+
the on-robot store. That means that, without a default, it will
|
|
49
|
+
fail to parse. Once a default is defined, the automated schema will
|
|
50
|
+
mark this as a non-required field, which is misleading as this is
|
|
51
|
+
a response from the server to the client and it will always have an
|
|
52
|
+
errorCode defined. This hack is required because it informs the client
|
|
53
|
+
that it does not, in fact, have to account for a missing errorCode, wrappedError, or errorInfo.
|
|
54
|
+
"""
|
|
55
|
+
schema["required"].extend(["errorCode", "wrappedErrors", "errorInfo"])
|
|
56
|
+
|
|
42
57
|
id: str = Field(..., description="Unique identifier of this error occurrence.")
|
|
43
58
|
createdAt: datetime = Field(..., description="When the error occurred.")
|
|
44
59
|
|
|
@@ -145,23 +160,7 @@ class ErrorOccurrence(BaseModel):
|
|
|
145
160
|
default=[], description="Errors that may have caused this one."
|
|
146
161
|
)
|
|
147
162
|
|
|
148
|
-
|
|
149
|
-
"""Customize configuration for this model."""
|
|
150
|
-
|
|
151
|
-
@staticmethod
|
|
152
|
-
def schema_extra(schema: Dict[str, Any], model: object) -> None:
|
|
153
|
-
"""Append the schema to make the errorCode appear required.
|
|
154
|
-
|
|
155
|
-
`errorCode`, `wrappedErrors`, and `errorInfo` have defaults because they are not included in earlier
|
|
156
|
-
versions of this model, _and_ this model is loaded directly from
|
|
157
|
-
the on-robot store. That means that, without a default, it will
|
|
158
|
-
fail to parse. Once a default is defined, the automated schema will
|
|
159
|
-
mark this as a non-required field, which is misleading as this is
|
|
160
|
-
a response from the server to the client and it will always have an
|
|
161
|
-
errorCode defined. This hack is required because it informs the client
|
|
162
|
-
that it does not, in fact, have to account for a missing errorCode, wrappedError, or errorInfo.
|
|
163
|
-
"""
|
|
164
|
-
schema["required"].extend(["errorCode", "wrappedErrors", "errorInfo"])
|
|
163
|
+
model_config = ConfigDict(json_schema_extra=schema_extra)
|
|
165
164
|
|
|
166
165
|
|
|
167
166
|
# TODO (tz, 7-12-23): move this to exceptions.py when we stop relaying on ErrorOccurrence.
|
|
@@ -180,4 +179,4 @@ class ProtocolCommandFailedError(ProtocolEngineError):
|
|
|
180
179
|
self.original_error = original_error
|
|
181
180
|
|
|
182
181
|
|
|
183
|
-
ErrorOccurrence.
|
|
182
|
+
ErrorOccurrence.model_rebuild()
|
|
@@ -244,6 +244,19 @@ class LiquidDoesNotExistError(ProtocolEngineError):
|
|
|
244
244
|
super().__init__(ErrorCodes.GENERAL_ERROR, message, details, wrapping)
|
|
245
245
|
|
|
246
246
|
|
|
247
|
+
class InvalidLiquidError(ProtocolEngineError):
|
|
248
|
+
"""Raised when attempting to add a liquid with an invalid property."""
|
|
249
|
+
|
|
250
|
+
def __init__(
|
|
251
|
+
self,
|
|
252
|
+
message: Optional[str] = None,
|
|
253
|
+
details: Optional[Dict[str, Any]] = None,
|
|
254
|
+
wrapping: Optional[Sequence[EnumeratedError]] = None,
|
|
255
|
+
) -> None:
|
|
256
|
+
"""Build an InvalidLiquidError."""
|
|
257
|
+
super().__init__(ErrorCodes.INVALID_PROTOCOL_DATA, message, details, wrapping)
|
|
258
|
+
|
|
259
|
+
|
|
247
260
|
class LabwareDefinitionDoesNotExistError(ProtocolEngineError):
|
|
248
261
|
"""Raised when referencing a labware definition that does not exist."""
|
|
249
262
|
|
|
@@ -270,6 +283,19 @@ class LabwareCannotBeStackedError(ProtocolEngineError):
|
|
|
270
283
|
super().__init__(ErrorCodes.GENERAL_ERROR, message, details, wrapping)
|
|
271
284
|
|
|
272
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
|
+
|
|
273
299
|
class LabwareIsInStackError(ProtocolEngineError):
|
|
274
300
|
"""Raised when trying to move to or physically interact with a labware that has another labware on top."""
|
|
275
301
|
|
|
@@ -348,6 +374,32 @@ class TouchTipDisabledError(ProtocolEngineError):
|
|
|
348
374
|
super().__init__(ErrorCodes.GENERAL_ERROR, message, details, wrapping)
|
|
349
375
|
|
|
350
376
|
|
|
377
|
+
class TouchTipIncompatibleArgumentsError(ProtocolEngineError):
|
|
378
|
+
"""Raised when touch tip is used with both a custom radius and a mmFromEdge argument."""
|
|
379
|
+
|
|
380
|
+
def __init__(
|
|
381
|
+
self,
|
|
382
|
+
message: Optional[str] = None,
|
|
383
|
+
details: Optional[Dict[str, Any]] = None,
|
|
384
|
+
wrapping: Optional[Sequence[EnumeratedError]] = None,
|
|
385
|
+
) -> None:
|
|
386
|
+
"""Build a TouchTipIncompatibleArgumentsError."""
|
|
387
|
+
super().__init__(ErrorCodes.GENERAL_ERROR, message, details, wrapping)
|
|
388
|
+
|
|
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
|
+
|
|
351
403
|
class WellDoesNotExistError(ProtocolEngineError):
|
|
352
404
|
"""Raised when referencing a well that does not exist."""
|
|
353
405
|
|
|
@@ -1155,3 +1207,27 @@ class StorageLimitReachedError(ProtocolEngineError):
|
|
|
1155
1207
|
) -> None:
|
|
1156
1208
|
"""Build an StorageLimitReached."""
|
|
1157
1209
|
super().__init__(ErrorCodes.GENERAL_ERROR, message, detail, wrapping)
|
|
1210
|
+
|
|
1211
|
+
|
|
1212
|
+
class LiquidClassDoesNotExistError(ProtocolEngineError):
|
|
1213
|
+
"""Raised when referencing a liquid class that has not been loaded."""
|
|
1214
|
+
|
|
1215
|
+
def __init__(
|
|
1216
|
+
self,
|
|
1217
|
+
message: Optional[str] = None,
|
|
1218
|
+
details: Optional[Dict[str, Any]] = None,
|
|
1219
|
+
wrapping: Optional[Sequence[EnumeratedError]] = None,
|
|
1220
|
+
) -> None:
|
|
1221
|
+
super().__init__(ErrorCodes.GENERAL_ERROR, message, details, wrapping)
|
|
1222
|
+
|
|
1223
|
+
|
|
1224
|
+
class LiquidClassRedefinitionError(ProtocolEngineError):
|
|
1225
|
+
"""Raised when attempting to load a liquid class that conflicts with a liquid class already loaded."""
|
|
1226
|
+
|
|
1227
|
+
def __init__(
|
|
1228
|
+
self,
|
|
1229
|
+
message: Optional[str] = None,
|
|
1230
|
+
details: Optional[Dict[str, Any]] = None,
|
|
1231
|
+
wrapping: Optional[Sequence[EnumeratedError]] = None,
|
|
1232
|
+
) -> None:
|
|
1233
|
+
super().__init__(ErrorCodes.GENERAL_ERROR, message, details, wrapping)
|
|
@@ -188,7 +188,7 @@ class CommandExecutor:
|
|
|
188
188
|
"completedAt": self._model_utils.get_timestamp(),
|
|
189
189
|
"notes": note_tracker.get_notes(),
|
|
190
190
|
}
|
|
191
|
-
succeeded_command = running_command.
|
|
191
|
+
succeeded_command = running_command.model_copy(update=update)
|
|
192
192
|
self._action_dispatcher.dispatch(
|
|
193
193
|
SucceedCommandAction(
|
|
194
194
|
command=succeeded_command,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Equipment command side-effect logic."""
|
|
2
2
|
from dataclasses import dataclass
|
|
3
|
-
from typing import Optional, overload, Union
|
|
3
|
+
from typing import Optional, overload, Union, List
|
|
4
4
|
|
|
5
5
|
from opentrons_shared_data.pipette.types import PipetteNameType
|
|
6
6
|
|
|
@@ -152,10 +152,6 @@ class EquipmentHandler:
|
|
|
152
152
|
Returns:
|
|
153
153
|
A LoadedLabwareData object.
|
|
154
154
|
"""
|
|
155
|
-
labware_id = (
|
|
156
|
-
labware_id if labware_id is not None else self._model_utils.generate_id()
|
|
157
|
-
)
|
|
158
|
-
|
|
159
155
|
definition_uri = uri_from_details(
|
|
160
156
|
load_name=load_name,
|
|
161
157
|
namespace=namespace,
|
|
@@ -172,6 +168,10 @@ class EquipmentHandler:
|
|
|
172
168
|
version=version,
|
|
173
169
|
)
|
|
174
170
|
|
|
171
|
+
labware_id = (
|
|
172
|
+
labware_id if labware_id is not None else self._model_utils.generate_id()
|
|
173
|
+
)
|
|
174
|
+
|
|
175
175
|
# Allow propagation of ModuleNotLoadedError.
|
|
176
176
|
offset_id = self.find_applicable_labware_offset_id(
|
|
177
177
|
labware_definition_uri=definition_uri,
|
|
@@ -379,6 +379,74 @@ class EquipmentHandler:
|
|
|
379
379
|
definition=attached_module.definition,
|
|
380
380
|
)
|
|
381
381
|
|
|
382
|
+
async def load_lids(
|
|
383
|
+
self,
|
|
384
|
+
load_name: str,
|
|
385
|
+
namespace: str,
|
|
386
|
+
version: int,
|
|
387
|
+
location: LabwareLocation,
|
|
388
|
+
quantity: int,
|
|
389
|
+
) -> List[LoadedLabwareData]:
|
|
390
|
+
"""Load one or many lid labware by assigning an identifier and pulling required data.
|
|
391
|
+
|
|
392
|
+
Args:
|
|
393
|
+
load_name: The lid labware's load name.
|
|
394
|
+
namespace: The lid labware's namespace.
|
|
395
|
+
version: The lid labware's version.
|
|
396
|
+
location: The deck location at which lid(s) will be placed.
|
|
397
|
+
labware_ids: An optional list of identifiers to assign the labware. If None,
|
|
398
|
+
an identifier will be generated.
|
|
399
|
+
|
|
400
|
+
Raises:
|
|
401
|
+
ModuleNotLoadedError: If `location` references a module ID
|
|
402
|
+
that doesn't point to a valid loaded module.
|
|
403
|
+
|
|
404
|
+
Returns:
|
|
405
|
+
A list of LoadedLabwareData objects.
|
|
406
|
+
"""
|
|
407
|
+
definition_uri = uri_from_details(
|
|
408
|
+
load_name=load_name,
|
|
409
|
+
namespace=namespace,
|
|
410
|
+
version=version,
|
|
411
|
+
)
|
|
412
|
+
try:
|
|
413
|
+
# Try to use existing definition in state.
|
|
414
|
+
definition = self._state_store.labware.get_definition_by_uri(definition_uri)
|
|
415
|
+
except LabwareDefinitionDoesNotExistError:
|
|
416
|
+
definition = await self._labware_data_provider.get_labware_definition(
|
|
417
|
+
load_name=load_name,
|
|
418
|
+
namespace=namespace,
|
|
419
|
+
version=version,
|
|
420
|
+
)
|
|
421
|
+
|
|
422
|
+
stack_limit = definition.stackLimit if definition.stackLimit is not None else 1
|
|
423
|
+
if quantity > stack_limit:
|
|
424
|
+
raise ValueError(
|
|
425
|
+
f"Requested quantity {quantity} is greater than the stack limit of {stack_limit} provided by definition for {load_name}."
|
|
426
|
+
)
|
|
427
|
+
|
|
428
|
+
# Allow propagation of ModuleNotLoadedError.
|
|
429
|
+
if (
|
|
430
|
+
isinstance(location, DeckSlotLocation)
|
|
431
|
+
and definition.parameters.isDeckSlotCompatible is not None
|
|
432
|
+
and not definition.parameters.isDeckSlotCompatible
|
|
433
|
+
):
|
|
434
|
+
raise ValueError(
|
|
435
|
+
f"Lid Labware {load_name} cannot be loaded onto a Deck Slot."
|
|
436
|
+
)
|
|
437
|
+
|
|
438
|
+
load_labware_data_list = []
|
|
439
|
+
for i in range(quantity):
|
|
440
|
+
load_labware_data_list.append(
|
|
441
|
+
LoadedLabwareData(
|
|
442
|
+
labware_id=self._model_utils.generate_id(),
|
|
443
|
+
definition=definition,
|
|
444
|
+
offsetId=None,
|
|
445
|
+
)
|
|
446
|
+
)
|
|
447
|
+
|
|
448
|
+
return load_labware_data_list
|
|
449
|
+
|
|
382
450
|
async def configure_for_volume(
|
|
383
451
|
self, pipette_id: str, volume: float, tip_overlap_version: Optional[str]
|
|
384
452
|
) -> LoadedConfigureForVolumeData:
|