opentrons 8.7.0a7__py3-none-any.whl → 8.7.0a8__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/_version.py +2 -2
- opentrons/drivers/asyncio/communication/serial_connection.py +55 -129
- opentrons/drivers/flex_stacker/driver.py +6 -1
- opentrons/drivers/heater_shaker/abstract.py +0 -5
- opentrons/drivers/heater_shaker/driver.py +0 -10
- opentrons/drivers/heater_shaker/simulator.py +0 -4
- opentrons/drivers/thermocycler/abstract.py +0 -6
- opentrons/drivers/thermocycler/driver.py +10 -61
- opentrons/drivers/thermocycler/simulator.py +0 -6
- opentrons/hardware_control/api.py +5 -24
- opentrons/hardware_control/backends/controller.py +2 -8
- opentrons/hardware_control/backends/flex_protocol.py +1 -0
- opentrons/hardware_control/backends/ot3controller.py +3 -3
- opentrons/hardware_control/backends/ot3simulator.py +2 -2
- opentrons/hardware_control/backends/simulator.py +1 -2
- opentrons/hardware_control/backends/subsystem_manager.py +2 -5
- opentrons/hardware_control/emulation/abstract_emulator.py +4 -6
- opentrons/hardware_control/emulation/connection_handler.py +5 -8
- opentrons/hardware_control/emulation/heater_shaker.py +3 -12
- opentrons/hardware_control/emulation/settings.py +1 -1
- opentrons/hardware_control/emulation/thermocycler.py +15 -67
- opentrons/hardware_control/module_control.py +8 -82
- opentrons/hardware_control/modules/__init__.py +0 -3
- opentrons/hardware_control/modules/absorbance_reader.py +4 -11
- opentrons/hardware_control/modules/flex_stacker.py +9 -38
- opentrons/hardware_control/modules/heater_shaker.py +5 -42
- opentrons/hardware_control/modules/magdeck.py +4 -8
- opentrons/hardware_control/modules/mod_abc.py +5 -13
- opentrons/hardware_control/modules/tempdeck.py +5 -25
- opentrons/hardware_control/modules/thermocycler.py +11 -68
- opentrons/hardware_control/modules/types.py +1 -20
- opentrons/hardware_control/modules/utils.py +4 -11
- opentrons/hardware_control/nozzle_manager.py +0 -3
- opentrons/hardware_control/ot3api.py +7 -26
- opentrons/hardware_control/poller.py +8 -22
- opentrons/hardware_control/protocols/gripper_controller.py +1 -0
- opentrons/hardware_control/scripts/update_module_fw.py +0 -5
- opentrons/hardware_control/types.py +2 -31
- opentrons/legacy_commands/module_commands.py +0 -23
- opentrons/legacy_commands/protocol_commands.py +0 -20
- opentrons/legacy_commands/types.py +0 -80
- opentrons/motion_planning/deck_conflict.py +12 -17
- opentrons/motion_planning/waypoints.py +29 -15
- opentrons/protocol_api/__init__.py +1 -5
- opentrons/protocol_api/_types.py +1 -6
- opentrons/protocol_api/core/common.py +1 -3
- opentrons/protocol_api/core/engine/_default_labware_versions.py +11 -32
- opentrons/protocol_api/core/engine/labware.py +1 -8
- opentrons/protocol_api/core/engine/module_core.py +8 -75
- opentrons/protocol_api/core/engine/protocol.py +1 -18
- opentrons/protocol_api/core/engine/well.py +0 -8
- opentrons/protocol_api/core/legacy/legacy_module_core.py +4 -24
- opentrons/protocol_api/core/legacy/legacy_protocol_core.py +1 -11
- opentrons/protocol_api/core/legacy/legacy_well_core.py +0 -4
- opentrons/protocol_api/core/legacy_simulator/legacy_protocol_core.py +2 -14
- opentrons/protocol_api/core/module.py +4 -37
- opentrons/protocol_api/core/protocol.py +2 -11
- opentrons/protocol_api/core/well.py +0 -4
- opentrons/protocol_api/labware.py +0 -5
- opentrons/protocol_api/module_contexts.py +11 -117
- opentrons/protocol_api/protocol_context.py +4 -26
- opentrons/protocol_api/robot_context.py +21 -38
- opentrons/protocol_api/validation.py +1 -6
- opentrons/protocol_engine/actions/__init__.py +2 -4
- opentrons/protocol_engine/actions/actions.py +9 -22
- opentrons/protocol_engine/clients/sync_client.py +7 -42
- opentrons/protocol_engine/commands/__init__.py +0 -42
- opentrons/protocol_engine/commands/absorbance_reader/close_lid.py +15 -2
- opentrons/protocol_engine/commands/absorbance_reader/open_lid.py +15 -2
- opentrons/protocol_engine/commands/aspirate.py +0 -1
- opentrons/protocol_engine/commands/command.py +0 -1
- opentrons/protocol_engine/commands/command_unions.py +0 -49
- opentrons/protocol_engine/commands/dispense.py +0 -1
- opentrons/protocol_engine/commands/drop_tip.py +8 -32
- opentrons/protocol_engine/commands/heater_shaker/__init__.py +0 -14
- opentrons/protocol_engine/commands/heater_shaker/set_and_wait_for_shake_speed.py +4 -5
- opentrons/protocol_engine/commands/heater_shaker/set_target_temperature.py +5 -31
- opentrons/protocol_engine/commands/movement_common.py +0 -2
- opentrons/protocol_engine/commands/pick_up_tip.py +11 -21
- opentrons/protocol_engine/commands/temperature_module/set_target_temperature.py +7 -38
- opentrons/protocol_engine/commands/thermocycler/__init__.py +0 -16
- opentrons/protocol_engine/commands/thermocycler/run_extended_profile.py +0 -6
- opentrons/protocol_engine/commands/thermocycler/run_profile.py +0 -8
- opentrons/protocol_engine/commands/thermocycler/set_target_block_temperature.py +6 -40
- opentrons/protocol_engine/commands/thermocycler/set_target_lid_temperature.py +5 -29
- opentrons/protocol_engine/commands/touch_tip.py +1 -1
- opentrons/protocol_engine/commands/unsafe/unsafe_place_labware.py +22 -6
- opentrons/protocol_engine/errors/__init__.py +0 -4
- opentrons/protocol_engine/errors/exceptions.py +0 -55
- opentrons/protocol_engine/execution/__init__.py +0 -2
- opentrons/protocol_engine/execution/command_executor.py +0 -8
- opentrons/protocol_engine/execution/create_queue_worker.py +1 -5
- opentrons/protocol_engine/execution/labware_movement.py +21 -10
- opentrons/protocol_engine/execution/movement.py +0 -2
- opentrons/protocol_engine/execution/queue_worker.py +0 -4
- opentrons/protocol_engine/execution/run_control.py +0 -8
- opentrons/protocol_engine/protocol_engine.py +34 -75
- opentrons/protocol_engine/resources/__init__.py +0 -2
- opentrons/protocol_engine/resources/deck_configuration_provider.py +0 -7
- opentrons/protocol_engine/resources/labware_validation.py +6 -10
- opentrons/protocol_engine/state/_labware_origin_math.py +636 -0
- opentrons/protocol_engine/state/_well_math.py +18 -60
- opentrons/protocol_engine/state/addressable_areas.py +0 -2
- opentrons/protocol_engine/state/commands.py +11 -14
- opentrons/protocol_engine/state/geometry.py +374 -213
- opentrons/protocol_engine/state/labware.py +102 -52
- opentrons/protocol_engine/state/module_substates/thermocycler_module_substate.py +0 -37
- opentrons/protocol_engine/state/modules.py +8 -21
- opentrons/protocol_engine/state/motion.py +0 -44
- opentrons/protocol_engine/state/state.py +0 -14
- opentrons/protocol_engine/state/state_summary.py +0 -2
- opentrons/protocol_engine/state/tips.py +258 -177
- opentrons/protocol_engine/state/update_types.py +9 -16
- opentrons/protocol_engine/types/__init__.py +3 -9
- opentrons/protocol_engine/types/deck_configuration.py +1 -5
- opentrons/protocol_engine/types/instrument.py +1 -8
- opentrons/protocol_engine/types/labware.py +13 -1
- opentrons/protocol_engine/types/module.py +0 -10
- opentrons/protocol_engine/types/tip.py +0 -9
- opentrons/protocol_runner/create_simulating_orchestrator.py +2 -29
- opentrons/protocol_runner/run_orchestrator.py +2 -18
- opentrons/protocols/api_support/definitions.py +1 -1
- opentrons/protocols/api_support/types.py +1 -2
- opentrons/simulate.py +15 -48
- opentrons/system/camera.py +1 -1
- {opentrons-8.7.0a7.dist-info → opentrons-8.7.0a8.dist-info}/METADATA +4 -4
- {opentrons-8.7.0a7.dist-info → opentrons-8.7.0a8.dist-info}/RECORD +130 -146
- opentrons/protocol_api/core/engine/tasks.py +0 -48
- opentrons/protocol_api/core/legacy/tasks.py +0 -19
- opentrons/protocol_api/core/legacy_simulator/tasks.py +0 -19
- opentrons/protocol_api/core/tasks.py +0 -31
- opentrons/protocol_api/tasks.py +0 -48
- opentrons/protocol_engine/commands/create_timer.py +0 -83
- opentrons/protocol_engine/commands/heater_shaker/common.py +0 -20
- opentrons/protocol_engine/commands/heater_shaker/set_shake_speed.py +0 -136
- opentrons/protocol_engine/commands/set_tip_state.py +0 -97
- opentrons/protocol_engine/commands/thermocycler/start_run_extended_profile.py +0 -191
- opentrons/protocol_engine/commands/wait_for_tasks.py +0 -98
- opentrons/protocol_engine/execution/task_handler.py +0 -157
- opentrons/protocol_engine/resources/concurrency_provider.py +0 -27
- opentrons/protocol_engine/state/labware_origin_math/errors.py +0 -94
- opentrons/protocol_engine/state/labware_origin_math/stackup_origin_to_labware_origin.py +0 -1331
- opentrons/protocol_engine/state/tasks.py +0 -139
- opentrons/protocol_engine/types/tasks.py +0 -38
- {opentrons-8.7.0a7.dist-info → opentrons-8.7.0a8.dist-info}/WHEEL +0 -0
- {opentrons-8.7.0a7.dist-info → opentrons-8.7.0a8.dist-info}/entry_points.txt +0 -0
- {opentrons-8.7.0a7.dist-info → opentrons-8.7.0a8.dist-info}/licenses/LICENSE +0 -0
|
@@ -14,7 +14,7 @@ from opentrons.protocols.parameters.exceptions import (
|
|
|
14
14
|
RuntimeParameterRequired as RuntimeParameterRequiredError,
|
|
15
15
|
)
|
|
16
16
|
from opentrons.protocols.parameters.csv_parameter_interface import CSVParameter
|
|
17
|
-
|
|
17
|
+
|
|
18
18
|
from .protocol_context import ProtocolContext
|
|
19
19
|
from .deck import Deck
|
|
20
20
|
from .robot_context import RobotContext
|
|
@@ -33,7 +33,6 @@ from .module_contexts import (
|
|
|
33
33
|
from .disposal_locations import TrashBin, WasteChute
|
|
34
34
|
from ._liquid import Liquid, LiquidClass
|
|
35
35
|
from ._types import (
|
|
36
|
-
OffDeckType,
|
|
37
36
|
OFF_DECK,
|
|
38
37
|
PLUNGER_BLOWOUT,
|
|
39
38
|
PLUNGER_TOP,
|
|
@@ -89,7 +88,6 @@ __all__ = [
|
|
|
89
88
|
"ROW",
|
|
90
89
|
"ALL",
|
|
91
90
|
# Deck location types
|
|
92
|
-
"OffDeckType",
|
|
93
91
|
"OFF_DECK",
|
|
94
92
|
# Pipette plunger types
|
|
95
93
|
"PLUNGER_BLOWOUT",
|
|
@@ -101,8 +99,6 @@ __all__ = [
|
|
|
101
99
|
"BLOWOUT_ACTION",
|
|
102
100
|
"RuntimeParameterRequiredError",
|
|
103
101
|
"CSVParameter",
|
|
104
|
-
# Concurrent task types
|
|
105
|
-
"Task",
|
|
106
102
|
# For internal Opentrons use only:
|
|
107
103
|
"create_protocol_context",
|
|
108
104
|
"ProtocolEngineCoreRequiredError",
|
opentrons/protocol_api/_types.py
CHANGED
|
@@ -3,13 +3,8 @@ from typing_extensions import Final
|
|
|
3
3
|
import enum
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# TODO (tz, 5-18-23): think about a better name for it that would also work when we include staging area slots in the type.
|
|
7
7
|
class OffDeckType(enum.Enum):
|
|
8
|
-
"""The type of the :py:obj:`OFF_DECK` constant.
|
|
9
|
-
|
|
10
|
-
Do not use directly, except in type annotations and ``isinstance`` calls.
|
|
11
|
-
"""
|
|
12
|
-
|
|
13
8
|
OFF_DECK = "off-deck"
|
|
14
9
|
|
|
15
10
|
|
|
@@ -16,7 +16,6 @@ from .module import (
|
|
|
16
16
|
from .protocol import AbstractProtocol
|
|
17
17
|
from .well import AbstractWellCore
|
|
18
18
|
from .robot import AbstractRobot
|
|
19
|
-
from .tasks import AbstractTaskCore
|
|
20
19
|
|
|
21
20
|
|
|
22
21
|
WellCore = AbstractWellCore
|
|
@@ -31,5 +30,4 @@ MagneticBlockCore = AbstractMagneticBlockCore[LabwareCore]
|
|
|
31
30
|
AbsorbanceReaderCore = AbstractAbsorbanceReaderCore[LabwareCore]
|
|
32
31
|
FlexStackerCore = AbstractFlexStackerCore[LabwareCore]
|
|
33
32
|
RobotCore = AbstractRobot
|
|
34
|
-
|
|
35
|
-
ProtocolCore = AbstractProtocol[InstrumentCore, LabwareCore, ModuleCore, TaskCore]
|
|
33
|
+
ProtocolCore = AbstractProtocol[InstrumentCore, LabwareCore, ModuleCore]
|
|
@@ -112,37 +112,6 @@ DEFAULT_LABWARE_VERSIONS: DefaultLabwareVersions = {
|
|
|
112
112
|
"thermoscientificnunc_96_wellplate_2000ul": 3,
|
|
113
113
|
"usascientific_96_wellplate_2.4ml_deep": 3,
|
|
114
114
|
},
|
|
115
|
-
APIVersion(2, 27): {
|
|
116
|
-
"agilent_1_reservoir_290ml": 4,
|
|
117
|
-
"axygen_1_reservoir_90ml": 3,
|
|
118
|
-
"biorad_96_wellplate_200ul_pcr": 5,
|
|
119
|
-
"corning_12_wellplate_6.9ml_flat": 5,
|
|
120
|
-
"corning_24_wellplate_3.4ml_flat": 5,
|
|
121
|
-
"corning_384_wellplate_112ul_flat": 5,
|
|
122
|
-
"corning_48_wellplate_1.6ml_flat": 6,
|
|
123
|
-
"corning_6_wellplate_16.8ml_flat": 5,
|
|
124
|
-
"corning_96_wellplate_360ul_flat": 5,
|
|
125
|
-
"nest_12_reservoir_15ml": 3,
|
|
126
|
-
"nest_1_reservoir_195ml": 4,
|
|
127
|
-
"nest_1_reservoir_290ml": 4,
|
|
128
|
-
"nest_96_wellplate_100ul_pcr_full_skirt": 5,
|
|
129
|
-
"nest_96_wellplate_200ul_flat": 5,
|
|
130
|
-
"nest_96_wellplate_2ml_deep": 5,
|
|
131
|
-
"opentrons_10_tuberack_falcon_4x50ml_6x15ml_conical": 3,
|
|
132
|
-
"opentrons_15_tuberack_falcon_15ml_conical": 3,
|
|
133
|
-
"opentrons_24_aluminumblock_nest_0.5ml_screwcap": 4,
|
|
134
|
-
"opentrons_24_aluminumblock_nest_1.5ml_screwcap": 3,
|
|
135
|
-
"opentrons_24_aluminumblock_nest_1.5ml_snapcap": 3,
|
|
136
|
-
"opentrons_24_aluminumblock_nest_2ml_screwcap": 3,
|
|
137
|
-
"opentrons_24_aluminumblock_nest_2ml_snapcap": 3,
|
|
138
|
-
"opentrons_24_tuberack_eppendorf_1.5ml_safelock_snapcap": 3,
|
|
139
|
-
"opentrons_24_tuberack_eppendorf_2ml_safelock_snapcap": 3,
|
|
140
|
-
"opentrons_24_tuberack_nest_0.5ml_screwcap": 4,
|
|
141
|
-
"opentrons_6_tuberack_nest_50ml_conical": 3,
|
|
142
|
-
"opentrons_96_aluminumblock_generic_pcr_strip_200ul": 4,
|
|
143
|
-
"usascientific_12_reservoir_22ml": 4,
|
|
144
|
-
"usascientific_96_wellplate_2.4ml_deep": 4,
|
|
145
|
-
},
|
|
146
115
|
}
|
|
147
116
|
|
|
148
117
|
|
|
@@ -170,7 +139,17 @@ KNOWN_EXCEPTIONS_FOR_TESTS: set[str] = {
|
|
|
170
139
|
"schema3test_flex_tiprack_lid",
|
|
171
140
|
"schema3test_tough_pcr_auto_sealing_lid",
|
|
172
141
|
"schema3test_universal_flat_adapter",
|
|
173
|
-
|
|
142
|
+
# These were supposed to be short-lived drafts as part of of a one-two punch of
|
|
143
|
+
# https://github.com/Opentrons/opentrons/pull/18266 + https://github.com/Opentrons/opentrons/pull/18284,
|
|
144
|
+
# but the second punch took a while. We should merge the second punch after v8.6.0
|
|
145
|
+
# and remove these exceptions as part of that.
|
|
146
|
+
"agilent_1_reservoir_290ml",
|
|
147
|
+
"corning_384_wellplate_112ul_flat",
|
|
148
|
+
"nest_1_reservoir_290ml",
|
|
149
|
+
"opentrons_24_aluminumblock_nest_0.5ml_screwcap",
|
|
150
|
+
"opentrons_24_tuberack_nest_0.5ml_screwcap",
|
|
151
|
+
"opentrons_96_aluminumblock_generic_pcr_strip_200ul",
|
|
152
|
+
"usascientific_12_reservoir_22ml",
|
|
174
153
|
}
|
|
175
154
|
|
|
176
155
|
|
|
@@ -23,7 +23,6 @@ from opentrons.protocol_engine.clients import SyncClient as ProtocolEngineClient
|
|
|
23
23
|
from opentrons.protocol_engine.types import (
|
|
24
24
|
LabwareOffsetCreate,
|
|
25
25
|
LabwareOffsetVector,
|
|
26
|
-
TipRackWellState,
|
|
27
26
|
)
|
|
28
27
|
from opentrons.types import DeckSlotName, NozzleMapInterface, Point, StagingSlotName
|
|
29
28
|
|
|
@@ -166,13 +165,7 @@ class LabwareCore(AbstractLabware[WellCore]):
|
|
|
166
165
|
|
|
167
166
|
def reset_tips(self) -> None:
|
|
168
167
|
if self.is_tip_rack():
|
|
169
|
-
self._engine_client.
|
|
170
|
-
cmd.SetTipStateParams(
|
|
171
|
-
labwareId=self._labware_id,
|
|
172
|
-
wellNames=list(self._definition.wells),
|
|
173
|
-
tipWellState=TipRackWellState.CLEAN,
|
|
174
|
-
)
|
|
175
|
-
)
|
|
168
|
+
self._engine_client.reset_tips(labware_id=self.labware_id)
|
|
176
169
|
else:
|
|
177
170
|
raise TypeError(f"{self.get_display_name()} is not a tip rack.")
|
|
178
171
|
|
|
@@ -51,7 +51,6 @@ from ..module import (
|
|
|
51
51
|
from .exceptions import InvalidMagnetEngageHeightError
|
|
52
52
|
|
|
53
53
|
from .labware import LabwareCore
|
|
54
|
-
from .tasks import EngineTaskCore
|
|
55
54
|
from . import load_labware_params
|
|
56
55
|
|
|
57
56
|
if TYPE_CHECKING:
|
|
@@ -176,17 +175,13 @@ class TemperatureModuleCore(ModuleCore, AbstractTemperatureModuleCore[LabwareCor
|
|
|
176
175
|
|
|
177
176
|
_sync_module_hardware: SynchronousAdapter[hw_modules.TempDeck]
|
|
178
177
|
|
|
179
|
-
def set_target_temperature(self, celsius: float) ->
|
|
178
|
+
def set_target_temperature(self, celsius: float) -> None:
|
|
180
179
|
"""Set the Temperature Module's target temperature in °C."""
|
|
181
|
-
|
|
180
|
+
self._engine_client.execute_command(
|
|
182
181
|
cmd.temperature_module.SetTargetTemperatureParams(
|
|
183
182
|
moduleId=self.module_id, celsius=celsius
|
|
184
183
|
)
|
|
185
184
|
)
|
|
186
|
-
temperature_task = EngineTaskCore(
|
|
187
|
-
engine_client=self._engine_client, task_id=result.taskId
|
|
188
|
-
)
|
|
189
|
-
return temperature_task
|
|
190
185
|
|
|
191
186
|
def wait_for_target_temperature(self, celsius: Optional[float] = None) -> None:
|
|
192
187
|
"""Wait until the module's target temperature is reached.
|
|
@@ -322,24 +317,18 @@ class ThermocyclerModuleCore(ModuleCore, AbstractThermocyclerCore[LabwareCore]):
|
|
|
322
317
|
def set_target_block_temperature(
|
|
323
318
|
self,
|
|
324
319
|
celsius: float,
|
|
325
|
-
ramp_rate: Optional[float],
|
|
326
320
|
hold_time_seconds: Optional[float] = None,
|
|
327
321
|
block_max_volume: Optional[float] = None,
|
|
328
|
-
) ->
|
|
322
|
+
) -> None:
|
|
329
323
|
"""Set the target temperature for the well block, in °C."""
|
|
330
|
-
|
|
324
|
+
self._engine_client.execute_command(
|
|
331
325
|
cmd.thermocycler.SetTargetBlockTemperatureParams(
|
|
332
326
|
moduleId=self.module_id,
|
|
333
327
|
celsius=celsius,
|
|
334
328
|
blockMaxVolumeUl=block_max_volume,
|
|
335
329
|
holdTimeSeconds=hold_time_seconds,
|
|
336
|
-
ramp_rate=ramp_rate,
|
|
337
330
|
)
|
|
338
331
|
)
|
|
339
|
-
block_temperature_task = EngineTaskCore(
|
|
340
|
-
engine_client=self._engine_client, task_id=result.taskId
|
|
341
|
-
)
|
|
342
|
-
return block_temperature_task
|
|
343
332
|
|
|
344
333
|
def wait_for_block_temperature(self) -> None:
|
|
345
334
|
"""Wait for target block temperature to be reached."""
|
|
@@ -347,17 +336,13 @@ class ThermocyclerModuleCore(ModuleCore, AbstractThermocyclerCore[LabwareCore]):
|
|
|
347
336
|
cmd.thermocycler.WaitForBlockTemperatureParams(moduleId=self.module_id)
|
|
348
337
|
)
|
|
349
338
|
|
|
350
|
-
def set_target_lid_temperature(self, celsius: float) ->
|
|
339
|
+
def set_target_lid_temperature(self, celsius: float) -> None:
|
|
351
340
|
"""Set the target temperature for the heated lid, in °C."""
|
|
352
|
-
|
|
341
|
+
self._engine_client.execute_command(
|
|
353
342
|
cmd.thermocycler.SetTargetLidTemperatureParams(
|
|
354
343
|
moduleId=self.module_id, celsius=celsius
|
|
355
344
|
)
|
|
356
345
|
)
|
|
357
|
-
lid_temperature_task = EngineTaskCore(
|
|
358
|
-
engine_client=self._engine_client, task_id=result.taskId
|
|
359
|
-
)
|
|
360
|
-
return lid_temperature_task
|
|
361
346
|
|
|
362
347
|
def wait_for_lid_temperature(self) -> None:
|
|
363
348
|
"""Wait for target lid temperature to be reached."""
|
|
@@ -376,7 +361,6 @@ class ThermocyclerModuleCore(ModuleCore, AbstractThermocyclerCore[LabwareCore]):
|
|
|
376
361
|
cmd.thermocycler.RunProfileStepParams(
|
|
377
362
|
celsius=step["temperature"],
|
|
378
363
|
holdSeconds=step["hold_time_seconds"],
|
|
379
|
-
rampRate=step["ramp_rate"],
|
|
380
364
|
)
|
|
381
365
|
for step in steps
|
|
382
366
|
]
|
|
@@ -405,7 +389,6 @@ class ThermocyclerModuleCore(ModuleCore, AbstractThermocyclerCore[LabwareCore]):
|
|
|
405
389
|
cmd.thermocycler.ProfileStep(
|
|
406
390
|
celsius=step["temperature"],
|
|
407
391
|
holdSeconds=step["hold_time_seconds"],
|
|
408
|
-
rampRate=step["ramp_rate"],
|
|
409
392
|
)
|
|
410
393
|
for step in steps
|
|
411
394
|
],
|
|
@@ -433,42 +416,6 @@ class ThermocyclerModuleCore(ModuleCore, AbstractThermocyclerCore[LabwareCore]):
|
|
|
433
416
|
else:
|
|
434
417
|
return self._execute_profile_pre_221(steps, repetitions, block_max_volume)
|
|
435
418
|
|
|
436
|
-
def start_execute_profile(
|
|
437
|
-
self,
|
|
438
|
-
steps: List[ThermocyclerStep],
|
|
439
|
-
repetitions: int,
|
|
440
|
-
block_max_volume: Optional[float] = None,
|
|
441
|
-
) -> EngineTaskCore:
|
|
442
|
-
"""Start the execution of a hermocycler profile and return a task."""
|
|
443
|
-
self._repetitions = repetitions
|
|
444
|
-
self._step_count = len(steps)
|
|
445
|
-
engine_steps: List[
|
|
446
|
-
Union[cmd.thermocycler.ProfileStep, cmd.thermocycler.ProfileCycle]
|
|
447
|
-
] = [
|
|
448
|
-
cmd.thermocycler.ProfileCycle(
|
|
449
|
-
repetitions=repetitions,
|
|
450
|
-
steps=[
|
|
451
|
-
cmd.thermocycler.ProfileStep(
|
|
452
|
-
celsius=step["temperature"],
|
|
453
|
-
holdSeconds=step["hold_time_seconds"],
|
|
454
|
-
rampRate=step["ramp_rate"],
|
|
455
|
-
)
|
|
456
|
-
for step in steps
|
|
457
|
-
],
|
|
458
|
-
)
|
|
459
|
-
]
|
|
460
|
-
result = self._engine_client.execute_command_without_recovery(
|
|
461
|
-
cmd.thermocycler.StartRunExtendedProfileParams(
|
|
462
|
-
moduleId=self.module_id,
|
|
463
|
-
profileElements=engine_steps,
|
|
464
|
-
blockMaxVolumeUl=block_max_volume,
|
|
465
|
-
)
|
|
466
|
-
)
|
|
467
|
-
start_execute_profile_result = EngineTaskCore(
|
|
468
|
-
engine_client=self._engine_client, task_id=result.taskId
|
|
469
|
-
)
|
|
470
|
-
return start_execute_profile_result
|
|
471
|
-
|
|
472
419
|
def deactivate_lid(self) -> None:
|
|
473
420
|
"""Turn off the heated lid."""
|
|
474
421
|
self._engine_client.execute_command(
|
|
@@ -560,17 +507,13 @@ class HeaterShakerModuleCore(ModuleCore, AbstractHeaterShakerCore[LabwareCore]):
|
|
|
560
507
|
|
|
561
508
|
_sync_module_hardware: SynchronousAdapter[hw_modules.HeaterShaker]
|
|
562
509
|
|
|
563
|
-
def set_target_temperature(self, celsius: float) ->
|
|
510
|
+
def set_target_temperature(self, celsius: float) -> None:
|
|
564
511
|
"""Set the labware plate's target temperature in °C."""
|
|
565
|
-
|
|
512
|
+
self._engine_client.execute_command(
|
|
566
513
|
cmd.heater_shaker.SetTargetTemperatureParams(
|
|
567
514
|
moduleId=self.module_id, celsius=celsius
|
|
568
515
|
)
|
|
569
516
|
)
|
|
570
|
-
temperature_task = EngineTaskCore(
|
|
571
|
-
engine_client=self._engine_client, task_id=result.taskId
|
|
572
|
-
)
|
|
573
|
-
return temperature_task
|
|
574
517
|
|
|
575
518
|
def wait_for_target_temperature(self) -> None:
|
|
576
519
|
"""Wait for the labware plate's target temperature to be reached."""
|
|
@@ -586,16 +529,6 @@ class HeaterShakerModuleCore(ModuleCore, AbstractHeaterShakerCore[LabwareCore]):
|
|
|
586
529
|
)
|
|
587
530
|
)
|
|
588
531
|
|
|
589
|
-
def set_shake_speed(self, rpm: int) -> EngineTaskCore:
|
|
590
|
-
"""Set the shaker's target shake speed and wait for it to spin up."""
|
|
591
|
-
result = self._engine_client.execute_command_without_recovery(
|
|
592
|
-
cmd.heater_shaker.SetShakeSpeedParams(moduleId=self.module_id, rpm=rpm)
|
|
593
|
-
)
|
|
594
|
-
shake_task = EngineTaskCore(
|
|
595
|
-
engine_client=self._engine_client, task_id=result.taskId
|
|
596
|
-
)
|
|
597
|
-
return shake_task
|
|
598
|
-
|
|
599
532
|
def open_labware_latch(self) -> None:
|
|
600
533
|
"""Open the labware latch."""
|
|
601
534
|
self._engine_client.execute_command(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""ProtocolEngine-based Protocol API core implementation."""
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
|
-
from typing import Dict, Optional, Type, Union, List, Tuple, TYPE_CHECKING
|
|
4
|
+
from typing import Dict, Optional, Type, Union, List, Tuple, TYPE_CHECKING
|
|
5
5
|
|
|
6
6
|
from opentrons_shared_data.liquid_classes import LiquidClassDefinitionDoesNotExist
|
|
7
7
|
from opentrons_shared_data.deck.types import DeckDefinitionV5, SlotDefV3
|
|
@@ -64,7 +64,6 @@ from ...disposal_locations import TrashBin, WasteChute
|
|
|
64
64
|
from ..protocol import AbstractProtocol
|
|
65
65
|
from ..labware import LabwareLoadParams
|
|
66
66
|
from .labware import LabwareCore
|
|
67
|
-
from .tasks import EngineTaskCore
|
|
68
67
|
from .instrument import InstrumentCore
|
|
69
68
|
from .robot import RobotCore
|
|
70
69
|
from .module_core import (
|
|
@@ -96,7 +95,6 @@ class ProtocolCore(
|
|
|
96
95
|
InstrumentCore,
|
|
97
96
|
LabwareCore,
|
|
98
97
|
Union[ModuleCore, NonConnectedModuleCore],
|
|
99
|
-
EngineTaskCore,
|
|
100
98
|
]
|
|
101
99
|
):
|
|
102
100
|
"""Protocol API core using a ProtocolEngine.
|
|
@@ -914,21 +912,6 @@ class ProtocolCore(
|
|
|
914
912
|
cmd.WaitForDurationParams(seconds=seconds, message=msg)
|
|
915
913
|
)
|
|
916
914
|
|
|
917
|
-
def wait_for_tasks(self, task_cores: Sequence[EngineTaskCore]) -> None:
|
|
918
|
-
"""Wait for specified tasks to complete."""
|
|
919
|
-
task_ids = task_ids = [task._id for task in task_cores if task._id is not None]
|
|
920
|
-
self._engine_client.execute_command(cmd.WaitForTasksParams(task_ids=task_ids))
|
|
921
|
-
|
|
922
|
-
def create_timer(self, seconds: float) -> EngineTaskCore:
|
|
923
|
-
"""Create a timer task that runs in the background."""
|
|
924
|
-
result = self._engine_client.execute_command_without_recovery(
|
|
925
|
-
cmd.CreateTimerParams(time=seconds)
|
|
926
|
-
)
|
|
927
|
-
timer_task = EngineTaskCore(
|
|
928
|
-
engine_client=self._engine_client, task_id=result.task_id
|
|
929
|
-
)
|
|
930
|
-
return timer_task
|
|
931
|
-
|
|
932
915
|
def home(self) -> None:
|
|
933
916
|
"""Move all axes to their home positions."""
|
|
934
917
|
self._engine_client.execute_command(cmd.HomeParams(axes=None))
|
|
@@ -216,14 +216,6 @@ class WellCore(AbstractWellCore):
|
|
|
216
216
|
labware_id=labware_id, well_name=well_name
|
|
217
217
|
)
|
|
218
218
|
|
|
219
|
-
def has_tracked_liquid(self) -> bool:
|
|
220
|
-
"""Return true if liquid has been loaded or probed."""
|
|
221
|
-
labware_id = self.labware_id
|
|
222
|
-
well_name = self._name
|
|
223
|
-
return self._engine_client.state.geometry.well_has_tracked_liquid(
|
|
224
|
-
labware_id=labware_id, well_name=well_name
|
|
225
|
-
)
|
|
226
|
-
|
|
227
219
|
def get_liquid_volume(self) -> LiquidTrackingType:
|
|
228
220
|
"""Return the current volume in a well."""
|
|
229
221
|
labware_id = self.labware_id
|
|
@@ -31,7 +31,6 @@ from ..module import (
|
|
|
31
31
|
)
|
|
32
32
|
|
|
33
33
|
from .legacy_labware_core import LegacyLabwareCore
|
|
34
|
-
from .tasks import LegacyTaskCore
|
|
35
34
|
from .module_geometry import ModuleGeometry, ThermocyclerGeometry, HeaterShakerGeometry
|
|
36
35
|
from ...labware import Labware
|
|
37
36
|
|
|
@@ -117,10 +116,9 @@ class LegacyTemperatureModuleCore(
|
|
|
117
116
|
|
|
118
117
|
_sync_module_hardware: SynchronousAdapter[hw_modules.TempDeck]
|
|
119
118
|
|
|
120
|
-
def set_target_temperature(self, celsius: float) ->
|
|
119
|
+
def set_target_temperature(self, celsius: float) -> None:
|
|
121
120
|
"""Set the Temperature Module's target temperature in °C."""
|
|
122
121
|
self._sync_module_hardware.start_set_temperature(celsius)
|
|
123
|
-
return LegacyTaskCore()
|
|
124
122
|
|
|
125
123
|
def wait_for_target_temperature(self, celsius: Optional[float] = None) -> None:
|
|
126
124
|
"""Wait until the module's target temperature is reached.
|
|
@@ -265,27 +263,23 @@ class LegacyThermocyclerCore(
|
|
|
265
263
|
def set_target_block_temperature(
|
|
266
264
|
self,
|
|
267
265
|
celsius: float,
|
|
268
|
-
ramp_rate: Optional[float],
|
|
269
266
|
hold_time_seconds: Optional[float] = None,
|
|
270
267
|
block_max_volume: Optional[float] = None,
|
|
271
|
-
) ->
|
|
268
|
+
) -> None:
|
|
272
269
|
"""Set the target temperature for the well block, in °C."""
|
|
273
270
|
self._sync_module_hardware.set_target_block_temperature(
|
|
274
271
|
celsius=celsius,
|
|
275
272
|
hold_time_seconds=hold_time_seconds,
|
|
276
273
|
volume=block_max_volume,
|
|
277
|
-
ramp_rate=ramp_rate,
|
|
278
274
|
)
|
|
279
|
-
return LegacyTaskCore()
|
|
280
275
|
|
|
281
276
|
def wait_for_block_temperature(self) -> None:
|
|
282
277
|
"""Wait for target block temperature to be reached."""
|
|
283
278
|
self._sync_module_hardware.wait_for_block_target()
|
|
284
279
|
|
|
285
|
-
def set_target_lid_temperature(self, celsius: float) ->
|
|
280
|
+
def set_target_lid_temperature(self, celsius: float) -> None:
|
|
286
281
|
"""Set the target temperature for the heated lid, in °C."""
|
|
287
282
|
self._sync_module_hardware.set_target_lid_temperature(celsius=celsius)
|
|
288
|
-
return LegacyTaskCore()
|
|
289
283
|
|
|
290
284
|
def wait_for_lid_temperature(self) -> None:
|
|
291
285
|
"""Wait for target lid temperature to be reached."""
|
|
@@ -302,15 +296,6 @@ class LegacyThermocyclerCore(
|
|
|
302
296
|
steps=steps, repetitions=repetitions, volume=block_max_volume
|
|
303
297
|
)
|
|
304
298
|
|
|
305
|
-
def start_execute_profile(
|
|
306
|
-
self,
|
|
307
|
-
steps: List[ThermocyclerStep],
|
|
308
|
-
repetitions: int,
|
|
309
|
-
block_max_volume: Optional[float] = None,
|
|
310
|
-
) -> LegacyTaskCore:
|
|
311
|
-
"""Start a Thermocycler Profile."""
|
|
312
|
-
assert False, "start_execute_profile only supported on engine core"
|
|
313
|
-
|
|
314
299
|
def deactivate_lid(self) -> None:
|
|
315
300
|
"""Turn off the heated lid."""
|
|
316
301
|
self._sync_module_hardware.deactivate_lid()
|
|
@@ -428,10 +413,9 @@ class LegacyHeaterShakerCore(
|
|
|
428
413
|
_sync_module_hardware: SynchronousAdapter[hw_modules.HeaterShaker]
|
|
429
414
|
_geometry: HeaterShakerGeometry
|
|
430
415
|
|
|
431
|
-
def set_target_temperature(self, celsius: float) ->
|
|
416
|
+
def set_target_temperature(self, celsius: float) -> None:
|
|
432
417
|
"""Set the labware plate's target temperature in °C."""
|
|
433
418
|
self._sync_module_hardware.start_set_temperature(celsius)
|
|
434
|
-
return LegacyTaskCore()
|
|
435
419
|
|
|
436
420
|
def wait_for_target_temperature(self) -> None:
|
|
437
421
|
"""Wait for the labware plate's target temperature to be reached."""
|
|
@@ -458,10 +442,6 @@ class LegacyHeaterShakerCore(
|
|
|
458
442
|
"Cannot start shaking unless labware latch is closed."
|
|
459
443
|
)
|
|
460
444
|
|
|
461
|
-
def set_shake_speed(self, rpm: int) -> LegacyTaskCore:
|
|
462
|
-
"""Set heatershaker speed."""
|
|
463
|
-
assert False, "set_shake_speed only supported on engine core."
|
|
464
|
-
|
|
465
445
|
def open_labware_latch(self) -> None:
|
|
466
446
|
"""Open the labware latch."""
|
|
467
447
|
if self.get_speed_status() != SpeedStatus.IDLE:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import Dict, List, Optional, Set, Union, cast, Tuple
|
|
2
|
+
from typing import Dict, List, Optional, Set, Union, cast, Tuple
|
|
3
3
|
|
|
4
4
|
from opentrons_shared_data.deck.types import DeckDefinitionV5, SlotDefV3
|
|
5
5
|
from opentrons_shared_data.labware.types import LabwareDefinition
|
|
@@ -34,7 +34,6 @@ from .legacy_instrument_core import LegacyInstrumentCore
|
|
|
34
34
|
from .labware_offset_provider import AbstractLabwareOffsetProvider
|
|
35
35
|
from .legacy_labware_core import LegacyLabwareCore
|
|
36
36
|
from .load_info import LoadInfo, InstrumentLoadInfo, LabwareLoadInfo, ModuleLoadInfo
|
|
37
|
-
from .tasks import LegacyTaskCore
|
|
38
37
|
|
|
39
38
|
logger = logging.getLogger(__name__)
|
|
40
39
|
|
|
@@ -44,7 +43,6 @@ class LegacyProtocolCore(
|
|
|
44
43
|
LegacyInstrumentCore,
|
|
45
44
|
LegacyLabwareCore,
|
|
46
45
|
legacy_module_core.LegacyModuleCore,
|
|
47
|
-
LegacyTaskCore,
|
|
48
46
|
]
|
|
49
47
|
):
|
|
50
48
|
def __init__(
|
|
@@ -612,11 +610,3 @@ class LegacyProtocolCore(
|
|
|
612
610
|
]:
|
|
613
611
|
"""Get labware parent location."""
|
|
614
612
|
assert False, "get_labware_location only supported on engine core"
|
|
615
|
-
|
|
616
|
-
def wait_for_tasks(self, task: Sequence[LegacyTaskCore]) -> None:
|
|
617
|
-
"""Wait for list of tasks to complete before executing subsequent commands."""
|
|
618
|
-
assert False, "wait_for_tasks only supported on engine core"
|
|
619
|
-
|
|
620
|
-
def create_timer(self, seconds: float) -> LegacyTaskCore:
|
|
621
|
-
"""Create a timer task that runs in the background."""
|
|
622
|
-
assert False, "create_timer only supported on engine core"
|
|
@@ -151,10 +151,6 @@ class LegacyWellCore(AbstractWellCore):
|
|
|
151
151
|
"""Return the volume contained in a well at any height."""
|
|
152
152
|
return 0.0
|
|
153
153
|
|
|
154
|
-
def has_tracked_liquid(self) -> bool:
|
|
155
|
-
"""Return true if liquid has been loaded or probed."""
|
|
156
|
-
return False
|
|
157
|
-
|
|
158
154
|
# TODO(mc, 2022-10-28): is this used and/or necessary?
|
|
159
155
|
def __repr__(self) -> str:
|
|
160
156
|
"""Use the well's display name as its repr."""
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import Dict, Optional
|
|
2
|
+
from typing import Dict, Optional
|
|
3
3
|
|
|
4
4
|
from opentrons_shared_data.pipette.types import PipetteNameType
|
|
5
5
|
from opentrons_shared_data.pipette.pipette_load_name_conversions import (
|
|
@@ -16,7 +16,6 @@ from ..legacy.legacy_module_core import LegacyModuleCore
|
|
|
16
16
|
from ..legacy.load_info import InstrumentLoadInfo
|
|
17
17
|
|
|
18
18
|
from .legacy_instrument_core import LegacyInstrumentCoreSimulator
|
|
19
|
-
from .tasks import LegacyTaskCore
|
|
20
19
|
|
|
21
20
|
logger = logging.getLogger(__name__)
|
|
22
21
|
|
|
@@ -24,10 +23,7 @@ logger = logging.getLogger(__name__)
|
|
|
24
23
|
class LegacyProtocolCoreSimulator(
|
|
25
24
|
LegacyProtocolCore,
|
|
26
25
|
AbstractProtocol[
|
|
27
|
-
LegacyInstrumentCoreSimulator,
|
|
28
|
-
LegacyLabwareCore,
|
|
29
|
-
LegacyModuleCore,
|
|
30
|
-
LegacyTaskCore,
|
|
26
|
+
LegacyInstrumentCoreSimulator, LegacyLabwareCore, LegacyModuleCore
|
|
31
27
|
],
|
|
32
28
|
):
|
|
33
29
|
_instruments: Dict[Mount, Optional[LegacyInstrumentCoreSimulator]] # type: ignore[assignment]
|
|
@@ -87,11 +83,3 @@ class LegacyProtocolCoreSimulator(
|
|
|
87
83
|
)
|
|
88
84
|
|
|
89
85
|
return new_instr
|
|
90
|
-
|
|
91
|
-
def wait_for_tasks(self, task: Sequence[LegacyTaskCore]) -> None:
|
|
92
|
-
"""Wait for list of tasks to complete before executing subsequent commands."""
|
|
93
|
-
assert False, "wait_for_tasks only supported on engine core"
|
|
94
|
-
|
|
95
|
-
def create_timer(self, seconds: float) -> LegacyTaskCore:
|
|
96
|
-
"""Create a timer task that runs in the background."""
|
|
97
|
-
assert False, "create_timer only supported on engine core"
|
|
@@ -18,7 +18,6 @@ from opentrons.hardware_control.modules.types import (
|
|
|
18
18
|
SpeedStatus,
|
|
19
19
|
)
|
|
20
20
|
from .labware import LabwareCoreType, AbstractLabware
|
|
21
|
-
from .tasks import AbstractTaskCore
|
|
22
21
|
from opentrons.protocol_engine.types import ABSMeasureMode
|
|
23
22
|
from opentrons.types import DeckSlotName
|
|
24
23
|
|
|
@@ -60,7 +59,7 @@ class AbstractTemperatureModuleCore(
|
|
|
60
59
|
"""Get the module's unique hardware serial number."""
|
|
61
60
|
|
|
62
61
|
@abstractmethod
|
|
63
|
-
def set_target_temperature(self, celsius: float) ->
|
|
62
|
+
def set_target_temperature(self, celsius: float) -> None:
|
|
64
63
|
"""Set the Temperature Module's target temperature in °C."""
|
|
65
64
|
|
|
66
65
|
@abstractmethod
|
|
@@ -162,10 +161,9 @@ class AbstractThermocyclerCore(
|
|
|
162
161
|
def set_target_block_temperature(
|
|
163
162
|
self,
|
|
164
163
|
celsius: float,
|
|
165
|
-
ramp_rate: Optional[float],
|
|
166
164
|
hold_time_seconds: Optional[float] = None,
|
|
167
165
|
block_max_volume: Optional[float] = None,
|
|
168
|
-
) ->
|
|
166
|
+
) -> None:
|
|
169
167
|
"""Set the target temperature for the well block, in °C.
|
|
170
168
|
|
|
171
169
|
Note:
|
|
@@ -185,7 +183,7 @@ class AbstractThermocyclerCore(
|
|
|
185
183
|
"""Wait for target block temperature to be reached."""
|
|
186
184
|
|
|
187
185
|
@abstractmethod
|
|
188
|
-
def set_target_lid_temperature(self, celsius: float) ->
|
|
186
|
+
def set_target_lid_temperature(self, celsius: float) -> None:
|
|
189
187
|
"""Set the target temperature for the heated lid, in °C."""
|
|
190
188
|
|
|
191
189
|
@abstractmethod
|
|
@@ -219,33 +217,6 @@ class AbstractThermocyclerCore(
|
|
|
219
217
|
will default to 25µL/well.
|
|
220
218
|
"""
|
|
221
219
|
|
|
222
|
-
@abstractmethod
|
|
223
|
-
def start_execute_profile(
|
|
224
|
-
self,
|
|
225
|
-
steps: List[ThermocyclerStep],
|
|
226
|
-
repetitions: int,
|
|
227
|
-
block_max_volume: Optional[float] = None,
|
|
228
|
-
) -> AbstractTaskCore:
|
|
229
|
-
"""Start a Thermocycler Profile.
|
|
230
|
-
|
|
231
|
-
Profile defined as a cycle of ``steps`` to repeat for a given number of ``repetitions``
|
|
232
|
-
|
|
233
|
-
Note:
|
|
234
|
-
Unlike the :py:meth:`execute_profile`, once the profile has started
|
|
235
|
-
the protocol will immediately move on to the next command, rather than waiting
|
|
236
|
-
for it to finish.
|
|
237
|
-
Args:
|
|
238
|
-
steps: List of unique steps that make up a single cycle.
|
|
239
|
-
Each list item should be a dictionary that maps to
|
|
240
|
-
the parameters of the :py:meth:`set_block_temperature`
|
|
241
|
-
method with keys 'temperature', 'hold_time_seconds',
|
|
242
|
-
and 'hold_time_minutes'.
|
|
243
|
-
repetitions: The number of times to repeat the cycled steps.
|
|
244
|
-
block_max_volume: The maximum volume of any individual well
|
|
245
|
-
of the loaded labware. If not supplied, the thermocycler
|
|
246
|
-
will default to 25µL/well.
|
|
247
|
-
"""
|
|
248
|
-
|
|
249
220
|
@abstractmethod
|
|
250
221
|
def deactivate_lid(self) -> None:
|
|
251
222
|
"""Turn off the heated lid."""
|
|
@@ -323,7 +294,7 @@ class AbstractHeaterShakerCore(
|
|
|
323
294
|
"""Get the module's unique hardware serial number."""
|
|
324
295
|
|
|
325
296
|
@abstractmethod
|
|
326
|
-
def set_target_temperature(self, celsius: float) ->
|
|
297
|
+
def set_target_temperature(self, celsius: float) -> None:
|
|
327
298
|
"""Set the labware plate's target temperature in °C."""
|
|
328
299
|
|
|
329
300
|
@abstractmethod
|
|
@@ -334,10 +305,6 @@ class AbstractHeaterShakerCore(
|
|
|
334
305
|
def set_and_wait_for_shake_speed(self, rpm: int) -> None:
|
|
335
306
|
"""Set the shaker's target shake speed and wait for it to spin up."""
|
|
336
307
|
|
|
337
|
-
@abstractmethod
|
|
338
|
-
def set_shake_speed(self, rpm: int) -> AbstractTaskCore:
|
|
339
|
-
"""Set the shaker's target shake speed."""
|
|
340
|
-
|
|
341
308
|
@abstractmethod
|
|
342
309
|
def open_labware_latch(self) -> None:
|
|
343
310
|
"""Open the labware latch."""
|