opentrons 8.1.0a0__py2.py3-none-any.whl → 8.2.0a0__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.
Files changed (230) hide show
  1. opentrons/cli/analyze.py +71 -7
  2. opentrons/config/__init__.py +9 -0
  3. opentrons/config/advanced_settings.py +22 -0
  4. opentrons/config/defaults_ot3.py +14 -36
  5. opentrons/config/feature_flags.py +4 -0
  6. opentrons/config/types.py +6 -17
  7. opentrons/drivers/absorbance_reader/abstract.py +27 -3
  8. opentrons/drivers/absorbance_reader/async_byonoy.py +207 -154
  9. opentrons/drivers/absorbance_reader/driver.py +24 -15
  10. opentrons/drivers/absorbance_reader/hid_protocol.py +79 -50
  11. opentrons/drivers/absorbance_reader/simulator.py +32 -6
  12. opentrons/drivers/types.py +23 -1
  13. opentrons/execute.py +2 -2
  14. opentrons/hardware_control/api.py +18 -10
  15. opentrons/hardware_control/backends/controller.py +3 -2
  16. opentrons/hardware_control/backends/flex_protocol.py +11 -5
  17. opentrons/hardware_control/backends/ot3controller.py +18 -50
  18. opentrons/hardware_control/backends/ot3simulator.py +7 -6
  19. opentrons/hardware_control/instruments/ot2/pipette_handler.py +22 -82
  20. opentrons/hardware_control/instruments/ot3/pipette_handler.py +10 -2
  21. opentrons/hardware_control/module_control.py +43 -2
  22. opentrons/hardware_control/modules/__init__.py +7 -1
  23. opentrons/hardware_control/modules/absorbance_reader.py +230 -83
  24. opentrons/hardware_control/modules/errors.py +7 -0
  25. opentrons/hardware_control/modules/heater_shaker.py +8 -3
  26. opentrons/hardware_control/modules/magdeck.py +12 -3
  27. opentrons/hardware_control/modules/mod_abc.py +27 -2
  28. opentrons/hardware_control/modules/tempdeck.py +15 -7
  29. opentrons/hardware_control/modules/thermocycler.py +69 -3
  30. opentrons/hardware_control/modules/types.py +11 -5
  31. opentrons/hardware_control/modules/update.py +11 -5
  32. opentrons/hardware_control/modules/utils.py +3 -1
  33. opentrons/hardware_control/ot3_calibration.py +6 -6
  34. opentrons/hardware_control/ot3api.py +126 -89
  35. opentrons/hardware_control/poller.py +15 -11
  36. opentrons/hardware_control/protocols/__init__.py +1 -7
  37. opentrons/hardware_control/protocols/instrument_configurer.py +14 -2
  38. opentrons/hardware_control/protocols/liquid_handler.py +5 -0
  39. opentrons/motion_planning/__init__.py +2 -0
  40. opentrons/motion_planning/waypoints.py +32 -0
  41. opentrons/protocol_api/__init__.py +2 -1
  42. opentrons/protocol_api/_liquid.py +87 -1
  43. opentrons/protocol_api/_parameter_context.py +10 -1
  44. opentrons/protocol_api/core/engine/deck_conflict.py +0 -297
  45. opentrons/protocol_api/core/engine/instrument.py +29 -25
  46. opentrons/protocol_api/core/engine/labware.py +10 -2
  47. opentrons/protocol_api/core/engine/module_core.py +129 -17
  48. opentrons/protocol_api/core/engine/pipette_movement_conflict.py +355 -0
  49. opentrons/protocol_api/core/engine/protocol.py +55 -2
  50. opentrons/protocol_api/core/instrument.py +2 -0
  51. opentrons/protocol_api/core/legacy/legacy_instrument_core.py +2 -0
  52. opentrons/protocol_api/core/legacy/legacy_protocol_core.py +5 -2
  53. opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py +2 -0
  54. opentrons/protocol_api/core/module.py +22 -4
  55. opentrons/protocol_api/core/protocol.py +5 -2
  56. opentrons/protocol_api/instrument_context.py +52 -20
  57. opentrons/protocol_api/labware.py +13 -1
  58. opentrons/protocol_api/module_contexts.py +68 -13
  59. opentrons/protocol_api/protocol_context.py +38 -4
  60. opentrons/protocol_api/validation.py +5 -3
  61. opentrons/protocol_engine/__init__.py +10 -9
  62. opentrons/protocol_engine/actions/__init__.py +5 -0
  63. opentrons/protocol_engine/actions/actions.py +42 -25
  64. opentrons/protocol_engine/actions/get_state_update.py +38 -0
  65. opentrons/protocol_engine/clients/sync_client.py +7 -1
  66. opentrons/protocol_engine/clients/transports.py +1 -1
  67. opentrons/protocol_engine/commands/__init__.py +0 -4
  68. opentrons/protocol_engine/commands/absorbance_reader/__init__.py +41 -11
  69. opentrons/protocol_engine/commands/absorbance_reader/close_lid.py +161 -0
  70. opentrons/protocol_engine/commands/absorbance_reader/initialize.py +53 -9
  71. opentrons/protocol_engine/commands/absorbance_reader/open_lid.py +160 -0
  72. opentrons/protocol_engine/commands/absorbance_reader/read.py +196 -0
  73. opentrons/protocol_engine/commands/aspirate.py +29 -16
  74. opentrons/protocol_engine/commands/aspirate_in_place.py +32 -15
  75. opentrons/protocol_engine/commands/blow_out.py +63 -14
  76. opentrons/protocol_engine/commands/blow_out_in_place.py +55 -13
  77. opentrons/protocol_engine/commands/calibration/calibrate_gripper.py +2 -5
  78. opentrons/protocol_engine/commands/calibration/calibrate_module.py +3 -4
  79. opentrons/protocol_engine/commands/calibration/calibrate_pipette.py +2 -5
  80. opentrons/protocol_engine/commands/calibration/move_to_maintenance_position.py +6 -4
  81. opentrons/protocol_engine/commands/command.py +28 -17
  82. opentrons/protocol_engine/commands/command_unions.py +37 -24
  83. opentrons/protocol_engine/commands/comment.py +5 -3
  84. opentrons/protocol_engine/commands/configure_for_volume.py +11 -14
  85. opentrons/protocol_engine/commands/configure_nozzle_layout.py +9 -15
  86. opentrons/protocol_engine/commands/custom.py +5 -3
  87. opentrons/protocol_engine/commands/dispense.py +42 -20
  88. opentrons/protocol_engine/commands/dispense_in_place.py +32 -14
  89. opentrons/protocol_engine/commands/drop_tip.py +68 -15
  90. opentrons/protocol_engine/commands/drop_tip_in_place.py +52 -11
  91. opentrons/protocol_engine/commands/get_tip_presence.py +5 -3
  92. opentrons/protocol_engine/commands/heater_shaker/close_labware_latch.py +6 -6
  93. opentrons/protocol_engine/commands/heater_shaker/deactivate_heater.py +6 -6
  94. opentrons/protocol_engine/commands/heater_shaker/deactivate_shaker.py +6 -6
  95. opentrons/protocol_engine/commands/heater_shaker/open_labware_latch.py +8 -6
  96. opentrons/protocol_engine/commands/heater_shaker/set_and_wait_for_shake_speed.py +8 -4
  97. opentrons/protocol_engine/commands/heater_shaker/set_target_temperature.py +6 -4
  98. opentrons/protocol_engine/commands/heater_shaker/wait_for_temperature.py +6 -6
  99. opentrons/protocol_engine/commands/home.py +11 -5
  100. opentrons/protocol_engine/commands/liquid_probe.py +146 -88
  101. opentrons/protocol_engine/commands/load_labware.py +19 -5
  102. opentrons/protocol_engine/commands/load_liquid.py +18 -7
  103. opentrons/protocol_engine/commands/load_module.py +43 -6
  104. opentrons/protocol_engine/commands/load_pipette.py +18 -17
  105. opentrons/protocol_engine/commands/magnetic_module/disengage.py +6 -6
  106. opentrons/protocol_engine/commands/magnetic_module/engage.py +6 -4
  107. opentrons/protocol_engine/commands/move_labware.py +106 -19
  108. opentrons/protocol_engine/commands/move_relative.py +15 -3
  109. opentrons/protocol_engine/commands/move_to_addressable_area.py +29 -4
  110. opentrons/protocol_engine/commands/move_to_addressable_area_for_drop_tip.py +13 -4
  111. opentrons/protocol_engine/commands/move_to_coordinates.py +11 -5
  112. opentrons/protocol_engine/commands/move_to_well.py +37 -10
  113. opentrons/protocol_engine/commands/pick_up_tip.py +50 -29
  114. opentrons/protocol_engine/commands/pipetting_common.py +39 -15
  115. opentrons/protocol_engine/commands/prepare_to_aspirate.py +62 -15
  116. opentrons/protocol_engine/commands/reload_labware.py +13 -4
  117. opentrons/protocol_engine/commands/retract_axis.py +6 -3
  118. opentrons/protocol_engine/commands/save_position.py +2 -3
  119. opentrons/protocol_engine/commands/set_rail_lights.py +5 -3
  120. opentrons/protocol_engine/commands/set_status_bar.py +5 -3
  121. opentrons/protocol_engine/commands/temperature_module/deactivate.py +6 -4
  122. opentrons/protocol_engine/commands/temperature_module/set_target_temperature.py +3 -4
  123. opentrons/protocol_engine/commands/temperature_module/wait_for_temperature.py +6 -6
  124. opentrons/protocol_engine/commands/thermocycler/__init__.py +19 -0
  125. opentrons/protocol_engine/commands/thermocycler/close_lid.py +8 -8
  126. opentrons/protocol_engine/commands/thermocycler/deactivate_block.py +6 -4
  127. opentrons/protocol_engine/commands/thermocycler/deactivate_lid.py +6 -4
  128. opentrons/protocol_engine/commands/thermocycler/open_lid.py +8 -4
  129. opentrons/protocol_engine/commands/thermocycler/run_extended_profile.py +165 -0
  130. opentrons/protocol_engine/commands/thermocycler/run_profile.py +6 -6
  131. opentrons/protocol_engine/commands/thermocycler/set_target_block_temperature.py +3 -4
  132. opentrons/protocol_engine/commands/thermocycler/set_target_lid_temperature.py +3 -4
  133. opentrons/protocol_engine/commands/thermocycler/wait_for_block_temperature.py +6 -4
  134. opentrons/protocol_engine/commands/thermocycler/wait_for_lid_temperature.py +6 -4
  135. opentrons/protocol_engine/commands/touch_tip.py +19 -7
  136. opentrons/protocol_engine/commands/unsafe/__init__.py +30 -0
  137. opentrons/protocol_engine/commands/unsafe/unsafe_blow_out_in_place.py +6 -4
  138. opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py +12 -4
  139. opentrons/protocol_engine/commands/unsafe/unsafe_engage_axes.py +5 -3
  140. opentrons/protocol_engine/commands/unsafe/unsafe_place_labware.py +194 -0
  141. opentrons/protocol_engine/commands/unsafe/unsafe_ungrip_labware.py +75 -0
  142. opentrons/protocol_engine/commands/unsafe/update_position_estimators.py +5 -3
  143. opentrons/protocol_engine/commands/verify_tip_presence.py +5 -5
  144. opentrons/protocol_engine/commands/wait_for_duration.py +5 -3
  145. opentrons/protocol_engine/commands/wait_for_resume.py +5 -3
  146. opentrons/protocol_engine/create_protocol_engine.py +41 -8
  147. opentrons/protocol_engine/engine_support.py +2 -1
  148. opentrons/protocol_engine/error_recovery_policy.py +14 -3
  149. opentrons/protocol_engine/errors/__init__.py +18 -0
  150. opentrons/protocol_engine/errors/exceptions.py +114 -2
  151. opentrons/protocol_engine/execution/__init__.py +2 -0
  152. opentrons/protocol_engine/execution/command_executor.py +22 -13
  153. opentrons/protocol_engine/execution/create_queue_worker.py +5 -1
  154. opentrons/protocol_engine/execution/door_watcher.py +1 -1
  155. opentrons/protocol_engine/execution/equipment.py +2 -1
  156. opentrons/protocol_engine/execution/error_recovery_hardware_state_synchronizer.py +101 -0
  157. opentrons/protocol_engine/execution/gantry_mover.py +4 -2
  158. opentrons/protocol_engine/execution/hardware_stopper.py +3 -3
  159. opentrons/protocol_engine/execution/heater_shaker_movement_flagger.py +1 -4
  160. opentrons/protocol_engine/execution/labware_movement.py +6 -3
  161. opentrons/protocol_engine/execution/movement.py +8 -3
  162. opentrons/protocol_engine/execution/pipetting.py +7 -4
  163. opentrons/protocol_engine/execution/queue_worker.py +6 -2
  164. opentrons/protocol_engine/execution/run_control.py +1 -1
  165. opentrons/protocol_engine/execution/thermocycler_movement_flagger.py +1 -1
  166. opentrons/protocol_engine/execution/thermocycler_plate_lifter.py +2 -1
  167. opentrons/protocol_engine/execution/tip_handler.py +77 -43
  168. opentrons/protocol_engine/notes/__init__.py +14 -2
  169. opentrons/protocol_engine/notes/notes.py +18 -1
  170. opentrons/protocol_engine/plugins.py +1 -1
  171. opentrons/protocol_engine/protocol_engine.py +54 -31
  172. opentrons/protocol_engine/resources/__init__.py +2 -0
  173. opentrons/protocol_engine/resources/deck_data_provider.py +58 -5
  174. opentrons/protocol_engine/resources/file_provider.py +157 -0
  175. opentrons/protocol_engine/resources/fixture_validation.py +5 -0
  176. opentrons/protocol_engine/resources/labware_validation.py +10 -0
  177. opentrons/protocol_engine/state/__init__.py +0 -70
  178. opentrons/protocol_engine/state/addressable_areas.py +1 -1
  179. opentrons/protocol_engine/state/command_history.py +21 -2
  180. opentrons/protocol_engine/state/commands.py +110 -31
  181. opentrons/protocol_engine/state/files.py +59 -0
  182. opentrons/protocol_engine/state/frustum_helpers.py +440 -0
  183. opentrons/protocol_engine/state/geometry.py +359 -15
  184. opentrons/protocol_engine/state/labware.py +166 -63
  185. opentrons/protocol_engine/state/liquids.py +1 -1
  186. opentrons/protocol_engine/state/module_substates/absorbance_reader_substate.py +19 -3
  187. opentrons/protocol_engine/state/modules.py +167 -85
  188. opentrons/protocol_engine/state/motion.py +16 -9
  189. opentrons/protocol_engine/state/pipettes.py +157 -317
  190. opentrons/protocol_engine/state/state.py +30 -1
  191. opentrons/protocol_engine/state/state_summary.py +3 -0
  192. opentrons/protocol_engine/state/tips.py +69 -114
  193. opentrons/protocol_engine/state/update_types.py +408 -0
  194. opentrons/protocol_engine/state/wells.py +236 -0
  195. opentrons/protocol_engine/types.py +90 -0
  196. opentrons/protocol_reader/file_format_validator.py +83 -15
  197. opentrons/protocol_runner/json_translator.py +21 -5
  198. opentrons/protocol_runner/legacy_command_mapper.py +27 -6
  199. opentrons/protocol_runner/legacy_context_plugin.py +27 -71
  200. opentrons/protocol_runner/protocol_runner.py +6 -3
  201. opentrons/protocol_runner/run_orchestrator.py +26 -6
  202. opentrons/protocols/advanced_control/mix.py +3 -5
  203. opentrons/protocols/advanced_control/transfers.py +125 -56
  204. opentrons/protocols/api_support/constants.py +1 -1
  205. opentrons/protocols/api_support/definitions.py +1 -1
  206. opentrons/protocols/api_support/labware_like.py +4 -4
  207. opentrons/protocols/api_support/tip_tracker.py +2 -2
  208. opentrons/protocols/api_support/types.py +15 -2
  209. opentrons/protocols/api_support/util.py +30 -42
  210. opentrons/protocols/duration/errors.py +1 -1
  211. opentrons/protocols/duration/estimator.py +50 -29
  212. opentrons/protocols/execution/dev_types.py +2 -2
  213. opentrons/protocols/execution/execute_json_v4.py +15 -10
  214. opentrons/protocols/execution/execute_python.py +8 -3
  215. opentrons/protocols/geometry/planning.py +12 -12
  216. opentrons/protocols/labware.py +17 -33
  217. opentrons/simulate.py +3 -3
  218. opentrons/types.py +30 -3
  219. opentrons/util/logging_config.py +34 -0
  220. {opentrons-8.1.0a0.dist-info → opentrons-8.2.0a0.dist-info}/METADATA +5 -4
  221. {opentrons-8.1.0a0.dist-info → opentrons-8.2.0a0.dist-info}/RECORD +227 -215
  222. opentrons/protocol_engine/commands/absorbance_reader/measure.py +0 -94
  223. opentrons/protocol_engine/commands/configuring_common.py +0 -26
  224. opentrons/protocol_runner/thread_async_queue.py +0 -174
  225. /opentrons/protocol_engine/state/{abstract_store.py → _abstract_store.py} +0 -0
  226. /opentrons/protocol_engine/state/{move_types.py → _move_types.py} +0 -0
  227. {opentrons-8.1.0a0.dist-info → opentrons-8.2.0a0.dist-info}/LICENSE +0 -0
  228. {opentrons-8.1.0a0.dist-info → opentrons-8.2.0a0.dist-info}/WHEEL +0 -0
  229. {opentrons-8.1.0a0.dist-info → opentrons-8.2.0a0.dist-info}/entry_points.txt +0 -0
  230. {opentrons-8.1.0a0.dist-info → opentrons-8.2.0a0.dist-info}/top_level.txt +0 -0
