opentrons 8.3.2__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.2.dist-info → opentrons-8.4.0.dist-info}/METADATA +4 -4
  188. {opentrons-8.3.2.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.2.dist-info → opentrons-8.4.0.dist-info}/LICENSE +0 -0
  194. {opentrons-8.3.2.dist-info → opentrons-8.4.0.dist-info}/WHEEL +0 -0
  195. {opentrons-8.3.2.dist-info → opentrons-8.4.0.dist-info}/entry_points.txt +0 -0
  196. {opentrons-8.3.2.dist-info → opentrons-8.4.0.dist-info}/top_level.txt +0 -0
@@ -3,7 +3,8 @@
3
3
  from typing import List, Optional, cast, Dict
4
4
 
5
5
  from opentrons_shared_data.labware.types import (
6
- LabwareParameters as LabwareParametersDict,
6
+ LabwareParameters2 as LabwareParameters2Dict,
7
+ LabwareParameters3 as LabwareParameters3Dict,
7
8
  LabwareDefinition as LabwareDefinitionDict,
8
9
  )
9
10
 
@@ -29,6 +30,9 @@ from ..labware import AbstractLabware, LabwareLoadParams
29
30
  from .well import WellCore
30
31
 
31
32
 
33
+ _LabwareParametersDict = LabwareParameters2Dict | LabwareParameters3Dict
34
+
35
+
32
36
  class LabwareCore(AbstractLabware[WellCore]):
