opentrons 8.2.0__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.

Potentially problematic release.


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

Files changed (62) hide show
  1. opentrons/drivers/absorbance_reader/async_byonoy.py +5 -6
  2. opentrons/hardware_control/backends/ot3utils.py +0 -1
  3. opentrons/hardware_control/modules/absorbance_reader.py +0 -2
  4. opentrons/hardware_control/ot3api.py +5 -5
  5. opentrons/hardware_control/protocols/position_estimator.py +1 -3
  6. opentrons/hardware_control/types.py +0 -2
  7. opentrons/legacy_commands/helpers.py +2 -8
  8. opentrons/protocol_api/core/engine/labware.py +2 -10
  9. opentrons/protocol_api/core/engine/module_core.py +1 -38
  10. opentrons/protocol_api/core/engine/pipette_movement_conflict.py +5 -12
  11. opentrons/protocol_api/core/engine/protocol.py +30 -5
  12. opentrons/protocol_api/core/labware.py +0 -4
  13. opentrons/protocol_api/core/legacy/legacy_labware_core.py +0 -5
  14. opentrons/protocol_api/core/legacy/legacy_protocol_core.py +0 -1
  15. opentrons/protocol_api/core/protocol.py +0 -1
  16. opentrons/protocol_api/module_contexts.py +26 -69
  17. opentrons/protocol_api/protocol_context.py +2 -12
  18. opentrons/protocol_engine/actions/__init__.py +2 -0
  19. opentrons/protocol_engine/actions/actions.py +12 -0
  20. opentrons/protocol_engine/clients/sync_client.py +6 -0
  21. opentrons/protocol_engine/commands/absorbance_reader/close_lid.py +31 -18
  22. opentrons/protocol_engine/commands/absorbance_reader/initialize.py +7 -19
  23. opentrons/protocol_engine/commands/absorbance_reader/open_lid.py +29 -17
  24. opentrons/protocol_engine/commands/absorbance_reader/read.py +0 -4
  25. opentrons/protocol_engine/commands/aspirate_in_place.py +3 -3
  26. opentrons/protocol_engine/commands/command.py +1 -3
  27. opentrons/protocol_engine/commands/dispense_in_place.py +1 -1
  28. opentrons/protocol_engine/commands/drop_tip.py +1 -2
  29. opentrons/protocol_engine/commands/drop_tip_in_place.py +2 -7
  30. opentrons/protocol_engine/commands/load_labware.py +0 -9
  31. opentrons/protocol_engine/commands/load_module.py +39 -0
  32. opentrons/protocol_engine/commands/move_labware.py +4 -49
  33. opentrons/protocol_engine/commands/pick_up_tip.py +1 -1
  34. opentrons/protocol_engine/commands/pipetting_common.py +1 -8
  35. opentrons/protocol_engine/commands/unsafe/unsafe_place_labware.py +35 -49
  36. opentrons/protocol_engine/commands/unsafe/unsafe_ungrip_labware.py +1 -3
  37. opentrons/protocol_engine/commands/unsafe/update_position_estimators.py +1 -5
  38. opentrons/protocol_engine/create_protocol_engine.py +1 -18
  39. opentrons/protocol_engine/errors/__init__.py +0 -2
  40. opentrons/protocol_engine/errors/error_occurrence.py +3 -8
  41. opentrons/protocol_engine/errors/exceptions.py +0 -13
  42. opentrons/protocol_engine/execution/labware_movement.py +21 -69
  43. opentrons/protocol_engine/execution/movement.py +4 -9
  44. opentrons/protocol_engine/protocol_engine.py +7 -0
  45. opentrons/protocol_engine/resources/deck_data_provider.py +39 -0
  46. opentrons/protocol_engine/resources/file_provider.py +7 -11
  47. opentrons/protocol_engine/resources/fixture_validation.py +1 -6
  48. opentrons/protocol_engine/state/geometry.py +49 -91
  49. opentrons/protocol_engine/state/labware.py +25 -102
  50. opentrons/protocol_engine/state/module_substates/absorbance_reader_substate.py +1 -3
  51. opentrons/protocol_engine/state/modules.py +80 -53
  52. opentrons/protocol_engine/state/motion.py +5 -17
  53. opentrons/protocol_engine/state/update_types.py +0 -16
  54. opentrons/protocol_runner/run_orchestrator.py +0 -15
  55. opentrons/protocols/parameters/csv_parameter_interface.py +1 -3
  56. opentrons/util/logging_config.py +1 -1
  57. {opentrons-8.2.0.dist-info → opentrons-8.2.0a0.dist-info}/METADATA +4 -4
  58. {opentrons-8.2.0.dist-info → opentrons-8.2.0a0.dist-info}/RECORD +62 -62
  59. {opentrons-8.2.0.dist-info → opentrons-8.2.0a0.dist-info}/LICENSE +0 -0
  60. {opentrons-8.2.0.dist-info → opentrons-8.2.0a0.dist-info}/WHEEL +0 -0
  61. {opentrons-8.2.0.dist-info → opentrons-8.2.0a0.dist-info}/entry_points.txt +0 -0
  62. {opentrons-8.2.0.dist-info → opentrons-8.2.0a0.dist-info}/top_level.txt +0 -0