opentrons/cli/analyze.py CHANGED
@@ -23,8 +23,14 @@ from typing import (
23
23
  )
24
24
  import logging
25
25
  import sys
26
+ import json
26
27
 
27
- from opentrons.protocol_engine.types import RunTimeParameter, EngineStatus
28
+ from opentrons.protocol_engine.types import (
29
+ RunTimeParameter,
30
+ CSVRuntimeParamPaths,
31
+ PrimitiveRunTimeParamValuesType,
32
+ EngineStatus,
33
+ )
28
34
  from opentrons.protocols.api_support.types import APIVersion
29
35
  from opentrons.protocol_reader import (
30
36
  ProtocolReader,
@@ -104,8 +110,22 @@ class _Output:
104
110
  type=click.Choice(["DEBUG", "INFO", "WARNING", "ERROR"], case_sensitive=False),
105
111
  default="WARNING",
106
112
  )
113
+ @click.option(
114
+ "--rtp-values",
115
+ help="Serialized JSON of runtime parameter variable names to values.",
116
+ default="{}",
117
+ type=str,
118
+ )
119
+ @click.option(
120
+ "--rtp-files",
121
+ help="Serialized JSON of runtime parameter variable names to file paths.",
122
+ default="{}",
123
+ type=str,
124
+ )
107
125
  def analyze(
108
126
  files: Sequence[Path],
127
+ rtp_values: str,
128
+ rtp_files: str,
109
129
  json_output: Optional[IO[bytes]],
110
130
  human_json_output: Optional[IO[bytes]],
111
131
  log_output: str,
@@ -125,7 +145,7 @@ def analyze(
125
145
 
126
146
  try:
127
147
  with _capture_logs(log_output, log_level):
128
- sys.exit(run(_analyze, files, outputs, check))
148
+ sys.exit(run(_analyze, files, rtp_values, rtp_files, outputs, check))
129
149
  except click.ClickException:
130
150
  raise
131
151
  except Exception as e:
@@ -194,6 +214,37 @@ def _get_input_files(files_and_dirs: Sequence[Path]) -> List[Path]:
194
214
  return results
195
215
 
196
216
 
217
+ def _get_runtime_parameter_values(
218
+ serialized_rtp_values: str,
219
+ ) -> PrimitiveRunTimeParamValuesType:
220
+ rtp_values = {}
221
+ try:
222
+ for variable_name, value in json.loads(serialized_rtp_values).items():
223
+ if not isinstance(value, (bool, int, float, str)):
224
+ raise click.BadParameter(
225
+ f"Runtime parameter '{value}' is not of allowed type boolean, integer, float or string",
226
+ param_hint="--rtp-values",
227
+ )
228
+ rtp_values[variable_name] = value
229
+ except json.JSONDecodeError as error:
230
+ raise click.BadParameter(
231
+ f"JSON decode error: {error}", param_hint="--rtp-values"
232
+ )
233
+ return rtp_values
234
+
235
+
236
+ def _get_runtime_parameter_paths(serialized_rtp_files: str) -> CSVRuntimeParamPaths:
237
+ try:
238
+ return {
239
+ variable_name: Path(path_string)
240
+ for variable_name, path_string in json.loads(serialized_rtp_files).items()
241
+ }
242
+ except json.JSONDecodeError as error:
243
+ raise click.BadParameter(
244
+ f"JSON decode error: {error}", param_hint="--rtp-files"
245
+ )
246
+
247
+
197
248
  R = TypeVar("R")
198
249
 
199
250
 
@@ -238,7 +289,11 @@ class UnexpectedAnalysisError(EnumeratedError):
238
289
  )
239
290
 
240
291
 
241
- async def _do_analyze(protocol_source: ProtocolSource) -> RunResult:
292
+ async def _do_analyze(
293
+ protocol_source: ProtocolSource,
294
+ rtp_values: PrimitiveRunTimeParamValuesType,
295
+ rtp_paths: CSVRuntimeParamPaths,
296
+ ) -> RunResult:
242
297
 
243
298
  orchestrator = await create_simulating_orchestrator(
244
299
  robot_type=protocol_source.robot_type, protocol_config=protocol_source.config
@@ -247,8 +302,8 @@ async def _do_analyze(protocol_source: ProtocolSource) -> RunResult:
247
302
  await orchestrator.load(
248
303
  protocol_source=protocol_source,
249
304
  parse_mode=ParseMode.NORMAL,
250
- run_time_param_values=None,
251
- run_time_param_paths=None,
305
+ run_time_param_values=rtp_values,
306
+ run_time_param_paths=rtp_paths,
252
307
  )
253
308
  except Exception as error:
254
309
  err_id = "analysis-setup-error"
@@ -275,7 +330,9 @@ async def _do_analyze(protocol_source: ProtocolSource) -> RunResult:
275
330
  modules=[],
276
331
  labwareOffsets=[],
277
332
  liquids=[],
333
+ wells=[],
278
334
  hasEverEnteredErrorRecovery=False,
335
+ files=[],
279
336
  ),
280
337
  parameters=[],
281
338
  )
