opentrons 8.3.2a0__py2.py3-none-any.whl → 8.4.0__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of opentrons might be problematic. Click here for more details.

Files changed (196) hide show
  1. opentrons/calibration_storage/ot2/mark_bad_calibration.py +2 -0
  2. opentrons/calibration_storage/ot2/tip_length.py +6 -6
  3. opentrons/config/advanced_settings.py +9 -11
  4. opentrons/config/feature_flags.py +0 -4
  5. opentrons/config/reset.py +7 -2
  6. opentrons/drivers/asyncio/communication/__init__.py +2 -0
  7. opentrons/drivers/asyncio/communication/async_serial.py +4 -0
  8. opentrons/drivers/asyncio/communication/errors.py +41 -8
  9. opentrons/drivers/asyncio/communication/serial_connection.py +36 -10
  10. opentrons/drivers/flex_stacker/__init__.py +9 -3
  11. opentrons/drivers/flex_stacker/abstract.py +140 -15
  12. opentrons/drivers/flex_stacker/driver.py +593 -47
  13. opentrons/drivers/flex_stacker/errors.py +64 -0
  14. opentrons/drivers/flex_stacker/simulator.py +222 -24
  15. opentrons/drivers/flex_stacker/types.py +211 -15
  16. opentrons/drivers/flex_stacker/utils.py +19 -0
  17. opentrons/execute.py +4 -2
  18. opentrons/hardware_control/api.py +5 -0
  19. opentrons/hardware_control/backends/flex_protocol.py +4 -0
  20. opentrons/hardware_control/backends/ot3controller.py +12 -1
  21. opentrons/hardware_control/backends/ot3simulator.py +3 -0
  22. opentrons/hardware_control/backends/subsystem_manager.py +8 -4
  23. opentrons/hardware_control/instruments/ot2/instrument_calibration.py +10 -6
  24. opentrons/hardware_control/instruments/ot3/pipette_handler.py +59 -6
  25. opentrons/hardware_control/modules/__init__.py +12 -1
  26. opentrons/hardware_control/modules/absorbance_reader.py +11 -9
  27. opentrons/hardware_control/modules/flex_stacker.py +498 -0
  28. opentrons/hardware_control/modules/heater_shaker.py +12 -10
  29. opentrons/hardware_control/modules/magdeck.py +5 -1
  30. opentrons/hardware_control/modules/tempdeck.py +5 -1
  31. opentrons/hardware_control/modules/thermocycler.py +15 -14
  32. opentrons/hardware_control/modules/types.py +191 -1
  33. opentrons/hardware_control/modules/utils.py +3 -0
  34. opentrons/hardware_control/motion_utilities.py +20 -0
  35. opentrons/hardware_control/ot3api.py +145 -15
  36. opentrons/hardware_control/protocols/liquid_handler.py +47 -1
  37. opentrons/hardware_control/types.py +6 -0
  38. opentrons/legacy_commands/commands.py +102 -5
  39. opentrons/legacy_commands/helpers.py +74 -1
  40. opentrons/legacy_commands/types.py +33 -2
  41. opentrons/protocol_api/__init__.py +2 -0
  42. opentrons/protocol_api/_liquid.py +39 -8
  43. opentrons/protocol_api/_liquid_properties.py +20 -19
  44. opentrons/protocol_api/_transfer_liquid_validation.py +91 -0
  45. opentrons/protocol_api/core/common.py +3 -1
  46. opentrons/protocol_api/core/engine/deck_conflict.py +11 -1
  47. opentrons/protocol_api/core/engine/instrument.py +1356 -107
  48. opentrons/protocol_api/core/engine/labware.py +8 -4
  49. opentrons/protocol_api/core/engine/load_labware_params.py +68 -10
  50. opentrons/protocol_api/core/engine/module_core.py +118 -2
  51. opentrons/protocol_api/core/engine/pipette_movement_conflict.py +6 -14
  52. opentrons/protocol_api/core/engine/protocol.py +253 -11
  53. opentrons/protocol_api/core/engine/stringify.py +19 -8
  54. opentrons/protocol_api/core/engine/transfer_components_executor.py +858 -0
  55. opentrons/protocol_api/core/engine/well.py +73 -5
  56. opentrons/protocol_api/core/instrument.py +71 -21
  57. opentrons/protocol_api/core/labware.py +6 -2
  58. opentrons/protocol_api/core/legacy/labware_offset_provider.py +7 -3
  59. opentrons/protocol_api/core/legacy/legacy_instrument_core.py +76 -49
  60. opentrons/protocol_api/core/legacy/legacy_labware_core.py +8 -4
  61. opentrons/protocol_api/core/legacy/legacy_protocol_core.py +36 -0
  62. opentrons/protocol_api/core/legacy/legacy_well_core.py +27 -2
  63. opentrons/protocol_api/core/legacy/load_info.py +4 -12
  64. opentrons/protocol_api/core/legacy/module_geometry.py +6 -1
  65. opentrons/protocol_api/core/legacy/well_geometry.py +3 -3
  66. opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py +73 -23
  67. opentrons/protocol_api/core/module.py +43 -0
  68. opentrons/protocol_api/core/protocol.py +33 -0
  69. opentrons/protocol_api/core/well.py +23 -2
  70. opentrons/protocol_api/instrument_context.py +454 -150
  71. opentrons/protocol_api/labware.py +98 -50
  72. opentrons/protocol_api/module_contexts.py +140 -0
  73. opentrons/protocol_api/protocol_context.py +163 -19
  74. opentrons/protocol_api/validation.py +51 -41
  75. opentrons/protocol_engine/__init__.py +21 -2
  76. opentrons/protocol_engine/actions/actions.py +5 -5
  77. opentrons/protocol_engine/clients/sync_client.py +6 -0
  78. opentrons/protocol_engine/commands/__init__.py +66 -36
  79. opentrons/protocol_engine/commands/absorbance_reader/__init__.py +0 -1
  80. opentrons/protocol_engine/commands/air_gap_in_place.py +3 -2
  81. opentrons/protocol_engine/commands/aspirate.py +6 -2
  82. opentrons/protocol_engine/commands/aspirate_in_place.py +3 -1
  83. opentrons/protocol_engine/commands/aspirate_while_tracking.py +210 -0
  84. opentrons/protocol_engine/commands/blow_out.py +2 -0
  85. opentrons/protocol_engine/commands/blow_out_in_place.py +4 -1
  86. opentrons/protocol_engine/commands/command_unions.py +102 -33
  87. opentrons/protocol_engine/commands/configure_for_volume.py +3 -0
  88. opentrons/protocol_engine/commands/dispense.py +3 -1
  89. opentrons/protocol_engine/commands/dispense_in_place.py +3 -0
  90. opentrons/protocol_engine/commands/dispense_while_tracking.py +204 -0
  91. opentrons/protocol_engine/commands/drop_tip.py +23 -1
  92. opentrons/protocol_engine/commands/flex_stacker/__init__.py +106 -0
  93. opentrons/protocol_engine/commands/flex_stacker/close_latch.py +72 -0
  94. opentrons/protocol_engine/commands/flex_stacker/common.py +15 -0
  95. opentrons/protocol_engine/commands/flex_stacker/empty.py +161 -0
  96. opentrons/protocol_engine/commands/flex_stacker/fill.py +164 -0
  97. opentrons/protocol_engine/commands/flex_stacker/open_latch.py +70 -0
  98. opentrons/protocol_engine/commands/flex_stacker/prepare_shuttle.py +112 -0
  99. opentrons/protocol_engine/commands/flex_stacker/retrieve.py +394 -0
  100. opentrons/protocol_engine/commands/flex_stacker/set_stored_labware.py +190 -0
  101. opentrons/protocol_engine/commands/flex_stacker/store.py +291 -0
  102. opentrons/protocol_engine/commands/generate_command_schema.py +31 -2
  103. opentrons/protocol_engine/commands/labware_handling_common.py +29 -0
  104. opentrons/protocol_engine/commands/liquid_probe.py +27 -13
  105. opentrons/protocol_engine/commands/load_labware.py +42 -39
  106. opentrons/protocol_engine/commands/load_lid.py +21 -13
  107. opentrons/protocol_engine/commands/load_lid_stack.py +130 -47
  108. opentrons/protocol_engine/commands/load_module.py +18 -17
  109. opentrons/protocol_engine/commands/load_pipette.py +3 -0
  110. opentrons/protocol_engine/commands/move_labware.py +139 -20
  111. opentrons/protocol_engine/commands/move_to_well.py +5 -11
  112. opentrons/protocol_engine/commands/pick_up_tip.py +5 -2
  113. opentrons/protocol_engine/commands/pipetting_common.py +159 -8
  114. opentrons/protocol_engine/commands/prepare_to_aspirate.py +15 -5
  115. opentrons/protocol_engine/commands/{evotip_dispense.py → pressure_dispense.py} +33 -34
  116. opentrons/protocol_engine/commands/reload_labware.py +6 -19
  117. opentrons/protocol_engine/commands/{evotip_seal_pipette.py → seal_pipette_to_tip.py} +97 -76
  118. opentrons/protocol_engine/commands/unsafe/unsafe_blow_out_in_place.py +3 -1
  119. opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py +6 -1
  120. opentrons/protocol_engine/commands/{evotip_unseal_pipette.py → unseal_pipette_from_tip.py} +31 -40
  121. opentrons/protocol_engine/errors/__init__.py +10 -0
  122. opentrons/protocol_engine/errors/exceptions.py +62 -0
  123. opentrons/protocol_engine/execution/equipment.py +123 -106
  124. opentrons/protocol_engine/execution/labware_movement.py +8 -6
  125. opentrons/protocol_engine/execution/pipetting.py +235 -25
  126. opentrons/protocol_engine/execution/tip_handler.py +82 -32
  127. opentrons/protocol_engine/labware_offset_standardization.py +194 -0
  128. opentrons/protocol_engine/protocol_engine.py +22 -13
  129. opentrons/protocol_engine/resources/deck_configuration_provider.py +98 -2
  130. opentrons/protocol_engine/resources/deck_data_provider.py +1 -1
  131. opentrons/protocol_engine/resources/labware_data_provider.py +32 -12
  132. opentrons/protocol_engine/resources/labware_validation.py +7 -5
  133. opentrons/protocol_engine/slot_standardization.py +11 -23
  134. opentrons/protocol_engine/state/addressable_areas.py +84 -46
  135. opentrons/protocol_engine/state/frustum_helpers.py +36 -14
  136. opentrons/protocol_engine/state/geometry.py +892 -227
  137. opentrons/protocol_engine/state/labware.py +252 -55
  138. opentrons/protocol_engine/state/module_substates/__init__.py +4 -0
  139. opentrons/protocol_engine/state/module_substates/flex_stacker_substate.py +68 -0
  140. opentrons/protocol_engine/state/module_substates/heater_shaker_module_substate.py +22 -0
  141. opentrons/protocol_engine/state/module_substates/temperature_module_substate.py +13 -0
  142. opentrons/protocol_engine/state/module_substates/thermocycler_module_substate.py +20 -0
  143. opentrons/protocol_engine/state/modules.py +210 -67
  144. opentrons/protocol_engine/state/pipettes.py +54 -0
  145. opentrons/protocol_engine/state/state.py +1 -1
  146. opentrons/protocol_engine/state/tips.py +14 -0
  147. opentrons/protocol_engine/state/update_types.py +180 -25
  148. opentrons/protocol_engine/state/wells.py +55 -9
  149. opentrons/protocol_engine/types/__init__.py +300 -0
  150. opentrons/protocol_engine/types/automatic_tip_selection.py +39 -0
  151. opentrons/protocol_engine/types/command_annotations.py +53 -0
  152. opentrons/protocol_engine/types/deck_configuration.py +72 -0
  153. opentrons/protocol_engine/types/execution.py +96 -0
  154. opentrons/protocol_engine/types/hardware_passthrough.py +25 -0
  155. opentrons/protocol_engine/types/instrument.py +47 -0
  156. opentrons/protocol_engine/types/instrument_sensors.py +47 -0
  157. opentrons/protocol_engine/types/labware.py +111 -0
  158. opentrons/protocol_engine/types/labware_movement.py +22 -0
  159. opentrons/protocol_engine/types/labware_offset_location.py +111 -0
  160. opentrons/protocol_engine/types/labware_offset_vector.py +33 -0
  161. opentrons/protocol_engine/types/liquid.py +40 -0
  162. opentrons/protocol_engine/types/liquid_class.py +59 -0
  163. opentrons/protocol_engine/types/liquid_handling.py +13 -0
  164. opentrons/protocol_engine/types/liquid_level_detection.py +131 -0
  165. opentrons/protocol_engine/types/location.py +194 -0
  166. opentrons/protocol_engine/types/module.py +301 -0
  167. opentrons/protocol_engine/types/partial_tip_configuration.py +76 -0
  168. opentrons/protocol_engine/types/run_time_parameters.py +133 -0
  169. opentrons/protocol_engine/types/tip.py +18 -0
  170. opentrons/protocol_engine/types/util.py +21 -0
  171. opentrons/protocol_engine/types/well_position.py +124 -0
  172. opentrons/protocol_reader/extract_labware_definitions.py +7 -3
  173. opentrons/protocol_reader/file_format_validator.py +5 -3
  174. opentrons/protocol_runner/json_translator.py +4 -2
  175. opentrons/protocol_runner/legacy_command_mapper.py +6 -2
  176. opentrons/protocol_runner/run_orchestrator.py +4 -1
  177. opentrons/protocols/advanced_control/transfers/common.py +48 -1
  178. opentrons/protocols/advanced_control/transfers/transfer_liquid_utils.py +204 -0
  179. opentrons/protocols/api_support/definitions.py +1 -1
  180. opentrons/protocols/api_support/instrument.py +16 -3
  181. opentrons/protocols/labware.py +27 -23
  182. opentrons/protocols/models/__init__.py +0 -21
  183. opentrons/simulate.py +4 -2
  184. opentrons/types.py +20 -7
  185. opentrons/util/logging_config.py +94 -25
  186. opentrons/util/logging_queue_handler.py +61 -0
  187. {opentrons-8.3.2a0.dist-info → opentrons-8.4.0.dist-info}/METADATA +4 -4
  188. {opentrons-8.3.2a0.dist-info → opentrons-8.4.0.dist-info}/RECORD +192 -151
  189. opentrons/calibration_storage/ot2/models/defaults.py +0 -0
  190. opentrons/calibration_storage/ot3/models/defaults.py +0 -0
  191. opentrons/protocol_api/core/legacy/legacy_robot_core.py +0 -0
  192. opentrons/protocol_engine/types.py +0 -1311
  193. {opentrons-8.3.2a0.dist-info → opentrons-8.4.0.dist-info}/LICENSE +0 -0
  194. {opentrons-8.3.2a0.dist-info → opentrons-8.4.0.dist-info}/WHEEL +0 -0
  195. {opentrons-8.3.2a0.dist-info → opentrons-8.4.0.dist-info}/entry_points.txt +0 -0
  196. {opentrons-8.3.2a0.dist-info → opentrons-8.4.0.dist-info}/top_level.txt +0 -0