33
37
  """Labware API core using a ProtocolEngine.
34
38
 
@@ -96,9 +100,9 @@ class LabwareCore(AbstractLabware[WellCore]):
96
100
  LabwareDefinitionDict, self._definition.model_dump(exclude_none=True)
97
101
  )
98
102
 
99
- def get_parameters(self) -> LabwareParametersDict:
103
+ def get_parameters(self) -> _LabwareParametersDict:
100
104
  return cast(
101
- LabwareParametersDict,
105
+ _LabwareParametersDict,
102
106
  self._definition.parameters.model_dump(exclude_none=True),
103
107
  )
104
108
 
@@ -122,7 +126,7 @@ class LabwareCore(AbstractLabware[WellCore]):
122
126
 
123
127
  request = LabwareOffsetCreate.model_construct(
124
128
  definitionUri=self.get_uri(),
125
- location=offset_location,
129
+ locationSequence=offset_location,
126
130
  vector=LabwareOffsetVector(x=delta.x, y=delta.y, z=delta.z),
127
131
  )
128
132
  self._engine_client.add_labware_offset(request)
@@ -1,7 +1,6 @@
1
- from typing import Dict, Tuple, List, Optional
2
-
3
1
  from opentrons.protocols.api_support.constants import OPENTRONS_NAMESPACE
4
2
  from opentrons.protocol_engine.state.labware import LabwareLoadParams
3
+ from opentrons.protocols.api_support.types import APIVersion
5
4
 
6
5
 
7
6
  # Default versions of Opentrons standard labware definitions in Python Protocol API
@@ -9,7 +8,7 @@ from opentrons.protocol_engine.state.labware import LabwareLoadParams
9
8
  #
10
9
  # TODO(jbl 2023-08-01) this needs to be done more holistically, both to find the version and make sure that
11
10
  # it corresponds to the API level is was released with
12
- _APILEVEL_2_14_OT_DEFAULT_VERSIONS: Dict[str, int] = {
11
+ _APILEVEL_2_14_OT_DEFAULT_VERSIONS: dict[str, int] = {
13
12
  # v1 of many labware definitions have wrong `zDimension`s. (Jira RSS-202.)
14
13
  # For "opentrons_96_aluminumblock_generic_pcr_strip_200ul" and
15
14
  # "opentrons_24_aluminumblock_generic_2ml_screwcap", they're wrong enough to
@@ -34,6 +33,54 @@ _APILEVEL_2_14_OT_DEFAULT_VERSIONS: Dict[str, int] = {
34
33
  "corning_24_wellplate_3.4ml_flat": 2,
35
34
  }
36
35
 
36
+ _APILEVEL_2_23_OT_DEFAULT_VERSIONS: dict[str, int] = {
37
+ "agilent_1_reservoir_290ml": 2,
38
+ "appliedbiosystemsmicroamp_384_wellplate_40ul": 2,
39
+ "armadillo_96_wellplate_200ul_pcr_full_skirt": 3,
40
+ "axygen_1_reservoir_90ml": 2,
41
+ "biorad_384_wellplate_50ul": 3,
42
+ "biorad_96_wellplate_200ul_pcr": 3,
43
+ "corning_12_wellplate_6.9ml_flat": 3,
44
+ "corning_24_wellplate_3.4ml_flat": 3,
45
+ "corning_384_wellplate_112ul_flat": 3,
46
+ "corning_48_wellplate_1.6ml_flat": 3,
47
+ "corning_6_wellplate_16.8ml_flat": 3,
48
+ "corning_96_wellplate_360ul_flat": 3,
49
+ "nest_12_reservoir_15ml": 2,
50
+ "nest_1_reservoir_195ml": 3,
51
+ "nest_1_reservoir_290ml": 2,
52
+ "nest_96_wellplate_100ul_pcr_full_skirt": 3,
53
+ "nest_96_wellplate_200ul_flat": 3,
54
+ "nest_96_wellplate_2ml_deep": 3,
55
+ "opentrons_10_tuberack_falcon_4x50ml_6x15ml_conical": 2,
56
+ "opentrons_10_tuberack_nest_4x50ml_6x15ml_conical": 2,
57
+ "opentrons_15_tuberack_falcon_15ml_conical": 2,
58
+ "opentrons_15_tuberack_nest_15ml_conical": 2,
59
+ "opentrons_24_aluminumblock_generic_2ml_screwcap": 3,
60
+ "opentrons_24_aluminumblock_nest_0.5ml_screwcap": 2,
61
+ "opentrons_24_aluminumblock_nest_1.5ml_screwcap": 2,
62
+ "opentrons_24_aluminumblock_nest_1.5ml_snapcap": 2,
63
+ "opentrons_24_aluminumblock_nest_2ml_screwcap": 2,
64
+ "opentrons_24_aluminumblock_nest_2ml_snapcap": 2,
65
+ "opentrons_24_tuberack_eppendorf_1.5ml_safelock_snapcap": 2,
66
+ "opentrons_24_tuberack_eppendorf_2ml_safelock_snapcap": 2,
67
+ "opentrons_24_tuberack_generic_2ml_screwcap": 2,
68
+ "opentrons_24_tuberack_nest_0.5ml_screwcap": 2,
69
+ "opentrons_24_tuberack_nest_1.5ml_screwcap": 2,
70
+ "opentrons_24_tuberack_nest_1.5ml_snapcap": 2,
71
+ "opentrons_24_tuberack_nest_2ml_screwcap": 2,
72
+ "opentrons_24_tuberack_nest_2ml_snapcap": 2,
73
+ "opentrons_6_tuberack_falcon_50ml_conical": 2,
74
+ "opentrons_6_tuberack_nest_50ml_conical": 2,
75
+ "opentrons_96_aluminumblock_generic_pcr_strip_200ul": 3,
76
+ "opentrons_96_wellplate_200ul_pcr_full_skirt": 3,
77
+ "opentrons_tough_pcr_auto_sealing_lid": 2,
78
+ "thermoscientificnunc_96_wellplate_1300ul": 2,
79
+ "thermoscientificnunc_96_wellplate_2000ul": 2,
80
+ "usascientific_12_reservoir_22ml": 2,
81
+ "usascientific_96_wellplate_2.4ml_deep": 2,
82
+ }
83
+
37
84
 
38
85
  class AmbiguousLoadLabwareParamsError(RuntimeError):
39
86
  """Error raised when specific labware parameters cannot be found due to multiple matching labware definitions."""
@@ -41,10 +88,11 @@ class AmbiguousLoadLabwareParamsError(RuntimeError):
41
88
 
42
89
  def resolve(
43
90
  load_name: str,
44
- namespace: Optional[str],
45
- version: Optional[int],
46
- custom_load_labware_params: List[LabwareLoadParams],
47
- ) -> Tuple[str, int]:
91
+ namespace: str | None,
92
+ version: int | None,
93
+ custom_load_labware_params: list[LabwareLoadParams],
94
+ api_version: APIVersion,
95
+ ) -> tuple[str, int]:
48
96
  """Resolve the load labware parameters that best matches any custom labware, or default to opentrons standards
49
97
 
50
98
  Args:
