opentrons 8.7.0a9__py3-none-any.whl → 8.8.0a7__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/_version.py +2 -2
- opentrons/cli/analyze.py +4 -1
- opentrons/config/__init__.py +7 -0
- opentrons/drivers/asyncio/communication/serial_connection.py +126 -49
- opentrons/drivers/heater_shaker/abstract.py +5 -0
- opentrons/drivers/heater_shaker/driver.py +10 -0
- opentrons/drivers/heater_shaker/simulator.py +4 -0
- opentrons/drivers/thermocycler/abstract.py +6 -0
- opentrons/drivers/thermocycler/driver.py +61 -10
- opentrons/drivers/thermocycler/simulator.py +6 -0
- opentrons/drivers/vacuum_module/__init__.py +5 -0
- opentrons/drivers/vacuum_module/abstract.py +93 -0
- opentrons/drivers/vacuum_module/driver.py +208 -0
- opentrons/drivers/vacuum_module/errors.py +39 -0
- opentrons/drivers/vacuum_module/simulator.py +85 -0
- opentrons/drivers/vacuum_module/types.py +79 -0
- opentrons/execute.py +3 -0
- opentrons/hardware_control/api.py +24 -5
- opentrons/hardware_control/backends/controller.py +8 -2
- opentrons/hardware_control/backends/flex_protocol.py +1 -0
- opentrons/hardware_control/backends/ot3controller.py +35 -2
- opentrons/hardware_control/backends/ot3simulator.py +3 -1
- opentrons/hardware_control/backends/ot3utils.py +37 -0
- opentrons/hardware_control/backends/simulator.py +2 -1
- opentrons/hardware_control/backends/subsystem_manager.py +5 -2
- opentrons/hardware_control/emulation/abstract_emulator.py +6 -4
- opentrons/hardware_control/emulation/connection_handler.py +8 -5
- opentrons/hardware_control/emulation/heater_shaker.py +12 -3
- opentrons/hardware_control/emulation/settings.py +1 -1
- opentrons/hardware_control/emulation/thermocycler.py +67 -15
- opentrons/hardware_control/module_control.py +105 -10
- opentrons/hardware_control/modules/__init__.py +3 -0
- opentrons/hardware_control/modules/absorbance_reader.py +11 -4
- opentrons/hardware_control/modules/flex_stacker.py +38 -9
- opentrons/hardware_control/modules/heater_shaker.py +42 -5
- opentrons/hardware_control/modules/magdeck.py +8 -4
- opentrons/hardware_control/modules/mod_abc.py +14 -6
- opentrons/hardware_control/modules/tempdeck.py +25 -5
- opentrons/hardware_control/modules/thermocycler.py +68 -11
- opentrons/hardware_control/modules/types.py +20 -1
- opentrons/hardware_control/modules/utils.py +11 -4
- opentrons/hardware_control/motion_utilities.py +6 -6
- opentrons/hardware_control/nozzle_manager.py +3 -0
- opentrons/hardware_control/ot3api.py +85 -17
- opentrons/hardware_control/poller.py +22 -8
- opentrons/hardware_control/protocols/liquid_handler.py +6 -2
- opentrons/hardware_control/scripts/update_module_fw.py +5 -0
- opentrons/hardware_control/types.py +43 -2
- opentrons/legacy_commands/commands.py +58 -5
- opentrons/legacy_commands/module_commands.py +52 -0
- opentrons/legacy_commands/protocol_commands.py +53 -1
- opentrons/legacy_commands/types.py +155 -1
- opentrons/motion_planning/deck_conflict.py +17 -12
- opentrons/motion_planning/waypoints.py +15 -29
- opentrons/protocol_api/__init__.py +5 -1
- opentrons/protocol_api/_transfer_liquid_validation.py +17 -2
- opentrons/protocol_api/_types.py +8 -1
- opentrons/protocol_api/core/common.py +3 -1
- opentrons/protocol_api/core/engine/_default_labware_versions.py +33 -11
- opentrons/protocol_api/core/engine/deck_conflict.py +3 -1
- opentrons/protocol_api/core/engine/instrument.py +109 -26
- opentrons/protocol_api/core/engine/labware.py +8 -1
- opentrons/protocol_api/core/engine/module_core.py +95 -4
- opentrons/protocol_api/core/engine/protocol.py +51 -2
- opentrons/protocol_api/core/engine/stringify.py +2 -0
- opentrons/protocol_api/core/engine/tasks.py +48 -0
- opentrons/protocol_api/core/engine/well.py +8 -0
- opentrons/protocol_api/core/instrument.py +19 -2
- opentrons/protocol_api/core/legacy/legacy_instrument_core.py +19 -2
- opentrons/protocol_api/core/legacy/legacy_module_core.py +33 -2
- opentrons/protocol_api/core/legacy/legacy_protocol_core.py +23 -1
- opentrons/protocol_api/core/legacy/legacy_well_core.py +4 -0
- opentrons/protocol_api/core/legacy/tasks.py +19 -0
- opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py +19 -2
- opentrons/protocol_api/core/legacy_simulator/legacy_protocol_core.py +14 -2
- opentrons/protocol_api/core/legacy_simulator/tasks.py +19 -0
- opentrons/protocol_api/core/module.py +58 -2
- opentrons/protocol_api/core/protocol.py +23 -2
- opentrons/protocol_api/core/tasks.py +31 -0
- opentrons/protocol_api/core/well.py +4 -0
- opentrons/protocol_api/instrument_context.py +388 -2
- opentrons/protocol_api/labware.py +10 -2
- opentrons/protocol_api/module_contexts.py +170 -6
- opentrons/protocol_api/protocol_context.py +87 -21
- opentrons/protocol_api/robot_context.py +41 -25
- opentrons/protocol_api/tasks.py +48 -0
- opentrons/protocol_api/validation.py +49 -3
- opentrons/protocol_engine/__init__.py +4 -0
- opentrons/protocol_engine/actions/__init__.py +6 -2
- opentrons/protocol_engine/actions/actions.py +31 -9
- opentrons/protocol_engine/clients/sync_client.py +42 -7
- opentrons/protocol_engine/commands/__init__.py +56 -0
- opentrons/protocol_engine/commands/absorbance_reader/close_lid.py +2 -15
- opentrons/protocol_engine/commands/absorbance_reader/open_lid.py +2 -15
- opentrons/protocol_engine/commands/absorbance_reader/read.py +22 -23
- opentrons/protocol_engine/commands/aspirate.py +1 -0
- opentrons/protocol_engine/commands/aspirate_while_tracking.py +52 -19
- opentrons/protocol_engine/commands/capture_image.py +302 -0
- opentrons/protocol_engine/commands/command.py +2 -0
- opentrons/protocol_engine/commands/command_unions.py +62 -0
- opentrons/protocol_engine/commands/create_timer.py +83 -0
- opentrons/protocol_engine/commands/dispense.py +1 -0
- opentrons/protocol_engine/commands/dispense_while_tracking.py +56 -19
- opentrons/protocol_engine/commands/drop_tip.py +32 -8
- opentrons/protocol_engine/commands/flex_stacker/common.py +35 -0
- opentrons/protocol_engine/commands/flex_stacker/set_stored_labware.py +7 -0
- opentrons/protocol_engine/commands/heater_shaker/__init__.py +14 -0
- opentrons/protocol_engine/commands/heater_shaker/common.py +20 -0
- opentrons/protocol_engine/commands/heater_shaker/set_and_wait_for_shake_speed.py +5 -4
- opentrons/protocol_engine/commands/heater_shaker/set_shake_speed.py +136 -0
- opentrons/protocol_engine/commands/heater_shaker/set_target_temperature.py +31 -5
- opentrons/protocol_engine/commands/move_labware.py +3 -4
- opentrons/protocol_engine/commands/move_to_addressable_area_for_drop_tip.py +1 -1
- opentrons/protocol_engine/commands/movement_common.py +31 -2
- opentrons/protocol_engine/commands/pick_up_tip.py +21 -11
- opentrons/protocol_engine/commands/pipetting_common.py +48 -3
- opentrons/protocol_engine/commands/set_tip_state.py +97 -0
- opentrons/protocol_engine/commands/temperature_module/set_target_temperature.py +38 -7
- opentrons/protocol_engine/commands/thermocycler/__init__.py +16 -0
- opentrons/protocol_engine/commands/thermocycler/run_extended_profile.py +6 -0
- opentrons/protocol_engine/commands/thermocycler/run_profile.py +8 -0
- opentrons/protocol_engine/commands/thermocycler/set_target_block_temperature.py +44 -7
- opentrons/protocol_engine/commands/thermocycler/set_target_lid_temperature.py +43 -14
- opentrons/protocol_engine/commands/thermocycler/start_run_extended_profile.py +191 -0
- opentrons/protocol_engine/commands/touch_tip.py +1 -1
- opentrons/protocol_engine/commands/unsafe/unsafe_place_labware.py +6 -22
- opentrons/protocol_engine/commands/wait_for_tasks.py +98 -0
- opentrons/protocol_engine/create_protocol_engine.py +12 -0
- opentrons/protocol_engine/engine_support.py +3 -0
- opentrons/protocol_engine/errors/__init__.py +12 -0
- opentrons/protocol_engine/errors/exceptions.py +119 -0
- opentrons/protocol_engine/execution/__init__.py +4 -0
- opentrons/protocol_engine/execution/command_executor.py +62 -1
- opentrons/protocol_engine/execution/create_queue_worker.py +9 -2
- opentrons/protocol_engine/execution/labware_movement.py +13 -15
- opentrons/protocol_engine/execution/movement.py +2 -0
- opentrons/protocol_engine/execution/pipetting.py +19 -25
- opentrons/protocol_engine/execution/queue_worker.py +4 -0
- opentrons/protocol_engine/execution/run_control.py +8 -0
- opentrons/protocol_engine/execution/task_handler.py +157 -0
- opentrons/protocol_engine/protocol_engine.py +137 -36
- opentrons/protocol_engine/resources/__init__.py +4 -0
- opentrons/protocol_engine/resources/camera_provider.py +110 -0
- opentrons/protocol_engine/resources/concurrency_provider.py +27 -0
- opentrons/protocol_engine/resources/deck_configuration_provider.py +7 -0
- opentrons/protocol_engine/resources/file_provider.py +133 -58
- opentrons/protocol_engine/resources/labware_validation.py +10 -6
- opentrons/protocol_engine/slot_standardization.py +2 -0
- opentrons/protocol_engine/state/_well_math.py +60 -18
- opentrons/protocol_engine/state/addressable_areas.py +2 -0
- opentrons/protocol_engine/state/camera.py +54 -0
- opentrons/protocol_engine/state/commands.py +37 -14
- opentrons/protocol_engine/state/geometry.py +276 -379
- opentrons/protocol_engine/state/labware.py +62 -108
- opentrons/protocol_engine/state/labware_origin_math/errors.py +94 -0
- opentrons/protocol_engine/state/labware_origin_math/stackup_origin_to_labware_origin.py +1336 -0
- opentrons/protocol_engine/state/module_substates/thermocycler_module_substate.py +37 -0
- opentrons/protocol_engine/state/modules.py +30 -8
- opentrons/protocol_engine/state/motion.py +44 -0
- opentrons/protocol_engine/state/preconditions.py +59 -0
- opentrons/protocol_engine/state/state.py +44 -0
- opentrons/protocol_engine/state/state_summary.py +4 -0
- opentrons/protocol_engine/state/tasks.py +139 -0
- opentrons/protocol_engine/state/tips.py +177 -258
- opentrons/protocol_engine/state/update_types.py +26 -9
- opentrons/protocol_engine/types/__init__.py +23 -4
- opentrons/protocol_engine/types/command_preconditions.py +18 -0
- opentrons/protocol_engine/types/deck_configuration.py +5 -1
- opentrons/protocol_engine/types/instrument.py +8 -1
- opentrons/protocol_engine/types/labware.py +1 -13
- opentrons/protocol_engine/types/location.py +26 -2
- opentrons/protocol_engine/types/module.py +11 -1
- opentrons/protocol_engine/types/tasks.py +38 -0
- opentrons/protocol_engine/types/tip.py +9 -0
- opentrons/protocol_runner/create_simulating_orchestrator.py +29 -2
- opentrons/protocol_runner/protocol_runner.py +14 -1
- opentrons/protocol_runner/run_orchestrator.py +49 -2
- opentrons/protocols/advanced_control/transfers/transfer_liquid_utils.py +2 -2
- opentrons/protocols/api_support/definitions.py +1 -1
- opentrons/protocols/api_support/types.py +2 -1
- opentrons/simulate.py +51 -15
- opentrons/system/camera.py +334 -4
- opentrons/system/ffmpeg.py +110 -0
- {opentrons-8.7.0a9.dist-info → opentrons-8.8.0a7.dist-info}/METADATA +4 -4
- {opentrons-8.7.0a9.dist-info → opentrons-8.8.0a7.dist-info}/RECORD +188 -160
- opentrons/protocol_engine/state/_labware_origin_math.py +0 -636
- {opentrons-8.7.0a9.dist-info → opentrons-8.8.0a7.dist-info}/WHEEL +0 -0
- {opentrons-8.7.0a9.dist-info → opentrons-8.8.0a7.dist-info}/entry_points.txt +0 -0
- {opentrons-8.7.0a9.dist-info → opentrons-8.8.0a7.dist-info}/licenses/LICENSE +0 -0
|
@@ -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, Sequence
|
|
5
5
|
|
|
6
6
|
from opentrons_shared_data.liquid_classes import LiquidClassDefinitionDoesNotExist
|
|
7
7
|
from opentrons_shared_data.deck.types import DeckDefinitionV5, SlotDefV3
|
|
@@ -49,6 +49,7 @@ from opentrons.protocol_engine.types import (
|
|
|
49
49
|
OFF_DECK_LOCATION,
|
|
50
50
|
SYSTEM_LOCATION,
|
|
51
51
|
LoadableLabwareLocation,
|
|
52
|
+
WASTE_CHUTE_LOCATION,
|
|
52
53
|
NonStackedLocation,
|
|
53
54
|
)
|
|
54
55
|
from opentrons.protocol_engine.clients import SyncClient as ProtocolEngineClient
|
|
@@ -64,6 +65,7 @@ from ...disposal_locations import TrashBin, WasteChute
|
|
|
64
65
|
from ..protocol import AbstractProtocol
|
|
65
66
|
from ..labware import LabwareLoadParams
|
|
66
67
|
from .labware import LabwareCore
|
|
68
|
+
from .tasks import EngineTaskCore
|
|
67
69
|
from .instrument import InstrumentCore
|
|
68
70
|
from .robot import RobotCore
|
|
69
71
|
from .module_core import (
|
|
@@ -95,6 +97,7 @@ class ProtocolCore(
|
|
|
95
97
|
InstrumentCore,
|
|
96
98
|
LabwareCore,
|
|
97
99
|
Union[ModuleCore, NonConnectedModuleCore],
|
|
100
|
+
EngineTaskCore,
|
|
98
101
|
]
|
|
99
102
|
):
|
|
100
103
|
"""Protocol API core using a ProtocolEngine.
|
|
@@ -912,6 +915,21 @@ class ProtocolCore(
|
|
|
912
915
|
cmd.WaitForDurationParams(seconds=seconds, message=msg)
|
|
913
916
|
)
|
|
914
917
|
|
|
918
|
+
def wait_for_tasks(self, task_cores: Sequence[EngineTaskCore]) -> None:
|
|
919
|
+
"""Wait for specified tasks to complete."""
|
|
920
|
+
task_ids = task_ids = [task._id for task in task_cores if task._id is not None]
|
|
921
|
+
self._engine_client.execute_command(cmd.WaitForTasksParams(task_ids=task_ids))
|
|
922
|
+
|
|
923
|
+
def create_timer(self, seconds: float) -> EngineTaskCore:
|
|
924
|
+
"""Create a timer task that runs in the background."""
|
|
925
|
+
result = self._engine_client.execute_command_without_recovery(
|
|
926
|
+
cmd.CreateTimerParams(time=seconds)
|
|
927
|
+
)
|
|
928
|
+
timer_task = EngineTaskCore(
|
|
929
|
+
engine_client=self._engine_client, task_id=result.task_id
|
|
930
|
+
)
|
|
931
|
+
return timer_task
|
|
932
|
+
|
|
915
933
|
def home(self) -> None:
|
|
916
934
|
"""Move all axes to their home positions."""
|
|
917
935
|
self._engine_client.execute_command(cmd.HomeParams(axes=None))
|
|
@@ -1151,9 +1169,38 @@ class ProtocolCore(
|
|
|
1151
1169
|
return self._module_cores_by_id[labware_location.moduleId]
|
|
1152
1170
|
elif isinstance(labware_location, OnLabwareLocation):
|
|
1153
1171
|
return self._labware_cores_by_id[labware_location.labwareId]
|
|
1154
|
-
|
|
1172
|
+
elif labware_location == WASTE_CHUTE_LOCATION:
|
|
1173
|
+
return OffDeckType.WASTE_CHUTE
|
|
1155
1174
|
return OffDeckType.OFF_DECK
|
|
1156
1175
|
|
|
1176
|
+
def capture_image(
|
|
1177
|
+
self,
|
|
1178
|
+
filename: Optional[str] = None,
|
|
1179
|
+
resolution: Optional[Tuple[int, int]] = None,
|
|
1180
|
+
zoom: Optional[float] = None,
|
|
1181
|
+
contrast: Optional[float] = None,
|
|
1182
|
+
brightness: Optional[float] = None,
|
|
1183
|
+
saturation: Optional[float] = None,
|
|
1184
|
+
) -> None:
|
|
1185
|
+
"""Capture an image using a camera.
|
|
1186
|
+
Args:
|
|
1187
|
+
resolution: Width by height resolution in pixels for the image to be captured with.
|
|
1188
|
+
zoom: Multiplier to use when cropping and scaling a captured image. Scale is 1.0 to 2.0.
|
|
1189
|
+
contrast: The contrast to use when processing an image. Scale is 0% to 100%
|
|
1190
|
+
brightness: The brightness to use when processing an image. Scale is 0% to 100%.
|
|
1191
|
+
saturation: The saturation to use when processing an image. Scale is 0% to 100%.
|
|
1192
|
+
"""
|
|
1193
|
+
self._engine_client.execute_command(
|
|
1194
|
+
cmd.CaptureImageParams(
|
|
1195
|
+
fileName=filename,
|
|
1196
|
+
resolution=resolution,
|
|
1197
|
+
zoom=zoom,
|
|
1198
|
+
contrast=contrast,
|
|
1199
|
+
brightness=brightness,
|
|
1200
|
+
saturation=saturation,
|
|
1201
|
+
)
|
|
1202
|
+
)
|
|
1203
|
+
|
|
1157
1204
|
def _convert_labware_location(
|
|
1158
1205
|
self,
|
|
1159
1206
|
location: Union[
|
|
@@ -1188,6 +1235,8 @@ class ProtocolCore(
|
|
|
1188
1235
|
return ModuleLocation(moduleId=location.module_id)
|
|
1189
1236
|
elif location is OffDeckType.OFF_DECK:
|
|
1190
1237
|
return OFF_DECK_LOCATION
|
|
1238
|
+
elif location is OffDeckType.WASTE_CHUTE:
|
|
1239
|
+
return AddressableAreaLocation(addressableAreaName="gripperWasteChute")
|
|
1191
1240
|
elif isinstance(location, DeckSlotName):
|
|
1192
1241
|
return DeckSlotLocation(slotName=location)
|
|
1193
1242
|
elif isinstance(location, StagingSlotName):
|
|
@@ -60,6 +60,8 @@ def _labware_location_string(
|
|
|
60
60
|
return (
|
|
61
61
|
f"stored in {_module_in_location_string(location.moduleId, engine_client)}"
|
|
62
62
|
)
|
|
63
|
+
elif location == "wasteChuteLocation":
|
|
64
|
+
return "in waste chute"
|
|
63
65
|
|
|
64
66
|
|
|
65
67
|
def _labware_name(engine_client: SyncClient, labware_id: str) -> str:
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
from ..tasks import AbstractTaskCore
|
|
3
|
+
from opentrons.protocol_engine.clients import SyncClient as ProtocolEngineClient
|
|
4
|
+
from opentrons.protocol_engine.errors.exceptions import NoTaskFoundError
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class EngineTaskCore(AbstractTaskCore):
|
|
8
|
+
def __init__(
|
|
9
|
+
self, task_id: str | None, engine_client: ProtocolEngineClient
|
|
10
|
+
) -> None:
|
|
11
|
+
self._id = task_id
|
|
12
|
+
self._engine_client = engine_client
|
|
13
|
+
|
|
14
|
+
def get_created_at_timestamp(self) -> datetime:
|
|
15
|
+
if self._id is None:
|
|
16
|
+
raise NoTaskFoundError
|
|
17
|
+
try:
|
|
18
|
+
task = self._engine_client.state.tasks.get(self._id)
|
|
19
|
+
return task.createdAt
|
|
20
|
+
except NoTaskFoundError:
|
|
21
|
+
raise NoTaskFoundError
|
|
22
|
+
|
|
23
|
+
def is_done(self) -> bool:
|
|
24
|
+
if self._id is None:
|
|
25
|
+
raise NoTaskFoundError
|
|
26
|
+
try:
|
|
27
|
+
self._engine_client.state.tasks.get_finished(self._id)
|
|
28
|
+
return True
|
|
29
|
+
except NoTaskFoundError:
|
|
30
|
+
return False
|
|
31
|
+
|
|
32
|
+
def is_started(self) -> bool:
|
|
33
|
+
if self._id is None:
|
|
34
|
+
raise NoTaskFoundError
|
|
35
|
+
try:
|
|
36
|
+
self._engine_client.state.tasks.get_current(self._id)
|
|
37
|
+
return True
|
|
38
|
+
except NoTaskFoundError:
|
|
39
|
+
return self.is_done()
|
|
40
|
+
|
|
41
|
+
def get_finished_at_timestamp(self) -> datetime | None:
|
|
42
|
+
if self._id is None:
|
|
43
|
+
raise NoTaskFoundError
|
|
44
|
+
try:
|
|
45
|
+
finished_task = self._engine_client.state.tasks.get_finished(self._id)
|
|
46
|
+
return finished_task.finishedAt
|
|
47
|
+
except NoTaskFoundError:
|
|
48
|
+
return None
|
|
@@ -216,6 +216,14 @@ 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
|
+
|
|
219
227
|
def get_liquid_volume(self) -> LiquidTrackingType:
|
|
220
228
|
"""Return the current volume in a well."""
|
|
221
229
|
labware_id = self.labware_id
|
|
@@ -48,7 +48,10 @@ class AbstractInstrument(ABC, Generic[WellCoreType, LabwareCoreType]):
|
|
|
48
48
|
flow_rate: float,
|
|
49
49
|
in_place: bool,
|
|
50
50
|
meniscus_tracking: Optional[types.MeniscusTrackingTarget] = None,
|
|
51
|
+
end_location: Optional[types.Location] = None,
|
|
52
|
+
end_meniscus_tracking: Optional[types.MeniscusTrackingTarget] = None,
|
|
51
53
|
correction_volume: Optional[float] = None,
|
|
54
|
+
movement_delay: Optional[float] = None,
|
|
52
55
|
) -> None:
|
|
53
56
|
"""Aspirate a given volume of liquid from the specified location.
|
|
54
57
|
Args:
|
|
@@ -74,7 +77,10 @@ class AbstractInstrument(ABC, Generic[WellCoreType, LabwareCoreType]):
|
|
|
74
77
|
in_place: bool,
|
|
75
78
|
push_out: Optional[float],
|
|
76
79
|
meniscus_tracking: Optional[types.MeniscusTrackingTarget] = None,
|
|
80
|
+
end_location: Optional[types.Location] = None,
|
|
81
|
+
end_meniscus_tracking: Optional[types.MeniscusTrackingTarget] = None,
|
|
77
82
|
correction_volume: Optional[float] = None,
|
|
83
|
+
movement_delay: Optional[float] = None,
|
|
78
84
|
) -> None:
|
|
79
85
|
"""Dispense a given volume of liquid into the specified location.
|
|
80
86
|
Args:
|
|
@@ -378,6 +384,7 @@ class AbstractInstrument(ABC, Generic[WellCoreType, LabwareCoreType]):
|
|
|
378
384
|
trash_location: Union[types.Location, TrashBin, WasteChute],
|
|
379
385
|
return_tip: bool,
|
|
380
386
|
keep_last_tip: bool,
|
|
387
|
+
tips: Optional[List[WellCoreType]],
|
|
381
388
|
) -> None:
|
|
382
389
|
"""Transfer a liquid from source to dest according to liquid class properties."""
|
|
383
390
|
...
|
|
@@ -389,12 +396,17 @@ class AbstractInstrument(ABC, Generic[WellCoreType, LabwareCoreType]):
|
|
|
389
396
|
volume: float,
|
|
390
397
|
source: Tuple[types.Location, WellCoreType],
|
|
391
398
|
dest: List[Tuple[types.Location, WellCoreType]],
|
|
392
|
-
new_tip: Literal[
|
|
399
|
+
new_tip: Literal[
|
|
400
|
+
TransferTipPolicyV2.NEVER,
|
|
401
|
+
TransferTipPolicyV2.ONCE,
|
|
402
|
+
TransferTipPolicyV2.ALWAYS,
|
|
403
|
+
],
|
|
393
404
|
tip_racks: List[Tuple[types.Location, LabwareCoreType]],
|
|
394
405
|
starting_tip: Optional[WellCoreType],
|
|
395
406
|
trash_location: Union[types.Location, TrashBin, WasteChute],
|
|
396
407
|
return_tip: bool,
|
|
397
408
|
keep_last_tip: bool,
|
|
409
|
+
tips: Optional[List[WellCoreType]],
|
|
398
410
|
) -> None:
|
|
399
411
|
"""
|
|
400
412
|
Distribute a liquid from single source to multiple destinations
|
|
@@ -409,12 +421,17 @@ class AbstractInstrument(ABC, Generic[WellCoreType, LabwareCoreType]):
|
|
|
409
421
|
volume: float,
|
|
410
422
|
source: List[Tuple[types.Location, WellCoreType]],
|
|
411
423
|
dest: Union[Tuple[types.Location, WellCoreType], TrashBin, WasteChute],
|
|
412
|
-
new_tip: Literal[
|
|
424
|
+
new_tip: Literal[
|
|
425
|
+
TransferTipPolicyV2.NEVER,
|
|
426
|
+
TransferTipPolicyV2.ONCE,
|
|
427
|
+
TransferTipPolicyV2.ALWAYS,
|
|
428
|
+
],
|
|
413
429
|
tip_racks: List[Tuple[types.Location, LabwareCoreType]],
|
|
414
430
|
starting_tip: Optional[WellCoreType],
|
|
415
431
|
trash_location: Union[types.Location, TrashBin, WasteChute],
|
|
416
432
|
return_tip: bool,
|
|
417
433
|
keep_last_tip: bool,
|
|
434
|
+
tips: Optional[List[WellCoreType]],
|
|
418
435
|
) -> None:
|
|
419
436
|
"""
|
|
420
437
|
Consolidate liquid from multiple sources to a single destination
|
|
@@ -93,7 +93,10 @@ class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore, LegacyLabwareCore]
|
|
|
93
93
|
flow_rate: float,
|
|
94
94
|
in_place: bool,
|
|
95
95
|
meniscus_tracking: Optional[types.MeniscusTrackingTarget] = None,
|
|
96
|
+
end_location: Optional[types.Location] = None,
|
|
97
|
+
end_meniscus_tracking: Optional[types.MeniscusTrackingTarget] = None,
|
|
96
98
|
correction_volume: Optional[float] = None,
|
|
99
|
+
movement_delay: Optional[float] = None,
|
|
97
100
|
) -> None:
|
|
98
101
|
"""Aspirate a given volume of liquid from the specified location.
|
|
99
102
|
Args:
|
|
@@ -139,7 +142,10 @@ class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore, LegacyLabwareCore]
|
|
|
139
142
|
in_place: bool,
|
|
140
143
|
push_out: Optional[float],
|
|
141
144
|
meniscus_tracking: Optional[types.MeniscusTrackingTarget] = None,
|
|
145
|
+
end_location: Optional[types.Location] = None,
|
|
146
|
+
end_meniscus_tracking: Optional[types.MeniscusTrackingTarget] = None,
|
|
142
147
|
correction_volume: Optional[float] = None,
|
|
148
|
+
movement_delay: Optional[float] = None,
|
|
143
149
|
) -> None:
|
|
144
150
|
"""Dispense a given volume of liquid into the specified location.
|
|
145
151
|
Args:
|
|
@@ -622,6 +628,7 @@ class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore, LegacyLabwareCore]
|
|
|
622
628
|
trash_location: Union[types.Location, TrashBin, WasteChute],
|
|
623
629
|
return_tip: bool,
|
|
624
630
|
keep_last_tip: bool,
|
|
631
|
+
tips: Optional[List[LegacyWellCore]],
|
|
625
632
|
) -> None:
|
|
626
633
|
"""This will never be called because it was added in API 2.23"""
|
|
627
634
|
assert False, "transfer_liquid is not supported in legacy context"
|
|
@@ -632,12 +639,17 @@ class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore, LegacyLabwareCore]
|
|
|
632
639
|
volume: float,
|
|
633
640
|
source: Tuple[types.Location, LegacyWellCore],
|
|
634
641
|
dest: List[Tuple[types.Location, LegacyWellCore]],
|
|
635
|
-
new_tip: Literal[
|
|
642
|
+
new_tip: Literal[
|
|
643
|
+
TransferTipPolicyV2.NEVER,
|
|
644
|
+
TransferTipPolicyV2.ONCE,
|
|
645
|
+
TransferTipPolicyV2.ALWAYS,
|
|
646
|
+
],
|
|
636
647
|
tip_racks: List[Tuple[types.Location, LegacyLabwareCore]],
|
|
637
648
|
starting_tip: Optional[LegacyWellCore],
|
|
638
649
|
trash_location: Union[types.Location, TrashBin, WasteChute],
|
|
639
650
|
return_tip: bool,
|
|
640
651
|
keep_last_tip: bool,
|
|
652
|
+
tips: Optional[List[LegacyWellCore]],
|
|
641
653
|
) -> None:
|
|
642
654
|
"""This will never be called because it was added in API 2.23"""
|
|
643
655
|
assert False, "distribute_liquid is not supported in legacy context"
|
|
@@ -648,12 +660,17 @@ class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore, LegacyLabwareCore]
|
|
|
648
660
|
volume: float,
|
|
649
661
|
source: List[Tuple[types.Location, LegacyWellCore]],
|
|
650
662
|
dest: Union[Tuple[types.Location, LegacyWellCore], TrashBin, WasteChute],
|
|
651
|
-
new_tip: Literal[
|
|
663
|
+
new_tip: Literal[
|
|
664
|
+
TransferTipPolicyV2.NEVER,
|
|
665
|
+
TransferTipPolicyV2.ONCE,
|
|
666
|
+
TransferTipPolicyV2.ALWAYS,
|
|
667
|
+
],
|
|
652
668
|
tip_racks: List[Tuple[types.Location, LegacyLabwareCore]],
|
|
653
669
|
starting_tip: Optional[LegacyWellCore],
|
|
654
670
|
trash_location: Union[types.Location, TrashBin, WasteChute],
|
|
655
671
|
return_tip: bool,
|
|
656
672
|
keep_last_tip: bool,
|
|
673
|
+
tips: Optional[List[LegacyWellCore]],
|
|
657
674
|
) -> None:
|
|
658
675
|
"""This will never be called because it was added in API 2.23."""
|
|
659
676
|
assert False, "consolidate_liquid is not supported in legacy context"
|
|
@@ -31,6 +31,7 @@ from ..module import (
|
|
|
31
31
|
)
|
|
32
32
|
|
|
33
33
|
from .legacy_labware_core import LegacyLabwareCore
|
|
34
|
+
from .tasks import LegacyTaskCore
|
|
34
35
|
from .module_geometry import ModuleGeometry, ThermocyclerGeometry, HeaterShakerGeometry
|
|
35
36
|
from ...labware import Labware
|
|
36
37
|
|
|
@@ -116,9 +117,10 @@ class LegacyTemperatureModuleCore(
|
|
|
116
117
|
|
|
117
118
|
_sync_module_hardware: SynchronousAdapter[hw_modules.TempDeck]
|
|
118
119
|
|
|
119
|
-
def set_target_temperature(self, celsius: float) ->
|
|
120
|
+
def set_target_temperature(self, celsius: float) -> LegacyTaskCore:
|
|
120
121
|
"""Set the Temperature Module's target temperature in °C."""
|
|
121
122
|
self._sync_module_hardware.start_set_temperature(celsius)
|
|
123
|
+
return LegacyTaskCore()
|
|
122
124
|
|
|
123
125
|
def wait_for_target_temperature(self, celsius: Optional[float] = None) -> None:
|
|
124
126
|
"""Wait until the module's target temperature is reached.
|
|
@@ -263,6 +265,7 @@ class LegacyThermocyclerCore(
|
|
|
263
265
|
def set_target_block_temperature(
|
|
264
266
|
self,
|
|
265
267
|
celsius: float,
|
|
268
|
+
ramp_rate: Optional[float],
|
|
266
269
|
hold_time_seconds: Optional[float] = None,
|
|
267
270
|
block_max_volume: Optional[float] = None,
|
|
268
271
|
) -> None:
|
|
@@ -271,6 +274,7 @@ class LegacyThermocyclerCore(
|
|
|
271
274
|
celsius=celsius,
|
|
272
275
|
hold_time_seconds=hold_time_seconds,
|
|
273
276
|
volume=block_max_volume,
|
|
277
|
+
ramp_rate=ramp_rate,
|
|
274
278
|
)
|
|
275
279
|
|
|
276
280
|
def wait_for_block_temperature(self) -> None:
|
|
@@ -281,6 +285,19 @@ class LegacyThermocyclerCore(
|
|
|
281
285
|
"""Set the target temperature for the heated lid, in °C."""
|
|
282
286
|
self._sync_module_hardware.set_target_lid_temperature(celsius=celsius)
|
|
283
287
|
|
|
288
|
+
def start_set_target_lid_temperature(self, celsius: float) -> LegacyTaskCore:
|
|
289
|
+
"""Set the target temperature for the heated lid, in °C."""
|
|
290
|
+
assert False, "start_set_target_lid_temperature only supported on engine core"
|
|
291
|
+
|
|
292
|
+
def start_set_target_block_temperature(
|
|
293
|
+
self,
|
|
294
|
+
celsius: float,
|
|
295
|
+
ramp_rate: Optional[float],
|
|
296
|
+
block_max_volume: Optional[float] = None,
|
|
297
|
+
) -> LegacyTaskCore:
|
|
298
|
+
"""Set the target temperature for the heated block, in °C."""
|
|
299
|
+
assert False, "start_set_target_block_temperature only supported on engine core"
|
|
300
|
+
|
|
284
301
|
def wait_for_lid_temperature(self) -> None:
|
|
285
302
|
"""Wait for target lid temperature to be reached."""
|
|
286
303
|
self._sync_module_hardware.wait_for_lid_target()
|
|
@@ -296,6 +313,15 @@ class LegacyThermocyclerCore(
|
|
|
296
313
|
steps=steps, repetitions=repetitions, volume=block_max_volume
|
|
297
314
|
)
|
|
298
315
|
|
|
316
|
+
def start_execute_profile(
|
|
317
|
+
self,
|
|
318
|
+
steps: List[ThermocyclerStep],
|
|
319
|
+
repetitions: int,
|
|
320
|
+
block_max_volume: Optional[float] = None,
|
|
321
|
+
) -> LegacyTaskCore:
|
|
322
|
+
"""Start a Thermocycler Profile."""
|
|
323
|
+
assert False, "start_execute_profile only supported on engine core"
|
|
324
|
+
|
|
299
325
|
def deactivate_lid(self) -> None:
|
|
300
326
|
"""Turn off the heated lid."""
|
|
301
327
|
self._sync_module_hardware.deactivate_lid()
|
|
@@ -413,9 +439,10 @@ class LegacyHeaterShakerCore(
|
|
|
413
439
|
_sync_module_hardware: SynchronousAdapter[hw_modules.HeaterShaker]
|
|
414
440
|
_geometry: HeaterShakerGeometry
|
|
415
441
|
|
|
416
|
-
def set_target_temperature(self, celsius: float) ->
|
|
442
|
+
def set_target_temperature(self, celsius: float) -> LegacyTaskCore:
|
|
417
443
|
"""Set the labware plate's target temperature in °C."""
|
|
418
444
|
self._sync_module_hardware.start_set_temperature(celsius)
|
|
445
|
+
return LegacyTaskCore()
|
|
419
446
|
|
|
420
447
|
def wait_for_target_temperature(self) -> None:
|
|
421
448
|
"""Wait for the labware plate's target temperature to be reached."""
|
|
@@ -442,6 +469,10 @@ class LegacyHeaterShakerCore(
|
|
|
442
469
|
"Cannot start shaking unless labware latch is closed."
|
|
443
470
|
)
|
|
444
471
|
|
|
472
|
+
def set_shake_speed(self, rpm: int) -> LegacyTaskCore:
|
|
473
|
+
"""Set heatershaker speed."""
|
|
474
|
+
assert False, "set_shake_speed only supported on engine core."
|
|
475
|
+
|
|
445
476
|
def open_labware_latch(self) -> None:
|
|
446
477
|
"""Open the labware latch."""
|
|
447
478
|
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, Sequence
|
|
3
3
|
|
|
4
4
|
from opentrons_shared_data.deck.types import DeckDefinitionV5, SlotDefV3
|
|
5
5
|
from opentrons_shared_data.labware.types import LabwareDefinition
|
|
@@ -34,6 +34,7 @@ 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
|
|
37
38
|
|
|
38
39
|
logger = logging.getLogger(__name__)
|
|
39
40
|
|
|
@@ -43,6 +44,7 @@ class LegacyProtocolCore(
|
|
|
43
44
|
LegacyInstrumentCore,
|
|
44
45
|
LegacyLabwareCore,
|
|
45
46
|
legacy_module_core.LegacyModuleCore,
|
|
47
|
+
LegacyTaskCore,
|
|
46
48
|
]
|
|
47
49
|
):
|
|
48
50
|
def __init__(
|
|
@@ -610,3 +612,23 @@ class LegacyProtocolCore(
|
|
|
610
612
|
]:
|
|
611
613
|
"""Get labware parent location."""
|
|
612
614
|
assert False, "get_labware_location only supported on engine core"
|
|
615
|
+
|
|
616
|
+
def capture_image(
|
|
617
|
+
self,
|
|
618
|
+
filename: Optional[str] = None,
|
|
619
|
+
resolution: Optional[Tuple[int, int]] = None,
|
|
620
|
+
zoom: Optional[float] = None,
|
|
621
|
+
contrast: Optional[float] = None,
|
|
622
|
+
brightness: Optional[float] = None,
|
|
623
|
+
saturation: Optional[float] = None,
|
|
624
|
+
) -> None:
|
|
625
|
+
"Capture an image using a camera."
|
|
626
|
+
assert False, "capture_image only supported on engine core"
|
|
627
|
+
|
|
628
|
+
def wait_for_tasks(self, task: Sequence[LegacyTaskCore]) -> None:
|
|
629
|
+
"""Wait for list of tasks to complete before executing subsequent commands."""
|
|
630
|
+
assert False, "wait_for_tasks only supported on engine core"
|
|
631
|
+
|
|
632
|
+
def create_timer(self, seconds: float) -> LegacyTaskCore:
|
|
633
|
+
"""Create a timer task that runs in the background."""
|
|
634
|
+
assert False, "create_timer only supported on engine core"
|
|
@@ -151,6 +151,10 @@ 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
|
+
|
|
154
158
|
# TODO(mc, 2022-10-28): is this used and/or necessary?
|
|
155
159
|
def __repr__(self) -> str:
|
|
156
160
|
"""Use the well's display name as its repr."""
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from ..tasks import AbstractTaskCore
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class LegacyTaskCore(AbstractTaskCore):
|
|
6
|
+
def __init__(self) -> None:
|
|
7
|
+
pass
|
|
8
|
+
|
|
9
|
+
def get_created_at_timestamp(self) -> datetime:
|
|
10
|
+
raise NotImplementedError("Legacy protocols do not implement tasks.")
|
|
11
|
+
|
|
12
|
+
def is_done(self) -> bool:
|
|
13
|
+
raise NotImplementedError("Legacy protocols do not implement tasks.")
|
|
14
|
+
|
|
15
|
+
def is_started(self) -> bool:
|
|
16
|
+
raise NotImplementedError("Legacy protocols do not implement tasks.")
|
|
17
|
+
|
|
18
|
+
def get_finished_at_timestamp(self) -> datetime | None:
|
|
19
|
+
raise NotImplementedError("Legacy protocols do not implement tasks.")
|
|
@@ -106,7 +106,10 @@ class LegacyInstrumentCoreSimulator(
|
|
|
106
106
|
flow_rate: float,
|
|
107
107
|
in_place: bool,
|
|
108
108
|
meniscus_tracking: Optional[types.MeniscusTrackingTarget] = None,
|
|
109
|
+
end_location: Optional[types.Location] = None,
|
|
110
|
+
end_meniscus_tracking: Optional[types.MeniscusTrackingTarget] = None,
|
|
109
111
|
correction_volume: Optional[float] = None,
|
|
112
|
+
movement_delay: Optional[float] = None,
|
|
110
113
|
) -> None:
|
|
111
114
|
if self.get_current_volume() == 0:
|
|
112
115
|
# Make sure we're at the top of the labware and clear of any
|
|
@@ -149,7 +152,10 @@ class LegacyInstrumentCoreSimulator(
|
|
|
149
152
|
in_place: bool,
|
|
150
153
|
push_out: Optional[float],
|
|
151
154
|
meniscus_tracking: Optional[types.MeniscusTrackingTarget] = None,
|
|
155
|
+
end_location: Optional[types.Location] = None,
|
|
156
|
+
end_meniscus_tracking: Optional[types.MeniscusTrackingTarget] = None,
|
|
152
157
|
correction_volume: Optional[float] = None,
|
|
158
|
+
movement_delay: Optional[float] = None,
|
|
153
159
|
) -> None:
|
|
154
160
|
if isinstance(location, (TrashBin, WasteChute)):
|
|
155
161
|
raise APIVersionError(
|
|
@@ -536,6 +542,7 @@ class LegacyInstrumentCoreSimulator(
|
|
|
536
542
|
trash_location: Union[types.Location, TrashBin, WasteChute],
|
|
537
543
|
return_tip: bool,
|
|
538
544
|
keep_last_tip: bool,
|
|
545
|
+
tips: Optional[List[LegacyWellCore]],
|
|
539
546
|
) -> None:
|
|
540
547
|
"""This will never be called because it was added in API 2.23."""
|
|
541
548
|
assert False, "transfer_liquid is not supported in legacy context"
|
|
@@ -546,12 +553,17 @@ class LegacyInstrumentCoreSimulator(
|
|
|
546
553
|
volume: float,
|
|
547
554
|
source: Tuple[types.Location, LegacyWellCore],
|
|
548
555
|
dest: List[Tuple[types.Location, LegacyWellCore]],
|
|
549
|
-
new_tip: Literal[
|
|
556
|
+
new_tip: Literal[
|
|
557
|
+
TransferTipPolicyV2.NEVER,
|
|
558
|
+
TransferTipPolicyV2.ONCE,
|
|
559
|
+
TransferTipPolicyV2.ALWAYS,
|
|
560
|
+
],
|
|
550
561
|
tip_racks: List[Tuple[types.Location, LegacyLabwareCore]],
|
|
551
562
|
starting_tip: Optional[LegacyWellCore],
|
|
552
563
|
trash_location: Union[types.Location, TrashBin, WasteChute],
|
|
553
564
|
return_tip: bool,
|
|
554
565
|
keep_last_tip: bool,
|
|
566
|
+
tips: Optional[List[LegacyWellCore]],
|
|
555
567
|
) -> None:
|
|
556
568
|
"""This will never be called because it was added in API 2.23."""
|
|
557
569
|
assert False, "distribute_liquid is not supported in legacy context"
|
|
@@ -562,12 +574,17 @@ class LegacyInstrumentCoreSimulator(
|
|
|
562
574
|
volume: float,
|
|
563
575
|
source: List[Tuple[types.Location, LegacyWellCore]],
|
|
564
576
|
dest: Union[Tuple[types.Location, LegacyWellCore], TrashBin, WasteChute],
|
|
565
|
-
new_tip: Literal[
|
|
577
|
+
new_tip: Literal[
|
|
578
|
+
TransferTipPolicyV2.NEVER,
|
|
579
|
+
TransferTipPolicyV2.ONCE,
|
|
580
|
+
TransferTipPolicyV2.ALWAYS,
|
|
581
|
+
],
|
|
566
582
|
tip_racks: List[Tuple[types.Location, LegacyLabwareCore]],
|
|
567
583
|
starting_tip: Optional[LegacyWellCore],
|
|
568
584
|
trash_location: Union[types.Location, TrashBin, WasteChute],
|
|
569
585
|
return_tip: bool,
|
|
570
586
|
keep_last_tip: bool,
|
|
587
|
+
tips: Optional[List[LegacyWellCore]],
|
|
571
588
|
) -> None:
|
|
572
589
|
"""This will never be called because it was added in API 2.23."""
|
|
573
590
|
assert False, "consolidate_liquid is not supported in legacy context"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import Dict, Optional
|
|
2
|
+
from typing import Dict, Optional, Sequence
|
|
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,6 +16,7 @@ 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
|
|
19
20
|
|
|
20
21
|
logger = logging.getLogger(__name__)
|
|
21
22
|
|
|
@@ -23,7 +24,10 @@ logger = logging.getLogger(__name__)
|
|
|
23
24
|
class LegacyProtocolCoreSimulator(
|
|
24
25
|
LegacyProtocolCore,
|
|
25
26
|
AbstractProtocol[
|
|
26
|
-
LegacyInstrumentCoreSimulator,
|
|
27
|
+
LegacyInstrumentCoreSimulator,
|
|
28
|
+
LegacyLabwareCore,
|
|
29
|
+
LegacyModuleCore,
|
|
30
|
+
LegacyTaskCore,
|
|
27
31
|
],
|
|
28
32
|
):
|
|
29
33
|
_instruments: Dict[Mount, Optional[LegacyInstrumentCoreSimulator]] # type: ignore[assignment]
|
|
@@ -83,3 +87,11 @@ class LegacyProtocolCoreSimulator(
|
|
|
83
87
|
)
|
|
84
88
|
|
|
85
89
|
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"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from ..tasks import AbstractTaskCore
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class LegacyTaskCore(AbstractTaskCore):
|
|
6
|
+
def __init__(self, created_at: datetime) -> None:
|
|
7
|
+
raise NotImplementedError("Legacy protocols do not implement tasks.")
|
|
8
|
+
|
|
9
|
+
def get_created_at_timestamp(self) -> datetime:
|
|
10
|
+
raise NotImplementedError("Legacy protocols do not implement tasks.")
|
|
11
|
+
|
|
12
|
+
def is_done(self) -> bool:
|
|
13
|
+
raise NotImplementedError("Legacy protocols do not implement tasks.")
|
|
14
|
+
|
|
15
|
+
def is_started(self) -> bool:
|
|
16
|
+
raise NotImplementedError("Legacy protocols do not implement tasks.")
|
|
17
|
+
|
|
18
|
+
def get_finished_at_timestamp(self) -> datetime | None:
|
|
19
|
+
raise NotImplementedError("Legacy protocols do not implement tasks.")
|