@@ -14,17 +14,19 @@ from typing import (
14
14
 
15
15
  from opentrons_shared_data.labware.types import LabwareDefinition
16
16
  from opentrons_shared_data.pipette.types import PipetteNameType
17
- from opentrons_shared_data.robot.types import RobotTypeEnum
18
17
 
19
18
  from opentrons.types import Mount, Location, DeckLocation, DeckSlotName, StagingSlotName
20
- from opentrons.config import feature_flags
21
19
  from opentrons.legacy_broker import LegacyBroker
22
20
  from opentrons.hardware_control.modules.types import (
23
21
  MagneticBlockModel,
24
22
  AbsorbanceReaderModel,
23
+ FlexStackerModuleModel,
25
24
  )
26
25
  from opentrons.legacy_commands import protocol_commands as cmds, types as cmd_types
27
- from opentrons.legacy_commands.helpers import stringify_labware_movement_command
26
+ from opentrons.legacy_commands.helpers import (
27
+ stringify_labware_movement_command,
28
+ stringify_lid_movement_command,
29
+ )
28
30
  from opentrons.legacy_commands.publisher import (
29
31
  CommandPublisher,
30
32
  publish,
@@ -58,6 +60,7 @@ from .core.module import (
58
60
  AbstractHeaterShakerCore,
59
61
  AbstractMagneticBlockCore,
60
62
  AbstractAbsorbanceReaderCore,
63
+ AbstractFlexStackerCore,
61
64
  )
62
65
  from .robot_context import RobotContext, HardwareManager
63
66
  from .core.engine import ENGINE_CORE_API_VERSION
@@ -76,6 +79,7 @@ from .module_contexts import (
76
79
  HeaterShakerContext,
77
80
  MagneticBlockContext,
78
81
  AbsorbanceReaderContext,
82
+ FlexStackerContext,
79
83
  ModuleContext,
80
84
  )
81
85
  from ._parameters import Parameters
@@ -91,6 +95,7 @@ ModuleTypes = Union[
91
95
  HeaterShakerContext,
92
96
  MagneticBlockContext,
93
97
  AbsorbanceReaderContext,
98
+ FlexStackerContext,
94
99
  ]
95
100
 
96
101
 
@@ -444,13 +449,16 @@ class ProtocolContext(CommandPublisher):
444
449
  values as the ``load_name`` parameter of :py:meth:`.load_adapter`. The
445
450
  adapter will use the same namespace as the labware, and the API will
446
451
  choose the adapter's version automatically.
447
- :param lid: A lid to load the on top of the main labware. Accepts the same
452
+
453
+ .. versionadded:: 2.15
454
+ :param lid: A lid to load on the top of the main labware. Accepts the same
448
455
  values as the ``load_name`` parameter of :py:meth:`.load_lid_stack`. The
449
456
  lid will use the same namespace as the labware, and the API will
450
- choose the lid's version automatically.
457
+ choose the adapter's version automatically.
451
458
 
452
- .. versionadded:: 2.15
459
+ .. versionadded:: 2.23
453
460
  """
461
+
454
462
  if isinstance(location, OffDeckType) and self._api_version < APIVersion(2, 15):
455
463
  raise APIVersionError(
456
464
  api_element="Loading a labware off-deck",
@@ -859,6 +867,10 @@ class ProtocolContext(CommandPublisher):
859
867
 
860
868
  .. versionchanged:: 2.15
861
869
  Added ``MagneticBlockContext`` return value.
870
+
871
+ .. TODO uncomment when 2.23 is ready
872
+ versionchanged:: 2.23
873
+ Added ``FlexStackerModuleContext`` return value.
862
874
  """
863
875
  if configuration:
864
876
  if self._api_version < APIVersion(2, 4):
@@ -887,7 +899,18 @@ class ProtocolContext(CommandPublisher):
887
899
  requested_model, AbsorbanceReaderModel
888
900
  ) and self._api_version < APIVersion(2, 21):
889
901
  raise APIVersionError(
890
- f"Module of type {module_name} is only available in versions 2.21 and above."
902
+ api_element=f"Module of type {module_name}",
903
+ until_version="2.21",
904
+ current_version=f"{self._api_version}",
905
+ )
906
+ if (
907
+ isinstance(requested_model, FlexStackerModuleModel)
908
+ and self._api_version < validation.FLEX_STACKER_VERSION_GATE
909
+ ):
910
+ raise APIVersionError(
911
+ api_element=f"Module of type {module_name}",
912
+ until_version=str(validation.FLEX_STACKER_VERSION_GATE),
913
+ current_version=f"{self._api_version}",
891
914
  )
892
915
 
893
916
  deck_slot = (
@@ -898,7 +921,11 @@ class ProtocolContext(CommandPublisher):
898
921
  )
899
922
  )