@@ -284,9 +341,16 @@ async def _do_analyze(protocol_source: ProtocolSource) -> RunResult:
284
341
 
285
342
 
286
343
  async def _analyze(
287
- files_and_dirs: Sequence[Path], outputs: Sequence[_Output], check: bool
344
+ files_and_dirs: Sequence[Path],
345
+ rtp_values: str,
346
+ rtp_files: str,
347
+ outputs: Sequence[_Output],
348
+ check: bool,
288
349
  ) -> int:
289
350
  input_files = _get_input_files(files_and_dirs)
351
+ parsed_rtp_values = _get_runtime_parameter_values(rtp_values)
352
+ rtp_paths = _get_runtime_parameter_paths(rtp_files)
353
+
290
354
  try:
291
355
  protocol_source = await ProtocolReader().read_saved(
292
356
  files=input_files,
@@ -295,7 +359,7 @@ async def _analyze(
295
359
  except ProtocolFilesInvalidError as error:
296
360
  raise click.ClickException(str(error))
297
361
 
298
- analysis = await _do_analyze(protocol_source)
362
+ analysis = await _do_analyze(protocol_source, parsed_rtp_values, rtp_paths)
299
363
  return_code = _get_return_code(analysis)
300
364
 
301
365
  if not outputs:
@@ -202,6 +202,15 @@ CONFIG_ELEMENTS = (
202
202
  " absolute path, it will be used directly. If it is a "
203
203
  "relative path it will be relative to log_dir",
204
204
  ),
205
+ ConfigElement(
206
+ "sensor_log_file",
207
+ "Sensor Log File",
208
+ Path("logs") / "sensor.log",
209
+ ConfigElementType.FILE,
210
+ "The location of the file to save sensor logs to. If this is an"
211
+ " absolute path, it will be used directly. If it is a "
212
+ "relative path it will be relative to log_dir",
213
+ ),
205
214
  ConfigElement(
206
215
  "serial_log_file",
207
216
  "Serial Log File",
@@ -222,6 +222,17 @@ settings = [
222
222
  robot_type=[RobotTypeEnum.OT2, RobotTypeEnum.FLEX],
223
223
  internal_only=True,
224
224
  ),
225
+ SettingDefinition(
226
+ _id="allowLiquidClasses",
227
+ title="Allow the use of liquid classes",
228
+ description=(
229
+ "Do not enable."
230
+ " This is an Opentrons internal setting to allow using in-development"
231
+ " liquid classes."
232
+ ),
233
+ robot_type=[RobotTypeEnum.OT2, RobotTypeEnum.FLEX],
234
+ internal_only=True,
235
+ ),
225
236
  ]
226
237
 
227
238
 
@@ -715,6 +726,16 @@ def _migrate34to35(previous: SettingsMap) -> SettingsMap:
715
726
  return newmap
716
727
 
717
728
 
729
+ def _migrate35to36(previous: SettingsMap) -> SettingsMap:
730
+ """Migrate to version 36 of the feature flags file.
731
+
732
+ - Adds the allowLiquidClasses config element.
733
+ """
734
+ newmap = {k: v for k, v in previous.items()}
735
+ newmap["allowLiquidClasses"] = None
736
+ return newmap
737
+
738
+
718
739
  _MIGRATIONS = [
719
740
  _migrate0to1,
720
741
  _migrate1to2,
@@ -751,6 +772,7 @@ _MIGRATIONS = [
751
772
  _migrate32to33,
752
773
  _migrate33to34,
753
774
  _migrate34to35,
775
+ _migrate35to36,
754
776
  ]
755
777
  """
756
778
  List of all migrations to apply, indexed by (version - 1). See _migrate below
@@ -15,7 +15,6 @@ from .types import (
15
15
  LiquidProbeSettings,
16
16
  ZSenseSettings,
17
17
  EdgeSenseSettings,
18
- OutputOptions,
19
18
  )
20
19
 
21
20
 
@@ -27,9 +26,11 @@ DEFAULT_LIQUID_PROBE_SETTINGS: Final[LiquidProbeSettings] = LiquidProbeSettings(
27
26
  plunger_speed=15,
28
27
  plunger_impulse_time=0.2,
29
28
  sensor_threshold_pascals=15,
30
- output_option=OutputOptions.sync_buffer_to_csv,
31
29
  aspirate_while_sensing=False,
32
- data_files={InstrumentProbeType.PRIMARY: "/data/pressure_sensor_data.csv"},
30
+ z_overlap_between_passes_mm=0.1,
31
+ plunger_reset_offset=2.0,
32
+ samples_for_baselining=20,
33
+ sample_time_sec=0.004,
33
34
  )
34
35
 
35
36
  DEFAULT_CALIBRATION_SETTINGS: Final[OT3CalibrationSettings] = OT3CalibrationSettings(
@@ -39,7 +40,6 @@ DEFAULT_CALIBRATION_SETTINGS: Final[OT3CalibrationSettings] = OT3CalibrationSett
39
40
  max_overrun_distance_mm=5.0,
40
41
  speed_mm_per_s=1.0,
41
42
  sensor_threshold_pf=3.0,
42
- output_option=OutputOptions.sync_only,
43
43
  ),
44
44
  ),
45
45
  edge_sense=EdgeSenseSettings(
@@ -50,7 +50,6 @@ DEFAULT_CALIBRATION_SETTINGS: Final[OT3CalibrationSettings] = OT3CalibrationSett
50
50
  max_overrun_distance_mm=0.5,
51
51
  speed_mm_per_s=1,
52
52
  sensor_threshold_pf=3.0,
53
- output_option=OutputOptions.sync_only,
54
53
  ),
55
54
  search_initial_tolerance_mm=12.0,
56
55
  search_iteration_limit=8,
@@ -191,23 +190,6 @@ DEFAULT_RUN_CURRENT: Final[ByGantryLoad[Dict[OT3AxisKind, float]]] = ByGantryLoa
191
190
  )
192
191
 
193
192
 
194
- def _build_output_option_with_default(
195
- from_conf: Any, default: OutputOptions
196
- ) -> OutputOptions:
197
- if from_conf is None:
198
- return default
199
- else:
200
- if isinstance(from_conf, OutputOptions):
201
- return from_conf
202
- else:
203
- try:
204
- enumval = OutputOptions[from_conf]
205
- except KeyError: # not an enum entry
206
- return default
207
- else:
208
- return enumval
209
-
210
-
211
193
  def _build_log_files_with_default(
212
194
  from_conf: Any,
213
195
  default: Optional[Dict[InstrumentProbeType, str]],
@@ -312,24 +294,12 @@ def _build_default_cap_pass(
312
294
  sensor_threshold_pf=from_conf.get(
313
295
  "sensor_threshold_pf", default.sensor_threshold_pf
314
296
  ),
315
- output_option=from_conf.get("output_option", default.output_option),
316
297
  )
317
298
 
318
299
 
319
300
  def _build_default_liquid_probe(
320
301
  from_conf: Any, default: LiquidProbeSettings
321
302
  ) -> LiquidProbeSettings:
322
- output_option = _build_output_option_with_default(
323
- from_conf.get("output_option", None), default.output_option
324
- )
325
- data_files: Optional[Dict[InstrumentProbeType, str]] = None
326
- if (
327
- output_option is OutputOptions.sync_buffer_to_csv
328
- or output_option is OutputOptions.stream_to_csv
329
- ):
330
- data_files = _build_log_files_with_default(
331
- from_conf.get("data_files", None), default.data_files
332
- )
333
303
  return LiquidProbeSettings(
334
304
  mount_speed=from_conf.get("mount_speed", default.mount_speed),
335
305
  plunger_speed=from_conf.get("plunger_speed", default.plunger_speed),
@@ -339,11 +309,19 @@ def _build_default_liquid_probe(
339
309
  sensor_threshold_pascals=from_conf.get(
340
310
  "sensor_threshold_pascals", default.sensor_threshold_pascals
341
311
  ),
342
- output_option=from_conf.get("output_option", default.output_option),
343
312
  aspirate_while_sensing=from_conf.get(
344
313
  "aspirate_while_sensing", default.aspirate_while_sensing
345
314
  ),
346
- data_files=data_files,
315
+ z_overlap_between_passes_mm=from_conf.get(
316
+ "z_overlap_between_passes_mm", default.z_overlap_between_passes_mm
317
+ ),
318
+ plunger_reset_offset=from_conf.get(
319
+ "plunger_reset_offset", default.plunger_reset_offset
320
+ ),
321
+ samples_for_baselining=from_conf.get(
322
+ "samples_for_baselining", default.samples_for_baselining
323
+ ),
324
+ sample_time_sec=from_conf.get("sample_time_sec", default.sample_time_sec),
347
325
  )
348
326
 
349
327
 
@@ -78,3 +78,7 @@ def enable_performance_metrics(robot_type: RobotTypeEnum) -> bool:
78
78
 
79
79
  def oem_mode_enabled() -> bool:
80
80
  return advs.get_setting_with_env_overload("enableOEMMode", RobotTypeEnum.FLEX)
81
+
82
+
83
+ def allow_liquid_classes(robot_type: RobotTypeEnum) -> bool:
84
+ return advs.get_setting_with_env_overload("allowLiquidClasses", robot_type)
opentrons/config/types.py CHANGED
@@ -1,8 +1,8 @@
1
1
  from enum import Enum
2
2
  from dataclasses import dataclass, asdict, fields
3
- from typing import Dict, Tuple, TypeVar, Generic, List, cast, Optional
3
+ from typing import Dict, Tuple, TypeVar, Generic, List, cast
4
4
  from typing_extensions import TypedDict, Literal
5
- from opentrons.hardware_control.types import OT3AxisKind, InstrumentProbeType
5
+ from opentrons.hardware_control.types import OT3AxisKind
6
6
 
7
7
 
8
8
  class AxisDict(TypedDict):
@@ -103,25 +103,12 @@ class OT3CurrentSettings:
103
103
  )
104
104
 
105
105
 
106
- class OutputOptions(int, Enum):
107
- """Specifies where we should report sensor data to during a sensor pass."""
108
-
109
- stream_to_csv = 0x1 # compile sensor data stream into a csv file, in addition to can_bus_only behavior
110
- sync_buffer_to_csv = 0x2 # collect sensor data on pipette mcu, then stream to robot server and compile into a csv file, in addition to can_bus_only behavior
111
- can_bus_only = (
112
- 0x4 # stream sensor data over CAN bus, in addition to sync_only behavior
113
- )
114
- sync_only = 0x8 # trigger pipette sync line upon sensor's detection of something
115
-
116
-
117
106
  @dataclass(frozen=True)
118
107
  class CapacitivePassSettings:
119
108
  prep_distance_mm: float
120
109
  max_overrun_distance_mm: float
121
110
  speed_mm_per_s: float
122
111
  sensor_threshold_pf: float
123
- output_option: OutputOptions
124
- data_files: Optional[Dict[InstrumentProbeType, str]] = None
125
112
 
126
113
 
127
114
  @dataclass(frozen=True)
@@ -135,9 +122,11 @@ class LiquidProbeSettings:
135
122
  plunger_speed: float
136
123
  plunger_impulse_time: float
137
124
  sensor_threshold_pascals: float
138
- output_option: OutputOptions
139
125
  aspirate_while_sensing: bool
140
- data_files: Optional[Dict[InstrumentProbeType, str]]
126
+ z_overlap_between_passes_mm: float
127
+ plunger_reset_offset: float
128
+ samples_for_baselining: int
129
+ sample_time_sec: float
141
130
 
142
131
 
143
132
  @dataclass(frozen=True)
@@ -1,8 +1,10 @@
1
1
  from abc import ABC, abstractmethod
2
- from typing import Dict, List
2
+ from typing import Dict, List, Optional, Tuple
3
3
  from opentrons.drivers.types import (
4
+ ABSMeasurementMode,
4
5
  AbsorbanceReaderLidStatus,
5
6
  AbsorbanceReaderDeviceState,
7
+ AbsorbanceReaderPlatePresence,
6
8
  )
7
9
 
8
10
 
@@ -31,11 +33,18 @@ class AbstractAbsorbanceReaderDriver(ABC):
31
33
  ...
32
34
 
33
35
  @abstractmethod
34
- async def get_single_measurement(self, wavelength: int) -> List[float]:
36
+ async def initialize_measurement(
37
+ self,
38
+ wavelengths: List[int],
39
+ mode: ABSMeasurementMode = ABSMeasurementMode.SINGLE,
40
+ reference_wavelength: Optional[int] = None,
41
+ ) -> None:
42
+ """Initialize measurement for the device in single or multi mode for the given wavelengths"""
35
43
  ...
36
44
 
37
45
  @abstractmethod
38
- async def initialize_measurement(self, wavelength: int) -> None:
46
+ async def get_measurement(self) -> List[List[float]]:
47
+ """Gets one or more measurements based on the current configuration."""
39
48
  ...
40
49
 
41
50
  @abstractmethod
@@ -46,3 +55,18 @@ class AbstractAbsorbanceReaderDriver(ABC):
46
55
  async def get_device_info(self) -> Dict[str, str]:
47
56
  """Get device info"""
48
57
  ...
58
+
59
+ @abstractmethod
60
+ async def get_uptime(self) -> int:
61
+ """Get device uptime"""
62
+ ...
63
+
64
+ @abstractmethod
65
+ async def get_plate_presence(self) -> AbsorbanceReaderPlatePresence:
66
+ """Check if there is a plate in the reader."""
67
+ ...
68
+
69
+ @abstractmethod
70
+ async def update_firmware(self, firmware_file_path: str) -> Tuple[bool, str]:
71
+ """Updates the firmware on the device."""
72
+ ...