opentrons 8.1.0__py2.py3-none-any.whl → 8.2.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.
- opentrons/cli/analyze.py +71 -7
- opentrons/config/__init__.py +9 -0
- opentrons/config/advanced_settings.py +22 -0
- opentrons/config/defaults_ot3.py +14 -36
- opentrons/config/feature_flags.py +4 -0
- opentrons/config/types.py +6 -17
- opentrons/drivers/absorbance_reader/abstract.py +27 -3
- opentrons/drivers/absorbance_reader/async_byonoy.py +208 -154
- opentrons/drivers/absorbance_reader/driver.py +24 -15
- opentrons/drivers/absorbance_reader/hid_protocol.py +79 -50
- opentrons/drivers/absorbance_reader/simulator.py +32 -6
- opentrons/drivers/types.py +23 -1
- opentrons/execute.py +2 -2
- opentrons/hardware_control/api.py +18 -10
- opentrons/hardware_control/backends/controller.py +3 -2
- opentrons/hardware_control/backends/flex_protocol.py +11 -5
- opentrons/hardware_control/backends/ot3controller.py +18 -50
- opentrons/hardware_control/backends/ot3simulator.py +7 -6
- opentrons/hardware_control/backends/ot3utils.py +1 -0
- opentrons/hardware_control/instruments/ot2/pipette_handler.py +22 -82
- opentrons/hardware_control/instruments/ot3/pipette_handler.py +10 -2
- opentrons/hardware_control/module_control.py +43 -2
- opentrons/hardware_control/modules/__init__.py +7 -1
- opentrons/hardware_control/modules/absorbance_reader.py +232 -83
- opentrons/hardware_control/modules/errors.py +7 -0
- opentrons/hardware_control/modules/heater_shaker.py +8 -3
- opentrons/hardware_control/modules/magdeck.py +12 -3
- opentrons/hardware_control/modules/mod_abc.py +27 -2
- opentrons/hardware_control/modules/tempdeck.py +15 -7
- opentrons/hardware_control/modules/thermocycler.py +69 -3
- opentrons/hardware_control/modules/types.py +11 -5
- opentrons/hardware_control/modules/update.py +11 -5
- opentrons/hardware_control/modules/utils.py +3 -1
- opentrons/hardware_control/ot3_calibration.py +6 -6
- opentrons/hardware_control/ot3api.py +131 -94
- opentrons/hardware_control/poller.py +15 -11
- opentrons/hardware_control/protocols/__init__.py +1 -7
- opentrons/hardware_control/protocols/instrument_configurer.py +14 -2
- opentrons/hardware_control/protocols/liquid_handler.py +5 -0
- opentrons/hardware_control/protocols/position_estimator.py +3 -1
- opentrons/hardware_control/types.py +2 -0
- opentrons/legacy_commands/helpers.py +8 -2
- opentrons/motion_planning/__init__.py +2 -0
- opentrons/motion_planning/waypoints.py +32 -0
- opentrons/protocol_api/__init__.py +2 -1
- opentrons/protocol_api/_liquid.py +87 -1
- opentrons/protocol_api/_parameter_context.py +10 -1
- opentrons/protocol_api/core/engine/deck_conflict.py +0 -297
- opentrons/protocol_api/core/engine/instrument.py +29 -25
- opentrons/protocol_api/core/engine/labware.py +20 -4
- opentrons/protocol_api/core/engine/module_core.py +166 -17
- opentrons/protocol_api/core/engine/pipette_movement_conflict.py +362 -0
- opentrons/protocol_api/core/engine/protocol.py +30 -2
- opentrons/protocol_api/core/instrument.py +2 -0
- opentrons/protocol_api/core/labware.py +4 -0
- opentrons/protocol_api/core/legacy/legacy_instrument_core.py +2 -0
- opentrons/protocol_api/core/legacy/legacy_labware_core.py +5 -0
- opentrons/protocol_api/core/legacy/legacy_protocol_core.py +6 -2
- opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py +2 -0
- opentrons/protocol_api/core/module.py +22 -4
- opentrons/protocol_api/core/protocol.py +6 -2
- opentrons/protocol_api/instrument_context.py +52 -20
- opentrons/protocol_api/labware.py +13 -1
- opentrons/protocol_api/module_contexts.py +115 -17
- opentrons/protocol_api/protocol_context.py +49 -5
- opentrons/protocol_api/validation.py +5 -3
- opentrons/protocol_engine/__init__.py +10 -9
- opentrons/protocol_engine/actions/__init__.py +3 -0
- opentrons/protocol_engine/actions/actions.py +30 -25
- opentrons/protocol_engine/actions/get_state_update.py +38 -0
- opentrons/protocol_engine/clients/sync_client.py +1 -1
- opentrons/protocol_engine/clients/transports.py +1 -1
- opentrons/protocol_engine/commands/__init__.py +0 -4
- opentrons/protocol_engine/commands/absorbance_reader/__init__.py +41 -11
- opentrons/protocol_engine/commands/absorbance_reader/close_lid.py +148 -0
- opentrons/protocol_engine/commands/absorbance_reader/initialize.py +65 -9
- opentrons/protocol_engine/commands/absorbance_reader/open_lid.py +148 -0
- opentrons/protocol_engine/commands/absorbance_reader/read.py +200 -0
- opentrons/protocol_engine/commands/aspirate.py +29 -16
- opentrons/protocol_engine/commands/aspirate_in_place.py +33 -16
- opentrons/protocol_engine/commands/blow_out.py +63 -14
- opentrons/protocol_engine/commands/blow_out_in_place.py +55 -13
- opentrons/protocol_engine/commands/calibration/calibrate_gripper.py +2 -5
- opentrons/protocol_engine/commands/calibration/calibrate_module.py +3 -4
- opentrons/protocol_engine/commands/calibration/calibrate_pipette.py +2 -5
- opentrons/protocol_engine/commands/calibration/move_to_maintenance_position.py +6 -4
- opentrons/protocol_engine/commands/command.py +31 -18
- opentrons/protocol_engine/commands/command_unions.py +37 -24
- opentrons/protocol_engine/commands/comment.py +5 -3
- opentrons/protocol_engine/commands/configure_for_volume.py +11 -14
- opentrons/protocol_engine/commands/configure_nozzle_layout.py +9 -15
- opentrons/protocol_engine/commands/custom.py +5 -3
- opentrons/protocol_engine/commands/dispense.py +42 -20
- opentrons/protocol_engine/commands/dispense_in_place.py +32 -14
- opentrons/protocol_engine/commands/drop_tip.py +70 -16
- opentrons/protocol_engine/commands/drop_tip_in_place.py +59 -13
- opentrons/protocol_engine/commands/get_tip_presence.py +5 -3
- opentrons/protocol_engine/commands/heater_shaker/close_labware_latch.py +6 -6
- opentrons/protocol_engine/commands/heater_shaker/deactivate_heater.py +6 -6
- opentrons/protocol_engine/commands/heater_shaker/deactivate_shaker.py +6 -6
- opentrons/protocol_engine/commands/heater_shaker/open_labware_latch.py +8 -6
- opentrons/protocol_engine/commands/heater_shaker/set_and_wait_for_shake_speed.py +8 -4
- opentrons/protocol_engine/commands/heater_shaker/set_target_temperature.py +6 -4
- opentrons/protocol_engine/commands/heater_shaker/wait_for_temperature.py +6 -6
- opentrons/protocol_engine/commands/home.py +11 -5
- opentrons/protocol_engine/commands/liquid_probe.py +146 -88
- opentrons/protocol_engine/commands/load_labware.py +28 -5
- opentrons/protocol_engine/commands/load_liquid.py +18 -7
- opentrons/protocol_engine/commands/load_module.py +4 -6
- opentrons/protocol_engine/commands/load_pipette.py +18 -17
- opentrons/protocol_engine/commands/magnetic_module/disengage.py +6 -6
- opentrons/protocol_engine/commands/magnetic_module/engage.py +6 -4
- opentrons/protocol_engine/commands/move_labware.py +155 -23
- opentrons/protocol_engine/commands/move_relative.py +15 -3
- opentrons/protocol_engine/commands/move_to_addressable_area.py +29 -4
- opentrons/protocol_engine/commands/move_to_addressable_area_for_drop_tip.py +13 -4
- opentrons/protocol_engine/commands/move_to_coordinates.py +11 -5
- opentrons/protocol_engine/commands/move_to_well.py +37 -10
- opentrons/protocol_engine/commands/pick_up_tip.py +51 -30
- opentrons/protocol_engine/commands/pipetting_common.py +47 -16
- opentrons/protocol_engine/commands/prepare_to_aspirate.py +62 -15
- opentrons/protocol_engine/commands/reload_labware.py +13 -4
- opentrons/protocol_engine/commands/retract_axis.py +6 -3
- opentrons/protocol_engine/commands/save_position.py +2 -3
- opentrons/protocol_engine/commands/set_rail_lights.py +5 -3
- opentrons/protocol_engine/commands/set_status_bar.py +5 -3
- opentrons/protocol_engine/commands/temperature_module/deactivate.py +6 -4
- opentrons/protocol_engine/commands/temperature_module/set_target_temperature.py +3 -4
- opentrons/protocol_engine/commands/temperature_module/wait_for_temperature.py +6 -6
- opentrons/protocol_engine/commands/thermocycler/__init__.py +19 -0
- opentrons/protocol_engine/commands/thermocycler/close_lid.py +8 -8
- opentrons/protocol_engine/commands/thermocycler/deactivate_block.py +6 -4
- opentrons/protocol_engine/commands/thermocycler/deactivate_lid.py +6 -4
- opentrons/protocol_engine/commands/thermocycler/open_lid.py +8 -4
- opentrons/protocol_engine/commands/thermocycler/run_extended_profile.py +165 -0
- opentrons/protocol_engine/commands/thermocycler/run_profile.py +6 -6
- opentrons/protocol_engine/commands/thermocycler/set_target_block_temperature.py +3 -4
- opentrons/protocol_engine/commands/thermocycler/set_target_lid_temperature.py +3 -4
- opentrons/protocol_engine/commands/thermocycler/wait_for_block_temperature.py +6 -4
- opentrons/protocol_engine/commands/thermocycler/wait_for_lid_temperature.py +6 -4
- opentrons/protocol_engine/commands/touch_tip.py +19 -7
- opentrons/protocol_engine/commands/unsafe/__init__.py +30 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_blow_out_in_place.py +6 -4
- opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py +12 -4
- opentrons/protocol_engine/commands/unsafe/unsafe_engage_axes.py +5 -3
- opentrons/protocol_engine/commands/unsafe/unsafe_place_labware.py +208 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_ungrip_labware.py +77 -0
- opentrons/protocol_engine/commands/unsafe/update_position_estimators.py +10 -4
- opentrons/protocol_engine/commands/verify_tip_presence.py +5 -5
- opentrons/protocol_engine/commands/wait_for_duration.py +5 -3
- opentrons/protocol_engine/commands/wait_for_resume.py +5 -3
- opentrons/protocol_engine/create_protocol_engine.py +60 -10
- opentrons/protocol_engine/engine_support.py +2 -1
- opentrons/protocol_engine/error_recovery_policy.py +14 -3
- opentrons/protocol_engine/errors/__init__.py +20 -0
- opentrons/protocol_engine/errors/error_occurrence.py +8 -3
- opentrons/protocol_engine/errors/exceptions.py +127 -2
- opentrons/protocol_engine/execution/__init__.py +2 -0
- opentrons/protocol_engine/execution/command_executor.py +22 -13
- opentrons/protocol_engine/execution/create_queue_worker.py +5 -1
- opentrons/protocol_engine/execution/door_watcher.py +1 -1
- opentrons/protocol_engine/execution/equipment.py +2 -1
- opentrons/protocol_engine/execution/error_recovery_hardware_state_synchronizer.py +101 -0
- opentrons/protocol_engine/execution/gantry_mover.py +4 -2
- opentrons/protocol_engine/execution/hardware_stopper.py +3 -3
- opentrons/protocol_engine/execution/heater_shaker_movement_flagger.py +1 -4
- opentrons/protocol_engine/execution/labware_movement.py +73 -22
- opentrons/protocol_engine/execution/movement.py +17 -7
- opentrons/protocol_engine/execution/pipetting.py +7 -4
- opentrons/protocol_engine/execution/queue_worker.py +6 -2
- opentrons/protocol_engine/execution/run_control.py +1 -1
- opentrons/protocol_engine/execution/thermocycler_movement_flagger.py +1 -1
- opentrons/protocol_engine/execution/thermocycler_plate_lifter.py +2 -1
- opentrons/protocol_engine/execution/tip_handler.py +77 -43
- opentrons/protocol_engine/notes/__init__.py +14 -2
- opentrons/protocol_engine/notes/notes.py +18 -1
- opentrons/protocol_engine/plugins.py +1 -1
- opentrons/protocol_engine/protocol_engine.py +47 -31
- opentrons/protocol_engine/resources/__init__.py +2 -0
- opentrons/protocol_engine/resources/deck_data_provider.py +19 -5
- opentrons/protocol_engine/resources/file_provider.py +161 -0
- opentrons/protocol_engine/resources/fixture_validation.py +11 -1
- opentrons/protocol_engine/resources/labware_validation.py +10 -0
- opentrons/protocol_engine/state/__init__.py +0 -70
- opentrons/protocol_engine/state/addressable_areas.py +1 -1
- opentrons/protocol_engine/state/command_history.py +21 -2
- opentrons/protocol_engine/state/commands.py +110 -31
- opentrons/protocol_engine/state/files.py +59 -0
- opentrons/protocol_engine/state/frustum_helpers.py +440 -0
- opentrons/protocol_engine/state/geometry.py +445 -59
- opentrons/protocol_engine/state/labware.py +264 -84
- opentrons/protocol_engine/state/liquids.py +1 -1
- opentrons/protocol_engine/state/module_substates/absorbance_reader_substate.py +21 -3
- opentrons/protocol_engine/state/modules.py +145 -90
- opentrons/protocol_engine/state/motion.py +33 -14
- opentrons/protocol_engine/state/pipettes.py +157 -317
- opentrons/protocol_engine/state/state.py +30 -1
- opentrons/protocol_engine/state/state_summary.py +3 -0
- opentrons/protocol_engine/state/tips.py +69 -114
- opentrons/protocol_engine/state/update_types.py +424 -0
- opentrons/protocol_engine/state/wells.py +236 -0
- opentrons/protocol_engine/types.py +90 -0
- opentrons/protocol_reader/file_format_validator.py +83 -15
- opentrons/protocol_runner/json_translator.py +21 -5
- opentrons/protocol_runner/legacy_command_mapper.py +27 -6
- opentrons/protocol_runner/legacy_context_plugin.py +27 -71
- opentrons/protocol_runner/protocol_runner.py +6 -3
- opentrons/protocol_runner/run_orchestrator.py +41 -6
- opentrons/protocols/advanced_control/mix.py +3 -5
- opentrons/protocols/advanced_control/transfers.py +125 -56
- opentrons/protocols/api_support/constants.py +1 -1
- opentrons/protocols/api_support/definitions.py +1 -1
- opentrons/protocols/api_support/labware_like.py +4 -4
- opentrons/protocols/api_support/tip_tracker.py +2 -2
- opentrons/protocols/api_support/types.py +15 -2
- opentrons/protocols/api_support/util.py +30 -42
- opentrons/protocols/duration/errors.py +1 -1
- opentrons/protocols/duration/estimator.py +50 -29
- opentrons/protocols/execution/dev_types.py +2 -2
- opentrons/protocols/execution/execute_json_v4.py +15 -10
- opentrons/protocols/execution/execute_python.py +8 -3
- opentrons/protocols/geometry/planning.py +12 -12
- opentrons/protocols/labware.py +17 -33
- opentrons/protocols/parameters/csv_parameter_interface.py +3 -1
- opentrons/simulate.py +3 -3
- opentrons/types.py +30 -3
- opentrons/util/logging_config.py +34 -0
- {opentrons-8.1.0.dist-info → opentrons-8.2.0.dist-info}/METADATA +5 -4
- {opentrons-8.1.0.dist-info → opentrons-8.2.0.dist-info}/RECORD +235 -223
- opentrons/protocol_engine/commands/absorbance_reader/measure.py +0 -94
- opentrons/protocol_engine/commands/configuring_common.py +0 -26
- opentrons/protocol_runner/thread_async_queue.py +0 -174
- /opentrons/protocol_engine/state/{abstract_store.py → _abstract_store.py} +0 -0
- /opentrons/protocol_engine/state/{move_types.py → _move_types.py} +0 -0
- {opentrons-8.1.0.dist-info → opentrons-8.2.0.dist-info}/LICENSE +0 -0
- {opentrons-8.1.0.dist-info → opentrons-8.2.0.dist-info}/WHEEL +0 -0
- {opentrons-8.1.0.dist-info → opentrons-8.2.0.dist-info}/entry_points.txt +0 -0
- {opentrons-8.1.0.dist-info → opentrons-8.2.0.dist-info}/top_level.txt +0 -0
|
@@ -7,10 +7,11 @@ from pydantic import BaseModel, Field
|
|
|
7
7
|
|
|
8
8
|
from ..command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, SuccessData
|
|
9
9
|
from ...errors.error_occurrence import ErrorOccurrence
|
|
10
|
+
from ...state import update_types
|
|
10
11
|
from opentrons.protocol_engine.types import MotorAxis
|
|
11
12
|
|
|
12
13
|
if TYPE_CHECKING:
|
|
13
|
-
from opentrons.protocol_engine.state import StateView
|
|
14
|
+
from opentrons.protocol_engine.state.state import StateView
|
|
14
15
|
from opentrons.protocol_engine.execution import EquipmentHandler, MovementHandler
|
|
15
16
|
|
|
16
17
|
|
|
@@ -27,9 +28,7 @@ class CloseLidResult(BaseModel):
|
|
|
27
28
|
"""Result data from closing a Thermocycler's lid."""
|
|
28
29
|
|
|
29
30
|
|
|
30
|
-
class CloseLidImpl(
|
|
31
|
-
AbstractCommandImpl[CloseLidParams, SuccessData[CloseLidResult, None]]
|
|
32
|
-
):
|
|
31
|
+
class CloseLidImpl(AbstractCommandImpl[CloseLidParams, SuccessData[CloseLidResult]]):
|
|
33
32
|
"""Execution implementation of a Thermocycler's close lid command."""
|
|
34
33
|
|
|
35
34
|
def __init__(
|
|
@@ -43,10 +42,10 @@ class CloseLidImpl(
|
|
|
43
42
|
self._equipment = equipment
|
|
44
43
|
self._movement = movement
|
|
45
44
|
|
|
46
|
-
async def execute(
|
|
47
|
-
self, params: CloseLidParams
|
|
48
|
-
) -> SuccessData[CloseLidResult, None]:
|
|
45
|
+
async def execute(self, params: CloseLidParams) -> SuccessData[CloseLidResult]:
|
|
49
46
|
"""Close a Thermocycler's lid."""
|
|
47
|
+
state_update = update_types.StateUpdate()
|
|
48
|
+
|
|
50
49
|
thermocycler_state = self._state_view.modules.get_thermocycler_module_substate(
|
|
51
50
|
params.moduleId
|
|
52
51
|
)
|
|
@@ -61,11 +60,12 @@ class CloseLidImpl(
|
|
|
61
60
|
MotorAxis.Y,
|
|
62
61
|
] + self._state_view.motion.get_robot_mount_axes()
|
|
63
62
|
await self._movement.home(axes=axes_to_home)
|
|
63
|
+
state_update.clear_all_pipette_locations()
|
|
64
64
|
|
|
65
65
|
if thermocycler_hardware is not None:
|
|
66
66
|
await thermocycler_hardware.close()
|
|
67
67
|
|
|
68
|
-
return SuccessData(public=CloseLidResult(),
|
|
68
|
+
return SuccessData(public=CloseLidResult(), state_update=state_update)
|
|
69
69
|
|
|
70
70
|
|
|
71
71
|
class CloseLid(BaseCommand[CloseLidParams, CloseLidResult, ErrorOccurrence]):
|
|
@@ -9,7 +9,7 @@ from ..command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, Succe
|
|
|
9
9
|
from ...errors.error_occurrence import ErrorOccurrence
|
|
10
10
|
|
|
11
11
|
if TYPE_CHECKING:
|
|
12
|
-
from opentrons.protocol_engine.state import StateView
|
|
12
|
+
from opentrons.protocol_engine.state.state import StateView
|
|
13
13
|
from opentrons.protocol_engine.execution import EquipmentHandler
|
|
14
14
|
|
|
15
15
|
|
|
@@ -27,7 +27,7 @@ class DeactivateBlockResult(BaseModel):
|
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
class DeactivateBlockImpl(
|
|
30
|
-
AbstractCommandImpl[DeactivateBlockParams, SuccessData[DeactivateBlockResult
|
|
30
|
+
AbstractCommandImpl[DeactivateBlockParams, SuccessData[DeactivateBlockResult]]
|
|
31
31
|
):
|
|
32
32
|
"""Execution implementation of a Thermocycler's deactivate block command."""
|
|
33
33
|
|
|
@@ -42,7 +42,7 @@ class DeactivateBlockImpl(
|
|
|
42
42
|
|
|
43
43
|
async def execute(
|
|
44
44
|
self, params: DeactivateBlockParams
|
|
45
|
-
) -> SuccessData[DeactivateBlockResult
|
|
45
|
+
) -> SuccessData[DeactivateBlockResult]:
|
|
46
46
|
"""Unset a Thermocycler's target block temperature."""
|
|
47
47
|
thermocycler_state = self._state_view.modules.get_thermocycler_module_substate(
|
|
48
48
|
params.moduleId
|
|
@@ -54,7 +54,9 @@ class DeactivateBlockImpl(
|
|
|
54
54
|
if thermocycler_hardware is not None:
|
|
55
55
|
await thermocycler_hardware.deactivate_block()
|
|
56
56
|
|
|
57
|
-
return SuccessData(
|
|
57
|
+
return SuccessData(
|
|
58
|
+
public=DeactivateBlockResult(),
|
|
59
|
+
)
|
|
58
60
|
|
|
59
61
|
|
|
60
62
|
class DeactivateBlock(
|
|
@@ -9,7 +9,7 @@ from ..command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, Succe
|
|
|
9
9
|
from ...errors.error_occurrence import ErrorOccurrence
|
|
10
10
|
|
|
11
11
|
if TYPE_CHECKING:
|
|
12
|
-
from opentrons.protocol_engine.state import StateView
|
|
12
|
+
from opentrons.protocol_engine.state.state import StateView
|
|
13
13
|
from opentrons.protocol_engine.execution import EquipmentHandler
|
|
14
14
|
|
|
15
15
|
|
|
@@ -27,7 +27,7 @@ class DeactivateLidResult(BaseModel):
|
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
class DeactivateLidImpl(
|
|
30
|
-
AbstractCommandImpl[DeactivateLidParams, SuccessData[DeactivateLidResult
|
|
30
|
+
AbstractCommandImpl[DeactivateLidParams, SuccessData[DeactivateLidResult]]
|
|
31
31
|
):
|
|
32
32
|
"""Execution implementation of a Thermocycler's deactivate lid command."""
|
|
33
33
|
|
|
@@ -42,7 +42,7 @@ class DeactivateLidImpl(
|
|
|
42
42
|
|
|
43
43
|
async def execute(
|
|
44
44
|
self, params: DeactivateLidParams
|
|
45
|
-
) -> SuccessData[DeactivateLidResult
|
|
45
|
+
) -> SuccessData[DeactivateLidResult]:
|
|
46
46
|
"""Unset a Thermocycler's target lid temperature."""
|
|
47
47
|
thermocycler_state = self._state_view.modules.get_thermocycler_module_substate(
|
|
48
48
|
params.moduleId
|
|
@@ -54,7 +54,9 @@ class DeactivateLidImpl(
|
|
|
54
54
|
if thermocycler_hardware is not None:
|
|
55
55
|
await thermocycler_hardware.deactivate_lid()
|
|
56
56
|
|
|
57
|
-
return SuccessData(
|
|
57
|
+
return SuccessData(
|
|
58
|
+
public=DeactivateLidResult(),
|
|
59
|
+
)
|
|
58
60
|
|
|
59
61
|
|
|
60
62
|
class DeactivateLid(
|
|
@@ -6,11 +6,12 @@ from typing_extensions import Literal, Type
|
|
|
6
6
|
from pydantic import BaseModel, Field
|
|
7
7
|
|
|
8
8
|
from ..command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, SuccessData
|
|
9
|
+
from ...state import update_types
|
|
9
10
|
from ...errors.error_occurrence import ErrorOccurrence
|
|
10
11
|
from opentrons.protocol_engine.types import MotorAxis
|
|
11
12
|
|
|
12
13
|
if TYPE_CHECKING:
|
|
13
|
-
from opentrons.protocol_engine.state import StateView
|
|
14
|
+
from opentrons.protocol_engine.state.state import StateView
|
|
14
15
|
from opentrons.protocol_engine.execution import EquipmentHandler, MovementHandler
|
|
15
16
|
|
|
16
17
|
|
|
@@ -27,7 +28,7 @@ class OpenLidResult(BaseModel):
|
|
|
27
28
|
"""Result data from opening a Thermocycler's lid."""
|
|
28
29
|
|
|
29
30
|
|
|
30
|
-
class OpenLidImpl(AbstractCommandImpl[OpenLidParams, SuccessData[OpenLidResult
|
|
31
|
+
class OpenLidImpl(AbstractCommandImpl[OpenLidParams, SuccessData[OpenLidResult]]):
|
|
31
32
|
"""Execution implementation of a Thermocycler's open lid command."""
|
|
32
33
|
|
|
33
34
|
def __init__(
|
|
@@ -41,8 +42,10 @@ class OpenLidImpl(AbstractCommandImpl[OpenLidParams, SuccessData[OpenLidResult,
|
|
|
41
42
|
self._equipment = equipment
|
|
42
43
|
self._movement = movement
|
|
43
44
|
|
|
44
|
-
async def execute(self, params: OpenLidParams) -> SuccessData[OpenLidResult
|
|
45
|
+
async def execute(self, params: OpenLidParams) -> SuccessData[OpenLidResult]:
|
|
45
46
|
"""Open a Thermocycler's lid."""
|
|
47
|
+
state_update = update_types.StateUpdate()
|
|
48
|
+
|
|
46
49
|
thermocycler_state = self._state_view.modules.get_thermocycler_module_substate(
|
|
47
50
|
params.moduleId
|
|
48
51
|
)
|
|
@@ -57,11 +60,12 @@ class OpenLidImpl(AbstractCommandImpl[OpenLidParams, SuccessData[OpenLidResult,
|
|
|
57
60
|
MotorAxis.Y,
|
|
58
61
|
] + self._state_view.motion.get_robot_mount_axes()
|
|
59
62
|
await self._movement.home(axes=axes_to_home)
|
|
63
|
+
state_update.clear_all_pipette_locations()
|
|
60
64
|
|
|
61
65
|
if thermocycler_hardware is not None:
|
|
62
66
|
await thermocycler_hardware.open()
|
|
63
67
|
|
|
64
|
-
return SuccessData(public=OpenLidResult(),
|
|
68
|
+
return SuccessData(public=OpenLidResult(), state_update=state_update)
|
|
65
69
|
|
|
66
70
|
|
|
67
71
|
class OpenLid(BaseCommand[OpenLidParams, OpenLidResult, ErrorOccurrence]):
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"""Command models to execute a Thermocycler profile."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
from typing import List, Optional, TYPE_CHECKING, overload, Union
|
|
4
|
+
from typing_extensions import Literal, Type
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel, Field
|
|
7
|
+
|
|
8
|
+
from opentrons.hardware_control.modules.types import ThermocyclerStep, ThermocyclerCycle
|
|
9
|
+
|
|
10
|
+
from ..command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, SuccessData
|
|
11
|
+
from ...errors.error_occurrence import ErrorOccurrence
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from opentrons.protocol_engine.state.state import StateView
|
|
15
|
+
from opentrons.protocol_engine.execution import EquipmentHandler
|
|
16
|
+
from opentrons.protocol_engine.state.module_substates.thermocycler_module_substate import (
|
|
17
|
+
ThermocyclerModuleSubState,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
RunExtendedProfileCommandType = Literal["thermocycler/runExtendedProfile"]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ProfileStep(BaseModel):
|
|
25
|
+
"""An individual step in a Thermocycler extended profile."""
|
|
26
|
+
|
|
27
|
+
celsius: float = Field(..., description="Target temperature in °C.")
|
|
28
|
+
holdSeconds: float = Field(
|
|
29
|
+
..., description="Time to hold target temperature in seconds."
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class ProfileCycle(BaseModel):
|
|
34
|
+
"""An individual cycle in a Thermocycler extended profile."""
|
|
35
|
+
|
|
36
|
+
steps: List[ProfileStep] = Field(..., description="Steps to repeat.")
|
|
37
|
+
repetitions: int = Field(..., description="Number of times to repeat the steps.")
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class RunExtendedProfileParams(BaseModel):
|
|
41
|
+
"""Input parameters for an individual Thermocycler profile step."""
|
|
42
|
+
|
|
43
|
+
moduleId: str = Field(..., description="Unique ID of the Thermocycler.")
|
|
44
|
+
profileElements: List[Union[ProfileStep, ProfileCycle]] = Field(
|
|
45
|
+
...,
|
|
46
|
+
description="Elements of the profile. Each can be either a step or a cycle.",
|
|
47
|
+
)
|
|
48
|
+
blockMaxVolumeUl: Optional[float] = Field(
|
|
49
|
+
None,
|
|
50
|
+
description="Amount of liquid in uL of the most-full well"
|
|
51
|
+
" in labware loaded onto the thermocycler.",
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class RunExtendedProfileResult(BaseModel):
|
|
56
|
+
"""Result data from running a Thermocycler profile."""
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _transform_profile_step(
|
|
60
|
+
step: ProfileStep, thermocycler_state: ThermocyclerModuleSubState
|
|
61
|
+
) -> ThermocyclerStep:
|
|
62
|
+
return ThermocyclerStep(
|
|
63
|
+
temperature=thermocycler_state.validate_target_block_temperature(step.celsius),
|
|
64
|
+
hold_time_seconds=step.holdSeconds,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
@overload
|
|
69
|
+
def _transform_profile_element(
|
|
70
|
+
element: ProfileStep, thermocycler_state: ThermocyclerModuleSubState
|
|
71
|
+
) -> ThermocyclerStep:
|
|
72
|
+
...
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@overload
|
|
76
|
+
def _transform_profile_element(
|
|
77
|
+
element: ProfileCycle, thermocycler_state: ThermocyclerModuleSubState
|
|
78
|
+
) -> ThermocyclerCycle:
|
|
79
|
+
...
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _transform_profile_element(
|
|
83
|
+
element: Union[ProfileStep, ProfileCycle],
|
|
84
|
+
thermocycler_state: ThermocyclerModuleSubState,
|
|
85
|
+
) -> Union[ThermocyclerStep, ThermocyclerCycle]:
|
|
86
|
+
if isinstance(element, ProfileStep):
|
|
87
|
+
return _transform_profile_step(element, thermocycler_state)
|
|
88
|
+
else:
|
|
89
|
+
return ThermocyclerCycle(
|
|
90
|
+
steps=[
|
|
91
|
+
_transform_profile_step(step, thermocycler_state)
|
|
92
|
+
for step in element.steps
|
|
93
|
+
],
|
|
94
|
+
repetitions=element.repetitions,
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class RunExtendedProfileImpl(
|
|
99
|
+
AbstractCommandImpl[RunExtendedProfileParams, SuccessData[RunExtendedProfileResult]]
|
|
100
|
+
):
|
|
101
|
+
"""Execution implementation of a Thermocycler's run profile command."""
|
|
102
|
+
|
|
103
|
+
def __init__(
|
|
104
|
+
self,
|
|
105
|
+
state_view: StateView,
|
|
106
|
+
equipment: EquipmentHandler,
|
|
107
|
+
**unused_dependencies: object,
|
|
108
|
+
) -> None:
|
|
109
|
+
self._state_view = state_view
|
|
110
|
+
self._equipment = equipment
|
|
111
|
+
|
|
112
|
+
async def execute(
|
|
113
|
+
self, params: RunExtendedProfileParams
|
|
114
|
+
) -> SuccessData[RunExtendedProfileResult]:
|
|
115
|
+
"""Run a Thermocycler profile."""
|
|
116
|
+
thermocycler_state = self._state_view.modules.get_thermocycler_module_substate(
|
|
117
|
+
params.moduleId
|
|
118
|
+
)
|
|
119
|
+
thermocycler_hardware = self._equipment.get_module_hardware_api(
|
|
120
|
+
thermocycler_state.module_id
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
profile = [
|
|
124
|
+
_transform_profile_element(element, thermocycler_state)
|
|
125
|
+
for element in params.profileElements
|
|
126
|
+
]
|
|
127
|
+
target_volume: Optional[float]
|
|
128
|
+
if params.blockMaxVolumeUl is not None:
|
|
129
|
+
target_volume = thermocycler_state.validate_max_block_volume(
|
|
130
|
+
params.blockMaxVolumeUl
|
|
131
|
+
)
|
|
132
|
+
else:
|
|
133
|
+
target_volume = None
|
|
134
|
+
|
|
135
|
+
if thermocycler_hardware is not None:
|
|
136
|
+
# TODO(jbl 2022-06-27) hardcoded constant 1 for `repetitions` should be
|
|
137
|
+
# moved from HardwareControlAPI to the Python ProtocolContext
|
|
138
|
+
await thermocycler_hardware.execute_profile(
|
|
139
|
+
profile=profile, volume=target_volume
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
return SuccessData(
|
|
143
|
+
public=RunExtendedProfileResult(),
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
class RunExtendedProfile(
|
|
148
|
+
BaseCommand[RunExtendedProfileParams, RunExtendedProfileResult, ErrorOccurrence]
|
|
149
|
+
):
|
|
150
|
+
"""A command to execute a Thermocycler profile run."""
|
|
151
|
+
|
|
152
|
+
commandType: RunExtendedProfileCommandType = "thermocycler/runExtendedProfile"
|
|
153
|
+
params: RunExtendedProfileParams
|
|
154
|
+
result: Optional[RunExtendedProfileResult]
|
|
155
|
+
|
|
156
|
+
_ImplementationCls: Type[RunExtendedProfileImpl] = RunExtendedProfileImpl
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class RunExtendedProfileCreate(BaseCommandCreate[RunExtendedProfileParams]):
|
|
160
|
+
"""A request to execute a Thermocycler profile run."""
|
|
161
|
+
|
|
162
|
+
commandType: RunExtendedProfileCommandType = "thermocycler/runExtendedProfile"
|
|
163
|
+
params: RunExtendedProfileParams
|
|
164
|
+
|
|
165
|
+
_CommandCls: Type[RunExtendedProfile] = RunExtendedProfile
|
|
@@ -11,7 +11,7 @@ from ..command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, Succe
|
|
|
11
11
|
from ...errors.error_occurrence import ErrorOccurrence
|
|
12
12
|
|
|
13
13
|
if TYPE_CHECKING:
|
|
14
|
-
from opentrons.protocol_engine.state import StateView
|
|
14
|
+
from opentrons.protocol_engine.state.state import StateView
|
|
15
15
|
from opentrons.protocol_engine.execution import EquipmentHandler
|
|
16
16
|
|
|
17
17
|
|
|
@@ -47,7 +47,7 @@ class RunProfileResult(BaseModel):
|
|
|
47
47
|
|
|
48
48
|
|
|
49
49
|
class RunProfileImpl(
|
|
50
|
-
AbstractCommandImpl[RunProfileParams, SuccessData[RunProfileResult
|
|
50
|
+
AbstractCommandImpl[RunProfileParams, SuccessData[RunProfileResult]]
|
|
51
51
|
):
|
|
52
52
|
"""Execution implementation of a Thermocycler's run profile command."""
|
|
53
53
|
|
|
@@ -60,9 +60,7 @@ class RunProfileImpl(
|
|
|
60
60
|
self._state_view = state_view
|
|
61
61
|
self._equipment = equipment
|
|
62
62
|
|
|
63
|
-
async def execute(
|
|
64
|
-
self, params: RunProfileParams
|
|
65
|
-
) -> SuccessData[RunProfileResult, None]:
|
|
63
|
+
async def execute(self, params: RunProfileParams) -> SuccessData[RunProfileResult]:
|
|
66
64
|
"""Run a Thermocycler profile."""
|
|
67
65
|
thermocycler_state = self._state_view.modules.get_thermocycler_module_substate(
|
|
68
66
|
params.moduleId
|
|
@@ -96,7 +94,9 @@ class RunProfileImpl(
|
|
|
96
94
|
steps=steps, repetitions=1, volume=target_volume
|
|
97
95
|
)
|
|
98
96
|
|
|
99
|
-
return SuccessData(
|
|
97
|
+
return SuccessData(
|
|
98
|
+
public=RunProfileResult(),
|
|
99
|
+
)
|
|
100
100
|
|
|
101
101
|
|
|
102
102
|
class RunProfile(BaseCommand[RunProfileParams, RunProfileResult, ErrorOccurrence]):
|
|
@@ -9,7 +9,7 @@ from ..command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, Succe
|
|
|
9
9
|
from ...errors.error_occurrence import ErrorOccurrence
|
|
10
10
|
|
|
11
11
|
if TYPE_CHECKING:
|
|
12
|
-
from opentrons.protocol_engine.state import StateView
|
|
12
|
+
from opentrons.protocol_engine.state.state import StateView
|
|
13
13
|
from opentrons.protocol_engine.execution import EquipmentHandler
|
|
14
14
|
|
|
15
15
|
|
|
@@ -46,7 +46,7 @@ class SetTargetBlockTemperatureResult(BaseModel):
|
|
|
46
46
|
class SetTargetBlockTemperatureImpl(
|
|
47
47
|
AbstractCommandImpl[
|
|
48
48
|
SetTargetBlockTemperatureParams,
|
|
49
|
-
SuccessData[SetTargetBlockTemperatureResult
|
|
49
|
+
SuccessData[SetTargetBlockTemperatureResult],
|
|
50
50
|
]
|
|
51
51
|
):
|
|
52
52
|
"""Execution implementation of a Thermocycler's set block temperature command."""
|
|
@@ -63,7 +63,7 @@ class SetTargetBlockTemperatureImpl(
|
|
|
63
63
|
async def execute(
|
|
64
64
|
self,
|
|
65
65
|
params: SetTargetBlockTemperatureParams,
|
|
66
|
-
) -> SuccessData[SetTargetBlockTemperatureResult
|
|
66
|
+
) -> SuccessData[SetTargetBlockTemperatureResult]:
|
|
67
67
|
"""Set a Thermocycler's target block temperature."""
|
|
68
68
|
thermocycler_state = self._state_view.modules.get_thermocycler_module_substate(
|
|
69
69
|
params.moduleId
|
|
@@ -97,7 +97,6 @@ class SetTargetBlockTemperatureImpl(
|
|
|
97
97
|
public=SetTargetBlockTemperatureResult(
|
|
98
98
|
targetBlockTemperature=target_temperature
|
|
99
99
|
),
|
|
100
|
-
private=None,
|
|
101
100
|
)
|
|
102
101
|
|
|
103
102
|
|
|
@@ -9,7 +9,7 @@ from ..command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, Succe
|
|
|
9
9
|
from ...errors.error_occurrence import ErrorOccurrence
|
|
10
10
|
|
|
11
11
|
if TYPE_CHECKING:
|
|
12
|
-
from opentrons.protocol_engine.state import StateView
|
|
12
|
+
from opentrons.protocol_engine.state.state import StateView
|
|
13
13
|
from opentrons.protocol_engine.execution import EquipmentHandler
|
|
14
14
|
|
|
15
15
|
|
|
@@ -34,7 +34,7 @@ class SetTargetLidTemperatureResult(BaseModel):
|
|
|
34
34
|
|
|
35
35
|
class SetTargetLidTemperatureImpl(
|
|
36
36
|
AbstractCommandImpl[
|
|
37
|
-
SetTargetLidTemperatureParams, SuccessData[SetTargetLidTemperatureResult
|
|
37
|
+
SetTargetLidTemperatureParams, SuccessData[SetTargetLidTemperatureResult]
|
|
38
38
|
]
|
|
39
39
|
):
|
|
40
40
|
"""Execution implementation of a Thermocycler's set lid temperature command."""
|
|
@@ -51,7 +51,7 @@ class SetTargetLidTemperatureImpl(
|
|
|
51
51
|
async def execute(
|
|
52
52
|
self,
|
|
53
53
|
params: SetTargetLidTemperatureParams,
|
|
54
|
-
) -> SuccessData[SetTargetLidTemperatureResult
|
|
54
|
+
) -> SuccessData[SetTargetLidTemperatureResult]:
|
|
55
55
|
"""Set a Thermocycler's target lid temperature."""
|
|
56
56
|
thermocycler_state = self._state_view.modules.get_thermocycler_module_substate(
|
|
57
57
|
params.moduleId
|
|
@@ -70,7 +70,6 @@ class SetTargetLidTemperatureImpl(
|
|
|
70
70
|
public=SetTargetLidTemperatureResult(
|
|
71
71
|
targetLidTemperature=target_temperature
|
|
72
72
|
),
|
|
73
|
-
private=None,
|
|
74
73
|
)
|
|
75
74
|
|
|
76
75
|
|
|
@@ -9,7 +9,7 @@ from ..command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, Succe
|
|
|
9
9
|
from ...errors.error_occurrence import ErrorOccurrence
|
|
10
10
|
|
|
11
11
|
if TYPE_CHECKING:
|
|
12
|
-
from opentrons.protocol_engine.state import StateView
|
|
12
|
+
from opentrons.protocol_engine.state.state import StateView
|
|
13
13
|
from opentrons.protocol_engine.execution import EquipmentHandler
|
|
14
14
|
|
|
15
15
|
|
|
@@ -28,7 +28,7 @@ class WaitForBlockTemperatureResult(BaseModel):
|
|
|
28
28
|
|
|
29
29
|
class WaitForBlockTemperatureImpl(
|
|
30
30
|
AbstractCommandImpl[
|
|
31
|
-
WaitForBlockTemperatureParams, SuccessData[WaitForBlockTemperatureResult
|
|
31
|
+
WaitForBlockTemperatureParams, SuccessData[WaitForBlockTemperatureResult]
|
|
32
32
|
]
|
|
33
33
|
):
|
|
34
34
|
"""Execution implementation of Thermocycler's wait for block temperature command."""
|
|
@@ -45,7 +45,7 @@ class WaitForBlockTemperatureImpl(
|
|
|
45
45
|
async def execute(
|
|
46
46
|
self,
|
|
47
47
|
params: WaitForBlockTemperatureParams,
|
|
48
|
-
) -> SuccessData[WaitForBlockTemperatureResult
|
|
48
|
+
) -> SuccessData[WaitForBlockTemperatureResult]:
|
|
49
49
|
"""Wait for a Thermocycler's target block temperature."""
|
|
50
50
|
thermocycler_state = self._state_view.modules.get_thermocycler_module_substate(
|
|
51
51
|
params.moduleId
|
|
@@ -61,7 +61,9 @@ class WaitForBlockTemperatureImpl(
|
|
|
61
61
|
if thermocycler_hardware is not None:
|
|
62
62
|
await thermocycler_hardware.wait_for_block_target()
|
|
63
63
|
|
|
64
|
-
return SuccessData(
|
|
64
|
+
return SuccessData(
|
|
65
|
+
public=WaitForBlockTemperatureResult(),
|
|
66
|
+
)
|
|
65
67
|
|
|
66
68
|
|
|
67
69
|
class WaitForBlockTemperature(
|
|
@@ -9,7 +9,7 @@ from ..command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, Succe
|
|
|
9
9
|
from ...errors.error_occurrence import ErrorOccurrence
|
|
10
10
|
|
|
11
11
|
if TYPE_CHECKING:
|
|
12
|
-
from opentrons.protocol_engine.state import StateView
|
|
12
|
+
from opentrons.protocol_engine.state.state import StateView
|
|
13
13
|
from opentrons.protocol_engine.execution import EquipmentHandler
|
|
14
14
|
|
|
15
15
|
|
|
@@ -28,7 +28,7 @@ class WaitForLidTemperatureResult(BaseModel):
|
|
|
28
28
|
|
|
29
29
|
class WaitForLidTemperatureImpl(
|
|
30
30
|
AbstractCommandImpl[
|
|
31
|
-
WaitForLidTemperatureParams, SuccessData[WaitForLidTemperatureResult
|
|
31
|
+
WaitForLidTemperatureParams, SuccessData[WaitForLidTemperatureResult]
|
|
32
32
|
]
|
|
33
33
|
):
|
|
34
34
|
"""Execution implementation of Thermocycler's wait for lid temperature command."""
|
|
@@ -45,7 +45,7 @@ class WaitForLidTemperatureImpl(
|
|
|
45
45
|
async def execute(
|
|
46
46
|
self,
|
|
47
47
|
params: WaitForLidTemperatureParams,
|
|
48
|
-
) -> SuccessData[WaitForLidTemperatureResult
|
|
48
|
+
) -> SuccessData[WaitForLidTemperatureResult]:
|
|
49
49
|
"""Wait for a Thermocycler's lid temperature."""
|
|
50
50
|
thermocycler_state = self._state_view.modules.get_thermocycler_module_substate(
|
|
51
51
|
params.moduleId
|
|
@@ -61,7 +61,9 @@ class WaitForLidTemperatureImpl(
|
|
|
61
61
|
if thermocycler_hardware is not None:
|
|
62
62
|
await thermocycler_hardware.wait_for_lid_target()
|
|
63
63
|
|
|
64
|
-
return SuccessData(
|
|
64
|
+
return SuccessData(
|
|
65
|
+
public=WaitForLidTemperatureResult(),
|
|
66
|
+
)
|
|
65
67
|
|
|
66
68
|
|
|
67
69
|
class WaitForLidTemperature(
|
|
@@ -4,6 +4,8 @@ from pydantic import Field
|
|
|
4
4
|
from typing import TYPE_CHECKING, Optional, Type
|
|
5
5
|
from typing_extensions import Literal
|
|
6
6
|
|
|
7
|
+
from opentrons.protocol_engine.state import update_types
|
|
8
|
+
|
|
7
9
|
from ..errors import TouchTipDisabledError, LabwareIsTipRackError
|
|
8
10
|
from ..types import DeckPoint
|
|
9
11
|
from .command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, SuccessData
|
|
@@ -16,7 +18,7 @@ from .pipetting_common import (
|
|
|
16
18
|
|
|
17
19
|
if TYPE_CHECKING:
|
|
18
20
|
from ..execution import MovementHandler, GantryMover
|
|
19
|
-
from ..state import StateView
|
|
21
|
+
from ..state.state import StateView
|
|
20
22
|
|
|
21
23
|
|
|
22
24
|
TouchTipCommandType = Literal["touchTip"]
|
|
@@ -48,7 +50,7 @@ class TouchTipResult(DestinationPositionResult):
|
|
|
48
50
|
|
|
49
51
|
|
|
50
52
|
class TouchTipImplementation(
|
|
51
|
-
AbstractCommandImpl[TouchTipParams, SuccessData[TouchTipResult
|
|
53
|
+
AbstractCommandImpl[TouchTipParams, SuccessData[TouchTipResult]]
|
|
52
54
|
):
|
|
53
55
|
"""Touch tip command implementation."""
|
|
54
56
|
|
|
@@ -63,14 +65,14 @@ class TouchTipImplementation(
|
|
|
63
65
|
self._movement = movement
|
|
64
66
|
self._gantry_mover = gantry_mover
|
|
65
67
|
|
|
66
|
-
async def execute(
|
|
67
|
-
self, params: TouchTipParams
|
|
68
|
-
) -> SuccessData[TouchTipResult, None]:
|
|
68
|
+
async def execute(self, params: TouchTipParams) -> SuccessData[TouchTipResult]:
|
|
69
69
|
"""Touch tip to sides of a well using the requested pipette."""
|
|
70
70
|
pipette_id = params.pipetteId
|
|
71
71
|
labware_id = params.labwareId
|
|
72
72
|
well_name = params.wellName
|
|
73
73
|
|
|
74
|
+
state_update = update_types.StateUpdate()
|
|
75
|
+
|
|
74
76
|
if self._state_view.labware.get_has_quirk(labware_id, "touchTipDisabled"):
|
|
75
77
|
raise TouchTipDisabledError(
|
|
76
78
|
f"Touch tip not allowed on labware {labware_id}"
|
|
@@ -98,14 +100,24 @@ class TouchTipImplementation(
|
|
|
98
100
|
center_point=center_point,
|
|
99
101
|
)
|
|
100
102
|
|
|
101
|
-
|
|
103
|
+
final_point = await self._gantry_mover.move_to(
|
|
102
104
|
pipette_id=pipette_id,
|
|
103
105
|
waypoints=touch_waypoints,
|
|
104
106
|
speed=touch_speed,
|
|
105
107
|
)
|
|
108
|
+
final_deck_point = DeckPoint.construct(
|
|
109
|
+
x=final_point.x, y=final_point.y, z=final_point.z
|
|
110
|
+
)
|
|
111
|
+
state_update.set_pipette_location(
|
|
112
|
+
pipette_id=pipette_id,
|
|
113
|
+
new_labware_id=labware_id,
|
|
114
|
+
new_well_name=well_name,
|
|
115
|
+
new_deck_point=final_deck_point,
|
|
116
|
+
)
|
|
106
117
|
|
|
107
118
|
return SuccessData(
|
|
108
|
-
public=TouchTipResult(position=
|
|
119
|
+
public=TouchTipResult(position=final_deck_point),
|
|
120
|
+
state_update=state_update,
|
|
109
121
|
)
|
|
110
122
|
|
|
111
123
|
|
|
@@ -31,6 +31,24 @@ from .unsafe_engage_axes import (
|
|
|
31
31
|
UnsafeEngageAxesCreate,
|
|
32
32
|
)
|
|
33
33
|
|
|
34
|
+
from .unsafe_ungrip_labware import (
|
|
35
|
+
UnsafeUngripLabwareCommandType,
|
|
36
|
+
UnsafeUngripLabwareParams,
|
|
37
|
+
UnsafeUngripLabwareResult,
|
|
38
|
+
UnsafeUngripLabware,
|
|
39
|
+
UnsafeUngripLabwareCreate,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
from .unsafe_place_labware import (
|
|
44
|
+
UnsafePlaceLabwareCommandType,
|
|
45
|
+
UnsafePlaceLabwareParams,
|
|
46
|
+
UnsafePlaceLabwareResult,
|
|
47
|
+
UnsafePlaceLabware,
|
|
48
|
+
UnsafePlaceLabwareCreate,
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
34
52
|
__all__ = [
|
|
35
53
|
# Unsafe blow-out-in-place command models
|
|
36
54
|
"UnsafeBlowOutInPlaceCommandType",
|
|
@@ -56,4 +74,16 @@ __all__ = [
|
|
|
56
74
|
"UnsafeEngageAxesResult",
|
|
57
75
|
"UnsafeEngageAxes",
|
|
58
76
|
"UnsafeEngageAxesCreate",
|
|
77
|
+
# Unsafe ungrip labware
|
|
78
|
+
"UnsafeUngripLabwareCommandType",
|
|
79
|
+
"UnsafeUngripLabwareParams",
|
|
80
|
+
"UnsafeUngripLabwareResult",
|
|
81
|
+
"UnsafeUngripLabware",
|
|
82
|
+
"UnsafeUngripLabwareCreate",
|
|
83
|
+
# Unsafe place labware
|
|
84
|
+
"UnsafePlaceLabwareCommandType",
|
|
85
|
+
"UnsafePlaceLabwareParams",
|
|
86
|
+
"UnsafePlaceLabwareResult",
|
|
87
|
+
"UnsafePlaceLabware",
|
|
88
|
+
"UnsafePlaceLabwareCreate",
|
|
59
89
|
]
|
|
@@ -16,7 +16,7 @@ from opentrons.hardware_control.types import Axis
|
|
|
16
16
|
|
|
17
17
|
if TYPE_CHECKING:
|
|
18
18
|
from ...execution import PipettingHandler
|
|
19
|
-
from ...state import StateView
|
|
19
|
+
from ...state.state import StateView
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
UnsafeBlowOutInPlaceCommandType = Literal["unsafe/blowOutInPlace"]
|
|
@@ -36,7 +36,7 @@ class UnsafeBlowOutInPlaceResult(BaseModel):
|
|
|
36
36
|
|
|
37
37
|
class UnsafeBlowOutInPlaceImplementation(
|
|
38
38
|
AbstractCommandImpl[
|
|
39
|
-
UnsafeBlowOutInPlaceParams, SuccessData[UnsafeBlowOutInPlaceResult
|
|
39
|
+
UnsafeBlowOutInPlaceParams, SuccessData[UnsafeBlowOutInPlaceResult]
|
|
40
40
|
]
|
|
41
41
|
):
|
|
42
42
|
"""UnsafeBlowOutInPlace command implementation."""
|
|
@@ -54,7 +54,7 @@ class UnsafeBlowOutInPlaceImplementation(
|
|
|
54
54
|
|
|
55
55
|
async def execute(
|
|
56
56
|
self, params: UnsafeBlowOutInPlaceParams
|
|
57
|
-
) -> SuccessData[UnsafeBlowOutInPlaceResult
|
|
57
|
+
) -> SuccessData[UnsafeBlowOutInPlaceResult]:
|
|
58
58
|
"""Blow-out without moving the pipette even when position is unknown."""
|
|
59
59
|
ot3_hardware_api = ensure_ot3_hardware(self._hardware_api)
|
|
60
60
|
pipette_location = self._state_view.motion.get_pipette_location(
|
|
@@ -67,7 +67,9 @@ class UnsafeBlowOutInPlaceImplementation(
|
|
|
67
67
|
pipette_id=params.pipetteId, flow_rate=params.flowRate
|
|
68
68
|
)
|
|
69
69
|
|
|
70
|
-
return SuccessData(
|
|
70
|
+
return SuccessData(
|
|
71
|
+
public=UnsafeBlowOutInPlaceResult(),
|
|
72
|
+
)
|
|
71
73
|
|
|
72
74
|
|
|
73
75
|
class UnsafeBlowOutInPlace(
|