900
923
  if isinstance(deck_slot, StagingSlotName):
901
- raise ValueError("Cannot load a module onto a staging slot.")
924
+ # flex stacker modules can only be loaded into staging slot inside a protocol
925
+ if isinstance(requested_model, FlexStackerModuleModel):
926
+ deck_slot = validation.convert_flex_stacker_load_slot(deck_slot)
927
+ else:
928
+ raise ValueError(f"Cannot load {module_name} onto a staging slot.")
902
929
 
903
930
  module_core = self._core.load_module(
904
931
  model=requested_model,
@@ -1329,17 +1356,19 @@ class ProtocolContext(CommandPublisher):
1329
1356
  display_color=display_color,
1330
1357
  )
1331
1358
 
1359
+ @requires_version(2, 23)
1332
1360
  def define_liquid_class(
1333
1361
  self,
1334
1362
  name: str,
1335
1363
  ) -> LiquidClass:
1336
- """Define a liquid class for use in the protocol."""
1337
- if feature_flags.allow_liquid_classes(
1338
- robot_type=RobotTypeEnum.robot_literal_to_enum(self._core.robot_type)
1339
- ):
1340
- return self._core.define_liquid_class(name=name)
1341
- else:
1342
- raise NotImplementedError("This method is not implemented.")
1364
+ """
1365
+ Define a liquid class for use in the protocol.
1366
+ ..
1367
+ This is intended for Opentrons internal use only and is not a guaranteed API.
1368
+
1369
+ :meta private:
1370
+ """
1371
+ return self._core.define_liquid_class(name=name)
1343
1372
 