@@ -26,15 +26,13 @@ from opentrons.motion_planning.adjacent_slots_getters import (
26
26
  get_west_slot,
27
27
  get_adjacent_staging_slot,
28
28
  )
29
- from opentrons.protocol_engine.actions.get_state_update import get_state_updates
30
29
  from opentrons.protocol_engine.commands.calibration.calibrate_module import (
31
30
  CalibrateModuleResult,
32
31
  )
33
- from opentrons.protocol_engine.state import update_types
34
32
  from opentrons.protocol_engine.state.module_substates.absorbance_reader_substate import (
35
33
  AbsorbanceReaderMeasureMode,
36
34
  )
37
- from opentrons.types import DeckSlotName, MountType, StagingSlotName
35
+ from opentrons.types import DeckSlotName, MountType
38
36
  from ..errors import ModuleNotConnectedError
39
37
 
40
38
  from ..types import (
@@ -69,6 +67,7 @@ from ..actions import (
69
67
  Action,
70
68
  SucceedCommandAction,
71
69
  AddModuleAction,
70
+ AddAbsorbanceReaderLidAction,
72
71
  )
73
72
  from ._abstract_store import HasState, HandlesActions
74
73
  from .module_substates import (
@@ -235,14 +234,13 @@ class ModuleStore(HasState[ModuleState], HandlesActions):
235
234
  requested_model=None,
236
235
  module_live_data=action.module_live_data,
237
236
  )
238
-
239
- for state_update in get_state_updates(action):
240
- self._handle_state_update(state_update)
237
+ elif isinstance(action, AddAbsorbanceReaderLidAction):
238
+ self._update_absorbance_reader_lid_id(
239
+ module_id=action.module_id,
240
+ lid_id=action.lid_id,
241
+ )
241
242
 
242
243
  def _handle_command(self, command: Command) -> None:
243
- # todo(mm, 2024-11-04): Delete this function. Port these isinstance()
244
- # checks to the update_types.StateUpdate mechanism.
245
-
246
244
  if isinstance(command.result, LoadModuleResult):
247
245
  slot_name = command.params.location.slotName
248
246
  self._add_module_substate(
@@ -299,40 +297,38 @@ class ModuleStore(HasState[ModuleState], HandlesActions):
299
297
  if isinstance(
300
298
  command.result,
301
299
  (
300
+ absorbance_reader.CloseLidResult,
301
+ absorbance_reader.OpenLidResult,
302
302
  absorbance_reader.InitializeResult,
303
303
  absorbance_reader.ReadAbsorbanceResult,
304
304
  ),
305
305
  ):
306
306
  self._handle_absorbance_reader_commands(command)
307
307
 
308
- def _handle_state_update(self, state_update: update_types.StateUpdate) -> None:
309
- if state_update.absorbance_reader_lid != update_types.NO_CHANGE:
310
- module_id = state_update.absorbance_reader_lid.module_id
311
- is_lid_on = state_update.absorbance_reader_lid.is_lid_on
312
-
313
- # Get current values:
314
- absorbance_reader_substate = self._state.substate_by_module_id[module_id]
315
- assert isinstance(
316
- absorbance_reader_substate, AbsorbanceReaderSubState
317
- ), f"{module_id} is not an absorbance plate reader."
318
- configured = absorbance_reader_substate.configured
319
- measure_mode = absorbance_reader_substate.measure_mode
320
- configured_wavelengths = absorbance_reader_substate.configured_wavelengths
321
- reference_wavelength = absorbance_reader_substate.reference_wavelength
322
- data = absorbance_reader_substate.data
308
+ def _update_absorbance_reader_lid_id(
309
+ self,
310
+ module_id: str,
311
+ lid_id: str,
312
+ ) -> None:
313
+ abs_substate = self._state.substate_by_module_id.get(module_id)
314
+ assert isinstance(
315
+ abs_substate, AbsorbanceReaderSubState
316
+ ), f"{module_id} is not an absorbance plate reader."
323
317
 
324
- self._state.substate_by_module_id[module_id] = AbsorbanceReaderSubState(
325
- module_id=AbsorbanceReaderId(module_id),
326
- configured=configured,
327
- measured=True,
328
- is_lid_on=is_lid_on,
329
- measure_mode=measure_mode,
330
- configured_wavelengths=configured_wavelengths,
331
- reference_wavelength=reference_wavelength,
332
- data=data,
333
- )
318
+ prev_state: AbsorbanceReaderSubState = abs_substate
319
+ self._state.substate_by_module_id[module_id] = AbsorbanceReaderSubState(
320
+ module_id=AbsorbanceReaderId(module_id),
321
+ configured=prev_state.configured,
322
+ measured=prev_state.measured,
323
+ is_lid_on=prev_state.is_lid_on,
324
+ data=prev_state.data,
325
+ measure_mode=prev_state.measure_mode,
326
+ configured_wavelengths=prev_state.configured_wavelengths,
327
+ reference_wavelength=prev_state.reference_wavelength,
328
+ lid_id=lid_id,
329
+ )
334
330
 
335
- def _add_module_substate(
331
+ def _add_module_substate( # noqa: C901
336
332
  self,
337
333
  module_id: str,
338
334
  serial_number: Optional[str],
@@ -391,6 +387,16 @@ class ModuleStore(HasState[ModuleState], HandlesActions):
391
387
  module_id=MagneticBlockId(module_id)
392
388
  )
393
389
  elif ModuleModel.is_absorbance_reader(actual_model):
390
+ lid_labware_id = None
391
+ slot = self._state.slot_by_module_id[module_id]
392
+ if slot is not None:
393
+ reader_addressable_area = f"absorbanceReaderV1{slot.value}"
394
+ for labware in self._state.deck_fixed_labware:
395
+ if labware.location == AddressableAreaLocation(
396
+ addressableAreaName=reader_addressable_area
397
+ ):
398
+ lid_labware_id = labware.labware_id
399
+ break
394
400
  self._state.substate_by_module_id[module_id] = AbsorbanceReaderSubState(
395
401
  module_id=AbsorbanceReaderId(module_id),
396
402
  configured=False,
@@ -400,6 +406,7 @@ class ModuleStore(HasState[ModuleState], HandlesActions):
400
406
  measure_mode=None,
401
407
  configured_wavelengths=None,
402
408
  reference_wavelength=None,
409
+ lid_id=lid_labware_id,
403
410
  )
404
411
 
405
412
  def _update_additional_slots_occupied_by_thermocycler(
@@ -593,6 +600,8 @@ class ModuleStore(HasState[ModuleState], HandlesActions):
593
600
  command: Union[
594
601
  absorbance_reader.Initialize,
595
602
  absorbance_reader.ReadAbsorbance,
603
+ absorbance_reader.CloseLid,
604
+ absorbance_reader.OpenLid,
596
605
  ],
597
606
  ) -> None:
598
607
  module_id = command.params.moduleId
@@ -607,6 +616,8 @@ class ModuleStore(HasState[ModuleState], HandlesActions):
607
616
  configured_wavelengths = absorbance_reader_substate.configured_wavelengths
608
617
  reference_wavelength = absorbance_reader_substate.reference_wavelength
609
618
  is_lid_on = absorbance_reader_substate.is_lid_on
619
+ lid_id = absorbance_reader_substate.lid_id
620
+ data = absorbance_reader_substate.data
610
621
 
611
622
  if isinstance(command.result, absorbance_reader.InitializeResult):
612
623
  self._state.substate_by_module_id[module_id] = AbsorbanceReaderSubState(
@@ -614,6 +625,7 @@ class ModuleStore(HasState[ModuleState], HandlesActions):
614
625
  configured=True,
615
626
  measured=False,
616
627
  is_lid_on=is_lid_on,
628
+ lid_id=lid_id,
617
629
  measure_mode=AbsorbanceReaderMeasureMode(command.params.measureMode),
618
630
  configured_wavelengths=command.params.sampleWavelengths,
619
631
  reference_wavelength=command.params.referenceWavelength,
@@ -625,12 +637,39 @@ class ModuleStore(HasState[ModuleState], HandlesActions):
625
637
  configured=configured,
626
638
  measured=True,
627
639
  is_lid_on=is_lid_on,
640
+ lid_id=lid_id,
628
641
  measure_mode=measure_mode,
629
642
  configured_wavelengths=configured_wavelengths,
630
643
  reference_wavelength=reference_wavelength,
631
644
  data=command.result.data,
632
645
  )
633
646
 
647
+ elif isinstance(command.result, absorbance_reader.OpenLidResult):
648
+ self._state.substate_by_module_id[module_id] = AbsorbanceReaderSubState(
649
+ module_id=AbsorbanceReaderId(module_id),
650
+ configured=configured,
651
+ measured=True,
652
+ is_lid_on=False,
653
+ lid_id=lid_id,
654
+ measure_mode=measure_mode,
655
+ configured_wavelengths=configured_wavelengths,
656
+ reference_wavelength=reference_wavelength,
657
+ data=data,
658
+ )
659
+
660
+ elif isinstance(command.result, absorbance_reader.CloseLidResult):
661
+ self._state.substate_by_module_id[module_id] = AbsorbanceReaderSubState(
662
+ module_id=AbsorbanceReaderId(module_id),
663
+ configured=configured,
664
+ measured=True,
665
+ is_lid_on=True,
666
+ lid_id=lid_id,
667
+ measure_mode=measure_mode,
668
+ configured_wavelengths=configured_wavelengths,
669
+ reference_wavelength=reference_wavelength,
670
+ data=data,
671
+ )
672
+
634
673
 
635
674
  class ModuleView(HasState[ModuleState]):
636
675
  """Read-only view of computed module state."""
@@ -844,21 +883,12 @@ class ModuleView(HasState[ModuleState]):
844
883
  """Get the specified module's dimensions."""
845
884
  return self.get_definition(module_id).dimensions
846
885
 
847
- def get_nominal_offset_to_child(
886
+ def get_nominal_module_offset(
848
887
  self,
849
888
  module_id: str,
850
- # todo(mm, 2024-11-07): A method of one view taking a sibling view as an argument
851
- # is unusual, and may be bug-prone if the order in which the views are updated
852
- # matters. If we need to compute something that depends on module info and
853
- # addressable area info, can we do that computation in GeometryView instead of
854
- # here?
855
889
  addressable_areas: AddressableAreaView,
856
890
  ) -> LabwareOffsetVector:
857
- """Get the nominal offset from a module's location to its child labware's location.
858
-
859
- Includes the slot-specific transform. Does not include the child's
860
- Labware Position Check offset.
861
- """
891
+ """Get the module's nominal offset vector computed with slot transform."""
862
892
  if (
863
893
  self.state.deck_type == DeckType.OT2_STANDARD
864
894
  or self.state.deck_type == DeckType.OT2_SHORT_TRASH
@@ -966,7 +996,7 @@ class ModuleView(HasState[ModuleState]):
966
996
  default_lw_offset_point = self.get_definition(module_id).labwareOffset.z
967
997
  z_difference = module_height - default_lw_offset_point
968
998
 
969
- nominal_transformed_lw_offset_z = self.get_nominal_offset_to_child(
999
+ nominal_transformed_lw_offset_z = self.get_nominal_module_offset(
970
1000
  module_id=module_id, addressable_areas=addressable_areas
971
1001
  ).z
972
1002
  calibration_offset = self.get_module_calibration_offset(module_id)
@@ -1094,8 +1124,8 @@ class ModuleView(HasState[ModuleState]):
1094
1124
 
1095
1125
  def should_dodge_thermocycler(
1096
1126
  self,
1097
- from_slot: Union[DeckSlotName, StagingSlotName],
1098
- to_slot: Union[DeckSlotName, StagingSlotName],
1127
+ from_slot: DeckSlotName,
1128
+ to_slot: DeckSlotName,
1099
1129
  ) -> bool:
1100
1130
  """Decide if the requested path would cross the thermocycler, if installed.
1101
1131
 
@@ -1268,10 +1298,7 @@ class ModuleView(HasState[ModuleState]):
1268
1298
  row = chr(ord("A") + i // 12) # Convert index to row (A-H)
1269
1299
  col = (i % 12) + 1 # Convert index to column (1-12)
1270
1300
  well_key = f"{row}{col}"
1271
- truncated_value = float(
1272
- "{:.5}".format(str(value))
1273
- ) # Truncate the returned value to the third decimal place
1274
- well_map[well_key] = truncated_value
1301
+ well_map[well_key] = value
1275
1302
  return well_map
1276
1303
  else:
1277
1304
  raise ValueError(
@@ -2,7 +2,7 @@
2
2
  from dataclasses import dataclass
3
3
  from typing import List, Optional, Union
4
4
 
5
- from opentrons.types import MountType, Point, StagingSlotName
5
+ from opentrons.types import MountType, Point
6
6
  from opentrons.hardware_control.types import CriticalPoint
7
7
  from opentrons.motion_planning.adjacent_slots_getters import (
8
8
  get_east_west_slots,
@@ -277,13 +277,9 @@ class MotionView:
277
277
  current_location = self._pipettes.get_current_location()
278
278
  if current_location is not None:
279
279
  if isinstance(current_location, CurrentWell):
280
- ancestor = self._geometry.get_ancestor_slot_name(
280
+ pipette_deck_slot = self._geometry.get_ancestor_slot_name(
281
281
  current_location.labware_id
282
- )
283
- if isinstance(ancestor, StagingSlotName):
284
- # Staging Area Slots cannot intersect with the h/s
285
- return False
286
- pipette_deck_slot = ancestor.as_int()
282
+ ).as_int()
287
283
  else:
288
284
  pipette_deck_slot = (
289
285
  self._addressable_areas.get_addressable_area_base_slot(
@@ -303,13 +299,9 @@ class MotionView:
303
299
  current_location = self._pipettes.get_current_location()
304
300
  if current_location is not None:
305
301
  if isinstance(current_location, CurrentWell):
306
- ancestor = self._geometry.get_ancestor_slot_name(
302
+ pipette_deck_slot = self._geometry.get_ancestor_slot_name(
307
303
  current_location.labware_id
308
- )
309
- if isinstance(ancestor, StagingSlotName):
310
- # Staging Area Slots cannot intersect with the h/s
311
- return False
312
- pipette_deck_slot = ancestor.as_int()
304
+ ).as_int()
313
305
  else:
314
306
  pipette_deck_slot = (
315
307
  self._addressable_areas.get_addressable_area_base_slot(
@@ -332,10 +324,6 @@ class MotionView:
332
324
  """Get a list of touch points for a touch tip operation."""
333
325
  mount = self._pipettes.get_mount(pipette_id)
334
326
  labware_slot = self._geometry.get_ancestor_slot_name(labware_id)
335
- if isinstance(labware_slot, StagingSlotName):
336
- raise errors.LocationIsStagingSlotError(
337
- "Cannot perform Touch Tip on labware in Staging Area Slot."
338
- )
339
327
  next_to_module = self._modules.is_edge_move_unsafe(mount, labware_slot)
340
328
  edge_path_type = self._labware.get_edge_path_type(
341
329
  labware_id, well_name, mount, labware_slot, next_to_module
@@ -205,14 +205,6 @@ class LiquidOperatedUpdate:
205
205
  volume_added: float | ClearType
206
206
 
207
207
 
208
- @dataclasses.dataclass
209
- class AbsorbanceReaderLidUpdate:
210
- """An update to an absorbance reader's lid location."""
211
-
212
- module_id: str
213
- is_lid_on: bool
214
-
215
-
216
208
  @dataclasses.dataclass
217
209
  class StateUpdate:
218
210
  """Represents an update to perform on engine state."""
@@ -239,8 +231,6 @@ class StateUpdate:
239
231
 
240
232
  liquid_operated: LiquidOperatedUpdate | NoChangeType = NO_CHANGE
241
233
 
242
- absorbance_reader_lid: AbsorbanceReaderLidUpdate | NoChangeType = NO_CHANGE
243
-
244
234
  # These convenience functions let the caller avoid the boilerplate of constructing a
245
235
  # complicated dataclass tree.
246
236
 
@@ -416,9 +406,3 @@ class StateUpdate:
416
406
  well_name=well_name,
417
407
  volume_added=volume_added,
418
408
  )
419
-
420
- def set_absorbance_reader_lid(self, module_id: str, is_lid_on: bool) -> None:
421
- """Update an absorbance reader's lid location. See `AbsorbanceReaderLidUpdate`."""
422
- self.absorbance_reader_lid = AbsorbanceReaderLidUpdate(
423
- module_id=module_id, is_lid_on=is_lid_on
424
- )
@@ -418,21 +418,6 @@ class RunOrchestrator:
418
418
  """Get current nozzle maps keyed by pipette id."""
419
419
  return self._protocol_engine.state_view.tips.get_pipette_nozzle_maps()
420
420
 
421
- def get_tip_attached(self) -> Dict[str, bool]:
422
- """Get current tip state keyed by pipette id."""
423
-
424
- def has_tip_attached(pipette_id: str) -> bool:
425
- return (
426
- self._protocol_engine.state_view.pipettes.get_attached_tip(pipette_id)
427
- is not None
428
- )
429
-
430
- pipette_ids = (
431
- pipette.id
432
- for pipette in self._protocol_engine.state_view.pipettes.get_all()
433
- )
434
- return {pipette_id: has_tip_attached(pipette_id) for pipette_id in pipette_ids}
435
-
436
421
  def set_error_recovery_policy(self, policy: ErrorRecoveryPolicy) -> None:
437
422
  """Create error recovery policy for the run."""
438
423
  self._protocol_engine.set_error_recovery_policy(policy)
@@ -60,9 +60,7 @@ class CSVParameter:
60
60
  as appropriate.
61
61
 
62
62
  :param detect_dialect: If ``True``, examine the file and try to assign it a
63
- :py:class:`csv.Dialect` to improve parsing behavior. Set this to ``False``
64
- when using the file output of :py:meth:`.AbsorbanceReaderContext.read` as
65
- a runtime parameter.
63
+ :py:class:`csv.Dialect` to improve parsing behavior.
66
64
  :param kwargs: For advanced CSV handling, you can pass any of the
67
65
  `formatting parameters <https://docs.python.org/3/library/csv.html#csv-fmt-params>`_
68
66
  accepted by :py:func:`csv.reader` from the Python standard library.
@@ -5,7 +5,7 @@ from typing import Any, Dict
5
5
 
6
6
  from opentrons.config import CONFIG, ARCHITECTURE, SystemArchitecture
7
7
 
8
- if ARCHITECTURE is SystemArchitecture.YOCTO:
8
+ if ARCHITECTURE is SystemArchitecture.BUILDROOT:
9
9
  from opentrons_hardware.sensors import SENSOR_LOG_NAME
10
10
  else:
11
11
  # we don't use the sensor log on ot2 or host
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: opentrons
3
- Version: 8.2.0
3
+ Version: 8.2.0a0
4
4
  Summary: The Opentrons API is a simple framework designed to make writing automated biology lab protocols easy.
5
5
  Author: Opentrons
6
6
  Author-email: engineering@opentrons.com
@@ -21,7 +21,7 @@ Classifier: Programming Language :: Python :: 3.10
21
21
  Classifier: Topic :: Scientific/Engineering
22
22
  Requires-Python: >=3.10
23
23
  License-File: ../LICENSE
24
- Requires-Dist: opentrons-shared-data ==8.2.0
24
+ Requires-Dist: opentrons-shared-data ==8.2.0a0
25
25
  Requires-Dist: aionotify ==0.3.1
26
26
  Requires-Dist: anyio <4.0.0,>=3.6.1
27
27
  Requires-Dist: jsonschema <4.18.0,>=3.0.1
@@ -34,9 +34,9 @@ Requires-Dist: pyusb ==1.2.1
34
34
  Requires-Dist: packaging >=21.0
35
35
  Requires-Dist: importlib-metadata >=1.0 ; python_version < "3.8"
36
36
  Provides-Extra: flex-hardware
37
- Requires-Dist: opentrons-hardware[flex] ==8.2.0 ; extra == 'flex-hardware'
37
+ Requires-Dist: opentrons-hardware[flex] ==8.2.0a0 ; extra == 'flex-hardware'
38
38
  Provides-Extra: ot2-hardware
39
- Requires-Dist: opentrons-hardware ==8.2.0 ; extra == 'ot2-hardware'
39
+ Requires-Dist: opentrons-hardware ==8.2.0a0 ; extra == 'ot2-hardware'
40
40
 
41
41
  .. _Full API Documentation: http://docs.opentrons.com
42
42