opentrons 8.7.0a5__py3-none-any.whl → 8.7.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.
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 +129 -52
- 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/hardware_control/api.py +24 -5
- opentrons/hardware_control/backends/controller.py +8 -2
- opentrons/hardware_control/backends/ot3controller.py +3 -0
- opentrons/hardware_control/backends/ot3simulator.py +2 -1
- 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 +82 -8
- 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 +13 -5
- 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/nozzle_manager.py +3 -0
- opentrons/hardware_control/ot3api.py +26 -5
- opentrons/hardware_control/poller.py +22 -8
- opentrons/hardware_control/scripts/update_module_fw.py +5 -0
- opentrons/hardware_control/types.py +31 -2
- opentrons/legacy_commands/module_commands.py +23 -0
- opentrons/legacy_commands/protocol_commands.py +20 -0
- opentrons/legacy_commands/types.py +80 -0
- 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/_types.py +6 -1
- opentrons/protocol_api/core/common.py +3 -1
- opentrons/protocol_api/core/engine/_default_labware_versions.py +32 -11
- opentrons/protocol_api/core/engine/labware.py +8 -1
- opentrons/protocol_api/core/engine/module_core.py +75 -8
- opentrons/protocol_api/core/engine/protocol.py +18 -1
- opentrons/protocol_api/core/engine/tasks.py +48 -0
- opentrons/protocol_api/core/engine/well.py +8 -0
- opentrons/protocol_api/core/legacy/legacy_module_core.py +24 -4
- opentrons/protocol_api/core/legacy/legacy_protocol_core.py +11 -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_protocol_core.py +14 -2
- opentrons/protocol_api/core/legacy_simulator/tasks.py +19 -0
- opentrons/protocol_api/core/module.py +37 -4
- opentrons/protocol_api/core/protocol.py +11 -2
- opentrons/protocol_api/core/tasks.py +31 -0
- opentrons/protocol_api/core/well.py +4 -0
- opentrons/protocol_api/labware.py +5 -0
- opentrons/protocol_api/module_contexts.py +117 -11
- opentrons/protocol_api/protocol_context.py +26 -4
- opentrons/protocol_api/robot_context.py +38 -21
- opentrons/protocol_api/tasks.py +48 -0
- opentrons/protocol_api/validation.py +6 -1
- opentrons/protocol_engine/actions/__init__.py +4 -2
- opentrons/protocol_engine/actions/actions.py +22 -9
- opentrons/protocol_engine/clients/sync_client.py +42 -7
- opentrons/protocol_engine/commands/__init__.py +42 -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/aspirate.py +1 -0
- opentrons/protocol_engine/commands/command.py +1 -0
- opentrons/protocol_engine/commands/command_unions.py +49 -0
- opentrons/protocol_engine/commands/create_timer.py +83 -0
- opentrons/protocol_engine/commands/dispense.py +1 -0
- opentrons/protocol_engine/commands/drop_tip.py +32 -8
- 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/movement_common.py +2 -0
- opentrons/protocol_engine/commands/pick_up_tip.py +21 -11
- 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 +40 -6
- opentrons/protocol_engine/commands/thermocycler/set_target_lid_temperature.py +29 -5
- 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/errors/__init__.py +4 -0
- opentrons/protocol_engine/errors/exceptions.py +55 -0
- opentrons/protocol_engine/execution/__init__.py +2 -0
- opentrons/protocol_engine/execution/command_executor.py +8 -0
- opentrons/protocol_engine/execution/create_queue_worker.py +5 -1
- opentrons/protocol_engine/execution/labware_movement.py +9 -12
- opentrons/protocol_engine/execution/movement.py +2 -0
- 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 +75 -34
- opentrons/protocol_engine/resources/__init__.py +2 -0
- opentrons/protocol_engine/resources/concurrency_provider.py +27 -0
- opentrons/protocol_engine/resources/deck_configuration_provider.py +7 -0
- opentrons/protocol_engine/resources/labware_validation.py +10 -6
- opentrons/protocol_engine/state/_well_math.py +60 -18
- opentrons/protocol_engine/state/addressable_areas.py +2 -0
- opentrons/protocol_engine/state/commands.py +14 -11
- opentrons/protocol_engine/state/geometry.py +213 -374
- opentrons/protocol_engine/state/labware.py +52 -102
- opentrons/protocol_engine/state/labware_origin_math/errors.py +94 -0
- opentrons/protocol_engine/state/labware_origin_math/stackup_origin_to_labware_origin.py +1331 -0
- opentrons/protocol_engine/state/module_substates/thermocycler_module_substate.py +37 -0
- opentrons/protocol_engine/state/modules.py +21 -8
- opentrons/protocol_engine/state/motion.py +44 -0
- opentrons/protocol_engine/state/state.py +14 -0
- opentrons/protocol_engine/state/state_summary.py +2 -0
- opentrons/protocol_engine/state/tasks.py +139 -0
- opentrons/protocol_engine/state/tips.py +177 -258
- opentrons/protocol_engine/state/update_types.py +16 -9
- opentrons/protocol_engine/types/__init__.py +9 -3
- 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/module.py +10 -0
- 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/run_orchestrator.py +18 -2
- opentrons/protocols/api_support/definitions.py +1 -1
- opentrons/protocols/api_support/types.py +2 -1
- opentrons/simulate.py +48 -15
- opentrons/system/camera.py +1 -1
- {opentrons-8.7.0a5.dist-info → opentrons-8.7.0a7.dist-info}/METADATA +4 -4
- {opentrons-8.7.0a5.dist-info → opentrons-8.7.0a7.dist-info}/RECORD +143 -127
- opentrons/protocol_engine/state/_labware_origin_math.py +0 -636
- {opentrons-8.7.0a5.dist-info → opentrons-8.7.0a7.dist-info}/WHEEL +0 -0
- {opentrons-8.7.0a5.dist-info → opentrons-8.7.0a7.dist-info}/entry_points.txt +0 -0
- {opentrons-8.7.0a5.dist-info → opentrons-8.7.0a7.dist-info}/licenses/LICENSE +0 -0
|
@@ -2,12 +2,26 @@ from asyncio import Queue
|
|
|
2
2
|
import enum
|
|
3
3
|
import logging
|
|
4
4
|
from dataclasses import dataclass
|
|
5
|
-
from typing import
|
|
5
|
+
from typing import (
|
|
6
|
+
cast,
|
|
7
|
+
Tuple,
|
|
8
|
+
Union,
|
|
9
|
+
List,
|
|
10
|
+
Callable,
|
|
11
|
+
Dict,
|
|
12
|
+
TypeVar,
|
|
13
|
+
Type,
|
|
14
|
+
TYPE_CHECKING,
|
|
15
|
+
)
|
|
6
16
|
from typing_extensions import Literal
|
|
7
17
|
from opentrons import types as top_types
|
|
8
18
|
from opentrons_shared_data.pipette.types import PipetteChannelType
|
|
19
|
+
from opentrons_shared_data.errors.exceptions import EnumeratedError
|
|
9
20
|
from opentrons.config import feature_flags
|
|
10
21
|
|
|
22
|
+
if TYPE_CHECKING:
|
|
23
|
+
from .modules.types import ModuleModel
|
|
24
|
+
|
|
11
25
|
MODULE_LOG = logging.getLogger(__name__)
|
|
12
26
|
|
|
13
27
|
|
|
@@ -384,6 +398,7 @@ class HardwareEventType(enum.Enum):
|
|
|
384
398
|
DOOR_SWITCH_CHANGE = enum.auto()
|
|
385
399
|
ERROR_MESSAGE = enum.auto()
|
|
386
400
|
ESTOP_CHANGE = enum.auto()
|
|
401
|
+
ASYNCHRONOUS_MODULE_ERROR = enum.auto()
|
|
387
402
|
|
|
388
403
|
|
|
389
404
|
@dataclass
|
|
@@ -428,10 +443,24 @@ class ErrorMessageNotification:
|
|
|
428
443
|
event: Literal[HardwareEventType.ERROR_MESSAGE] = HardwareEventType.ERROR_MESSAGE
|
|
429
444
|
|
|
430
445
|
|
|
446
|
+
@dataclass(frozen=True)
|
|
447
|
+
class AsynchronousModuleErrorNotification:
|
|
448
|
+
exception: EnumeratedError
|
|
449
|
+
module_serial: str | None
|
|
450
|
+
module_model: "ModuleModel"
|
|
451
|
+
port: str
|
|
452
|
+
event: Literal[
|
|
453
|
+
HardwareEventType.ASYNCHRONOUS_MODULE_ERROR
|
|
454
|
+
] = HardwareEventType.ASYNCHRONOUS_MODULE_ERROR
|
|
455
|
+
|
|
456
|
+
|
|
431
457
|
# new event types get new dataclasses
|
|
432
458
|
# when we add more event types we add them here
|
|
433
459
|
HardwareEvent = Union[
|
|
434
|
-
DoorStateNotification,
|
|
460
|
+
DoorStateNotification,
|
|
461
|
+
ErrorMessageNotification,
|
|
462
|
+
EstopStateNotification,
|
|
463
|
+
AsynchronousModuleErrorNotification,
|
|
435
464
|
]
|
|
436
465
|
|
|
437
466
|
HardwareEventHandler = Callable[[HardwareEvent], None]
|
|
@@ -102,6 +102,19 @@ def thermocycler_execute_profile(
|
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
|
|
105
|
+
def thermocycler_start_execute_profile(
|
|
106
|
+
steps: List[ThermocyclerStep], repetitions: int
|
|
107
|
+
) -> command_types.ThermocyclerStartExecuteProfileCommand:
|
|
108
|
+
text = (
|
|
109
|
+
f"In the background, thermocycler starting to run {repetitions} repetitions "
|
|
110
|
+
f" of cycle composed of the following steps: {steps}"
|
|
111
|
+
)
|
|
112
|
+
return {
|
|
113
|
+
"name": command_types.THERMOCYCLER_START_EXECUTE_PROFILE,
|
|
114
|
+
"payload": {"text": text, "steps": steps},
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
|
|
105
118
|
def thermocycler_wait_for_hold() -> command_types.ThermocyclerWaitForHoldCommand:
|
|
106
119
|
text = "Waiting for hold time duration"
|
|
107
120
|
return {"name": command_types.THERMOCYCLER_WAIT_FOR_HOLD, "payload": {"text": text}}
|
|
@@ -183,6 +196,16 @@ def heater_shaker_set_and_wait_for_shake_speed(
|
|
|
183
196
|
}
|
|
184
197
|
|
|
185
198
|
|
|
199
|
+
def heater_shaker_set_shake_speed(
|
|
200
|
+
rpm: int,
|
|
201
|
+
) -> command_types.HeaterShakerSetShakeSpeedCommand:
|
|
202
|
+
text = f"Setting Heater-Shaker to Shake at {rpm} RPM"
|
|
203
|
+
return {
|
|
204
|
+
"name": command_types.HEATER_SHAKER_SET_SHAKE_SPEED,
|
|
205
|
+
"payload": {"text": text},
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
|
|
186
209
|
def heater_shaker_open_labware_latch() -> command_types.HeaterShakerOpenLabwareLatchCommand:
|
|
187
210
|
text = "Unlatching labware on Heater-Shaker"
|
|
188
211
|
return {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from datetime import timedelta
|
|
2
2
|
from typing import Optional
|
|
3
3
|
from . import types as command_types
|
|
4
|
+
from opentrons.protocol_api.tasks import Task
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
def comment(msg: str) -> command_types.CommentCommand:
|
|
@@ -52,3 +53,22 @@ def move_labware(text: str) -> command_types.MoveLabwareCommand:
|
|
|
52
53
|
"name": command_types.MOVE_LABWARE,
|
|
53
54
|
"payload": {"text": text},
|
|
54
55
|
}
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def wait_for_tasks(tasks: list[Task]) -> command_types.WaitForTasksCommand:
|
|
59
|
+
task_ids = [task.created_at.strftime("%Y-%m-%d %H:%M:%S") for task in tasks]
|
|
60
|
+
msg = f"Waiting for tasks that started at: {task_ids}."
|
|
61
|
+
return {
|
|
62
|
+
"name": command_types.WAIT_FOR_TASKS,
|
|
63
|
+
"payload": {"text": msg},
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def create_timer(seconds: float) -> command_types.CreateTimerCommand:
|
|
68
|
+
return {
|
|
69
|
+
"name": command_types.CREATE_TIMER,
|
|
70
|
+
"payload": {
|
|
71
|
+
"text": f"Creating background timer for {seconds} seconds.",
|
|
72
|
+
"time": seconds,
|
|
73
|
+
},
|
|
74
|
+
}
|
|
@@ -64,6 +64,7 @@ HEATER_SHAKER_WAIT_FOR_TEMPERATURE: Final = "command.HEATER_SHAKER_WAIT_FOR_TEMP
|
|
|
64
64
|
HEATER_SHAKER_SET_AND_WAIT_FOR_SHAKE_SPEED: Final = (
|
|
65
65
|
"command.HEATER_SHAKER_SET_AND_WAIT_FOR_SHAKE_SPEED"
|
|
66
66
|
)
|
|
67
|
+
HEATER_SHAKER_SET_SHAKE_SPEED: Final = "command.HEATER_SHAKER_SET_SHAKE_SPEED"
|
|
67
68
|
HEATER_SHAKER_OPEN_LABWARE_LATCH: Final = "command.HEATER_SHAKER_OPEN_LABWARE_LATCH"
|
|
68
69
|
HEATER_SHAKER_CLOSE_LABWARE_LATCH: Final = "command.HEATER_SHAKER_CLOSE_LABWARE_LATCH"
|
|
69
70
|
HEATER_SHAKER_DEACTIVATE_SHAKER: Final = "command.HEATER_SHAKER_DEACTIVATE_SHAKER"
|
|
@@ -81,6 +82,7 @@ THERMOCYCLER_OPEN: Final = "command.THERMOCYCLER_OPEN"
|
|
|
81
82
|
THERMOCYCLER_CLOSE: Final = "command.THERMOCYCLER_CLOSE"
|
|
82
83
|
THERMOCYCLER_SET_BLOCK_TEMP: Final = "command.THERMOCYCLER_SET_BLOCK_TEMP"
|
|
83
84
|
THERMOCYCLER_EXECUTE_PROFILE: Final = "command.THERMOCYCLER_EXECUTE_PROFILE"
|
|
85
|
+
THERMOCYCLER_START_EXECUTE_PROFILE: Final = "command.THERMOCYCLER_START_EXECUTE_PROFILE"
|
|
84
86
|
THERMOCYCLER_DEACTIVATE: Final = "command.THERMOCYCLER_DEACTIVATE"
|
|
85
87
|
THERMOCYCLER_WAIT_FOR_HOLD: Final = "command.THERMOCYCLER_WAIT_FOR_HOLD"
|
|
86
88
|
THERMOCYCLER_WAIT_FOR_TEMP: Final = "command.THERMOCYCLER_WAIT_FOR_TEMP"
|
|
@@ -102,6 +104,10 @@ ROBOT_MOVE_RELATIVE_TO: Final = "command.ROBOT_MOVE_RELATIVE_TO"
|
|
|
102
104
|
ROBOT_OPEN_GRIPPER_JAW: Final = "command.ROBOT_OPEN_GRIPPER_JAW"
|
|
103
105
|
ROBOT_CLOSE_GRIPPER_JAW: Final = "command.ROBOT_CLOSE_GRIPPER_JAW"
|
|
104
106
|
|
|
107
|
+
# Tasks #
|
|
108
|
+
WAIT_FOR_TASKS: Final = "command.WAIT_FOR_TASKS"
|
|
109
|
+
CREATE_TIMER: Final = "command.CREATE_TIMER"
|
|
110
|
+
|
|
105
111
|
|
|
106
112
|
class TextOnlyPayload(TypedDict):
|
|
107
113
|
text: str
|
|
@@ -190,6 +196,15 @@ class HeaterShakerSetAndWaitForShakeSpeedCommand(TypedDict):
|
|
|
190
196
|
payload: HeaterShakerSetAndWaitForShakeSpeedPayload
|
|
191
197
|
|
|
192
198
|
|
|
199
|
+
class HeaterShakerSetShakeSpeedPayload(TextOnlyPayload):
|
|
200
|
+
pass
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
class HeaterShakerSetShakeSpeedCommand(TypedDict):
|
|
204
|
+
name: Literal["command.HEATER_SHAKER_SET_SHAKE_SPEED"]
|
|
205
|
+
payload: HeaterShakerSetShakeSpeedPayload
|
|
206
|
+
|
|
207
|
+
|
|
193
208
|
class HeaterShakerOpenLabwareLatchPayload(TextOnlyPayload):
|
|
194
209
|
pass
|
|
195
210
|
|
|
@@ -308,6 +323,15 @@ class ThermocyclerExecuteProfileCommand(TypedDict):
|
|
|
308
323
|
payload: ThermocyclerExecuteProfileCommandPayload
|
|
309
324
|
|
|
310
325
|
|
|
326
|
+
class ThermocyclerStartExecuteProfileCommandPayload(TextOnlyPayload):
|
|
327
|
+
steps: List[ThermocyclerStep]
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
class ThermocyclerStartExecuteProfileCommand(TypedDict):
|
|
331
|
+
name: Literal["command.THERMOCYCLER_START_EXECUTE_PROFILE"]
|
|
332
|
+
payload: ThermocyclerStartExecuteProfileCommandPayload
|
|
333
|
+
|
|
334
|
+
|
|
311
335
|
class ThermocyclerWaitForHoldCommandPayload(TextOnlyPayload):
|
|
312
336
|
pass
|
|
313
337
|
|
|
@@ -714,6 +738,27 @@ class RobotCloseGripperJawCommand(TypedDict):
|
|
|
714
738
|
payload: GripperCommandPayload
|
|
715
739
|
|
|
716
740
|
|
|
741
|
+
# Task Commands and Payloads
|
|
742
|
+
|
|
743
|
+
|
|
744
|
+
class WaitForTasksPayload(TextOnlyPayload):
|
|
745
|
+
pass
|
|
746
|
+
|
|
747
|
+
|
|
748
|
+
class CreateTimerPayload(TextOnlyPayload):
|
|
749
|
+
time: float
|
|
750
|
+
|
|
751
|
+
|
|
752
|
+
class WaitForTasksCommand(TypedDict):
|
|
753
|
+
name: Literal["command.WAIT_FOR_TASKS"]
|
|
754
|
+
payload: WaitForTasksPayload
|
|
755
|
+
|
|
756
|
+
|
|
757
|
+
class CreateTimerCommand(TypedDict):
|
|
758
|
+
name: Literal["command.CREATE_TIMER"]
|
|
759
|
+
payload: CreateTimerPayload
|
|
760
|
+
|
|
761
|
+
|
|
717
762
|
Command = Union[
|
|
718
763
|
DropTipCommand,
|
|
719
764
|
DropTipInDisposalLocationCommand,
|
|
@@ -734,6 +779,7 @@ Command = Union[
|
|
|
734
779
|
HeaterShakerSetTargetTemperatureCommand,
|
|
735
780
|
HeaterShakerWaitForTemperatureCommand,
|
|
736
781
|
HeaterShakerSetAndWaitForShakeSpeedCommand,
|
|
782
|
+
HeaterShakerSetShakeSpeedCommand,
|
|
737
783
|
HeaterShakerOpenLabwareLatchCommand,
|
|
738
784
|
HeaterShakerCloseLabwareLatchCommand,
|
|
739
785
|
HeaterShakerDeactivateShakerCommand,
|
|
@@ -747,6 +793,7 @@ Command = Union[
|
|
|
747
793
|
ThermocyclerWaitForTempCommand,
|
|
748
794
|
ThermocyclerWaitForHoldCommand,
|
|
749
795
|
ThermocyclerExecuteProfileCommand,
|
|
796
|
+
ThermocyclerStartExecuteProfileCommand,
|
|
750
797
|
ThermocyclerSetBlockTempCommand,
|
|
751
798
|
ThermocyclerOpenCommand,
|
|
752
799
|
TempdeckDeactivateCommand,
|
|
@@ -782,6 +829,9 @@ Command = Union[
|
|
|
782
829
|
FlexStackerStoreCommand,
|
|
783
830
|
FlexStackerEmptyCommand,
|
|
784
831
|
FlexStackerFillCommand,
|
|
832
|
+
# Task commands
|
|
833
|
+
WaitForTasksCommand,
|
|
834
|
+
CreateTimerCommand,
|
|
785
835
|
]
|
|
786
836
|
|
|
787
837
|
|
|
@@ -791,6 +841,7 @@ CommandPayload = Union[
|
|
|
791
841
|
HeaterShakerSetTargetTemperaturePayload,
|
|
792
842
|
HeaterShakerWaitForTemperaturePayload,
|
|
793
843
|
HeaterShakerSetAndWaitForShakeSpeedPayload,
|
|
844
|
+
HeaterShakerSetShakeSpeedPayload,
|
|
794
845
|
HeaterShakerOpenLabwareLatchPayload,
|
|
795
846
|
HeaterShakerCloseLabwareLatchPayload,
|
|
796
847
|
HeaterShakerDeactivateShakerPayload,
|
|
@@ -823,6 +874,7 @@ CommandPayload = Union[
|
|
|
823
874
|
DispenseInDisposalLocationCommandPayload,
|
|
824
875
|
HomeCommandPayload,
|
|
825
876
|
ThermocyclerExecuteProfileCommandPayload,
|
|
877
|
+
ThermocyclerStartExecuteProfileCommandPayload,
|
|
826
878
|
ThermocyclerSetBlockTempCommandPayload,
|
|
827
879
|
TempdeckAwaitTempCommandPayload,
|
|
828
880
|
TempdeckSetTempCommandPayload,
|
|
@@ -842,6 +894,9 @@ CommandPayload = Union[
|
|
|
842
894
|
RobotMoveAxisRelativeCommandPayload,
|
|
843
895
|
RobotMoveAxisToCommandPayload,
|
|
844
896
|
GripperCommandPayload,
|
|
897
|
+
# Task payloads
|
|
898
|
+
WaitForTasksPayload,
|
|
899
|
+
CreateTimerPayload,
|
|
845
900
|
]
|
|
846
901
|
|
|
847
902
|
|
|
@@ -952,6 +1007,12 @@ class HeaterShakerSetAndWaitForShakeSpeedMessage(
|
|
|
952
1007
|
pass
|
|
953
1008
|
|
|
954
1009
|
|
|
1010
|
+
class HeaterShakerSetShakeSpeedMessage(
|
|
1011
|
+
CommandMessageFields, HeaterShakerSetShakeSpeedCommand
|
|
1012
|
+
):
|
|
1013
|
+
pass
|
|
1014
|
+
|
|
1015
|
+
|
|
955
1016
|
class HeaterShakerOpenLabwareLatchMessage(
|
|
956
1017
|
CommandMessageFields, HeaterShakerOpenLabwareLatchCommand
|
|
957
1018
|
):
|
|
@@ -1028,6 +1089,12 @@ class ThermocyclerExecuteProfileMessage(
|
|
|
1028
1089
|
pass
|
|
1029
1090
|
|
|
1030
1091
|
|
|
1092
|
+
class ThermocyclerStartExecuteProfileMessage(
|
|
1093
|
+
CommandMessageFields, ThermocyclerStartExecuteProfileCommand
|
|
1094
|
+
):
|
|
1095
|
+
pass
|
|
1096
|
+
|
|
1097
|
+
|
|
1031
1098
|
class ThermocyclerSetBlockTempMessage(
|
|
1032
1099
|
CommandMessageFields, ThermocyclerSetBlockTempCommand
|
|
1033
1100
|
):
|
|
@@ -1124,6 +1191,14 @@ class RobotCloseGripperJawMessage(CommandMessageFields, RobotCloseGripperJawComm
|
|
|
1124
1191
|
pass
|
|
1125
1192
|
|
|
1126
1193
|
|
|
1194
|
+
class WaitForTasksMessage(CommandMessageFields, WaitForTasksCommand):
|
|
1195
|
+
pass
|
|
1196
|
+
|
|
1197
|
+
|
|
1198
|
+
class CreateTimerMessage(CommandMessageFields, CreateTimerCommand):
|
|
1199
|
+
pass
|
|
1200
|
+
|
|
1201
|
+
|
|
1127
1202
|
CommandMessage = Union[
|
|
1128
1203
|
DropTipMessage,
|
|
1129
1204
|
DropTipInDisposalLocationMessage,
|
|
@@ -1144,6 +1219,7 @@ CommandMessage = Union[
|
|
|
1144
1219
|
HeaterShakerSetTargetTemperatureMessage,
|
|
1145
1220
|
HeaterShakerWaitForTemperatureMessage,
|
|
1146
1221
|
HeaterShakerSetAndWaitForShakeSpeedMessage,
|
|
1222
|
+
HeaterShakerSetShakeSpeedMessage,
|
|
1147
1223
|
HeaterShakerOpenLabwareLatchMessage,
|
|
1148
1224
|
HeaterShakerCloseLabwareLatchMessage,
|
|
1149
1225
|
HeaterShakerDeactivateShakerMessage,
|
|
@@ -1157,6 +1233,7 @@ CommandMessage = Union[
|
|
|
1157
1233
|
ThermocyclerWaitForTempMessage,
|
|
1158
1234
|
ThermocyclerWaitForHoldMessage,
|
|
1159
1235
|
ThermocyclerExecuteProfileMessage,
|
|
1236
|
+
ThermocyclerStartExecuteProfileMessage,
|
|
1160
1237
|
ThermocyclerSetBlockTempMessage,
|
|
1161
1238
|
ThermocyclerOpenMessage,
|
|
1162
1239
|
TempdeckSetTempMessage,
|
|
@@ -1183,4 +1260,7 @@ CommandMessage = Union[
|
|
|
1183
1260
|
FlexStackerStoreMessage,
|
|
1184
1261
|
FlexStackerEmptyMessage,
|
|
1185
1262
|
FlexStackerFillMessage,
|
|
1263
|
+
# Task Messages
|
|
1264
|
+
WaitForTasksMessage,
|
|
1265
|
+
CreateTimerMessage,
|
|
1186
1266
|
]
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
from collections.abc import Container
|
|
5
6
|
from dataclasses import dataclass
|
|
6
7
|
from typing import List, Mapping, NamedTuple, Optional, Set, Union
|
|
7
8
|
from typing_extensions import Final
|
|
@@ -15,6 +16,7 @@ from opentrons.motion_planning.adjacent_slots_getters import (
|
|
|
15
16
|
get_adjacent_staging_slot,
|
|
16
17
|
)
|
|
17
18
|
|
|
19
|
+
from opentrons.protocols.api_support.constants import OPENTRONS_NAMESPACE
|
|
18
20
|
from opentrons.types import DeckSlotName, StagingSlotName
|
|
19
21
|
|
|
20
22
|
_FIXED_TRASH_SLOT: Final[Set[DeckSlotName]] = {
|
|
@@ -37,14 +39,14 @@ HS_MAX_X_ADJACENT_ITEM_HEIGHT = 53.0
|
|
|
37
39
|
# For background, see: https://github.com/Opentrons/opentrons/issues/10316
|
|
38
40
|
#
|
|
39
41
|
# TODO(mc, 2022-06-16): move this constant to the module definition
|
|
40
|
-
HS_ALLOWED_ADJACENT_TALL_LABWARE =
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
42
|
+
HS_ALLOWED_ADJACENT_TALL_LABWARE = {
|
|
43
|
+
"opentrons_96_filtertiprack_10ul",
|
|
44
|
+
"opentrons_96_filtertiprack_200ul",
|
|
45
|
+
"opentrons_96_filtertiprack_20ul",
|
|
46
|
+
"opentrons_96_tiprack_10ul",
|
|
47
|
+
"opentrons_96_tiprack_20ul",
|
|
48
|
+
"opentrons_96_tiprack_300ul",
|
|
49
|
+
}
|
|
48
50
|
|
|
49
51
|
|
|
50
52
|
@dataclass
|
|
@@ -156,11 +158,15 @@ class _MaxHeight(NamedTuple):
|
|
|
156
158
|
source_item: DeckItem
|
|
157
159
|
source_location: DeckSlotName
|
|
158
160
|
max_height: float
|
|
159
|
-
|
|
161
|
+
allowed_labware_load_names: Container[str]
|
|
160
162
|
|
|
161
163
|
def is_allowed(self, item: DeckItem) -> bool:
|
|
162
164
|
if isinstance(item, Labware):
|
|
163
|
-
|
|
165
|
+
namespace, load_name, _version = item.uri.split("/")
|
|
166
|
+
if (
|
|
167
|
+
namespace == OPENTRONS_NAMESPACE
|
|
168
|
+
and load_name in self.allowed_labware_load_names
|
|
169
|
+
):
|
|
164
170
|
return True
|
|
165
171
|
else:
|
|
166
172
|
return item.highest_z < self.max_height
|
|
@@ -315,7 +321,7 @@ def _create_ot2_restrictions( # noqa: C901
|
|
|
315
321
|
source_item=item,
|
|
316
322
|
source_location=location,
|
|
317
323
|
max_height=HS_MAX_X_ADJACENT_ITEM_HEIGHT,
|
|
318
|
-
|
|
324
|
+
allowed_labware_load_names=HS_ALLOWED_ADJACENT_TALL_LABWARE,
|
|
319
325
|
)
|
|
320
326
|
)
|
|
321
327
|
|
|
@@ -434,7 +440,6 @@ def _create_flex_restrictions( # noqa: C901
|
|
|
434
440
|
def _create_restrictions(
|
|
435
441
|
item: DeckItem, location: Union[DeckSlotName, StagingSlotName], robot_type: str
|
|
436
442
|
) -> List[_DeckRestriction]:
|
|
437
|
-
|
|
438
443
|
if robot_type == "OT-2 Standard":
|
|
439
444
|
return _create_ot2_restrictions(item, location)
|
|
440
445
|
else:
|
|
@@ -7,7 +7,6 @@ from opentrons.hardware_control.types import CriticalPoint
|
|
|
7
7
|
|
|
8
8
|
from .types import Waypoint, MoveType, GripperMovementWaypointsWithJawStatus
|
|
9
9
|
from .errors import DestinationOutOfBoundsError, ArcOutOfBoundsError
|
|
10
|
-
from ..protocol_engine.types import LabwareMovementOffsetData
|
|
11
10
|
|
|
12
11
|
DEFAULT_GENERAL_ARC_Z_MARGIN: Final[float] = 10.0
|
|
13
12
|
DEFAULT_IN_LABWARE_ARC_Z_MARGIN: Final[float] = 5.0
|
|
@@ -125,47 +124,41 @@ def get_gripper_labware_movement_waypoints(
|
|
|
125
124
|
from_labware_center: Point,
|
|
126
125
|
to_labware_center: Point,
|
|
127
126
|
gripper_home_z: float,
|
|
128
|
-
offset_data: LabwareMovementOffsetData,
|
|
129
127
|
post_drop_slide_offset: Optional[Point],
|
|
130
128
|
gripper_home_z_offset: Optional[float] = None,
|
|
131
129
|
) -> List[GripperMovementWaypointsWithJawStatus]:
|
|
132
130
|
"""Get waypoints for moving labware using a gripper."""
|
|
133
|
-
pick_up_offset = offset_data.pickUpOffset
|
|
134
|
-
drop_offset = offset_data.dropOffset
|
|
135
|
-
|
|
136
|
-
pick_up_location = from_labware_center + Point(
|
|
137
|
-
pick_up_offset.x, pick_up_offset.y, pick_up_offset.z
|
|
138
|
-
)
|
|
139
|
-
drop_location = to_labware_center + Point(
|
|
140
|
-
drop_offset.x, drop_offset.y, drop_offset.z
|
|
141
|
-
)
|
|
142
|
-
|
|
143
131
|
gripper_max_z_home = gripper_home_z - (gripper_home_z_offset or 0)
|
|
144
|
-
|
|
145
|
-
post_drop_home_pos = Point(drop_location.x, drop_location.y, gripper_home_z)
|
|
132
|
+
post_drop_home_pos = Point(to_labware_center.x, to_labware_center.y, gripper_home_z)
|
|
146
133
|
|
|
147
134
|
waypoints_with_jaw_status = [
|
|
148
135
|
GripperMovementWaypointsWithJawStatus(
|
|
149
|
-
position=Point(
|
|
136
|
+
position=Point(
|
|
137
|
+
from_labware_center.x, from_labware_center.y, gripper_home_z
|
|
138
|
+
),
|
|
150
139
|
jaw_open=False,
|
|
151
140
|
dropping=False,
|
|
152
141
|
),
|
|
153
142
|
GripperMovementWaypointsWithJawStatus(
|
|
154
|
-
position=
|
|
143
|
+
position=from_labware_center, jaw_open=True, dropping=False
|
|
155
144
|
),
|
|
156
145
|
# Gripper grips the labware here
|
|
157
146
|
GripperMovementWaypointsWithJawStatus(
|
|
158
|
-
position=Point(
|
|
147
|
+
position=Point(
|
|
148
|
+
from_labware_center.x, from_labware_center.y, gripper_max_z_home
|
|
149
|
+
),
|
|
159
150
|
jaw_open=False,
|
|
160
151
|
dropping=False,
|
|
161
152
|
),
|
|
162
153
|
GripperMovementWaypointsWithJawStatus(
|
|
163
|
-
position=Point(
|
|
154
|
+
position=Point(
|
|
155
|
+
to_labware_center.x, to_labware_center.y, gripper_max_z_home
|
|
156
|
+
),
|
|
164
157
|
jaw_open=False,
|
|
165
158
|
dropping=False,
|
|
166
159
|
),
|
|
167
160
|
GripperMovementWaypointsWithJawStatus(
|
|
168
|
-
position=
|
|
161
|
+
position=to_labware_center, jaw_open=False, dropping=False
|
|
169
162
|
),
|
|
170
163
|
# Gripper ungrips here
|
|
171
164
|
GripperMovementWaypointsWithJawStatus(
|
|
@@ -189,25 +182,18 @@ def get_gripper_labware_movement_waypoints(
|
|
|
189
182
|
def get_gripper_labware_placement_waypoints(
|
|
190
183
|
to_labware_center: Point,
|
|
191
184
|
gripper_home_z: float,
|
|
192
|
-
drop_offset: Optional[Point],
|
|
193
185
|
) -> List[GripperMovementWaypointsWithJawStatus]:
|
|
194
186
|
"""Get waypoints for placing labware using a gripper."""
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
drop_location = to_labware_center + Point(
|
|
198
|
-
drop_offset.x, drop_offset.y, drop_offset.z
|
|
199
|
-
)
|
|
200
|
-
|
|
201
|
-
post_drop_home_pos = Point(drop_location.x, drop_location.y, gripper_home_z)
|
|
187
|
+
post_drop_home_pos = Point(to_labware_center.x, to_labware_center.y, gripper_home_z)
|
|
202
188
|
|
|
203
189
|
return [
|
|
204
190
|
GripperMovementWaypointsWithJawStatus(
|
|
205
|
-
position=Point(
|
|
191
|
+
position=Point(to_labware_center.x, to_labware_center.y, gripper_home_z),
|
|
206
192
|
jaw_open=False,
|
|
207
193
|
dropping=False,
|
|
208
194
|
),
|
|
209
195
|
GripperMovementWaypointsWithJawStatus(
|
|
210
|
-
position=
|
|
196
|
+
position=to_labware_center, jaw_open=False, dropping=False
|
|
211
197
|
),
|
|
212
198
|
# Gripper ungrips here
|
|
213
199
|
GripperMovementWaypointsWithJawStatus(
|
|
@@ -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
|
+
from .tasks import Task
|
|
18
18
|
from .protocol_context import ProtocolContext
|
|
19
19
|
from .deck import Deck
|
|
20
20
|
from .robot_context import RobotContext
|
|
@@ -33,6 +33,7 @@ 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,
|
|
36
37
|
OFF_DECK,
|
|
37
38
|
PLUNGER_BLOWOUT,
|
|
38
39
|
PLUNGER_TOP,
|
|
@@ -88,6 +89,7 @@ __all__ = [
|
|
|
88
89
|
"ROW",
|
|
89
90
|
"ALL",
|
|
90
91
|
# Deck location types
|
|
92
|
+
"OffDeckType",
|
|
91
93
|
"OFF_DECK",
|
|
92
94
|
# Pipette plunger types
|
|
93
95
|
"PLUNGER_BLOWOUT",
|
|
@@ -99,6 +101,8 @@ __all__ = [
|
|
|
99
101
|
"BLOWOUT_ACTION",
|
|
100
102
|
"RuntimeParameterRequiredError",
|
|
101
103
|
"CSVParameter",
|
|
104
|
+
# Concurrent task types
|
|
105
|
+
"Task",
|
|
102
106
|
# For internal Opentrons use only:
|
|
103
107
|
"create_protocol_context",
|
|
104
108
|
"ProtocolEngineCoreRequiredError",
|
opentrons/protocol_api/_types.py
CHANGED
|
@@ -3,8 +3,13 @@ from typing_extensions import Final
|
|
|
3
3
|
import enum
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# Implemented with an enum to support type narrowing via `== OFF_DECK`.
|
|
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
|
+
|
|
8
13
|
OFF_DECK = "off-deck"
|
|
9
14
|
|
|
10
15
|
|
|
@@ -16,6 +16,7 @@ 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
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
WellCore = AbstractWellCore
|
|
@@ -30,4 +31,5 @@ MagneticBlockCore = AbstractMagneticBlockCore[LabwareCore]
|
|
|
30
31
|
AbsorbanceReaderCore = AbstractAbsorbanceReaderCore[LabwareCore]
|
|
31
32
|
FlexStackerCore = AbstractFlexStackerCore[LabwareCore]
|
|
32
33
|
RobotCore = AbstractRobot
|
|
33
|
-
|
|
34
|
+
TaskCore = AbstractTaskCore
|
|
35
|
+
ProtocolCore = AbstractProtocol[InstrumentCore, LabwareCore, ModuleCore, TaskCore]
|
|
@@ -112,6 +112,37 @@ 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
|
+
},
|
|
115
146
|
}
|
|
116
147
|
|
|
117
148
|
|
|
@@ -139,17 +170,7 @@ KNOWN_EXCEPTIONS_FOR_TESTS: set[str] = {
|
|
|
139
170
|
"schema3test_flex_tiprack_lid",
|
|
140
171
|
"schema3test_tough_pcr_auto_sealing_lid",
|
|
141
172
|
"schema3test_universal_flat_adapter",
|
|
142
|
-
|
|
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",
|
|
173
|
+
"schema3test_96_wellplate_360ul_flat",
|
|
153
174
|
}
|
|
154
175
|
|
|
155
176
|
|
|
@@ -23,6 +23,7 @@ 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,
|
|
26
27
|
)
|
|
27
28
|
from opentrons.types import DeckSlotName, NozzleMapInterface, Point, StagingSlotName
|
|
28
29
|
|
|
@@ -165,7 +166,13 @@ class LabwareCore(AbstractLabware[WellCore]):
|
|
|
165
166
|
|
|
166
167
|
def reset_tips(self) -> None:
|
|
167
168
|
if self.is_tip_rack():
|
|
168
|
-
self._engine_client.
|
|
169
|
+
self._engine_client.execute_command(
|
|
170
|
+
cmd.SetTipStateParams(
|
|
171
|
+
labwareId=self._labware_id,
|
|
172
|
+
wellNames=list(self._definition.wells),
|
|
173
|
+
tipWellState=TipRackWellState.CLEAN,
|
|
174
|
+
)
|
|
175
|
+
)
|
|
169
176
|
else:
|
|
170
177
|
raise TypeError(f"{self.get_display_name()} is not a tip rack.")
|
|
171
178
|
|