1344
1373
  @property
1345
1374
  @requires_version(2, 5)
@@ -1364,13 +1393,13 @@ class ProtocolContext(CommandPublisher):
1364
1393
  version: Optional[int] = None,
1365
1394
  ) -> Labware:
1366
1395
  """
1367
- Load a stack of Lids onto a valid Deck Location or Adapter.
1396
+ Load a stack of Opentrons Tough Auto-Sealing Lids onto a valid deck location or adapter.
1368
1397
 
1369
1398
  :param str load_name: A string to use for looking up a lid definition.
1370
- You can find the ``load_name`` for any standard lid on the Opentrons
1399
+ You can find the ``load_name`` for any compatible lid on the Opentrons
1371
1400
  `Labware Library <https://labware.opentrons.com>`_.
1372
1401
  :param location: Either a :ref:`deck slot <deck-slots>`,
1373
- like ``1``, ``"1"``, or ``"D1"``, or the a valid Opentrons Adapter.
1402
+ like ``1``, ``"1"``, or ``"D1"``, or a valid Opentrons Adapter.
1374
1403
  :param int quantity: The quantity of lids to be loaded in the stack.
1375
1404
  :param adapter: An adapter to load the lid stack on top of. Accepts the same
1376
1405
  values as the ``load_name`` parameter of :py:meth:`.load_adapter`. The
@@ -1391,7 +1420,10 @@ class ProtocolContext(CommandPublisher):
1391
1420
  leave this unspecified to let ``load_lid_stack()`` choose a version
1392
1421
  automatically.
1393
1422
 
1394
- :return: The initialized and loaded labware object representing the Lid Stack.
1423
+ :return: The initialized and loaded labware object representing the lid stack.
1424
+
1425
+ .. versionadded:: 2.23
1426
+
1395
1427
  """
