opentrons 8.2.0a4__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 +36 -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 +1 -1
- 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 +52 -70
- 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.0a4.dist-info → opentrons-8.3.0.dist-info}/METADATA +16 -15
- {opentrons-8.2.0a4.dist-info → opentrons-8.3.0.dist-info}/RECORD +238 -208
- {opentrons-8.2.0a4.dist-info → opentrons-8.3.0.dist-info}/WHEEL +1 -1
- {opentrons-8.2.0a4.dist-info → opentrons-8.3.0.dist-info}/LICENSE +0 -0
- {opentrons-8.2.0a4.dist-info → opentrons-8.3.0.dist-info}/entry_points.txt +0 -0
- {opentrons-8.2.0a4.dist-info → opentrons-8.3.0.dist-info}/top_level.txt +0 -0
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"""Command models to start heating a Thermocycler's block."""
|
|
2
2
|
from __future__ import annotations
|
|
3
|
-
from typing import Optional, TYPE_CHECKING
|
|
3
|
+
from typing import Optional, TYPE_CHECKING, Any
|
|
4
4
|
from typing_extensions import Literal, Type
|
|
5
5
|
|
|
6
6
|
from pydantic import BaseModel, Field
|
|
7
|
+
from pydantic.json_schema import SkipJsonSchema
|
|
7
8
|
|
|
8
9
|
from ..command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, SuccessData
|
|
9
10
|
from ...errors.error_occurrence import ErrorOccurrence
|
|
@@ -16,21 +17,27 @@ if TYPE_CHECKING:
|
|
|
16
17
|
SetTargetBlockTemperatureCommandType = Literal["thermocycler/setTargetBlockTemperature"]
|
|
17
18
|
|
|
18
19
|
|
|
20
|
+
def _remove_default(s: dict[str, Any]) -> None:
|
|
21
|
+
s.pop("default", None)
|
|
22
|
+
|
|
23
|
+
|
|
19
24
|
class SetTargetBlockTemperatureParams(BaseModel):
|
|
20
25
|
"""Input parameters to set a Thermocycler's target block temperature."""
|
|
21
26
|
|
|
22
27
|
moduleId: str = Field(..., description="Unique ID of the Thermocycler Module.")
|
|
23
28
|
celsius: float = Field(..., description="Target temperature in °C.")
|
|
24
|
-
blockMaxVolumeUl:
|
|
29
|
+
blockMaxVolumeUl: float | SkipJsonSchema[None] = Field(
|
|
25
30
|
None,
|
|
26
31
|
description="Amount of liquid in uL of the most-full well"
|
|
27
32
|
" in labware loaded onto the thermocycler.",
|
|
33
|
+
json_schema_extra=_remove_default,
|
|
28
34
|
)
|
|
29
|
-
holdTimeSeconds:
|
|
35
|
+
holdTimeSeconds: float | SkipJsonSchema[None] = Field(
|
|
30
36
|
None,
|
|
31
37
|
description="Amount of time, in seconds, to hold the temperature for."
|
|
32
38
|
" If specified, a waitForBlockTemperature command will block until"
|
|
33
39
|
" the given hold time has elapsed.",
|
|
40
|
+
json_schema_extra=_remove_default,
|
|
34
41
|
)
|
|
35
42
|
|
|
36
43
|
|
|
@@ -113,7 +120,7 @@ class SetTargetBlockTemperature(
|
|
|
113
120
|
"thermocycler/setTargetBlockTemperature"
|
|
114
121
|
)
|
|
115
122
|
params: SetTargetBlockTemperatureParams
|
|
116
|
-
result: Optional[SetTargetBlockTemperatureResult]
|
|
123
|
+
result: Optional[SetTargetBlockTemperatureResult] = None
|
|
117
124
|
|
|
118
125
|
_ImplementationCls: Type[
|
|
119
126
|
SetTargetBlockTemperatureImpl
|
|
@@ -84,7 +84,7 @@ class SetTargetLidTemperature(
|
|
|
84
84
|
"thermocycler/setTargetLidTemperature"
|
|
85
85
|
)
|
|
86
86
|
params: SetTargetLidTemperatureParams
|
|
87
|
-
result: Optional[SetTargetLidTemperatureResult]
|
|
87
|
+
result: Optional[SetTargetLidTemperatureResult] = None
|
|
88
88
|
|
|
89
89
|
_ImplementationCls: Type[SetTargetLidTemperatureImpl] = SetTargetLidTemperatureImpl
|
|
90
90
|
|
|
@@ -77,7 +77,7 @@ class WaitForBlockTemperature(
|
|
|
77
77
|
"thermocycler/waitForBlockTemperature"
|
|
78
78
|
)
|
|
79
79
|
params: WaitForBlockTemperatureParams
|
|
80
|
-
result: Optional[WaitForBlockTemperatureResult]
|
|
80
|
+
result: Optional[WaitForBlockTemperatureResult] = None
|
|
81
81
|
|
|
82
82
|
_ImplementationCls: Type[WaitForBlockTemperatureImpl] = WaitForBlockTemperatureImpl
|
|
83
83
|
|
|
@@ -75,7 +75,7 @@ class WaitForLidTemperature(
|
|
|
75
75
|
|
|
76
76
|
commandType: WaitForLidTemperatureCommandType = "thermocycler/waitForLidTemperature"
|
|
77
77
|
params: WaitForLidTemperatureParams
|
|
78
|
-
result: Optional[WaitForLidTemperatureResult]
|
|
78
|
+
result: Optional[WaitForLidTemperatureResult] = None
|
|
79
79
|
|
|
80
80
|
_ImplementationCls: Type[WaitForLidTemperatureImpl] = WaitForLidTemperatureImpl
|
|
81
81
|
|
|
@@ -1,29 +1,50 @@
|
|
|
1
1
|
"""Touch tip command request, result, and implementation models."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
|
-
from
|
|
4
|
-
|
|
4
|
+
from typing import TYPE_CHECKING, Optional, Type, Any
|
|
5
|
+
|
|
5
6
|
from typing_extensions import Literal
|
|
7
|
+
from pydantic import Field
|
|
8
|
+
from pydantic.json_schema import SkipJsonSchema
|
|
6
9
|
|
|
7
|
-
from opentrons.
|
|
10
|
+
from opentrons.types import Point
|
|
8
11
|
|
|
9
|
-
from ..errors import
|
|
12
|
+
from ..errors import (
|
|
13
|
+
TouchTipDisabledError,
|
|
14
|
+
TouchTipIncompatibleArgumentsError,
|
|
15
|
+
LabwareIsTipRackError,
|
|
16
|
+
)
|
|
10
17
|
from ..types import DeckPoint
|
|
11
|
-
from .command import
|
|
12
|
-
|
|
18
|
+
from .command import (
|
|
19
|
+
AbstractCommandImpl,
|
|
20
|
+
BaseCommand,
|
|
21
|
+
BaseCommandCreate,
|
|
22
|
+
SuccessData,
|
|
23
|
+
DefinedErrorData,
|
|
24
|
+
)
|
|
13
25
|
from .pipetting_common import (
|
|
14
26
|
PipetteIdMixin,
|
|
27
|
+
)
|
|
28
|
+
from .movement_common import (
|
|
15
29
|
WellLocationMixin,
|
|
16
30
|
DestinationPositionResult,
|
|
31
|
+
StallOrCollisionError,
|
|
32
|
+
move_to_well,
|
|
17
33
|
)
|
|
18
34
|
|
|
19
35
|
if TYPE_CHECKING:
|
|
20
36
|
from ..execution import MovementHandler, GantryMover
|
|
21
37
|
from ..state.state import StateView
|
|
38
|
+
from ..resources.model_utils import ModelUtils
|
|
22
39
|
|
|
23
40
|
|
|
24
41
|
TouchTipCommandType = Literal["touchTip"]
|
|
25
42
|
|
|
26
43
|
|
|
44
|
+
def _remove_default(s: dict[str, Any]) -> None:
|
|
45
|
+
s.pop("default", None)
|
|
46
|
+
|
|
47
|
+
|
|
27
48
|
class TouchTipParams(PipetteIdMixin, WellLocationMixin):
|
|
28
49
|
"""Payload needed to touch a pipette tip the sides of a specific well."""
|
|
29
50
|
|
|
@@ -34,12 +55,20 @@ class TouchTipParams(PipetteIdMixin, WellLocationMixin):
|
|
|
34
55
|
),
|
|
35
56
|
)
|
|
36
57
|
|
|
37
|
-
|
|
58
|
+
mmFromEdge: float | SkipJsonSchema[None] = Field(
|
|
59
|
+
None,
|
|
60
|
+
description="Offset away from the the well edge, in millimeters."
|
|
61
|
+
"Incompatible when a radius is included as a non 1.0 value.",
|
|
62
|
+
json_schema_extra=_remove_default,
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
speed: float | SkipJsonSchema[None] = Field(
|
|
38
66
|
None,
|
|
39
67
|
description=(
|
|
40
68
|
"Override the travel speed in mm/s."
|
|
41
69
|
" This controls the straight linear speed of motion."
|
|
42
70
|
),
|
|
71
|
+
json_schema_extra=_remove_default,
|
|
43
72
|
)
|
|
44
73
|
|
|
45
74
|
|
|
@@ -50,7 +79,10 @@ class TouchTipResult(DestinationPositionResult):
|
|
|
50
79
|
|
|
51
80
|
|
|
52
81
|
class TouchTipImplementation(
|
|
53
|
-
AbstractCommandImpl[
|
|
82
|
+
AbstractCommandImpl[
|
|
83
|
+
TouchTipParams,
|
|
84
|
+
SuccessData[TouchTipResult] | DefinedErrorData[StallOrCollisionError],
|
|
85
|
+
]
|
|
54
86
|
):
|
|
55
87
|
"""Touch tip command implementation."""
|
|
56
88
|
|
|
@@ -59,19 +91,26 @@ class TouchTipImplementation(
|
|
|
59
91
|
state_view: StateView,
|
|
60
92
|
movement: MovementHandler,
|
|
61
93
|
gantry_mover: GantryMover,
|
|
94
|
+
model_utils: ModelUtils,
|
|
62
95
|
**kwargs: object,
|
|
63
96
|
) -> None:
|
|
64
97
|
self._state_view = state_view
|
|
65
98
|
self._movement = movement
|
|
66
99
|
self._gantry_mover = gantry_mover
|
|
100
|
+
self._model_utils = model_utils
|
|
67
101
|
|
|
68
|
-
async def execute(
|
|
102
|
+
async def execute(
|
|
103
|
+
self, params: TouchTipParams
|
|
104
|
+
) -> SuccessData[TouchTipResult] | DefinedErrorData[StallOrCollisionError]:
|
|
69
105
|
"""Touch tip to sides of a well using the requested pipette."""
|
|
70
106
|
pipette_id = params.pipetteId
|
|
71
107
|
labware_id = params.labwareId
|
|
72
108
|
well_name = params.wellName
|
|
73
109
|
|
|
74
|
-
|
|
110
|
+
if params.radius != 1.0 and params.mmFromEdge is not None:
|
|
111
|
+
raise TouchTipIncompatibleArgumentsError(
|
|
112
|
+
"Cannot use mmFromEdge with a radius that is not 1.0"
|
|
113
|
+
)
|
|
75
114
|
|
|
76
115
|
if self._state_view.labware.get_has_quirk(labware_id, "touchTipDisabled"):
|
|
77
116
|
raise TouchTipDisabledError(
|
|
@@ -81,23 +120,33 @@ class TouchTipImplementation(
|
|
|
81
120
|
if self._state_view.labware.is_tiprack(labware_id):
|
|
82
121
|
raise LabwareIsTipRackError("Cannot touch tip on tip rack")
|
|
83
122
|
|
|
84
|
-
|
|
123
|
+
center_result = await move_to_well(
|
|
124
|
+
movement=self._movement,
|
|
125
|
+
model_utils=self._model_utils,
|
|
85
126
|
pipette_id=pipette_id,
|
|
86
127
|
labware_id=labware_id,
|
|
87
128
|
well_name=well_name,
|
|
88
129
|
well_location=params.wellLocation,
|
|
89
130
|
)
|
|
131
|
+
if isinstance(center_result, DefinedErrorData):
|
|
132
|
+
return center_result
|
|
90
133
|
|
|
91
134
|
touch_speed = self._state_view.pipettes.get_movement_speed(
|
|
92
135
|
pipette_id, params.speed
|
|
93
136
|
)
|
|
94
137
|
|
|
138
|
+
mm_from_edge = params.mmFromEdge if params.mmFromEdge is not None else 0
|
|
95
139
|
touch_waypoints = self._state_view.motion.get_touch_tip_waypoints(
|
|
96
140
|
pipette_id=pipette_id,
|
|
97
141
|
labware_id=labware_id,
|
|
98
142
|
well_name=well_name,
|
|
99
143
|
radius=params.radius,
|
|
100
|
-
|
|
144
|
+
mm_from_edge=mm_from_edge,
|
|
145
|
+
center_point=Point(
|
|
146
|
+
center_result.public.position.x,
|
|
147
|
+
center_result.public.position.y,
|
|
148
|
+
center_result.public.position.z,
|
|
149
|
+
),
|
|
101
150
|
)
|
|
102
151
|
|
|
103
152
|
final_point = await self._gantry_mover.move_to(
|
|
@@ -105,10 +154,10 @@ class TouchTipImplementation(
|
|
|
105
154
|
waypoints=touch_waypoints,
|
|
106
155
|
speed=touch_speed,
|
|
107
156
|
)
|
|
108
|
-
final_deck_point = DeckPoint.
|
|
157
|
+
final_deck_point = DeckPoint.model_construct(
|
|
109
158
|
x=final_point.x, y=final_point.y, z=final_point.z
|
|
110
159
|
)
|
|
111
|
-
state_update.set_pipette_location(
|
|
160
|
+
state_update = center_result.state_update.set_pipette_location(
|
|
112
161
|
pipette_id=pipette_id,
|
|
113
162
|
new_labware_id=labware_id,
|
|
114
163
|
new_well_name=well_name,
|
|
@@ -121,12 +170,12 @@ class TouchTipImplementation(
|
|
|
121
170
|
)
|
|
122
171
|
|
|
123
172
|
|
|
124
|
-
class TouchTip(BaseCommand[TouchTipParams, TouchTipResult,
|
|
173
|
+
class TouchTip(BaseCommand[TouchTipParams, TouchTipResult, StallOrCollisionError]):
|
|
125
174
|
"""Touch up tip command model."""
|
|
126
175
|
|
|
127
176
|
commandType: TouchTipCommandType = "touchTip"
|
|
128
177
|
params: TouchTipParams
|
|
129
|
-
result: Optional[TouchTipResult]
|
|
178
|
+
result: Optional[TouchTipResult] = None
|
|
130
179
|
|
|
131
180
|
_ImplementationCls: Type[TouchTipImplementation] = TouchTipImplementation
|
|
132
181
|
|
|
@@ -10,6 +10,7 @@ from ..command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, Succe
|
|
|
10
10
|
from ..pipetting_common import PipetteIdMixin, FlowRateMixin
|
|
11
11
|
from ...resources import ensure_ot3_hardware
|
|
12
12
|
from ...errors.error_occurrence import ErrorOccurrence
|
|
13
|
+
from ...state import update_types
|
|
13
14
|
|
|
14
15
|
from opentrons.hardware_control import HardwareControlAPI
|
|
15
16
|
from opentrons.hardware_control.types import Axis
|
|
@@ -66,9 +67,11 @@ class UnsafeBlowOutInPlaceImplementation(
|
|
|
66
67
|
await self._pipetting.blow_out_in_place(
|
|
67
68
|
pipette_id=params.pipetteId, flow_rate=params.flowRate
|
|
68
69
|
)
|
|
70
|
+
state_update = update_types.StateUpdate()
|
|
71
|
+
state_update.set_fluid_empty(pipette_id=params.pipetteId)
|
|
69
72
|
|
|
70
73
|
return SuccessData(
|
|
71
|
-
public=UnsafeBlowOutInPlaceResult(),
|
|
74
|
+
public=UnsafeBlowOutInPlaceResult(), state_update=state_update
|
|
72
75
|
)
|
|
73
76
|
|
|
74
77
|
|
|
@@ -79,7 +82,7 @@ class UnsafeBlowOutInPlace(
|
|
|
79
82
|
|
|
80
83
|
commandType: UnsafeBlowOutInPlaceCommandType = "unsafe/blowOutInPlace"
|
|
81
84
|
params: UnsafeBlowOutInPlaceParams
|
|
82
|
-
result: Optional[UnsafeBlowOutInPlaceResult]
|
|
85
|
+
result: Optional[UnsafeBlowOutInPlaceResult] = None
|
|
83
86
|
|
|
84
87
|
_ImplementationCls: Type[
|
|
85
88
|
UnsafeBlowOutInPlaceImplementation
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
"""Command models to drop tip in place while plunger positions are unknown."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
|
-
from
|
|
4
|
+
from typing import TYPE_CHECKING, Optional, Type, Any
|
|
5
|
+
|
|
4
6
|
from pydantic import Field, BaseModel
|
|
5
|
-
from
|
|
7
|
+
from pydantic.json_schema import SkipJsonSchema
|
|
6
8
|
from typing_extensions import Literal
|
|
7
9
|
|
|
8
10
|
from opentrons.hardware_control import HardwareControlAPI
|
|
9
11
|
from opentrons.hardware_control.types import Axis
|
|
10
12
|
|
|
13
|
+
from opentrons.protocol_engine.state.update_types import StateUpdate
|
|
11
14
|
from ..pipetting_common import PipetteIdMixin
|
|
12
15
|
from ..command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, SuccessData
|
|
13
16
|
from ...errors.error_occurrence import ErrorOccurrence
|
|
@@ -21,16 +24,21 @@ if TYPE_CHECKING:
|
|
|
21
24
|
UnsafeDropTipInPlaceCommandType = Literal["unsafe/dropTipInPlace"]
|
|
22
25
|
|
|
23
26
|
|
|
27
|
+
def _remove_default(s: dict[str, Any]) -> None:
|
|
28
|
+
s.pop("default", None)
|
|
29
|
+
|
|
30
|
+
|
|
24
31
|
class UnsafeDropTipInPlaceParams(PipetteIdMixin):
|
|
25
32
|
"""Payload required to drop a tip in place even if the plunger position is not known."""
|
|
26
33
|
|
|
27
|
-
homeAfter:
|
|
34
|
+
homeAfter: bool | SkipJsonSchema[None] = Field(
|
|
28
35
|
None,
|
|
29
36
|
description=(
|
|
30
37
|
"Whether to home this pipette's plunger after dropping the tip."
|
|
31
38
|
" You should normally leave this unspecified to let the robot choose"
|
|
32
39
|
" a safe default depending on its hardware."
|
|
33
40
|
),
|
|
41
|
+
json_schema_extra=_remove_default,
|
|
34
42
|
)
|
|
35
43
|
|
|
36
44
|
|
|
@@ -77,6 +85,7 @@ class UnsafeDropTipInPlaceImplementation(
|
|
|
77
85
|
state_update.update_pipette_tip_state(
|
|
78
86
|
pipette_id=params.pipetteId, tip_geometry=None
|
|
79
87
|
)
|
|
88
|
+
state_update.set_fluid_unknown(pipette_id=params.pipetteId)
|
|
80
89
|
|
|
81
90
|
return SuccessData(
|
|
82
91
|
public=UnsafeDropTipInPlaceResult(), state_update=state_update
|
|
@@ -90,7 +99,7 @@ class UnsafeDropTipInPlace(
|
|
|
90
99
|
|
|
91
100
|
commandType: UnsafeDropTipInPlaceCommandType = "unsafe/dropTipInPlace"
|
|
92
101
|
params: UnsafeDropTipInPlaceParams
|
|
93
|
-
result: Optional[UnsafeDropTipInPlaceResult]
|
|
102
|
+
result: Optional[UnsafeDropTipInPlaceResult] = None
|
|
94
103
|
|
|
95
104
|
_ImplementationCls: Type[
|
|
96
105
|
UnsafeDropTipInPlaceImplementation
|
|
@@ -52,10 +52,7 @@ class UnsafeEngageAxesImplementation(
|
|
|
52
52
|
"""Enable exes."""
|
|
53
53
|
ot3_hardware_api = ensure_ot3_hardware(self._hardware_api)
|
|
54
54
|
await ot3_hardware_api.engage_axes(
|
|
55
|
-
|
|
56
|
-
self._gantry_mover.motor_axis_to_hardware_axis(axis)
|
|
57
|
-
for axis in params.axes
|
|
58
|
-
]
|
|
55
|
+
self._gantry_mover.motor_axes_to_present_hardware_axes(params.axes)
|
|
59
56
|
)
|
|
60
57
|
return SuccessData(
|
|
61
58
|
public=UnsafeEngageAxesResult(),
|
|
@@ -69,7 +66,7 @@ class UnsafeEngageAxes(
|
|
|
69
66
|
|
|
70
67
|
commandType: UnsafeEngageAxesCommandType = "unsafe/engageAxes"
|
|
71
68
|
params: UnsafeEngageAxesParams
|
|
72
|
-
result: Optional[UnsafeEngageAxesResult]
|
|
69
|
+
result: Optional[UnsafeEngageAxesResult] = None
|
|
73
70
|
|
|
74
71
|
_ImplementationCls: Type[
|
|
75
72
|
UnsafeEngageAxesImplementation
|
|
@@ -192,7 +192,7 @@ class UnsafePlaceLabware(
|
|
|
192
192
|
|
|
193
193
|
commandType: UnsafePlaceLabwareCommandType = "unsafe/placeLabware"
|
|
194
194
|
params: UnsafePlaceLabwareParams
|
|
195
|
-
result: Optional[UnsafePlaceLabwareResult]
|
|
195
|
+
result: Optional[UnsafePlaceLabwareResult] = None
|
|
196
196
|
|
|
197
197
|
_ImplementationCls: Type[
|
|
198
198
|
UnsafePlaceLabwareImplementation
|
|
@@ -61,7 +61,7 @@ class UnsafeUngripLabware(
|
|
|
61
61
|
|
|
62
62
|
commandType: UnsafeUngripLabwareCommandType = "unsafe/ungripLabware"
|
|
63
63
|
params: UnsafeUngripLabwareParams
|
|
64
|
-
result: Optional[UnsafeUngripLabwareResult]
|
|
64
|
+
result: Optional[UnsafeUngripLabwareResult] = None
|
|
65
65
|
|
|
66
66
|
_ImplementationCls: Type[
|
|
67
67
|
UnsafeUngripLabwareImplementation
|
|
@@ -58,10 +58,7 @@ class UpdatePositionEstimatorsImplementation(
|
|
|
58
58
|
"""Update axis position estimators from their encoders."""
|
|
59
59
|
ot3_hardware_api = ensure_ot3_hardware(self._hardware_api)
|
|
60
60
|
await ot3_hardware_api.update_axis_position_estimations(
|
|
61
|
-
|
|
62
|
-
self._gantry_mover.motor_axis_to_hardware_axis(axis)
|
|
63
|
-
for axis in params.axes
|
|
64
|
-
]
|
|
61
|
+
self._gantry_mover.motor_axes_to_present_hardware_axes(params.axes)
|
|
65
62
|
)
|
|
66
63
|
return SuccessData(
|
|
67
64
|
public=UpdatePositionEstimatorsResult(),
|
|
@@ -77,7 +74,7 @@ class UpdatePositionEstimators(
|
|
|
77
74
|
|
|
78
75
|
commandType: UpdatePositionEstimatorsCommandType = "unsafe/updatePositionEstimators"
|
|
79
76
|
params: UpdatePositionEstimatorsParams
|
|
80
|
-
result: Optional[UpdatePositionEstimatorsResult]
|
|
77
|
+
result: Optional[UpdatePositionEstimatorsResult] = None
|
|
81
78
|
|
|
82
79
|
_ImplementationCls: Type[
|
|
83
80
|
UpdatePositionEstimatorsImplementation
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"""Verify tip presence command request, result and implementation models."""
|
|
2
2
|
from __future__ import annotations
|
|
3
|
+
from typing import TYPE_CHECKING, Optional, Type, Any
|
|
3
4
|
|
|
4
5
|
from pydantic import Field, BaseModel
|
|
5
|
-
from
|
|
6
|
+
from pydantic.json_schema import SkipJsonSchema
|
|
6
7
|
from typing_extensions import Literal
|
|
7
8
|
|
|
8
9
|
from .pipetting_common import PipetteIdMixin
|
|
@@ -18,14 +19,20 @@ if TYPE_CHECKING:
|
|
|
18
19
|
VerifyTipPresenceCommandType = Literal["verifyTipPresence"]
|
|
19
20
|
|
|
20
21
|
|
|
22
|
+
def _remove_default(s: dict[str, Any]) -> None:
|
|
23
|
+
s.pop("default", None)
|
|
24
|
+
|
|
25
|
+
|
|
21
26
|
class VerifyTipPresenceParams(PipetteIdMixin):
|
|
22
27
|
"""Payload required for a VerifyTipPresence command."""
|
|
23
28
|
|
|
24
29
|
expectedState: TipPresenceStatus = Field(
|
|
25
30
|
..., description="The expected tip presence status on the pipette."
|
|
26
31
|
)
|
|
27
|
-
followSingularSensor:
|
|
28
|
-
default=None,
|
|
32
|
+
followSingularSensor: InstrumentSensorId | SkipJsonSchema[None] = Field(
|
|
33
|
+
default=None,
|
|
34
|
+
description="The sensor id to follow if the other can be ignored.",
|
|
35
|
+
json_schema_extra=_remove_default,
|
|
29
36
|
)
|
|
30
37
|
|
|
31
38
|
|
|
@@ -77,7 +84,7 @@ class VerifyTipPresence(
|
|
|
77
84
|
|
|
78
85
|
commandType: VerifyTipPresenceCommandType = "verifyTipPresence"
|
|
79
86
|
params: VerifyTipPresenceParams
|
|
80
|
-
result: Optional[VerifyTipPresenceResult]
|
|
87
|
+
result: Optional[VerifyTipPresenceResult] = None
|
|
81
88
|
|
|
82
89
|
_ImplementationCls: Type[
|
|
83
90
|
VerifyTipPresenceImplementation
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"""Wait for duration command request, result, and implementation models."""
|
|
2
2
|
from __future__ import annotations
|
|
3
|
+
from typing import TYPE_CHECKING, Optional, Type, Any
|
|
4
|
+
|
|
3
5
|
from pydantic import BaseModel, Field
|
|
4
|
-
from
|
|
6
|
+
from pydantic.json_schema import SkipJsonSchema
|
|
5
7
|
from typing_extensions import Literal
|
|
6
8
|
|
|
7
9
|
from .command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, SuccessData
|
|
@@ -14,13 +16,18 @@ if TYPE_CHECKING:
|
|
|
14
16
|
WaitForDurationCommandType = Literal["waitForDuration"]
|
|
15
17
|
|
|
16
18
|
|
|
19
|
+
def _remove_default(s: dict[str, Any]) -> None:
|
|
20
|
+
s.pop("default", None)
|
|
21
|
+
|
|
22
|
+
|
|
17
23
|
class WaitForDurationParams(BaseModel):
|
|
18
24
|
"""Payload required to pause the protocol."""
|
|
19
25
|
|
|
20
26
|
seconds: float = Field(..., description="Duration, in seconds, to wait for.")
|
|
21
|
-
message:
|
|
27
|
+
message: str | SkipJsonSchema[None] = Field(
|
|
22
28
|
None,
|
|
23
29
|
description="A user-facing message associated with the pause",
|
|
30
|
+
json_schema_extra=_remove_default,
|
|
24
31
|
)
|
|
25
32
|
|
|
26
33
|
|
|
@@ -53,7 +60,7 @@ class WaitForDuration(
|
|
|
53
60
|
|
|
54
61
|
commandType: WaitForDurationCommandType = "waitForDuration"
|
|
55
62
|
params: WaitForDurationParams
|
|
56
|
-
result: Optional[WaitForDurationResult]
|
|
63
|
+
result: Optional[WaitForDurationResult] = None
|
|
57
64
|
|
|
58
65
|
_ImplementationCls: Type[
|
|
59
66
|
WaitForDurationImplementation
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"""Wait for resume command request, result, and implementation models."""
|
|
2
2
|
from __future__ import annotations
|
|
3
|
+
from typing import TYPE_CHECKING, Optional, Type, Any
|
|
4
|
+
|
|
3
5
|
from pydantic import BaseModel, Field
|
|
4
|
-
from
|
|
6
|
+
from pydantic.json_schema import SkipJsonSchema
|
|
5
7
|
from typing_extensions import Literal
|
|
6
8
|
|
|
7
9
|
from .command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, SuccessData
|
|
@@ -16,12 +18,17 @@ if TYPE_CHECKING:
|
|
|
16
18
|
WaitForResumeCommandType = Literal["waitForResume", "pause"]
|
|
17
19
|
|
|
18
20
|
|
|
21
|
+
def _remove_default(s: dict[str, Any]) -> None:
|
|
22
|
+
s.pop("default", None)
|
|
23
|
+
|
|
24
|
+
|
|
19
25
|
class WaitForResumeParams(BaseModel):
|
|
20
26
|
"""Payload required to pause the protocol."""
|
|
21
27
|
|
|
22
|
-
message:
|
|
28
|
+
message: str | SkipJsonSchema[None] = Field(
|
|
23
29
|
None,
|
|
24
30
|
description="A user-facing message associated with the pause",
|
|
31
|
+
json_schema_extra=_remove_default,
|
|
25
32
|
)
|
|
26
33
|
|
|
27
34
|
|
|
@@ -54,7 +61,7 @@ class WaitForResume(
|
|
|
54
61
|
|
|
55
62
|
commandType: WaitForResumeCommandType = "waitForResume"
|
|
56
63
|
params: WaitForResumeParams
|
|
57
|
-
result: Optional[WaitForResumeResult]
|
|
64
|
+
result: Optional[WaitForResumeResult] = None
|
|
58
65
|
|
|
59
66
|
_ImplementationCls: Type[WaitForResumeImplementation] = WaitForResumeImplementation
|
|
60
67
|
|
|
@@ -11,6 +11,7 @@ from .exceptions import (
|
|
|
11
11
|
PickUpTipTipNotAttachedError,
|
|
12
12
|
TipAttachedError,
|
|
13
13
|
CommandDoesNotExistError,
|
|
14
|
+
UnsupportedLabwareForActionError,
|
|
14
15
|
LabwareNotLoadedError,
|
|
15
16
|
LabwareNotLoadedOnModuleError,
|
|
16
17
|
LabwareNotLoadedOnLabwareError,
|
|
@@ -18,12 +19,14 @@ from .exceptions import (
|
|
|
18
19
|
LiquidDoesNotExistError,
|
|
19
20
|
LabwareDefinitionDoesNotExistError,
|
|
20
21
|
LabwareCannotBeStackedError,
|
|
22
|
+
LabwareCannotSitOnDeckError,
|
|
21
23
|
LabwareIsInStackError,
|
|
22
24
|
LabwareOffsetDoesNotExistError,
|
|
23
25
|
LabwareIsNotTipRackError,
|
|
24
26
|
LabwareIsTipRackError,
|
|
25
27
|
LabwareIsAdapterError,
|
|
26
28
|
TouchTipDisabledError,
|
|
29
|
+
TouchTipIncompatibleArgumentsError,
|
|
27
30
|
WellDoesNotExistError,
|
|
28
31
|
PipetteNotLoadedError,
|
|
29
32
|
ModuleNotLoadedError,
|
|
@@ -78,6 +81,9 @@ from .exceptions import (
|
|
|
78
81
|
OperationLocationNotInWellError,
|
|
79
82
|
InvalidDispenseVolumeError,
|
|
80
83
|
StorageLimitReachedError,
|
|
84
|
+
InvalidLiquidError,
|
|
85
|
+
LiquidClassDoesNotExistError,
|
|
86
|
+
LiquidClassRedefinitionError,
|
|
81
87
|
)
|
|
82
88
|
|
|
83
89
|
from .error_occurrence import ErrorOccurrence, ProtocolCommandFailedError
|
|
@@ -99,14 +105,17 @@ __all__ = [
|
|
|
99
105
|
"LabwareNotLoadedOnLabwareError",
|
|
100
106
|
"LabwareNotOnDeckError",
|
|
101
107
|
"LiquidDoesNotExistError",
|
|
108
|
+
"UnsupportedLabwareForActionError",
|
|
102
109
|
"LabwareDefinitionDoesNotExistError",
|
|
103
110
|
"LabwareCannotBeStackedError",
|
|
111
|
+
"LabwareCannotSitOnDeckError",
|
|
104
112
|
"LabwareIsInStackError",
|
|
105
113
|
"LabwareOffsetDoesNotExistError",
|
|
106
114
|
"LabwareIsNotTipRackError",
|
|
107
115
|
"LabwareIsTipRackError",
|
|
108
116
|
"LabwareIsAdapterError",
|
|
109
117
|
"TouchTipDisabledError",
|
|
118
|
+
"TouchTipIncompatibleArgumentsError",
|
|
110
119
|
"WellDoesNotExistError",
|
|
111
120
|
"PipetteNotLoadedError",
|
|
112
121
|
"ModuleNotLoadedError",
|
|
@@ -138,6 +147,7 @@ __all__ = [
|
|
|
138
147
|
"InvalidTargetSpeedError",
|
|
139
148
|
"InvalidBlockVolumeError",
|
|
140
149
|
"InvalidHoldTimeError",
|
|
150
|
+
"InvalidLiquidError",
|
|
141
151
|
"InvalidWavelengthError",
|
|
142
152
|
"CannotPerformModuleAction",
|
|
143
153
|
"ResumeFromRecoveryNotAllowedError",
|
|
@@ -164,4 +174,6 @@ __all__ = [
|
|
|
164
174
|
"OperationLocationNotInWellError",
|
|
165
175
|
"InvalidDispenseVolumeError",
|
|
166
176
|
"StorageLimitReachedError",
|
|
177
|
+
"LiquidClassDoesNotExistError",
|
|
178
|
+
"LiquidClassRedefinitionError",
|
|
167
179
|
]
|
|
@@ -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()
|