opentrons 8.3.0a0__py2.py3-none-any.whl → 8.3.0a1__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- opentrons/calibration_storage/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/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 +28 -20
- opentrons/hardware_control/backends/flex_protocol.py +4 -6
- opentrons/hardware_control/backends/ot3controller.py +177 -59
- opentrons/hardware_control/backends/ot3simulator.py +10 -8
- opentrons/hardware_control/backends/ot3utils.py +3 -13
- opentrons/hardware_control/dev_types.py +2 -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 +9 -21
- 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 +13 -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 +34 -22
- 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 +18 -0
- opentrons/hardware_control/protocols/motion_controller.py +6 -0
- opentrons/hardware_control/robot_calibration.py +1 -1
- opentrons/hardware_control/types.py +61 -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 +67 -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 +42 -4
- opentrons/protocol_api/core/labware.py +13 -4
- opentrons/protocol_api/core/legacy/legacy_instrument_core.py +34 -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 +34 -3
- opentrons/protocol_api/core/protocol.py +34 -1
- opentrons/protocol_api/core/robot.py +51 -0
- opentrons/protocol_api/instrument_context.py +145 -43
- opentrons/protocol_api/labware.py +231 -7
- 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 +261 -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 +81 -0
- opentrons/protocol_engine/commands/absorbance_reader/close_lid.py +0 -2
- opentrons/protocol_engine/commands/absorbance_reader/initialize.py +19 -5
- opentrons/protocol_engine/commands/absorbance_reader/open_lid.py +0 -1
- opentrons/protocol_engine/commands/absorbance_reader/read.py +32 -9
- 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 +101 -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 +13 -3
- 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 +60 -25
- opentrons/protocol_engine/commands/load_labware.py +29 -7
- 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 +19 -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 +8 -2
- 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 +4 -1
- opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py +12 -3
- opentrons/protocol_engine/commands/unsafe/unsafe_engage_axes.py +1 -4
- opentrons/protocol_engine/commands/unsafe/update_position_estimators.py +1 -4
- 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 +8 -0
- opentrons/protocol_engine/errors/error_occurrence.py +19 -20
- opentrons/protocol_engine/errors/exceptions.py +50 -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 +364 -8
- opentrons/protocol_engine/execution/movement.py +27 -0
- opentrons/protocol_engine/execution/pipetting.py +5 -1
- opentrons/protocol_engine/execution/tip_handler.py +4 -6
- 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 +5 -0
- opentrons/protocol_engine/resources/module_data_provider.py +1 -1
- opentrons/protocol_engine/resources/pipette_data_provider.py +12 -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 +17 -13
- opentrons/protocol_engine/state/files.py +10 -12
- opentrons/protocol_engine/state/fluid_stack.py +138 -0
- opentrons/protocol_engine/state/frustum_helpers.py +57 -32
- opentrons/protocol_engine/state/geometry.py +47 -1
- opentrons/protocol_engine/state/labware.py +79 -25
- 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 +135 -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 +39 -6
- opentrons/protocols/models/json_protocol.py +5 -9
- opentrons/simulate.py +3 -1
- opentrons/types.py +162 -2
- opentrons/util/logging_config.py +1 -1
- {opentrons-8.3.0a0.dist-info → opentrons-8.3.0a1.dist-info}/METADATA +16 -15
- {opentrons-8.3.0a0.dist-info → opentrons-8.3.0a1.dist-info}/RECORD +228 -201
- {opentrons-8.3.0a0.dist-info → opentrons-8.3.0a1.dist-info}/WHEEL +1 -1
- {opentrons-8.3.0a0.dist-info → opentrons-8.3.0a1.dist-info}/LICENSE +0 -0
- {opentrons-8.3.0a0.dist-info → opentrons-8.3.0a1.dist-info}/entry_points.txt +0 -0
- {opentrons-8.3.0a0.dist-info → opentrons-8.3.0a1.dist-info}/top_level.txt +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"""Dispense-in-place command request, result, and implementation models."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
|
-
from typing import TYPE_CHECKING, Optional, Type, Union
|
|
4
|
+
from typing import TYPE_CHECKING, Optional, Type, Union, Any
|
|
4
5
|
from typing_extensions import Literal
|
|
5
6
|
from pydantic import Field
|
|
6
|
-
|
|
7
|
-
from opentrons_shared_data.errors.exceptions import PipetteOverpressureError
|
|
7
|
+
from pydantic.json_schema import SkipJsonSchema
|
|
8
8
|
|
|
9
9
|
from .pipetting_common import (
|
|
10
10
|
PipetteIdMixin,
|
|
@@ -12,6 +12,7 @@ from .pipetting_common import (
|
|
|
12
12
|
FlowRateMixin,
|
|
13
13
|
BaseLiquidHandlingResult,
|
|
14
14
|
OverpressureError,
|
|
15
|
+
dispense_in_place,
|
|
15
16
|
)
|
|
16
17
|
from .command import (
|
|
17
18
|
AbstractCommandImpl,
|
|
@@ -20,8 +21,7 @@ from .command import (
|
|
|
20
21
|
SuccessData,
|
|
21
22
|
DefinedErrorData,
|
|
22
23
|
)
|
|
23
|
-
from ..
|
|
24
|
-
from ..state.update_types import StateUpdate, CLEAR
|
|
24
|
+
from ..state.update_types import CLEAR
|
|
25
25
|
from ..types import CurrentWell
|
|
26
26
|
|
|
27
27
|
if TYPE_CHECKING:
|
|
@@ -33,12 +33,17 @@ if TYPE_CHECKING:
|
|
|
33
33
|
DispenseInPlaceCommandType = Literal["dispenseInPlace"]
|
|
34
34
|
|
|
35
35
|
|
|
36
|
+
def _remove_default(s: dict[str, Any]) -> None:
|
|
37
|
+
s.pop("default", None)
|
|
38
|
+
|
|
39
|
+
|
|
36
40
|
class DispenseInPlaceParams(PipetteIdMixin, DispenseVolumeMixin, FlowRateMixin):
|
|
37
41
|
"""Payload required to dispense in place."""
|
|
38
42
|
|
|
39
|
-
pushOut:
|
|
43
|
+
pushOut: float | SkipJsonSchema[None] = Field(
|
|
40
44
|
None,
|
|
41
45
|
description="push the plunger a small amount farther than necessary for accurate low-volume dispensing",
|
|
46
|
+
json_schema_extra=_remove_default,
|
|
42
47
|
)
|
|
43
48
|
|
|
44
49
|
|
|
@@ -74,63 +79,78 @@ class DispenseInPlaceImplementation(
|
|
|
74
79
|
|
|
75
80
|
async def execute(self, params: DispenseInPlaceParams) -> _ExecuteReturn:
|
|
76
81
|
"""Dispense without moving the pipette."""
|
|
77
|
-
state_update = StateUpdate()
|
|
78
82
|
current_location = self._state_view.pipettes.get_current_location()
|
|
79
83
|
current_position = await self._gantry_mover.get_position(params.pipetteId)
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
84
|
+
result = await dispense_in_place(
|
|
85
|
+
pipette_id=params.pipetteId,
|
|
86
|
+
volume=params.volume,
|
|
87
|
+
flow_rate=params.flowRate,
|
|
88
|
+
push_out=params.pushOut,
|
|
89
|
+
location_if_error={
|
|
90
|
+
"retryLocation": (
|
|
91
|
+
current_position.x,
|
|
92
|
+
current_position.y,
|
|
93
|
+
current_position.z,
|
|
94
|
+
)
|
|
95
|
+
},
|
|
96
|
+
pipetting=self._pipetting,
|
|
97
|
+
model_utils=self._model_utils,
|
|
98
|
+
)
|
|
99
|
+
if isinstance(result, DefinedErrorData):
|
|
88
100
|
if (
|
|
89
101
|
isinstance(current_location, CurrentWell)
|
|
90
102
|
and current_location.pipette_id == params.pipetteId
|
|
91
103
|
):
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
ErrorOccurrence.from_failed(
|
|
103
|
-
id=self._model_utils.generate_id(),
|
|
104
|
-
createdAt=self._model_utils.get_timestamp(),
|
|
105
|
-
error=e,
|
|
106
|
-
)
|
|
107
|
-
],
|
|
108
|
-
errorInfo=(
|
|
109
|
-
{
|
|
110
|
-
"retryLocation": (
|
|
111
|
-
current_position.x,
|
|
112
|
-
current_position.y,
|
|
113
|
-
current_position.z,
|
|
114
|
-
)
|
|
115
|
-
}
|
|
104
|
+
return DefinedErrorData(
|
|
105
|
+
public=result.public,
|
|
106
|
+
state_update=result.state_update.set_liquid_operated(
|
|
107
|
+
labware_id=current_location.labware_id,
|
|
108
|
+
well_names=self._state_view.geometry.get_wells_covered_by_pipette_with_active_well(
|
|
109
|
+
current_location.labware_id,
|
|
110
|
+
current_location.well_name,
|
|
111
|
+
params.pipetteId,
|
|
112
|
+
),
|
|
113
|
+
volume_added=CLEAR,
|
|
116
114
|
),
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
115
|
+
state_update_if_false_positive=result.state_update_if_false_positive,
|
|
116
|
+
)
|
|
117
|
+
else:
|
|
118
|
+
return result
|
|
120
119
|
else:
|
|
121
120
|
if (
|
|
122
121
|
isinstance(current_location, CurrentWell)
|
|
123
122
|
and current_location.pipette_id == params.pipetteId
|
|
124
123
|
):
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
124
|
+
volume_added = (
|
|
125
|
+
self._state_view.pipettes.get_liquid_dispensed_by_ejecting_volume(
|
|
126
|
+
pipette_id=params.pipetteId, volume=result.public.volume
|
|
127
|
+
)
|
|
128
|
+
)
|
|
129
|
+
if volume_added is not None:
|
|
130
|
+
volume_added *= self._state_view.geometry.get_nozzles_per_well(
|
|
131
|
+
current_location.labware_id,
|
|
132
|
+
current_location.well_name,
|
|
133
|
+
params.pipetteId,
|
|
134
|
+
)
|
|
135
|
+
return SuccessData(
|
|
136
|
+
public=DispenseInPlaceResult(volume=result.public.volume),
|
|
137
|
+
state_update=result.state_update.set_liquid_operated(
|
|
138
|
+
labware_id=current_location.labware_id,
|
|
139
|
+
well_names=self._state_view.geometry.get_wells_covered_by_pipette_with_active_well(
|
|
140
|
+
current_location.labware_id,
|
|
141
|
+
current_location.well_name,
|
|
142
|
+
params.pipetteId,
|
|
143
|
+
),
|
|
144
|
+
volume_added=volume_added
|
|
145
|
+
if volume_added is not None
|
|
146
|
+
else CLEAR,
|
|
147
|
+
),
|
|
148
|
+
)
|
|
149
|
+
else:
|
|
150
|
+
return SuccessData(
|
|
151
|
+
public=DispenseInPlaceResult(volume=result.public.volume),
|
|
152
|
+
state_update=result.state_update,
|
|
129
153
|
)
|
|
130
|
-
return SuccessData(
|
|
131
|
-
public=DispenseInPlaceResult(volume=volume),
|
|
132
|
-
state_update=state_update,
|
|
133
|
-
)
|
|
134
154
|
|
|
135
155
|
|
|
136
156
|
class DispenseInPlace(
|
|
@@ -140,7 +160,7 @@ class DispenseInPlace(
|
|
|
140
160
|
|
|
141
161
|
commandType: DispenseInPlaceCommandType = "dispenseInPlace"
|
|
142
162
|
params: DispenseInPlaceParams
|
|
143
|
-
result: Optional[DispenseInPlaceResult]
|
|
163
|
+
result: Optional[DispenseInPlaceResult] = None
|
|
144
164
|
|
|
145
165
|
_ImplementationCls: Type[
|
|
146
166
|
DispenseInPlaceImplementation
|
|
@@ -1,20 +1,27 @@
|
|
|
1
1
|
"""Drop tip command request, result, and implementation models."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
4
|
+
from typing import TYPE_CHECKING, Optional, Type, Any
|
|
3
5
|
|
|
4
6
|
from pydantic import Field
|
|
5
|
-
from
|
|
7
|
+
from pydantic.json_schema import SkipJsonSchema
|
|
8
|
+
|
|
6
9
|
from typing_extensions import Literal
|
|
7
10
|
|
|
8
11
|
from opentrons.protocol_engine.errors.exceptions import TipAttachedError
|
|
9
12
|
from opentrons.protocol_engine.resources.model_utils import ModelUtils
|
|
10
13
|
|
|
11
|
-
from ..state import
|
|
12
|
-
from ..types import DropTipWellLocation
|
|
14
|
+
from ..state.update_types import StateUpdate
|
|
15
|
+
from ..types import DropTipWellLocation
|
|
13
16
|
from .pipetting_common import (
|
|
14
17
|
PipetteIdMixin,
|
|
15
|
-
DestinationPositionResult,
|
|
16
18
|
TipPhysicallyAttachedError,
|
|
17
19
|
)
|
|
20
|
+
from .movement_common import (
|
|
21
|
+
DestinationPositionResult,
|
|
22
|
+
move_to_well,
|
|
23
|
+
StallOrCollisionError,
|
|
24
|
+
)
|
|
18
25
|
from .command import (
|
|
19
26
|
AbstractCommandImpl,
|
|
20
27
|
BaseCommand,
|
|
@@ -32,6 +39,10 @@ if TYPE_CHECKING:
|
|
|
32
39
|
DropTipCommandType = Literal["dropTip"]
|
|
33
40
|
|
|
34
41
|
|
|
42
|
+
def _remove_default(s: dict[str, Any]) -> None:
|
|
43
|
+
s.pop("default", None)
|
|
44
|
+
|
|
45
|
+
|
|
35
46
|
class DropTipParams(PipetteIdMixin):
|
|
36
47
|
"""Payload required to drop a tip in a specific well."""
|
|
37
48
|
|
|
@@ -41,15 +52,16 @@ class DropTipParams(PipetteIdMixin):
|
|
|
41
52
|
default_factory=DropTipWellLocation,
|
|
42
53
|
description="Relative well location at which to drop the tip.",
|
|
43
54
|
)
|
|
44
|
-
homeAfter:
|
|
55
|
+
homeAfter: bool | SkipJsonSchema[None] = Field(
|
|
45
56
|
None,
|
|
46
57
|
description=(
|
|
47
58
|
"Whether to home this pipette's plunger after dropping the tip."
|
|
48
59
|
" You should normally leave this unspecified to let the robot choose"
|
|
49
60
|
" a safe default depending on its hardware."
|
|
50
61
|
),
|
|
62
|
+
json_schema_extra=_remove_default,
|
|
51
63
|
)
|
|
52
|
-
alternateDropLocation:
|
|
64
|
+
alternateDropLocation: bool | SkipJsonSchema[None] = Field(
|
|
53
65
|
False,
|
|
54
66
|
description=(
|
|
55
67
|
"Whether to alternate location where tip is dropped within the labware."
|
|
@@ -58,6 +70,7 @@ class DropTipParams(PipetteIdMixin):
|
|
|
58
70
|
" labware well."
|
|
59
71
|
" If False, the tip will be dropped at the top center of the well."
|
|
60
72
|
),
|
|
73
|
+
json_schema_extra=_remove_default,
|
|
61
74
|
)
|
|
62
75
|
|
|
63
76
|
|
|
@@ -68,7 +81,9 @@ class DropTipResult(DestinationPositionResult):
|
|
|
68
81
|
|
|
69
82
|
|
|
70
83
|
_ExecuteReturn = (
|
|
71
|
-
SuccessData[DropTipResult]
|
|
84
|
+
SuccessData[DropTipResult]
|
|
85
|
+
| DefinedErrorData[TipPhysicallyAttachedError]
|
|
86
|
+
| DefinedErrorData[StallOrCollisionError]
|
|
72
87
|
)
|
|
73
88
|
|
|
74
89
|
|
|
@@ -95,8 +110,6 @@ class DropTipImplementation(AbstractCommandImpl[DropTipParams, _ExecuteReturn]):
|
|
|
95
110
|
well_name = params.wellName
|
|
96
111
|
home_after = params.homeAfter
|
|
97
112
|
|
|
98
|
-
state_update = update_types.StateUpdate()
|
|
99
|
-
|
|
100
113
|
if params.alternateDropLocation:
|
|
101
114
|
well_location = self._state_view.geometry.get_next_tip_drop_location(
|
|
102
115
|
labware_id=labware_id,
|
|
@@ -116,19 +129,16 @@ class DropTipImplementation(AbstractCommandImpl[DropTipParams, _ExecuteReturn]):
|
|
|
116
129
|
partially_configured=is_partially_configured,
|
|
117
130
|
)
|
|
118
131
|
|
|
119
|
-
|
|
132
|
+
move_result = await move_to_well(
|
|
133
|
+
movement=self._movement_handler,
|
|
134
|
+
model_utils=self._model_utils,
|
|
120
135
|
pipette_id=pipette_id,
|
|
121
136
|
labware_id=labware_id,
|
|
122
137
|
well_name=well_name,
|
|
123
138
|
well_location=tip_drop_location,
|
|
124
139
|
)
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
pipette_id=pipette_id,
|
|
128
|
-
new_labware_id=labware_id,
|
|
129
|
-
new_well_name=well_name,
|
|
130
|
-
new_deck_point=deck_point,
|
|
131
|
-
)
|
|
140
|
+
if isinstance(move_result, DefinedErrorData):
|
|
141
|
+
return move_result
|
|
132
142
|
|
|
133
143
|
try:
|
|
134
144
|
await self._tip_handler.drop_tip(
|
|
@@ -145,33 +155,44 @@ class DropTipImplementation(AbstractCommandImpl[DropTipParams, _ExecuteReturn]):
|
|
|
145
155
|
error=exception,
|
|
146
156
|
)
|
|
147
157
|
],
|
|
148
|
-
errorInfo={
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
158
|
+
errorInfo={
|
|
159
|
+
"retryLocation": (
|
|
160
|
+
move_result.public.position.x,
|
|
161
|
+
move_result.public.position.y,
|
|
162
|
+
move_result.public.position.z,
|
|
163
|
+
)
|
|
164
|
+
},
|
|
153
165
|
)
|
|
154
166
|
return DefinedErrorData(
|
|
155
167
|
public=error,
|
|
156
|
-
state_update=
|
|
157
|
-
|
|
168
|
+
state_update=StateUpdate.reduce(
|
|
169
|
+
StateUpdate(), move_result.state_update
|
|
170
|
+
).set_fluid_unknown(pipette_id=pipette_id),
|
|
171
|
+
state_update_if_false_positive=move_result.state_update.update_pipette_tip_state(
|
|
172
|
+
pipette_id=params.pipetteId, tip_geometry=None
|
|
173
|
+
),
|
|
158
174
|
)
|
|
159
175
|
else:
|
|
160
|
-
state_update.update_pipette_tip_state(
|
|
161
|
-
pipette_id=params.pipetteId, tip_geometry=None
|
|
162
|
-
)
|
|
163
176
|
return SuccessData(
|
|
164
|
-
public=DropTipResult(position=
|
|
165
|
-
state_update=state_update
|
|
177
|
+
public=DropTipResult(position=move_result.public.position),
|
|
178
|
+
state_update=move_result.state_update.set_fluid_unknown(
|
|
179
|
+
pipette_id=pipette_id
|
|
180
|
+
).update_pipette_tip_state(
|
|
181
|
+
pipette_id=params.pipetteId, tip_geometry=None
|
|
182
|
+
),
|
|
166
183
|
)
|
|
167
184
|
|
|
168
185
|
|
|
169
|
-
class DropTip(
|
|
186
|
+
class DropTip(
|
|
187
|
+
BaseCommand[
|
|
188
|
+
DropTipParams, DropTipResult, TipPhysicallyAttachedError | StallOrCollisionError
|
|
189
|
+
]
|
|
190
|
+
):
|
|
170
191
|
"""Drop tip command model."""
|
|
171
192
|
|
|
172
193
|
commandType: DropTipCommandType = "dropTip"
|
|
173
194
|
params: DropTipParams
|
|
174
|
-
result: Optional[DropTipResult]
|
|
195
|
+
result: Optional[DropTipResult] = None
|
|
175
196
|
|
|
176
197
|
_ImplementationCls: Type[DropTipImplementation] = DropTipImplementation
|
|
177
198
|
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
"""Drop tip in place command request, result, and implementation models."""
|
|
2
2
|
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from typing import TYPE_CHECKING, Optional, Type, Any
|
|
5
|
+
|
|
3
6
|
from pydantic import Field, BaseModel
|
|
4
|
-
from
|
|
7
|
+
from pydantic.json_schema import SkipJsonSchema
|
|
5
8
|
from typing_extensions import Literal
|
|
6
9
|
|
|
7
10
|
from .command import (
|
|
@@ -24,16 +27,21 @@ if TYPE_CHECKING:
|
|
|
24
27
|
DropTipInPlaceCommandType = Literal["dropTipInPlace"]
|
|
25
28
|
|
|
26
29
|
|
|
30
|
+
def _remove_default(s: dict[str, Any]) -> None:
|
|
31
|
+
s.pop("default", None)
|
|
32
|
+
|
|
33
|
+
|
|
27
34
|
class DropTipInPlaceParams(PipetteIdMixin):
|
|
28
35
|
"""Payload required to drop a tip in place."""
|
|
29
36
|
|
|
30
|
-
homeAfter:
|
|
37
|
+
homeAfter: bool | SkipJsonSchema[None] = Field(
|
|
31
38
|
None,
|
|
32
39
|
description=(
|
|
33
40
|
"Whether to home this pipette's plunger after dropping the tip."
|
|
34
41
|
" You should normally leave this unspecified to let the robot choose"
|
|
35
42
|
" a safe default depending on its hardware."
|
|
36
43
|
),
|
|
44
|
+
json_schema_extra=_remove_default,
|
|
37
45
|
)
|
|
38
46
|
|
|
39
47
|
|
|
@@ -79,6 +87,7 @@ class DropTipInPlaceImplementation(
|
|
|
79
87
|
state_update_if_false_positive.update_pipette_tip_state(
|
|
80
88
|
pipette_id=params.pipetteId, tip_geometry=None
|
|
81
89
|
)
|
|
90
|
+
state_update.set_fluid_unknown(pipette_id=params.pipetteId)
|
|
82
91
|
error = TipPhysicallyAttachedError(
|
|
83
92
|
id=self._model_utils.generate_id(),
|
|
84
93
|
createdAt=self._model_utils.get_timestamp(),
|
|
@@ -97,6 +106,7 @@ class DropTipInPlaceImplementation(
|
|
|
97
106
|
state_update_if_false_positive=state_update_if_false_positive,
|
|
98
107
|
)
|
|
99
108
|
else:
|
|
109
|
+
state_update.set_fluid_unknown(pipette_id=params.pipetteId)
|
|
100
110
|
state_update.update_pipette_tip_state(
|
|
101
111
|
pipette_id=params.pipetteId, tip_geometry=None
|
|
102
112
|
)
|
|
@@ -110,7 +120,7 @@ class DropTipInPlace(
|
|
|
110
120
|
|
|
111
121
|
commandType: DropTipInPlaceCommandType = "dropTipInPlace"
|
|
112
122
|
params: DropTipInPlaceParams
|
|
113
|
-
result: Optional[DropTipInPlaceResult]
|
|
123
|
+
result: Optional[DropTipInPlaceResult] = None
|
|
114
124
|
|
|
115
125
|
_ImplementationCls: Type[
|
|
116
126
|
DropTipInPlaceImplementation
|
|
@@ -1,24 +1,17 @@
|
|
|
1
1
|
"""Generate a JSON schema against which all create commands statically validate."""
|
|
2
|
+
|
|
2
3
|
import json
|
|
3
|
-
import pydantic
|
|
4
4
|
import argparse
|
|
5
5
|
import sys
|
|
6
|
-
from opentrons.protocol_engine.commands.command_unions import
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class CreateCommandUnion(pydantic.BaseModel):
|
|
10
|
-
"""Model that validates a union of all CommandCreate models."""
|
|
11
|
-
|
|
12
|
-
__root__: CommandCreate
|
|
6
|
+
from opentrons.protocol_engine.commands.command_unions import CommandCreateAdapter
|
|
13
7
|
|
|
14
8
|
|
|
15
9
|
def generate_command_schema(version: str) -> str:
|
|
16
10
|
"""Generate a JSON Schema that all valid create commands can validate against."""
|
|
17
|
-
|
|
18
|
-
schema_as_dict = json.loads(raw_json_schema)
|
|
11
|
+
schema_as_dict = CommandCreateAdapter.json_schema(mode="validation")
|
|
19
12
|
schema_as_dict["$id"] = f"opentronsCommandSchemaV{version}"
|
|
20
13
|
schema_as_dict["$schema"] = "http://json-schema.org/draft-07/schema#"
|
|
21
|
-
return json.dumps(schema_as_dict, indent=2)
|
|
14
|
+
return json.dumps(schema_as_dict, indent=2, sort_keys=True)
|
|
22
15
|
|
|
23
16
|
|
|
24
17
|
if __name__ == "__main__":
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"""Get next tip command request, result, and implementation models."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from pydantic import BaseModel, Field
|
|
5
|
+
from typing import TYPE_CHECKING, Any, Optional, Type, List, Literal, Union
|
|
6
|
+
|
|
7
|
+
from pydantic.json_schema import SkipJsonSchema
|
|
8
|
+
|
|
9
|
+
from opentrons.types import NozzleConfigurationType
|
|
10
|
+
|
|
11
|
+
from ..errors import ErrorOccurrence
|
|
12
|
+
from ..types import NextTipInfo, NoTipAvailable, NoTipReason
|
|
13
|
+
from .pipetting_common import PipetteIdMixin
|
|
14
|
+
|
|
15
|
+
from .command import (
|
|
16
|
+
AbstractCommandImpl,
|
|
17
|
+
BaseCommand,
|
|
18
|
+
BaseCommandCreate,
|
|
19
|
+
SuccessData,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
if TYPE_CHECKING:
|
|
23
|
+
from ..state.state import StateView
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _remove_default(s: dict[str, Any]) -> None:
|
|
27
|
+
s.pop("default", None)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
GetNextTipCommandType = Literal["getNextTip"]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class GetNextTipParams(PipetteIdMixin):
|
|
34
|
+
"""Payload needed to resolve the next available tip."""
|
|
35
|
+
|
|
36
|
+
labwareIds: List[str] = Field(
|
|
37
|
+
...,
|
|
38
|
+
description="Labware ID(s) of tip racks to resolve next available tip(s) from"
|
|
39
|
+
" Labware IDs will be resolved sequentially",
|
|
40
|
+
)
|
|
41
|
+
startingTipWell: str | SkipJsonSchema[None] = Field(
|
|
42
|
+
None,
|
|
43
|
+
description="Name of starting tip rack 'well'."
|
|
44
|
+
" This only applies to the first tip rack in the list provided in labwareIDs",
|
|
45
|
+
json_schema_extra=_remove_default,
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class GetNextTipResult(BaseModel):
|
|
50
|
+
"""Result data from the execution of a GetNextTip."""
|
|
51
|
+
|
|
52
|
+
nextTipInfo: Union[NextTipInfo, NoTipAvailable] = Field(
|
|
53
|
+
...,
|
|
54
|
+
description="Labware ID and well name of next available tip for a pipette,"
|
|
55
|
+
" or information why no tip could be resolved.",
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class GetNextTipImplementation(
|
|
60
|
+
AbstractCommandImpl[GetNextTipParams, SuccessData[GetNextTipResult]]
|
|
61
|
+
):
|
|
62
|
+
"""Get next tip command implementation."""
|
|
63
|
+
|
|
64
|
+
def __init__(
|
|
65
|
+
self,
|
|
66
|
+
state_view: StateView,
|
|
67
|
+
**kwargs: object,
|
|
68
|
+
) -> None:
|
|
69
|
+
self._state_view = state_view
|
|
70
|
+
|
|
71
|
+
async def execute(self, params: GetNextTipParams) -> SuccessData[GetNextTipResult]:
|
|
72
|
+
"""Get the next available tip for the requested pipette."""
|
|
73
|
+
pipette_id = params.pipetteId
|
|
74
|
+
starting_tip_name = params.startingTipWell
|
|
75
|
+
|
|
76
|
+
num_tips = self._state_view.tips.get_pipette_active_channels(pipette_id)
|
|
77
|
+
nozzle_map = self._state_view.tips.get_pipette_nozzle_map(pipette_id)
|
|
78
|
+
|
|
79
|
+
if (
|
|
80
|
+
starting_tip_name is not None
|
|
81
|
+
and nozzle_map.configuration != NozzleConfigurationType.FULL
|
|
82
|
+
):
|
|
83
|
+
# This is to match the behavior found in PAPI, but also because we don't have logic to automatically find
|
|
84
|
+
# the next tip with partial configuration and a starting tip. This will never work for a 96-channel due to
|
|
85
|
+
# x-axis overlap, but could eventually work with 8-channel if we better define starting tip USED or CLEAN
|
|
86
|
+
# state when starting a protocol to prevent accidental tip pick-up with starting non-full tip racks.
|
|
87
|
+
return SuccessData(
|
|
88
|
+
public=GetNextTipResult(
|
|
89
|
+
nextTipInfo=NoTipAvailable(
|
|
90
|
+
noTipReason=NoTipReason.STARTING_TIP_WITH_PARTIAL,
|
|
91
|
+
message="Cannot automatically resolve next tip with starting tip and partial tip configuration.",
|
|
92
|
+
)
|
|
93
|
+
)
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
next_tip: Union[NextTipInfo, NoTipAvailable]
|
|
97
|
+
for labware_id in params.labwareIds:
|
|
98
|
+
well_name = self._state_view.tips.get_next_tip(
|
|
99
|
+
labware_id=labware_id,
|
|
100
|
+
num_tips=num_tips,
|
|
101
|
+
starting_tip_name=starting_tip_name,
|
|
102
|
+
nozzle_map=nozzle_map,
|
|
103
|
+
)
|
|
104
|
+
if well_name is not None:
|
|
105
|
+
next_tip = NextTipInfo(labwareId=labware_id, tipStartingWell=well_name)
|
|
106
|
+
break
|
|
107
|
+
# After the first tip rack is exhausted, starting tip no longer applies
|
|
108
|
+
starting_tip_name = None
|
|
109
|
+
else:
|
|
110
|
+
next_tip = NoTipAvailable(
|
|
111
|
+
noTipReason=NoTipReason.NO_AVAILABLE_TIPS,
|
|
112
|
+
message="No available tips for given pipette, nozzle configuration and provided tip racks.",
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
return SuccessData(public=GetNextTipResult(nextTipInfo=next_tip))
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
class GetNextTip(BaseCommand[GetNextTipParams, GetNextTipResult, ErrorOccurrence]):
|
|
119
|
+
"""Get next tip command model."""
|
|
120
|
+
|
|
121
|
+
commandType: GetNextTipCommandType = "getNextTip"
|
|
122
|
+
params: GetNextTipParams
|
|
123
|
+
result: Optional[GetNextTipResult]
|
|
124
|
+
|
|
125
|
+
_ImplementationCls: Type[GetNextTipImplementation] = GetNextTipImplementation
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class GetNextTipCreate(BaseCommandCreate[GetNextTipParams]):
|
|
129
|
+
"""Get next tip command creation request model."""
|
|
130
|
+
|
|
131
|
+
commandType: GetNextTipCommandType = "getNextTip"
|
|
132
|
+
params: GetNextTipParams
|
|
133
|
+
|
|
134
|
+
_CommandCls: Type[GetNextTip] = GetNextTip
|
|
@@ -71,7 +71,7 @@ class GetTipPresence(
|
|
|
71
71
|
|
|
72
72
|
commandType: GetTipPresenceCommandType = "getTipPresence"
|
|
73
73
|
params: GetTipPresenceParams
|
|
74
|
-
result: Optional[GetTipPresenceResult]
|
|
74
|
+
result: Optional[GetTipPresenceResult] = None
|
|
75
75
|
|
|
76
76
|
_ImplementationCls: Type[
|
|
77
77
|
GetTipPresenceImplementation
|
|
@@ -69,7 +69,7 @@ class CloseLabwareLatch(
|
|
|
69
69
|
|
|
70
70
|
commandType: CloseLabwareLatchCommandType = "heaterShaker/closeLabwareLatch"
|
|
71
71
|
params: CloseLabwareLatchParams
|
|
72
|
-
result: Optional[CloseLabwareLatchResult]
|
|
72
|
+
result: Optional[CloseLabwareLatchResult] = None
|
|
73
73
|
|
|
74
74
|
_ImplementationCls: Type[CloseLabwareLatchImpl] = CloseLabwareLatchImpl
|
|
75
75
|
|
|
@@ -68,7 +68,7 @@ class DeactivateHeater(
|
|
|
68
68
|
|
|
69
69
|
commandType: DeactivateHeaterCommandType = "heaterShaker/deactivateHeater"
|
|
70
70
|
params: DeactivateHeaterParams
|
|
71
|
-
result: Optional[DeactivateHeaterResult]
|
|
71
|
+
result: Optional[DeactivateHeaterResult] = None
|
|
72
72
|
|
|
73
73
|
_ImplementationCls: Type[DeactivateHeaterImpl] = DeactivateHeaterImpl
|
|
74
74
|
|
|
@@ -70,7 +70,7 @@ class DeactivateShaker(
|
|
|
70
70
|
|
|
71
71
|
commandType: DeactivateShakerCommandType = "heaterShaker/deactivateShaker"
|
|
72
72
|
params: DeactivateShakerParams
|
|
73
|
-
result: Optional[DeactivateShakerResult]
|
|
73
|
+
result: Optional[DeactivateShakerResult] = None
|
|
74
74
|
|
|
75
75
|
_ImplementationCls: Type[DeactivateShakerImpl] = DeactivateShakerImpl
|
|
76
76
|
|
|
@@ -96,7 +96,7 @@ class OpenLabwareLatch(
|
|
|
96
96
|
|
|
97
97
|
commandType: OpenLabwareLatchCommandType = "heaterShaker/openLabwareLatch"
|
|
98
98
|
params: OpenLabwareLatchParams
|
|
99
|
-
result: Optional[OpenLabwareLatchResult]
|
|
99
|
+
result: Optional[OpenLabwareLatchResult] = None
|
|
100
100
|
|
|
101
101
|
_ImplementationCls: Type[OpenLabwareLatchImpl] = OpenLabwareLatchImpl
|
|
102
102
|
|
|
@@ -109,7 +109,7 @@ class SetAndWaitForShakeSpeed(
|
|
|
109
109
|
"heaterShaker/setAndWaitForShakeSpeed"
|
|
110
110
|
)
|
|
111
111
|
params: SetAndWaitForShakeSpeedParams
|
|
112
|
-
result: Optional[SetAndWaitForShakeSpeedResult]
|
|
112
|
+
result: Optional[SetAndWaitForShakeSpeedResult] = None
|
|
113
113
|
|
|
114
114
|
_ImplementationCls: Type[SetAndWaitForShakeSpeedImpl] = SetAndWaitForShakeSpeedImpl
|
|
115
115
|
|
|
@@ -76,7 +76,7 @@ class SetTargetTemperature(
|
|
|
76
76
|
|
|
77
77
|
commandType: SetTargetTemperatureCommandType = "heaterShaker/setTargetTemperature"
|
|
78
78
|
params: SetTargetTemperatureParams
|
|
79
|
-
result: Optional[SetTargetTemperatureResult]
|
|
79
|
+
result: Optional[SetTargetTemperatureResult] = None
|
|
80
80
|
|
|
81
81
|
_ImplementationCls: Type[SetTargetTemperatureImpl] = SetTargetTemperatureImpl
|
|
82
82
|
|