1396
1428
  if self._api_version < validation.LID_STACK_VERSION_GATE:
1397
1429
  raise APIVersionError(
@@ -1441,6 +1473,116 @@ class ProtocolContext(CommandPublisher):
1441
1473
  )
1442
1474
  return labware
1443
1475
 
1476
+ @requires_version(2, 23)
1477
+ def move_lid(
1478
+ self,
1479
+ source_location: Union[DeckLocation, Labware],
1480
+ new_location: Union[DeckLocation, Labware, OffDeckType, WasteChute, TrashBin],
1481
+ use_gripper: bool = False,
1482
+ pick_up_offset: Optional[Mapping[str, float]] = None,
1483
+ drop_offset: Optional[Mapping[str, float]] = None,
1484
+ ) -> Labware | None:
1485
+ """Move a compatible lid from a valid source to a new location. Can return a lid stack if one is created.
1486
+
1487
+ :param source_location: The lid's starting location. This is either:
1488
+
1489
+ * A deck slot like ``1``, ``"1"``, or ``"D1"``. See :ref:`deck-slots`.
1490
+ * A labware or adapter that's already been loaded on the deck
1491
+ with :py:meth:`load_labware` or :py:meth:`load_adapter`.
1492
+ * A lid stack that's already been loaded on the deck with
1493
+ with :py:meth:`load_lid_stack`.
1494
+
1495
+ :param new_location: Where to move the lid to. This is either:
1496
+
1497
+ * A deck slot like ``1``, ``"1"``, or ``"D1"``. See :ref:`deck-slots`.
1498
+ * A hardware module that's already been loaded on the deck
1499
+ with :py:meth:`load_module`.
1500
+ * A labware or adapter that's already been loaded on the deck
1501
+ with :py:meth:`load_labware` or :py:meth:`load_adapter`.
1502
+ * The special constant :py:obj:`OFF_DECK`.
1503
+
1504
+ :param use_gripper: Whether to use the Flex Gripper to move the lid.
1505
+
1506
+ * If ``True``, use the gripper to perform an automatic
1507
+ movement. This will raise an error in an OT-2 protocol.
1508
+ * If ``False``, pause protocol execution until the user
1509
+ performs the movement. Protocol execution remains paused until
1510
+ the user presses **Confirm and resume**.
1511
+
1512
+ Gripper-only parameters:
1513
+
1514
+ :param pick_up_offset: Optional x, y, z vector offset to use when picking up a lid.
1515
+ :param drop_offset: Optional x, y, z vector offset to use when dropping off a lid.
1516
+
1517
+ Before moving a lid to or from a labware in a hardware module, make sure that the
1518
+ labware's current and new locations are accessible, i.e., open the Thermocycler lid
1519
+ or open the Heater-Shaker's labware latch.
1520
+
1521
+ .. versionadded:: 2.23
1522
+
1523
+ """
1524
+ source: Union[LabwareCore, DeckSlotName, StagingSlotName]
1525
+ if isinstance(source_location, Labware):
1526
+ source = source_location._core
1527
+ else:
1528
+ source = validation.ensure_and_convert_deck_slot(
1529
+ source_location, self._api_version, self._core.robot_type
1530
+ )
1531
+
1532
+ destination: Union[
1533
+ ModuleCore,
1534
+ LabwareCore,
1535
+ WasteChute,
1536
+ OffDeckType,
1537
+ DeckSlotName,
1538
+ StagingSlotName,
1539
+ TrashBin,
1540
+ ]
1541
+ if isinstance(new_location, Labware):
1542
+ destination = new_location._core
1543
+ elif isinstance(new_location, (OffDeckType, WasteChute, TrashBin)):
1544
+ destination = new_location
1545
+ else:
1546
+ destination = validation.ensure_and_convert_deck_slot(
1547
+ new_location, self._api_version, self._core.robot_type
1548
+ )
1549
+
1550
+ _pick_up_offset = (
1551
+ validation.ensure_valid_labware_offset_vector(pick_up_offset)
1552
+ if pick_up_offset
1553
+ else None
1554
+ )
1555
+ _drop_offset = (
1556
+ validation.ensure_valid_labware_offset_vector(drop_offset)
1557
+ if drop_offset
1558
+ else None
1559
+ )
1560
+ with publish_context(
1561
+ broker=self.broker,
1562
+ command=cmds.move_labware(
1563
+ # This needs to be called from protocol context and not the command for import loop reasons
1564
+ text=stringify_lid_movement_command(
1565
+ source_location, new_location, use_gripper
1566
+ )
1567
+ ),
1568
+ ):
1569
+ result = self._core.move_lid(
1570
+ source_location=source,
1571
+ new_location=destination,
1572
+ use_gripper=use_gripper,
1573
+ pause_for_manual_move=True,
1574
+ pick_up_offset=_pick_up_offset,
1575
+ drop_offset=_drop_offset,
1576
+ )
1577
+ if result is not None:
1578
+ return Labware(
1579
+ core=result,
1580
+ api_version=self._api_version,
1581
+ protocol_core=self._core,
1582
+ core_map=self._core_map,
1583
+ )
1584
+ return None
1585
+
1444
1586
 
