opentrons 8.7.0a6__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.

Files changed (144) hide show
  1. opentrons/_version.py +2 -2
  2. opentrons/drivers/asyncio/communication/serial_connection.py +129 -52
  3. opentrons/drivers/heater_shaker/abstract.py +5 -0
  4. opentrons/drivers/heater_shaker/driver.py +10 -0
  5. opentrons/drivers/heater_shaker/simulator.py +4 -0
  6. opentrons/drivers/thermocycler/abstract.py +6 -0
  7. opentrons/drivers/thermocycler/driver.py +61 -10
  8. opentrons/drivers/thermocycler/simulator.py +6 -0
  9. opentrons/hardware_control/api.py +24 -5
  10. opentrons/hardware_control/backends/controller.py +8 -2
  11. opentrons/hardware_control/backends/ot3controller.py +3 -0
  12. opentrons/hardware_control/backends/ot3simulator.py +2 -1
  13. opentrons/hardware_control/backends/simulator.py +2 -1
  14. opentrons/hardware_control/backends/subsystem_manager.py +5 -2
  15. opentrons/hardware_control/emulation/abstract_emulator.py +6 -4
  16. opentrons/hardware_control/emulation/connection_handler.py +8 -5
  17. opentrons/hardware_control/emulation/heater_shaker.py +12 -3
  18. opentrons/hardware_control/emulation/settings.py +1 -1
  19. opentrons/hardware_control/emulation/thermocycler.py +67 -15
  20. opentrons/hardware_control/module_control.py +82 -8
  21. opentrons/hardware_control/modules/__init__.py +3 -0
  22. opentrons/hardware_control/modules/absorbance_reader.py +11 -4
  23. opentrons/hardware_control/modules/flex_stacker.py +38 -9
  24. opentrons/hardware_control/modules/heater_shaker.py +42 -5
  25. opentrons/hardware_control/modules/magdeck.py +8 -4
  26. opentrons/hardware_control/modules/mod_abc.py +13 -5
  27. opentrons/hardware_control/modules/tempdeck.py +25 -5
  28. opentrons/hardware_control/modules/thermocycler.py +68 -11
  29. opentrons/hardware_control/modules/types.py +20 -1
  30. opentrons/hardware_control/modules/utils.py +11 -4
  31. opentrons/hardware_control/nozzle_manager.py +3 -0
  32. opentrons/hardware_control/ot3api.py +26 -5
  33. opentrons/hardware_control/poller.py +22 -8
  34. opentrons/hardware_control/scripts/update_module_fw.py +5 -0
  35. opentrons/hardware_control/types.py +31 -2
  36. opentrons/legacy_commands/module_commands.py +23 -0
  37. opentrons/legacy_commands/protocol_commands.py +20 -0
  38. opentrons/legacy_commands/types.py +80 -0
  39. opentrons/motion_planning/deck_conflict.py +17 -12
  40. opentrons/motion_planning/waypoints.py +15 -29
  41. opentrons/protocol_api/__init__.py +5 -1
  42. opentrons/protocol_api/_types.py +6 -1
  43. opentrons/protocol_api/core/common.py +3 -1
  44. opentrons/protocol_api/core/engine/_default_labware_versions.py +32 -11
  45. opentrons/protocol_api/core/engine/labware.py +8 -1
  46. opentrons/protocol_api/core/engine/module_core.py +75 -8
  47. opentrons/protocol_api/core/engine/protocol.py +18 -1
  48. opentrons/protocol_api/core/engine/tasks.py +48 -0
  49. opentrons/protocol_api/core/engine/well.py +8 -0
  50. opentrons/protocol_api/core/legacy/legacy_module_core.py +24 -4
  51. opentrons/protocol_api/core/legacy/legacy_protocol_core.py +11 -1
  52. opentrons/protocol_api/core/legacy/legacy_well_core.py +4 -0
  53. opentrons/protocol_api/core/legacy/tasks.py +19 -0
  54. opentrons/protocol_api/core/legacy_simulator/legacy_protocol_core.py +14 -2
  55. opentrons/protocol_api/core/legacy_simulator/tasks.py +19 -0
  56. opentrons/protocol_api/core/module.py +37 -4
  57. opentrons/protocol_api/core/protocol.py +11 -2
  58. opentrons/protocol_api/core/tasks.py +31 -0
  59. opentrons/protocol_api/core/well.py +4 -0
  60. opentrons/protocol_api/labware.py +5 -0
  61. opentrons/protocol_api/module_contexts.py +117 -11
  62. opentrons/protocol_api/protocol_context.py +26 -4
  63. opentrons/protocol_api/robot_context.py +38 -21
  64. opentrons/protocol_api/tasks.py +48 -0
  65. opentrons/protocol_api/validation.py +6 -1
  66. opentrons/protocol_engine/actions/__init__.py +4 -2
  67. opentrons/protocol_engine/actions/actions.py +22 -9
  68. opentrons/protocol_engine/clients/sync_client.py +42 -7
  69. opentrons/protocol_engine/commands/__init__.py +42 -0
  70. opentrons/protocol_engine/commands/absorbance_reader/close_lid.py +2 -15
  71. opentrons/protocol_engine/commands/absorbance_reader/open_lid.py +2 -15
  72. opentrons/protocol_engine/commands/aspirate.py +1 -0
  73. opentrons/protocol_engine/commands/command.py +1 -0
  74. opentrons/protocol_engine/commands/command_unions.py +49 -0
  75. opentrons/protocol_engine/commands/create_timer.py +83 -0
  76. opentrons/protocol_engine/commands/dispense.py +1 -0
  77. opentrons/protocol_engine/commands/drop_tip.py +32 -8
  78. opentrons/protocol_engine/commands/heater_shaker/__init__.py +14 -0
  79. opentrons/protocol_engine/commands/heater_shaker/common.py +20 -0
  80. opentrons/protocol_engine/commands/heater_shaker/set_and_wait_for_shake_speed.py +5 -4
  81. opentrons/protocol_engine/commands/heater_shaker/set_shake_speed.py +136 -0
  82. opentrons/protocol_engine/commands/heater_shaker/set_target_temperature.py +31 -5
  83. opentrons/protocol_engine/commands/movement_common.py +2 -0
  84. opentrons/protocol_engine/commands/pick_up_tip.py +21 -11
  85. opentrons/protocol_engine/commands/set_tip_state.py +97 -0
  86. opentrons/protocol_engine/commands/temperature_module/set_target_temperature.py +38 -7
  87. opentrons/protocol_engine/commands/thermocycler/__init__.py +16 -0
  88. opentrons/protocol_engine/commands/thermocycler/run_extended_profile.py +6 -0
  89. opentrons/protocol_engine/commands/thermocycler/run_profile.py +8 -0
  90. opentrons/protocol_engine/commands/thermocycler/set_target_block_temperature.py +40 -6
  91. opentrons/protocol_engine/commands/thermocycler/set_target_lid_temperature.py +29 -5
  92. opentrons/protocol_engine/commands/thermocycler/start_run_extended_profile.py +191 -0
  93. opentrons/protocol_engine/commands/touch_tip.py +1 -1
  94. opentrons/protocol_engine/commands/unsafe/unsafe_place_labware.py +6 -22
  95. opentrons/protocol_engine/commands/wait_for_tasks.py +98 -0
  96. opentrons/protocol_engine/errors/__init__.py +4 -0
  97. opentrons/protocol_engine/errors/exceptions.py +55 -0
  98. opentrons/protocol_engine/execution/__init__.py +2 -0
  99. opentrons/protocol_engine/execution/command_executor.py +8 -0
  100. opentrons/protocol_engine/execution/create_queue_worker.py +5 -1
  101. opentrons/protocol_engine/execution/labware_movement.py +9 -12
  102. opentrons/protocol_engine/execution/movement.py +2 -0
  103. opentrons/protocol_engine/execution/queue_worker.py +4 -0
  104. opentrons/protocol_engine/execution/run_control.py +8 -0
  105. opentrons/protocol_engine/execution/task_handler.py +157 -0
  106. opentrons/protocol_engine/protocol_engine.py +75 -34
  107. opentrons/protocol_engine/resources/__init__.py +2 -0
  108. opentrons/protocol_engine/resources/concurrency_provider.py +27 -0
  109. opentrons/protocol_engine/resources/deck_configuration_provider.py +7 -0
  110. opentrons/protocol_engine/resources/labware_validation.py +10 -6
  111. opentrons/protocol_engine/state/_well_math.py +60 -18
  112. opentrons/protocol_engine/state/addressable_areas.py +2 -0
  113. opentrons/protocol_engine/state/commands.py +14 -11
  114. opentrons/protocol_engine/state/geometry.py +213 -374
  115. opentrons/protocol_engine/state/labware.py +52 -102
  116. opentrons/protocol_engine/state/labware_origin_math/errors.py +94 -0
  117. opentrons/protocol_engine/state/labware_origin_math/stackup_origin_to_labware_origin.py +1331 -0
  118. opentrons/protocol_engine/state/module_substates/thermocycler_module_substate.py +37 -0
  119. opentrons/protocol_engine/state/modules.py +21 -8
  120. opentrons/protocol_engine/state/motion.py +44 -0
  121. opentrons/protocol_engine/state/state.py +14 -0
  122. opentrons/protocol_engine/state/state_summary.py +2 -0
  123. opentrons/protocol_engine/state/tasks.py +139 -0
  124. opentrons/protocol_engine/state/tips.py +177 -258
  125. opentrons/protocol_engine/state/update_types.py +16 -9
  126. opentrons/protocol_engine/types/__init__.py +9 -3
  127. opentrons/protocol_engine/types/deck_configuration.py +5 -1
  128. opentrons/protocol_engine/types/instrument.py +8 -1
  129. opentrons/protocol_engine/types/labware.py +1 -13
  130. opentrons/protocol_engine/types/module.py +10 -0
  131. opentrons/protocol_engine/types/tasks.py +38 -0
  132. opentrons/protocol_engine/types/tip.py +9 -0
  133. opentrons/protocol_runner/create_simulating_orchestrator.py +29 -2
  134. opentrons/protocol_runner/run_orchestrator.py +18 -2
  135. opentrons/protocols/api_support/definitions.py +1 -1
  136. opentrons/protocols/api_support/types.py +2 -1
  137. opentrons/simulate.py +48 -15
  138. opentrons/system/camera.py +1 -1
  139. {opentrons-8.7.0a6.dist-info → opentrons-8.7.0a7.dist-info}/METADATA +4 -4
  140. {opentrons-8.7.0a6.dist-info → opentrons-8.7.0a7.dist-info}/RECORD +143 -127
  141. opentrons/protocol_engine/state/_labware_origin_math.py +0 -636
  142. {opentrons-8.7.0a6.dist-info → opentrons-8.7.0a7.dist-info}/WHEEL +0 -0
  143. {opentrons-8.7.0a6.dist-info → opentrons-8.7.0a7.dist-info}/entry_points.txt +0 -0
  144. {opentrons-8.7.0a6.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 cast, Tuple, Union, List, Callable, Dict, TypeVar, Type
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, ErrorMessageNotification, EstopStateNotification
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
- LabwareUri("opentrons/opentrons_96_filtertiprack_10ul/1"),
42
- LabwareUri("opentrons/opentrons_96_filtertiprack_200ul/1"),
43
- LabwareUri("opentrons/opentrons_96_filtertiprack_20ul/1"),
44
- LabwareUri("opentrons/opentrons_96_tiprack_10ul/1"),
45
- LabwareUri("opentrons/opentrons_96_tiprack_20ul/1"),
46
- LabwareUri("opentrons/opentrons_96_tiprack_300ul/1"),
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
- allowed_labware: List[LabwareUri]
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
- if item.uri in self.allowed_labware:
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
- allowed_labware=HS_ALLOWED_ADJACENT_TALL_LABWARE,
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(pick_up_location.x, pick_up_location.y, gripper_home_z),
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=pick_up_location, jaw_open=True, dropping=False
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(pick_up_location.x, pick_up_location.y, gripper_max_z_home),
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(drop_location.x, drop_location.y, gripper_max_z_home),
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=drop_location, jaw_open=False, dropping=False
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
- drop_offset = drop_offset or Point()
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(drop_location.x, drop_location.y, gripper_home_z),
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=drop_location, jaw_open=False, dropping=False
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",
@@ -3,8 +3,13 @@ from typing_extensions import Final
3
3
  import enum
4
4
 
5
5
 
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.
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
- ProtocolCore = AbstractProtocol[InstrumentCore, LabwareCore, ModuleCore]
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
- # 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",
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.reset_tips(labware_id=self.labware_id)
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