@@ -82,7 +130,9 @@ def resolve(
82
130
  resolved_version = (
83
131
  version
84
132
  if version is not None
85
- else _get_default_version_for_standard_labware(load_name=load_name)
133
+ else _get_default_version_for_standard_labware(
134
+ load_name=load_name, api_version=api_version
135
+ )
86
136
  )
87
137
 
88
138
  elif len(filtered_custom_params) > 1:
@@ -99,7 +149,15 @@ def resolve(
99
149
  return resolved_namespace, resolved_version
100
150
 
101
151
 
102
- def _get_default_version_for_standard_labware(load_name: str) -> int:
152
+ def _get_default_version_for_standard_labware(
153
+ load_name: str, api_version: APIVersion
154
+ ) -> int:
103
155
  # We know the protocol is running at least apiLevel 2.14 by this point because
104
156
  # apiLevel 2.13 and below has its own separate code path for resolving labware.
105
- return _APILEVEL_2_14_OT_DEFAULT_VERSIONS.get(load_name, 1)
157
+ if (
158
+ api_version >= APIVersion(2, 23)
159
+ and load_name in _APILEVEL_2_23_OT_DEFAULT_VERSIONS
160
+ ):
161
+ return _APILEVEL_2_23_OT_DEFAULT_VERSIONS[load_name]
162
+ else:
163
+ return _APILEVEL_2_14_OT_DEFAULT_VERSIONS.get(load_name, 1)
@@ -1,4 +1,5 @@
1
1
  """Protocol API module implementation logic."""
2
+
2
3
  from __future__ import annotations
3
4
 
4
5
  from typing import Optional, List, Dict, Union
@@ -17,7 +18,7 @@ from opentrons.drivers.types import (
17
18
  )
18
19
 
19
20
  from opentrons.protocol_engine import commands as cmd
20
- from opentrons.protocol_engine.types import ABSMeasureMode
21
+ from opentrons.protocol_engine.types import ABSMeasureMode, StackerFillEmptyStrategy
21
22
  from opentrons.types import DeckSlotName
22
23
  from opentrons.protocol_engine.clients import SyncClient as ProtocolEngineClient
23
24
  from opentrons.protocol_engine.errors.exceptions import (
@@ -37,9 +38,10 @@ from ..module import (
37
38
  AbstractHeaterShakerCore,
38
39
  AbstractMagneticBlockCore,
39
40
  AbstractAbsorbanceReaderCore,
41
+ AbstractFlexStackerCore,
40
42
  )
41
43
  from .exceptions import InvalidMagnetEngageHeightError
42
-
44
+ from . import load_labware_params
43
45
 
44
46
  # Valid wavelength range for absorbance reader
45
47
  ABS_WAVELENGTH_MIN = 350
@@ -692,3 +694,117 @@ class AbsorbanceReaderCore(ModuleCore, AbstractAbsorbanceReaderCore):
692
694
  self.module_id
693
695
  )
694
696
  return abs_state.is_lid_on
697
+
698
+
699
+ class FlexStackerCore(ModuleCore, AbstractFlexStackerCore):
700
+ """Flex Stacker core logic implementation for Python protocols."""
701
+
702
+ _sync_module_hardware: SynchronousAdapter[hw_modules.FlexStacker]
703
+
704
+ def retrieve(self) -> None:
705
+ """Retrieve a labware from the Flex Stacker's hopper."""
706
+ self._engine_client.execute_command(
707
+ cmd.flex_stacker.RetrieveParams(
708
+ moduleId=self.module_id,
709
+ )
710
+ )
711
+
712
+ def store(self) -> None:
713
+ """Store a labware into Flex Stacker's hopper."""
714
+ self._engine_client.execute_command(
715
+ cmd.flex_stacker.StoreParams(
716
+ moduleId=self.module_id,
717
+ )
718
+ )
719
+
720
+ def fill(self, message: str, count: int | None) -> None:
721
+ """Pause the protocol to add more labware to the Flex Stacker's hopper."""
722
+ self._engine_client.execute_command(
723
+ cmd.flex_stacker.FillParams(
724
+ moduleId=self.module_id,
725
+ strategy=StackerFillEmptyStrategy.MANUAL_WITH_PAUSE,
726
+ message=message,
727
+ count=count,
728
+ )
729
+ )
730
+
731
+ def empty(self, message: str) -> None:
732
+ """Pause the protocol to remove labware from the Flex Stacker's hopper."""
733
+ self._engine_client.execute_command(
734
+ cmd.flex_stacker.EmptyParams(
735
+ moduleId=self.module_id,
736
+ strategy=StackerFillEmptyStrategy.MANUAL_WITH_PAUSE,
737
+ message=message,
738
+ count=0,
739
+ )
740
+ )
741
+
742
+ def set_stored_labware(
743
+ self,
744
+ main_load_name: str,
745
+ main_namespace: str | None,
746
+ main_version: int | None,
747
+ lid_load_name: str | None,
748
+ lid_namespace: str | None,
749
+ lid_version: int | None,
750
+ adapter_load_name: str | None,
751
+ adapter_namespace: str | None,
752
+ adapter_version: int | None,
753
+ count: int | None,
754
+ ) -> None:
755
+ """Configure the kind of labware that the stacker stores."""
756
+
757
+ custom_labware_params = (
758
+ self._engine_client.state.labware.find_custom_labware_load_params()
759
+ )
760
+
761
+ main_namespace, main_version = load_labware_params.resolve(
762
+ main_load_name,
763
+ main_namespace,
764
+ main_version,
765
+ custom_labware_params,
766
+ self._api_version,
767
+ )
768
+ main_labware = cmd.flex_stacker.StackerStoredLabwareDetails(
769
+ loadName=main_load_name, namespace=main_namespace, version=main_version
770
+ )
771
+
772
+ lid_labware: cmd.flex_stacker.StackerStoredLabwareDetails | None = None
773
+
774
+ if lid_load_name:
775
+ lid_namespace, lid_version = load_labware_params.resolve(
776
+ lid_load_name,
777
+ lid_namespace,
778
+ lid_version,
779
+ custom_labware_params,
780
+ self._api_version,
781
+ )
782
+ lid_labware = cmd.flex_stacker.StackerStoredLabwareDetails(
783
+ loadName=lid_load_name, namespace=lid_namespace, version=lid_version
784
+ )
785
+
786
+ adapter_labware: cmd.flex_stacker.StackerStoredLabwareDetails | None = None
787
+
788
+ if adapter_load_name:
789
+ adapter_namespace, adapter_version = load_labware_params.resolve(
790
+ adapter_load_name,
791
+ adapter_namespace,
792
+ adapter_version,
793
+ custom_labware_params,
794
+ self._api_version,
795
+ )
796
+ adapter_labware = cmd.flex_stacker.StackerStoredLabwareDetails(
797
+ loadName=adapter_load_name,
798
+ namespace=adapter_namespace,
799
+ version=adapter_version,
800
+ )
801
+
802
+ self._engine_client.execute_command(
803
+ cmd.flex_stacker.SetStoredLabwareParams(
804
+ moduleId=self.module_id,
805
+ initialCount=count,
806
+ primaryLabware=main_labware,
807
+ lidLabware=lid_labware,
808
+ adapterLabware=adapter_labware,
809
+ )
810
+ )
@@ -19,14 +19,9 @@ from opentrons.protocol_engine import (
19
19
  StateView,
20
20
  DeckSlotLocation,
21
21
  OnLabwareLocation,
22
- WellLocation,
23
- LiquidHandlingWellLocation,
24
- PickUpTipWellLocation,
25
22
  DropTipWellLocation,
26
23
  )
27
- from opentrons.protocol_engine.types import (
28
- StagingSlotLocation,
29
- )
24
+ from opentrons.protocol_engine.types import StagingSlotLocation, WellLocationType
30
25
  from opentrons.types import DeckSlotName, StagingSlotName, Point
31
26
  from . import point_calculations
32
27
 
@@ -69,12 +64,7 @@ def check_safe_for_pipette_movement( # noqa: C901
69
64
  pipette_id: str,
70
65
  labware_id: str,
71
66
  well_name: str,
72
- well_location: Union[
73
- WellLocation,
74
- LiquidHandlingWellLocation,
75
- PickUpTipWellLocation,
76
- DropTipWellLocation,
77
- ],
67
+ well_location: WellLocationType,
78
68
  ) -> None:
79
69
  """Check if the labware is safe to move to with a pipette in partial tip configuration.
80
70
 
@@ -100,12 +90,14 @@ def check_safe_for_pipette_movement( # noqa: C901
100
90
  partially_configured=True,
101
91
  )
102
92
  well_location_point = engine_state.geometry.get_well_position(
103
- labware_id=labware_id, well_name=well_name, well_location=well_location
93
+ labware_id=labware_id,
94
+ well_name=well_name,
95
+ well_location=well_location,
96
+ pipette_id=pipette_id,
104
97
  )
105
98
  primary_nozzle = engine_state.pipettes.get_primary_nozzle(pipette_id)
106
99
 
107
100
  destination_cp = _get_critical_point_to_use(engine_state, labware_id)
108
-
109
101
  pipette_bounds_at_well_location = (
110
102
  engine_state.pipettes.get_pipette_bounds_at_specified_move_to_position(
111
103
  pipette_id=pipette_id,