1445
1587
  def _create_module_context(
1446
1588
  module_core: Union[ModuleCore, NonConnectedModuleCore],
@@ -1462,6 +1604,8 @@ def _create_module_context(
1462
1604
  module_cls = MagneticBlockContext
1463
1605
  elif isinstance(module_core, AbstractAbsorbanceReaderCore):
1464
1606
  module_cls = AbsorbanceReaderContext
1607
+ elif isinstance(module_core, AbstractFlexStackerCore):
1608
+ module_cls = FlexStackerContext
1465
1609
  else:
1466
1610
  assert False, "Unsupported module type"
1467
1611
 
@@ -14,13 +14,15 @@ from typing import (
14
14
  from math import isinf, isnan
15
15
  from typing_extensions import TypeGuard
16
16
 
17
- from opentrons_shared_data.labware.labware_definition import LabwareRole
18
- from opentrons_shared_data.pipette.types import PipetteNameType
17
+ from opentrons_shared_data.labware.labware_definition import (
18
+ LabwareDefinition,
19
+ LabwareRole,
20
+ )
21
+ from opentrons_shared_data.pipette.types import PipetteNameType, PIPETTE_API_NAMES_MAP
19
22
  from opentrons_shared_data.robot.types import RobotType
20
23
 
21
24
  from opentrons.protocols.api_support.types import APIVersion, ThermocyclerStep
22
25
  from opentrons.protocols.api_support.util import APIVersionError
23
- from opentrons.protocols.models import LabwareDefinition
24
26
  from opentrons.protocols.advanced_control.transfers.common import TransferTipPolicyV2
25
27
  from opentrons.types import (
26
28
  Mount,
@@ -39,6 +41,7 @@ from opentrons.hardware_control.modules.types import (
39
41
  HeaterShakerModuleModel,
40
42
  MagneticBlockModel,
41
43
  AbsorbanceReaderModel,
44
+ FlexStackerModuleModel,
42
45
  )
43
46
 
44
47
  from .disposal_locations import TrashBin, WasteChute
@@ -56,29 +59,8 @@ _STAGING_DECK_SLOT_VERSION_GATE = APIVersion(2, 16)
56
59
  # The first APIVersion where Python protocols can load lids as stacks and treat them as attributes of a parent labware.
57
60
  LID_STACK_VERSION_GATE = APIVersion(2, 23)
58
61
 
59
- # Mapping of public Python Protocol API pipette load names
60
- # to names used by the internal Opentrons system
61
- _PIPETTE_NAMES_MAP = {
62
- "p10_single": PipetteNameType.P10_SINGLE,
63
- "p10_multi": PipetteNameType.P10_MULTI,
64
- "p20_single_gen2": PipetteNameType.P20_SINGLE_GEN2,
65
- "p20_multi_gen2": PipetteNameType.P20_MULTI_GEN2,
66
- "p50_single": PipetteNameType.P50_SINGLE,
67
- "p50_multi": PipetteNameType.P50_MULTI,
68
- "p300_single": PipetteNameType.P300_SINGLE,
69
- "p300_multi": PipetteNameType.P300_MULTI,
70
- "p300_single_gen2": PipetteNameType.P300_SINGLE_GEN2,
71
- "p300_multi_gen2": PipetteNameType.P300_MULTI_GEN2,
72
- "p1000_single": PipetteNameType.P1000_SINGLE,
73
- "p1000_single_gen2": PipetteNameType.P1000_SINGLE_GEN2,
74
- "flex_1channel_50": PipetteNameType.P50_SINGLE_FLEX,
75
- "flex_8channel_50": PipetteNameType.P50_MULTI_FLEX,
76
- "flex_1channel_1000": PipetteNameType.P1000_SINGLE_FLEX,
77
- "flex_8channel_1000": PipetteNameType.P1000_MULTI_FLEX,
78
- "flex_8channel_1000_em": PipetteNameType.P1000_MULTI_EM,
79
- "flex_96channel_1000": PipetteNameType.P1000_96,
80
- "flex_96channel_200": PipetteNameType.P200_96,
81
- }
62
+ # The first APIVersion where Python protocols can use the Flex Stacker module.
63
+ FLEX_STACKER_VERSION_GATE = APIVersion(2, 23)
82
64
 
83
65
 
84
66
  class InvalidPipetteMountError(ValueError):
@@ -192,7 +174,7 @@ def ensure_pipette_name(pipette_name: str) -> PipetteNameType:
192
174
  pipette_name = ensure_lowercase_name(pipette_name)
193
175
 
194
176
  try:
195
- return _PIPETTE_NAMES_MAP[pipette_name]
177
+ return PIPETTE_API_NAMES_MAP[pipette_name]
196
178
  except KeyError:
197
179
  raise ValueError(
198
180
  f"Cannot resolve {pipette_name} to pipette, must be given valid pipette name."
@@ -411,6 +393,7 @@ _MODULE_MODELS: Dict[str, ModuleModel] = {
411
393
  "heaterShakerModuleV1": HeaterShakerModuleModel.HEATER_SHAKER_V1,
412
394
  "magneticBlockV1": MagneticBlockModel.MAGNETIC_BLOCK_V1,
413
395
  "absorbanceReaderV1": AbsorbanceReaderModel.ABSORBANCE_READER_V1,
396
+ "flexStackerModuleV1": FlexStackerModuleModel.FLEX_STACKER_V1,
414
397
  }
415
398
 
416
399
 
@@ -644,6 +627,16 @@ def ensure_positive_float(value: Union[int, float]) -> float:
644
627
  return float_value
645
628
 
646
629
 
630
+ def ensure_greater_than_zero_float(value: Union[int, float]) -> float:
631
+ """Ensure value is a positive and real float value."""
632
+ float_value = ensure_float(value)
633
+ if isnan(float_value) or isinf(float_value):
634
+ raise ValueError("Value must be a defined, non-infinite number.")
635
+ if float_value <= 0:
636
+ raise ValueError("Value must be a positive float greater than 0.")
637
+ return float_value
638
+
639
+
647
640
  def ensure_positive_int(value: int) -> int:
648
641
  """Ensure value is a positive integer."""
649
642
  if not isinstance(value, int):
@@ -711,20 +704,18 @@ def ensure_valid_flat_wells_list_for_transfer_v2(
711
704
  )
712
705
 
713
706
 
714
- def ensure_valid_tip_drop_location_for_transfer_v2(
715
- tip_drop_location: Union[Location, Well, TrashBin, WasteChute]
716
- ) -> Union[Location, Well, TrashBin, WasteChute]:
717
- """Ensure that the tip drop location is valid for v2 transfer."""
707
+ def ensure_valid_trash_location_for_transfer_v2(
708
+ trash_location: Union[Location, Well, TrashBin, WasteChute]
709
+ ) -> Union[Location, TrashBin, WasteChute]:
710
+ """Ensure that the trash location is valid for v2 transfer."""
718
711
  from .labware import Well
719
712
 
720
- if (
721
- isinstance(tip_drop_location, Well)
722
- or isinstance(tip_drop_location, TrashBin)
723
- or isinstance(tip_drop_location, WasteChute)
724
- ):
725
- return tip_drop_location
726
- elif isinstance(tip_drop_location, Location):
727
- _, maybe_well = tip_drop_location.labware.get_parent_labware_and_well()
713
+ if isinstance(trash_location, TrashBin) or isinstance(trash_location, WasteChute):
714
+ return trash_location
715
+ elif isinstance(trash_location, Well):
716
+ return trash_location.top()
717
+ elif isinstance(trash_location, Location):
718
+ _, maybe_well = trash_location.labware.get_parent_labware_and_well()
728
719
 
729
720
  if maybe_well is None:
730
721
  raise TypeError(
@@ -734,11 +725,30 @@ def ensure_valid_tip_drop_location_for_transfer_v2(
734
725
  " since that is where a tip is dropped."
735
726
  " However, the given location doesn't refer to any well."
736
727
  )
737
- return tip_drop_location
728
+ return trash_location
738
729
  else:
739
730
  raise TypeError(
740
731
  f"If specified, location should be an instance of"
741
732
  f" `types.Location` (e.g. the return value from `Well.top()`)"
742
733
  f" or `Well` (e.g. `reservoir.wells()[0]`) or an instance of `TrashBin` or `WasteChute`."
743
- f" However, it is '{tip_drop_location}'."
734
+ f" However, it is '{trash_location}'."
744
735
  )
736
+
737
+
738
+ def convert_flex_stacker_load_slot(slot_name: StagingSlotName) -> DeckSlotName:
739
+ """
740
+ Ensure a Flex Stacker load location to a deck slot location.
741
+
742
+ Args:
743
+ slot_name: The input staging slot location.
744
+
745
+ Returns:
746
+ A `DeckSlotName` on the deck.
747
+ """
748
+ _map = {
749
+ StagingSlotName.SLOT_A4: DeckSlotName.SLOT_A3,
750
+ StagingSlotName.SLOT_B4: DeckSlotName.SLOT_B3,
751
+ StagingSlotName.SLOT_C4: DeckSlotName.SLOT_C3,
752
+ StagingSlotName.SLOT_D4: DeckSlotName.SLOT_D3,
753
+ }
754
+ return _map[slot_name]
@@ -26,21 +26,30 @@ from .plugins import AbstractPlugin
26
26
 
27
27
  from .types import (
28
28
  LabwareOffset,
29
+ LegacyLabwareOffsetCreate,
29
30
  LabwareOffsetCreate,
30
31
  LabwareOffsetVector,
31
- LabwareOffsetLocation,
32
+ LegacyLabwareOffsetLocation,
33
+ LabwareOffsetLocationSequence,
34
+ OnLabwareOffsetLocationSequenceComponent,
35
+ OnModuleOffsetLocationSequenceComponent,
36
+ OnAddressableAreaOffsetLocationSequenceComponent,
37
+ LabwareOffsetLocationSequenceComponents,
32
38
  LabwareMovementStrategy,
33
39
  AddressableOffsetVector,
34
40
  DeckPoint,
35
41
  DeckType,
36
42
  DeckSlotLocation,
43
+ InStackerHopperLocation,
37
44
  ModuleLocation,
38
45
  OnLabwareLocation,
39
46
  AddressableAreaLocation,
40
47
  OFF_DECK_LOCATION,
48
+ SYSTEM_LOCATION,
41
49
  Dimensions,
42
50
  EngineStatus,
43
51
  LabwareLocation,
52
+ LoadableLabwareLocation,
44
53
  NonStackedLocation,
45
54
  LoadedLabware,
46
55
  LoadedModule,
@@ -94,8 +103,15 @@ __all__ = [
94
103
  # public value interfaces and models
95
104
  "LabwareOffset",
96
105
  "LabwareOffsetCreate",
106
+ "LegacyLabwareOffsetCreate",
107
+ "LabwareOffsetLocationSequence",
97
108
  "LabwareOffsetVector",
98
- "LabwareOffsetLocation",
109
+ "OnLabwareOffsetLocationSequenceComponent",
110
+ "OnModuleOffsetLocationSequenceComponent",
111
+ "OnAddressableAreaOffsetLocationSequenceComponent",
112
+ "LabwareOffsetLocationSequenceComponents",
113
+ "LegacyLabwareOffsetCreate",
114
+ "LegacyLabwareOffsetLocation",
99
115
  "LabwareMovementStrategy",
100
116
  "AddressableOffsetVector",
101
117
  "DeckSlotLocation",
@@ -104,10 +120,13 @@ __all__ = [
104
120
  "ModuleLocation",
105
121
  "OnLabwareLocation",
106
122
  "AddressableAreaLocation",
123
+ "InStackerHopperLocation",
107
124
  "OFF_DECK_LOCATION",
125
+ "SYSTEM_LOCATION",
108
126
  "Dimensions",
109
127
  "EngineStatus",
110
128
  "LabwareLocation",
129
+ "LoadableLabwareLocation",
111
130
  "NonStackedLocation",
112
131
  "LoadedLabware",
113
132
  "LoadedModule",
@@ -8,12 +8,12 @@ from datetime import datetime
8
8
  from enum import Enum
9
9
  from typing import List, Optional, Union
10
10
 
11
- from opentrons.protocols.models import LabwareDefinition
11
+ from opentrons_shared_data.errors import EnumeratedError
12
+ from opentrons_shared_data.labware.labware_definition import LabwareDefinition
13
+
12
14
  from opentrons.hardware_control.types import DoorState
13
15
  from opentrons.hardware_control.modules import LiveData
14
16
 
15
- from opentrons_shared_data.errors import EnumeratedError
16
-
17
17
  from ..commands import (
18
18
  Command,
19
19
  CommandCreate,
@@ -23,7 +23,7 @@ from ..error_recovery_policy import ErrorRecoveryPolicy, ErrorRecoveryType
23
23
  from ..notes.notes import CommandNote
24
24
  from ..state.update_types import StateUpdate
25
25
  from ..types import (
26
- LabwareOffsetCreate,
26
+ LabwareOffsetCreateInternal,
27
27
  ModuleDefinition,
28
28
  Liquid,
29
29
  DeckConfigurationType,
@@ -206,7 +206,7 @@ class AddLabwareOffsetAction:
206
206
 
207
207
  labware_offset_id: str
208
208
  created_at: datetime
209
- request: LabwareOffsetCreate
209
+ request: LabwareOffsetCreateInternal
210
210
 
211
211
 
212
212
  @dataclasses.dataclass(frozen=True)
@@ -107,6 +107,12 @@ class SyncClient:
107
107
  ) -> commands.LoadLiquidClassResult:
108
108
  pass
109
109
 
110
+ @overload
111
+ def execute_command_without_recovery(
112
+ self, params: commands.GetNextTipParams
113
+ ) -> commands.GetNextTipResult:
114
+ pass
115
+
110
116
  def execute_command_without_recovery(
111
117
  self, params: commands.CommandParams
112
118
  ) -> commands.CommandResult: