opentrons 8.2.0__py2.py3-none-any.whl → 8.2.0a1__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 (31) hide show
  1. opentrons/drivers/absorbance_reader/async_byonoy.py +4 -5
  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/protocol_api/module_contexts.py +26 -56
  8. opentrons/protocol_engine/commands/absorbance_reader/initialize.py +7 -19
  9. opentrons/protocol_engine/commands/absorbance_reader/read.py +0 -4
  10. opentrons/protocol_engine/commands/aspirate_in_place.py +3 -3
  11. opentrons/protocol_engine/commands/command.py +1 -3
  12. opentrons/protocol_engine/commands/dispense_in_place.py +1 -1
  13. opentrons/protocol_engine/commands/drop_tip.py +1 -2
  14. opentrons/protocol_engine/commands/drop_tip_in_place.py +2 -7
  15. opentrons/protocol_engine/commands/pick_up_tip.py +1 -1
  16. opentrons/protocol_engine/commands/pipetting_common.py +1 -8
  17. opentrons/protocol_engine/commands/unsafe/unsafe_place_labware.py +3 -8
  18. opentrons/protocol_engine/commands/unsafe/unsafe_ungrip_labware.py +1 -3
  19. opentrons/protocol_engine/commands/unsafe/update_position_estimators.py +1 -5
  20. opentrons/protocol_engine/errors/__init__.py +0 -2
  21. opentrons/protocol_engine/errors/error_occurrence.py +3 -8
  22. opentrons/protocol_engine/errors/exceptions.py +0 -13
  23. opentrons/protocol_engine/state/modules.py +1 -4
  24. opentrons/protocol_runner/run_orchestrator.py +0 -15
  25. opentrons/protocols/parameters/csv_parameter_interface.py +1 -3
  26. {opentrons-8.2.0.dist-info → opentrons-8.2.0a1.dist-info}/METADATA +4 -4
  27. {opentrons-8.2.0.dist-info → opentrons-8.2.0a1.dist-info}/RECORD +31 -31
  28. {opentrons-8.2.0.dist-info → opentrons-8.2.0a1.dist-info}/LICENSE +0 -0
  29. {opentrons-8.2.0.dist-info → opentrons-8.2.0a1.dist-info}/WHEEL +0 -0
  30. {opentrons-8.2.0.dist-info → opentrons-8.2.0a1.dist-info}/entry_points.txt +0 -0
  31. {opentrons-8.2.0.dist-info → opentrons-8.2.0a1.dist-info}/top_level.txt +0 -0
@@ -23,8 +23,7 @@ from opentrons.hardware_control.modules.errors import AbsorbanceReaderDisconnect
23
23
 
24
24
 
25
25
  SN_PARSER = re.compile(r'ATTRS{serial}=="(?P<serial>.+?)"')
26
- # match semver V0.0.0 (old format) or one integer (latest format)
27
- VERSION_PARSER = re.compile(r"(?P<version>(V\d+\.\d+\.\d+|^\d+$))")
26
+ VERSION_PARSER = re.compile(r"Absorbance (?P<version>V\d+\.\d+\.\d+)")
28
27
  SERIAL_PARSER = re.compile(r"(?P<serial>(OPT|BYO)[A-Z]{3}[0-9]+)")
29
28
 
30
29
 
@@ -157,10 +156,10 @@ class AsyncByonoy:
157
156
  func=partial(self._interface.get_device_information, handle),
158
157
  )
159
158
  self._raise_if_error(err.name, f"Error getting device information: {err}")
160
- serial_match = SERIAL_PARSER.match(device_info.sn)
161
- version_match = VERSION_PARSER.search(device_info.version)
159
+ serial_match = SERIAL_PARSER.fullmatch(device_info.sn)
160
+ version_match = VERSION_PARSER.match(device_info.version)
162
161
  serial = serial_match["serial"].strip() if serial_match else "OPTMAA00000"
163
- version = version_match["version"].lower() if version_match else "v0"
162
+ version = version_match["version"].lower() if version_match else "v0.0.0"
164
163
  info = {
165
164
  "serial": serial,
166
165
  "version": version,
@@ -652,7 +652,6 @@ _gripper_jaw_state_lookup: Dict[FirmwareGripperjawState, GripperJawState] = {
652
652
  FirmwareGripperjawState.force_controlling_home: GripperJawState.HOMED_READY,
653
653
  FirmwareGripperjawState.force_controlling: GripperJawState.GRIPPING,
654
654
  FirmwareGripperjawState.position_controlling: GripperJawState.HOLDING,
655
- FirmwareGripperjawState.stopped: GripperJawState.STOPPED,
656
655
  }
657
656
 
658
657
 
@@ -312,8 +312,6 @@ class AbsorbanceReader(mod_abc.AbstractModule):
312
312
  log.debug(f"Updating {self.name}: {self.port} with {firmware_file_path}")
313
313
  self._updating = True
314
314
  success, res = await self._driver.update_firmware(firmware_file_path)
315
- # it takes time for the plate reader to re-init after an update.
316
- await asyncio.sleep(10)
317
315
  self._device_info = await self._driver.get_device_info()
318
316
  await self._poller.start()
319
317
  self._updating = False
@@ -775,12 +775,12 @@ class OT3API(
775
775
  """
776
776
  Function to update motor estimation for a set of axes
777
777
  """
778
- if axes is None:
779
- axes = [ax for ax in Axis]
780
778
 
781
- axes = [ax for ax in axes if self._backend.axis_is_present(ax)]
782
-
783
- await self._backend.update_motor_estimation(axes)
779
+ if axes:
780
+ checked_axes = [ax for ax in axes if ax in Axis]
781
+ else:
782
+ checked_axes = [ax for ax in Axis]
783
+ await self._backend.update_motor_estimation(checked_axes)
784
784
 
785
785
  # Global actions API
786
786
  def pause(self, pause_type: PauseType) -> None:
@@ -10,7 +10,7 @@ class PositionEstimator(Protocol):
10
10
  """Update the specified axes' position estimators from their encoders.
11
11
 
12
12
  This will allow these axes to make a non-home move even if they do not currently have
13
- a position estimation (unless there is no tracked position from the encoders, as would be
13
+ a position estimation (unless there is no tracked poition from the encoders, as would be
14
14
  true immediately after boot).
15
15
 
16
16
  Axis encoders have less precision than their position estimators. Calling this function will
@@ -19,8 +19,6 @@ class PositionEstimator(Protocol):
19
19
 
20
20
  This function updates only the requested axes. If other axes have bad position estimation,
21
21
  moves that require those axes or attempts to get the position of those axes will still fail.
22
- Axes that are not currently available (like a plunger for a pipette that is not connected)
23
- will be ignored.
24
22
  """
25
23
  ...
26
24
 
@@ -625,8 +625,6 @@ class GripperJawState(enum.Enum):
625
625
  #: the gripper is actively force-control gripping something
626
626
  HOLDING = enum.auto()
627
627
  #: the gripper is in position-control mode
628
- STOPPED = enum.auto()
629
- #: the gripper has been homed before but is stopped now
630
628
 
631
629
 
632
630
  class InstrumentProbeType(enum.Enum):
@@ -581,7 +581,7 @@ class ThermocyclerContext(ModuleContext):
581
581
  individual well of the loaded labware, in µL.
582
582
  If not specified, the default is 25 µL.
583
583
 
584
- .. note::
584
+ .. note:
585
585
 
586
586
  If ``hold_time_minutes`` and ``hold_time_seconds`` are not
587
587
  specified, the Thermocycler will proceed to the next command
@@ -605,7 +605,7 @@ class ThermocyclerContext(ModuleContext):
605
605
  :param temperature: A value between 37 and 110, representing the target
606
606
  temperature in °C.
607
607
 
608
- .. note::
608
+ .. note:
609
609
 
610
610
  The Thermocycler will proceed to the next command immediately after
611
611
  ``temperature`` has been reached.
@@ -635,13 +635,13 @@ class ThermocyclerContext(ModuleContext):
635
635
  individual well of the loaded labware, in µL.
636
636
  If not specified, the default is 25 µL.
637
637
 
638
- .. note::
638
+ .. note:
639
639
 
640
640
  Unlike with :py:meth:`set_block_temperature`, either or both of
641
641
  ``hold_time_minutes`` and ``hold_time_seconds`` must be defined
642
642
  and for each step.
643
643
 
644
- .. note::
644
+ .. note:
645
645
 
646
646
  Before API Version 2.21, Thermocycler profiles run with this command
647
647
  would be listed in the app as having a number of repetitions equal to
@@ -991,7 +991,7 @@ class MagneticBlockContext(ModuleContext):
991
991
 
992
992
 
993
993
  class AbsorbanceReaderContext(ModuleContext):
994
- """An object representing a connected Absorbance Plate Reader Module.
994
+ """An object representing a connected Absorbance Reader Module.
995
995
 
996
996
  It should not be instantiated directly; instead, it should be
997
997
  created through :py:meth:`.ProtocolContext.load_module`.
@@ -1009,21 +1009,17 @@ class AbsorbanceReaderContext(ModuleContext):
1009
1009
 
1010
1010
  @requires_version(2, 21)
1011
1011
  def close_lid(self) -> None:
1012
- """Use the Flex Gripper to close the lid of the Absorbance Plate Reader.
1013
-
1014
- You must call this method before initializing the reader, even if the reader was
1015
- in the closed position at the start of the protocol.
1016
- """
1012
+ """Close the lid of the Absorbance Reader."""
1017
1013
  self._core.close_lid()
1018
1014
 
1019
1015
  @requires_version(2, 21)
1020
1016
  def open_lid(self) -> None:
1021
- """Use the Flex Gripper to open the lid of the Absorbance Plate Reader."""
1017
+ """Open the lid of the Absorbance Reader."""
1022
1018
  self._core.open_lid()
1023
1019
 
1024
1020
  @requires_version(2, 21)
1025
1021
  def is_lid_on(self) -> bool:
1026
- """Return ``True`` if the Absorbance Plate Reader's lid is currently closed."""
1022
+ """Return ``True`` if the Absorbance Reader's lid is currently closed."""
1027
1023
  return self._core.is_lid_on()
1028
1024
 
1029
1025
  @requires_version(2, 21)
@@ -1033,28 +1029,19 @@ class AbsorbanceReaderContext(ModuleContext):
1033
1029
  wavelengths: List[int],
1034
1030
  reference_wavelength: Optional[int] = None,
1035
1031
  ) -> None:
1036
- """Prepare the Absorbance Plate Reader to read a plate.
1037
-
1038
- See :ref:`absorbance-initialization` for examples.
1032
+ """Take a zero reading on the Absorbance Plate Reader Module.
1039
1033
 
1040
1034
  :param mode: Either ``"single"`` or ``"multi"``.
1041
1035
 
1042
- - In single measurement mode, :py:meth:`.AbsorbanceReaderContext.read` uses
1043
- one sample wavelength and an optional reference wavelength.
1044
- - In multiple measurement mode, :py:meth:`.AbsorbanceReaderContext.read` uses
1045
- a list of up to six sample wavelengths.
1046
- :param wavelengths: A list of wavelengths, in nm, to measure.
1047
-
1048
- - In the default hardware configuration, each wavelength must be one of
1049
- ``450`` (blue), ``562`` (green), ``600`` (orange), or ``650`` (red). In
1050
- custom hardware configurations, the module may accept other integers
1051
- between 350 and 1000.
1052
- - The list must contain only one item when initializing a single measurement.
1053
- - The list can contain one to six items when initializing a multiple measurement.
1054
- :param reference_wavelength: An optional reference wavelength, in nm. If provided,
1055
- :py:meth:`.AbsorbanceReaderContext.read` will read at the reference
1056
- wavelength and then subtract the reference wavelength values from the
1057
- measurement wavelength values. Can only be used with single measurements.
1036
+ - In single measurement mode, :py:meth:`.AbsorbanceReaderContext.read` uses
1037
+ one sample wavelength and an optional reference wavelength.
1038
+ - In multiple measurement mode, :py:meth:`.AbsorbanceReaderContext.read` uses
1039
+ a list of up to six sample wavelengths.
1040
+ :param wavelengths: A list of wavelengths, in mm, to measure.
1041
+ - Must contain only one item when initializing a single measurement.
1042
+ - Must contain one to six items when initializing a multiple measurement.
1043
+ :param reference_wavelength: An optional reference wavelength, in mm. Cannot be
1044
+ used with multiple measurements.
1058
1045
  """
1059
1046
  self._core.initialize(
1060
1047
  mode, wavelengths, reference_wavelength=reference_wavelength
@@ -1064,33 +1051,16 @@ class AbsorbanceReaderContext(ModuleContext):
1064
1051
  def read(
1065
1052
  self, export_filename: Optional[str] = None
1066
1053
  ) -> Dict[int, Dict[str, float]]:
1067
- """Read a plate on the Absorbance Plate Reader.
1068
-
1069
- This method always returns a dictionary of measurement data. It optionally will
1070
- save a CSV file of the results to the Flex filesystem, which you can access from
1071
- the Recent Protocol Runs screen in the Opentrons App. These files are `only` saved
1072
- if you specify ``export_filename``.
1073
-
1074
- In simulation, the values for each well key in the dictionary are set to zero, and
1075
- no files are written.
1076
-
1077
- .. note::
1078
-
1079
- Avoid divide-by-zero errors when simulating and using the results of this
1080
- method later in the protocol. If you divide by any of the measurement
1081
- values, use :py:meth:`.ProtocolContext.is_simulating` to use alternate dummy
1082
- data or skip the division step.
1054
+ """Initiate read on the Absorbance Reader.
1083
1055
 
1084
- :param export_filename: An optional file basename. If provided, this method
1085
- will write a CSV file for each measurement in the read operation. File
1086
- names will use the value of this parameter, the measurement wavelength
1087
- supplied in :py:meth:`~.AbsorbanceReaderContext.initialize`, and a
1088
- ``.csv`` extension. For example, when reading at wavelengths 450 and 562
1089
- with ``export_filename="my_data"``, there will be two output files:
1090
- ``my_data_450.csv`` and ``my_data_562.csv``.
1056
+ Returns a dictionary of wavelengths to dictionary of values ordered by well name.
1091
1057
 
1092
- See :ref:`absorbance-csv` for information on working with these CSV files.
1058
+ :param export_filename: Optional, if a filename is provided a CSV file will be saved
1059
+ as a result of the read action containing measurement data. The filename will
1060
+ be modified to include the wavelength used during measurement. If multiple
1061
+ measurements are taken, then a file will be generated for each wavelength provided.
1093
1062
 
1094
- :returns: A dictionary of wavelengths to dictionary of values ordered by well name.
1063
+ Example: If `export_filename="my_data"` and wavelengths 450 and 531 are used during
1064
+ measurement, the output files will be "my_data_450.csv" and "my_data_531.csv".
1095
1065
  """
1096
1066
  return self._core.read(filename=export_filename)
@@ -10,7 +10,6 @@ from opentrons.protocol_engine.types import ABSMeasureMode
10
10
 
11
11
  from ..command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, SuccessData
12
12
  from ...errors.error_occurrence import ErrorOccurrence
13
- from ...errors import InvalidWavelengthError
14
13
 
15
14
  if TYPE_CHECKING:
16
15
  from opentrons.protocol_engine.state.state import StateView
@@ -70,41 +69,30 @@ class InitializeImpl(
70
69
  unsupported_wavelengths = sample_wavelengths.difference(
71
70
  supported_wavelengths
72
71
  )
73
- sample_wl_str = ", ".join([str(w) + "nm" for w in sample_wavelengths])
74
- supported_wl_str = ", ".join([str(w) + "nm" for w in supported_wavelengths])
75
- unsupported_wl_str = ", ".join(
76
- [str(w) + "nm" for w in unsupported_wavelengths]
77
- )
78
72
  if unsupported_wavelengths:
79
- raise InvalidWavelengthError(
80
- f"Unsupported wavelengths: {unsupported_wl_str}. "
81
- f" Use one of {supported_wl_str} instead."
82
- )
73
+ raise ValueError(f"Unsupported wavelengths: {unsupported_wavelengths}")
83
74
 
84
75
  if params.measureMode == "single":
85
76
  if sample_wavelengths_len != 1:
86
77
  raise ValueError(
87
- f"Measure mode `single` requires one sample wavelength,"
88
- f" {sample_wl_str} provided instead."
78
+ f"single requires one sample wavelength, provided {sample_wavelengths}"
89
79
  )
90
80
  if (
91
81
  reference_wavelength is not None
92
82
  and reference_wavelength not in supported_wavelengths
93
83
  ):
94
- raise InvalidWavelengthError(
95
- f"Reference wavelength {reference_wavelength}nm is not supported."
96
- f" Use one of {supported_wl_str} instead."
84
+ raise ValueError(
85
+ f"Reference wavelength {reference_wavelength} not supported {supported_wavelengths}"
97
86
  )
98
87
 
99
88
  if params.measureMode == "multi":
100
89
  if sample_wavelengths_len < 1 or sample_wavelengths_len > 6:
101
90
  raise ValueError(
102
- f"Measure mode `multi` requires 1-6 sample wavelengths,"
103
- f" {sample_wl_str} provided instead."
91
+ f"multi requires 1-6 sample wavelengths, provided {sample_wavelengths}"
104
92
  )
105
93
  if reference_wavelength is not None:
106
- raise ValueError(
107
- "Reference wavelength cannot be used with Measure mode `multi`."
94
+ raise RuntimeError(
95
+ "Reference wavelength cannot be used with multi mode."
108
96
  )
109
97
 
110
98
  await abs_reader.set_sample_wavelength(
@@ -80,10 +80,6 @@ class ReadAbsorbanceImpl(
80
80
  raise CannotPerformModuleAction(
81
81
  "Cannot perform Read action on Absorbance Reader without calling `.initialize(...)` first."
82
82
  )
83
- if abs_reader_substate.is_lid_on is False:
84
- raise CannotPerformModuleAction(
85
- "Absorbance Plate Reader can't read a plate with the lid open. Call `close_lid()` first."
86
- )
87
83
 
88
84
  # TODO: we need to return a file ID and increase the file count even when a moduel is not attached
89
85
  if (
@@ -83,11 +83,10 @@ class AspirateInPlaceImplementation(
83
83
  TipNotAttachedError: if no tip is attached to the pipette.
84
84
  PipetteNotReadyToAspirateError: pipette plunger is not ready.
85
85
  """
86
- state_update = StateUpdate()
87
-
88
86
  ready_to_aspirate = self._pipetting.get_is_ready_to_aspirate(
89
87
  pipette_id=params.pipetteId,
90
88
  )
89
+
91
90
  if not ready_to_aspirate:
92
91
  raise PipetteNotReadyToAspirateError(
93
92
  "Pipette cannot aspirate in place because of a previous blow out."
@@ -95,10 +94,11 @@ class AspirateInPlaceImplementation(
95
94
  " so the plunger can be reset in a known safe position."
96
95
  )
97
96
 
97
+ state_update = StateUpdate()
98
98
  current_location = self._state_view.pipettes.get_current_location()
99
- current_position = await self._gantry_mover.get_position(params.pipetteId)
100
99
 
101
100
  try:
101
+ current_position = await self._gantry_mover.get_position(params.pipetteId)
102
102
  volume = await self._pipetting.aspirate_in_place(
103
103
  pipette_id=params.pipetteId,
104
104
  volume=params.volume,
@@ -185,9 +185,7 @@ class BaseCommand(
185
185
  )
186
186
  error: Union[
187
187
  _ErrorT,
188
- # ErrorOccurrence here is a catch-all for undefined errors not captured by
189
- # _ErrorT, or defined errors that don't parse into _ErrorT because, for example,
190
- # they are from an older software version that was missing some fields.
188
+ # ErrorOccurrence here is for undefined errors not captured by _ErrorT.
191
189
  ErrorOccurrence,
192
190
  None,
193
191
  ] = Field(
@@ -76,8 +76,8 @@ class DispenseInPlaceImplementation(
76
76
  """Dispense without moving the pipette."""
77
77
  state_update = StateUpdate()
78
78
  current_location = self._state_view.pipettes.get_current_location()
79
- current_position = await self._gantry_mover.get_position(params.pipetteId)
80
79
  try:
80
+ current_position = await self._gantry_mover.get_position(params.pipetteId)
81
81
  volume = await self._pipetting.dispense_in_place(
82
82
  pipette_id=params.pipetteId,
83
83
  volume=params.volume,
@@ -145,7 +145,6 @@ class DropTipImplementation(AbstractCommandImpl[DropTipParams, _ExecuteReturn]):
145
145
  error=exception,
146
146
  )
147
147
  ],
148
- errorInfo={"retryLocation": position},
149
148
  )
150
149
  state_update_if_false_positive = update_types.StateUpdate()
151
150
  state_update_if_false_positive.update_pipette_tip_state(
@@ -166,7 +165,7 @@ class DropTipImplementation(AbstractCommandImpl[DropTipParams, _ExecuteReturn]):
166
165
  )
167
166
 
168
167
 
169
- class DropTip(BaseCommand[DropTipParams, DropTipResult, TipPhysicallyAttachedError]):
168
+ class DropTip(BaseCommand[DropTipParams, DropTipResult, ErrorOccurrence]):
170
169
  """Drop tip command model."""
171
170
 
172
171
  commandType: DropTipCommandType = "dropTip"
@@ -18,7 +18,7 @@ from ..resources.model_utils import ModelUtils
18
18
  from ..state import update_types
19
19
 
20
20
  if TYPE_CHECKING:
21
- from ..execution import TipHandler, GantryMover
21
+ from ..execution import TipHandler
22
22
 
23
23
 
24
24
  DropTipInPlaceCommandType = Literal["dropTipInPlace"]
@@ -57,19 +57,15 @@ class DropTipInPlaceImplementation(
57
57
  self,
58
58
  tip_handler: TipHandler,
59
59
  model_utils: ModelUtils,
60
- gantry_mover: GantryMover,
61
60
  **kwargs: object,
62
61
  ) -> None:
63
62
  self._tip_handler = tip_handler
64
63
  self._model_utils = model_utils
65
- self._gantry_mover = gantry_mover
66
64
 
67
65
  async def execute(self, params: DropTipInPlaceParams) -> _ExecuteReturn:
68
66
  """Drop a tip using the requested pipette."""
69
67
  state_update = update_types.StateUpdate()
70
68
 
71
- retry_location = await self._gantry_mover.get_position(params.pipetteId)
72
-
73
69
  try:
74
70
  await self._tip_handler.drop_tip(
75
71
  pipette_id=params.pipetteId, home_after=params.homeAfter
@@ -89,7 +85,6 @@ class DropTipInPlaceImplementation(
89
85
  error=exception,
90
86
  )
91
87
  ],
92
- errorInfo={"retryLocation": retry_location},
93
88
  )
94
89
  return DefinedErrorData(
95
90
  public=error,
@@ -104,7 +99,7 @@ class DropTipInPlaceImplementation(
104
99
 
105
100
 
106
101
  class DropTipInPlace(
107
- BaseCommand[DropTipInPlaceParams, DropTipInPlaceResult, TipPhysicallyAttachedError]
102
+ BaseCommand[DropTipInPlaceParams, DropTipInPlaceResult, ErrorOccurrence]
108
103
  ):
109
104
  """Drop tip in place command model."""
110
105
 
@@ -82,7 +82,7 @@ class TipPhysicallyMissingError(ErrorOccurrence):
82
82
  isDefined: bool = True
83
83
  errorType: Literal["tipPhysicallyMissing"] = "tipPhysicallyMissing"
84
84
  errorCode: str = ErrorCodes.TIP_PICKUP_FAILED.value.code
85
- detail: str = "No Tip Detected"
85
+ detail: str = "No tip detected."
86
86
 
87
87
 
88
88
  _ExecuteReturn = Union[
@@ -148,12 +148,7 @@ class DestinationPositionResult(BaseModel):
148
148
 
149
149
 
150
150
  class ErrorLocationInfo(TypedDict):
151
- """Holds a retry location for in-place error recovery.
152
-
153
- This is appropriate to pass to a `moveToCoordinates` command,
154
- assuming the pipette has not been configured with a different nozzle layout
155
- in the meantime.
156
- """
151
+ """Holds a retry location for in-place error recovery."""
157
152
 
158
153
  retryLocation: Tuple[float, float, float]
159
154
 
@@ -206,5 +201,3 @@ class TipPhysicallyAttachedError(ErrorOccurrence):
206
201
 
207
202
  errorCode: str = ErrorCodes.TIP_DROP_FAILED.value.code
208
203
  detail: str = ErrorCodes.TIP_DROP_FAILED.value.detail
209
-
210
- errorInfo: ErrorLocationInfo
@@ -129,14 +129,9 @@ class UnsafePlaceLabwareImplementation(
129
129
  module.id
130
130
  )
131
131
 
132
- # NOTE: When the estop is pressed, the gantry loses position, lets use
133
- # the encoders to sync position.
134
- # Ideally, we'd do a full home, but this command is used when
135
- # the gripper is holding the plate reader, and a full home would
136
- # bang it into the right window.
137
- await ot3api.home(axes=[Axis.Z_L, Axis.Z_R, Axis.Z_G])
138
- await ot3api.engage_axes([Axis.X, Axis.Y])
139
- await ot3api.update_axis_position_estimations([Axis.X, Axis.Y])
132
+ # NOTE: When the estop is pressed, the gantry loses position,
133
+ # so the robot needs to home x, y to sync.
134
+ await ot3api.home(axes=[Axis.Z_L, Axis.Z_R, Axis.Z_G, Axis.X, Axis.Y])
140
135
 
141
136
  # Place the labware down
142
137
  await self._start_movement(ot3api, definition, location, drop_offset)
@@ -1,8 +1,6 @@
1
1
  """Ungrip labware payload, result, and implementaiton."""
2
2
 
3
3
  from __future__ import annotations
4
-
5
- from opentrons.hardware_control.types import Axis
6
4
  from opentrons.protocol_engine.errors.exceptions import GripperNotAttachedError
7
5
  from pydantic import BaseModel
8
6
  from typing import Optional, Type
@@ -48,7 +46,7 @@ class UnsafeUngripLabwareImplementation(
48
46
  ot3_hardware_api = ensure_ot3_hardware(self._hardware_api)
49
47
  if not ot3_hardware_api.has_gripper():
50
48
  raise GripperNotAttachedError("No gripper found to perform ungrip.")
51
- await ot3_hardware_api.home([Axis.G])
49
+ await ot3_hardware_api.ungrip()
52
50
  return SuccessData(
53
51
  public=UnsafeUngripLabwareResult(),
54
52
  )
@@ -23,11 +23,7 @@ class UpdatePositionEstimatorsParams(BaseModel):
23
23
  """Payload required for an UpdatePositionEstimators command."""
24
24
 
25
25
  axes: List[MotorAxis] = Field(
26
- ...,
27
- description=(
28
- "The axes for which to update the position estimators."
29
- " Any axes that are not physically present will be ignored."
30
- ),
26
+ ..., description="The axes for which to update the position estimators."
31
27
  )
32
28
 
33
29
 
@@ -55,7 +55,6 @@ from .exceptions import (
55
55
  InvalidTargetTemperatureError,
56
56
  InvalidBlockVolumeError,
57
57
  InvalidHoldTimeError,
58
- InvalidWavelengthError,
59
58
  CannotPerformModuleAction,
60
59
  PauseNotAllowedError,
61
60
  ResumeFromRecoveryNotAllowedError,
@@ -138,7 +137,6 @@ __all__ = [
138
137
  "InvalidTargetSpeedError",
139
138
  "InvalidBlockVolumeError",
140
139
  "InvalidHoldTimeError",
141
- "InvalidWavelengthError",
142
140
  "CannotPerformModuleAction",
143
141
  "ResumeFromRecoveryNotAllowedError",
144
142
  "PauseNotAllowedError",
@@ -12,6 +12,8 @@ from opentrons_shared_data.errors.exceptions import EnumeratedError
12
12
  log = getLogger(__name__)
13
13
 
14
14
 
15
+ # TODO(mc, 2021-11-12): flesh this model out with structured error data
16
+ # for each error type so client may produce better error messages
15
17
  class ErrorOccurrence(BaseModel):
16
18
  """An occurrence of a specific error during protocol execution."""
17
19
 
@@ -42,15 +44,8 @@ class ErrorOccurrence(BaseModel):
42
44
  id: str = Field(..., description="Unique identifier of this error occurrence.")
43
45
  createdAt: datetime = Field(..., description="When the error occurred.")
44
46
 
45
- # Our Python should probably always set this to False--if we want it to be True,
46
- # we should probably be using a more specific subclass of ErrorOccurrence anyway.
47
- # However, we can't make this Literal[False], because we want this class to be able
48
- # to act as a catch-all for parsing defined errors that might be missing some
49
- # `errorInfo` fields because they were serialized by older software.
50
47
  isDefined: bool = Field(
51
- # default=False for database backwards compatibility, so we can parse objects
52
- # serialized before isDefined existed.
53
- default=False,
48
+ default=False, # default=False for database backwards compatibility.
54
49
  description=dedent(
55
50
  """\
56
51
  Whether this error is *defined.*
@@ -773,19 +773,6 @@ class InvalidBlockVolumeError(ProtocolEngineError):
773
773
  super().__init__(ErrorCodes.GENERAL_ERROR, message, details, wrapping)
774
774
 
775
775
 
776
- class InvalidWavelengthError(ProtocolEngineError):
777
- """Raised when attempting to set an invalid absorbance wavelength."""
778
-
779
- def __init__(
780
- self,
781
- message: Optional[str] = None,
782
- details: Optional[Dict[str, Any]] = None,
783
- wrapping: Optional[Sequence[EnumeratedError]] = None,
784
- ) -> None:
785
- """Build a InvalidWavelengthError."""
786
- super().__init__(ErrorCodes.GENERAL_ERROR, message, details, wrapping)
787
-
788
-
789
776
  class InvalidHoldTimeError(ProtocolEngineError):
790
777
  """An error raised when attempting to set an invalid temperature hold time."""
791
778
 
@@ -1268,10 +1268,7 @@ class ModuleView(HasState[ModuleState]):
1268
1268
  row = chr(ord("A") + i // 12) # Convert index to row (A-H)
1269
1269
  col = (i % 12) + 1 # Convert index to column (1-12)
1270
1270
  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
1271
+ well_map[well_key] = value
1275
1272
  return well_map
1276
1273
  else:
1277
1274
  raise ValueError(
@@ -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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: opentrons
3
- Version: 8.2.0
3
+ Version: 8.2.0a1
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.0a1
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.0a1 ; 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.0a1 ; extra == 'ot2-hardware'
40
40
 
41
41
  .. _Full API Documentation: http://docs.opentrons.com
42
42
 
@@ -47,7 +47,7 @@ opentrons/drivers/types.py,sha256=muQKlqOMYcL6iglT9a3iEJ5EnqcBDCkgHz2KyePsm6I,22
47
47
  opentrons/drivers/utils.py,sha256=QmSTP07PPXq3_Qth1Idagn7lixWFjpkOzR8LFSpcw-g,7362
48
48
  opentrons/drivers/absorbance_reader/__init__.py,sha256=d9_-VJ_MKOyRy9C5Ioeg4CWsC1WIVgQlxGqBvgpoBRc,322
49
49
  opentrons/drivers/absorbance_reader/abstract.py,sha256=Egc7RKKXscEXFC0bPVx_r1vKe2-Df9PJyDpH0OFOIiw,2005
50
- opentrons/drivers/absorbance_reader/async_byonoy.py,sha256=zmRC1nTHDx1X_paN7mSPYdHMtKtKpmrs0KnEUDHdD58,13558
50
+ opentrons/drivers/absorbance_reader/async_byonoy.py,sha256=pp4lvODBd3ydKwac28RANQgWs_X5Ml2NdFw0ZHgpXPA,13502
51
51
  opentrons/drivers/absorbance_reader/driver.py,sha256=V8hLjNRVzlRPtVW04XEWrXytn06ZRBxG9LqL4ETj21g,2791
52
52
  opentrons/drivers/absorbance_reader/hid_protocol.py,sha256=OM6Ogkl1Lw3d501rfHcRI3lPZITAVKdxCR6JkHdKMCQ,3836
53
53
  opentrons/drivers/absorbance_reader/simulator.py,sha256=MiFQgnVNq2R35T3u59idcKlrj6SEFllt8tdupfH5jKQ,2419
@@ -100,14 +100,14 @@ opentrons/hardware_control/module_control.py,sha256=u0RpbOgr5pV5exgKg3qvNQdwdVuy
100
100
  opentrons/hardware_control/motion_utilities.py,sha256=LuOZBcnNJmTPra6-mYX5wN3jh8PA2l81dy5amCyYpcQ,7164
101
101
  opentrons/hardware_control/nozzle_manager.py,sha256=XNEyNdh00QdZ7VECb--JUO_BI-96EwoAPuQ7bdGXSGs,16788
102
102
  opentrons/hardware_control/ot3_calibration.py,sha256=ExWZDLDHpi8HUzdYvBzhOyAXXwT3z7BnxPH-2EpOerM,44717
103
- opentrons/hardware_control/ot3api.py,sha256=CMtyrIDYzw-H-FQuUlnjVpGEOA9YNWETFy7jDxT8zYk,118073
103
+ opentrons/hardware_control/ot3api.py,sha256=QCTBbJ2-KLFk43qCkEJctxSmk9ZwMV8Tj6QN89KFjXo,118083
104
104
  opentrons/hardware_control/pause_manager.py,sha256=wmNmraimE2yZQVqCxX_rtQHUWRzpzyQEaym9fLMgyww,888
105
105
  opentrons/hardware_control/poller.py,sha256=rx6Q-UxbUIj3ek69IlYenFh7BFuasszRO-GzzhRPuHQ,3885
106
106
  opentrons/hardware_control/robot_calibration.py,sha256=HiCQNmdp59SbkzXpDGtPsN8rSfUj-ZU4v63vcSw4AbI,7149
107
107
  opentrons/hardware_control/simulator_setup.py,sha256=3gelKslgMDobLpIlhVHmAqmZ5wXe1hZcK4RwKRMy3aM,9277
108
108
  opentrons/hardware_control/thread_manager.py,sha256=3-PrzUzJFSjUVtrgTUEF5GIStsDufvaSbp51B2x-yJY,17253
109
109
  opentrons/hardware_control/threaded_async_lock.py,sha256=qMaIrJ4KSMzvKm0hWt4o74Joah-sc404LlhMjCJue2g,3316
110
- opentrons/hardware_control/types.py,sha256=Df4FGgsoPeTiX5EQes4MGW4O1hoJxLI0SU3Fo-whsPs,20777
110
+ opentrons/hardware_control/types.py,sha256=1A0-2eWLXRWsbTJKSjm_OGyqLZiX5z9aaKN_AvOJE5o,20691
111
111
  opentrons/hardware_control/util.py,sha256=RSlfjzrmhtntSexamNpPn3-qrnbrdhuzEjOnxv8v7lA,8650
112
112
  opentrons/hardware_control/backends/__init__.py,sha256=u5Dg3AFZuvDV7hFqJ8I4F9D1dLDt6e-TsFJReyBYe4E,212
113
113
  opentrons/hardware_control/backends/controller.py,sha256=MOVMq9s1rY_jHhajHB1hQ1MgXXyY54-gMrrvAuMsOFg,14622
@@ -116,7 +116,7 @@ opentrons/hardware_control/backends/estop_state.py,sha256=_GYjI6OaD3CZNduWV2_RVe
116
116
  opentrons/hardware_control/backends/flex_protocol.py,sha256=PlGUMXTRISFl9c-ZxU2TdPDursLAprPw6ZLqtGMngIE,12030
117
117
  opentrons/hardware_control/backends/ot3controller.py,sha256=3y18NJbFDKMkfLk4X8ApIcZ9n3EMtZqCqag5hTUS74g,61020
118
118
  opentrons/hardware_control/backends/ot3simulator.py,sha256=N63d7Qf1DHg_-sVxsRZsKoJIZtTRJIRVNZL2V_EE5Os,29502
119
- opentrons/hardware_control/backends/ot3utils.py,sha256=Y0V26XqPxKzZmMhc0pBdfibC_En9pWmU77kyD7tDHOg,21955
119
+ opentrons/hardware_control/backends/ot3utils.py,sha256=3y3jb0NdveIXd06X7wllfkx2hkc5NYtxwRrr8OxW1Vs,21893
120
120
  opentrons/hardware_control/backends/simulator.py,sha256=q_9PQlBdOyCa9sj2gLqYWZ-fG9v4mddDAiScL-yHCXY,17549
121
121
  opentrons/hardware_control/backends/status_bar_state.py,sha256=ftNn2ouBhPZiFbUm79I4z6ndup7XDmcNowhb-KREspE,8529
122
122
  opentrons/hardware_control/backends/subsystem_manager.py,sha256=lv2ON2pZ7PY2tg3-qxpAlLYIg1SJxX3erHJvcfy5UGs,16484
@@ -160,7 +160,7 @@ opentrons/hardware_control/instruments/ot3/instrument_calibration.py,sha256=9ERA
160
160
  opentrons/hardware_control/instruments/ot3/pipette.py,sha256=rrbN1Du1pTL8-pZ19K38ns_w5SMDMHcUG3Wh5nuxdWo,32493
161
161
  opentrons/hardware_control/instruments/ot3/pipette_handler.py,sha256=G6cL5qjwgi4hXKUNwvnJDEaeX0u2xp-U-dEHLRo_5pc,36704
162
162
  opentrons/hardware_control/modules/__init__.py,sha256=YLYJShv7FDI_QHboB2lQkSxoILoW9ms6Opu45ZeMMBU,1306
163
- opentrons/hardware_control/modules/absorbance_reader.py,sha256=Z6ikQiySpDi4tP1VxT-Q0WCNLUqfyzJ-iw7B7t-CUNI,13573
163
+ opentrons/hardware_control/modules/absorbance_reader.py,sha256=dCbOyHvQdN3KXh2EUnLuD1C6Wpe-ft-dmcfX4H39KY8,13468
164
164
  opentrons/hardware_control/modules/errors.py,sha256=cREqoMc6nwGxQbLvZYDfIlq1mCv0alN42J7qxNBNiOY,165
165
165
  opentrons/hardware_control/modules/heater_shaker.py,sha256=tp-j8jbkY1oRrvHkXwmMRng-tX4ARPPrEJsS1mSQFCo,15026
166
166
  opentrons/hardware_control/modules/lid_temp_status.py,sha256=XKlr41I41g8aFxrrqGZxecHWgtBceG9ZrOSkyqq1khE,1201
@@ -189,7 +189,7 @@ opentrons/hardware_control/protocols/instrument_configurer.py,sha256=5zUCAchtoJ6
189
189
  opentrons/hardware_control/protocols/liquid_handler.py,sha256=UusmQYUncMqAwxuKTIcIIrlF93XpLPctu5SJuotsTws,7731
190
190
  opentrons/hardware_control/protocols/module_provider.py,sha256=QDKCWqrW-6IeI91IICBTJClK0C__mgq3A0-M3Wa9ee8,487
191
191
  opentrons/hardware_control/protocols/motion_controller.py,sha256=2sv-fc0uvmuFj-wA1h4VrEjLLTMTvswLCkisjEXwxXQ,9520
192
- opentrons/hardware_control/protocols/position_estimator.py,sha256=BrqK5AJn9747c4LX0ZWBJWgWHjyX977CHBI7WVvO-9Q,1922
192
+ opentrons/hardware_control/protocols/position_estimator.py,sha256=bEYQiNZYsh5k9r_J2XCDQg6FixrQmxr-7KTD9gfVmYc,1797
193
193
  opentrons/hardware_control/protocols/simulatable.py,sha256=ED3VHoO8q1h9FhBDv31g5N7YdTKB5hj7lp7BZcCaL7o,247
194
194
  opentrons/hardware_control/protocols/stoppable.py,sha256=ukI1WrJzXwsJm5ty2trhMqGJr0sT13ttlv914YMAUt8,226
195
195
  opentrons/hardware_control/protocols/types.py,sha256=UlejXW-ZHjuZWizKamphyGG4Iv7-liOuCfvQR29f0Do,613
@@ -222,7 +222,7 @@ opentrons/protocol_api/deck.py,sha256=94vFceg1SC1bAGd7TvC1ZpYwnJR-VlzurEZ6jkacYe
222
222
  opentrons/protocol_api/disposal_locations.py,sha256=NRiSGmDR0LnbyEkWSOM-o64uR2fUoB1NWJG7Y7SsJSs,7920
223
223
  opentrons/protocol_api/instrument_context.py,sha256=EnOs4BAmpIabaWMFKCqhwIJcrWpP-iEv32kmdV2t9Uo,97275
224
224
  opentrons/protocol_api/labware.py,sha256=qwjAO1Au9Ujx5jyGNQ0-HLDBOXUygnXNSuv5696tGCw,48177
225
- opentrons/protocol_api/module_contexts.py,sha256=qubmR4LrLwP8e-ONKQYBlLTRQ5gpB-H25fE3SV70sKI,42104
225
+ opentrons/protocol_api/module_contexts.py,sha256=TZiswcxFRSFP_t_OoE03BSnOkZo9XQjoayHiUlVeqwA,40455
226
226
  opentrons/protocol_api/module_validation_and_errors.py,sha256=XL_m72P8rcvGO2fynY7UzXLcpGuI6X4s0V6Xf735Iyc,1464
227
227
  opentrons/protocol_api/protocol_context.py,sha256=3nVIYxTpFp2Ho6kdW65hG8LhDaTRvlFuGbuy9LsQg5s,55459
228
228
  opentrons/protocol_api/robot_context.py,sha256=vph_ZqfdmREOwLwpjSkXiSZSpI1HO0HuilhqjhgT7Rw,2660
@@ -281,19 +281,19 @@ opentrons/protocol_engine/clients/sync_client.py,sha256=f65mhTO3zwTph1LtCl7Td6z3
281
281
  opentrons/protocol_engine/clients/transports.py,sha256=QejmtG5TjgOLUXpNhOzor_q-7MFI1qNfsguwkzY6Rxc,7177
282
282
  opentrons/protocol_engine/commands/__init__.py,sha256=FKOX8Uq3g2_syxMQN0A70qEtpJrsJDlJfPhAxS4ZAII,14006
283
283
  opentrons/protocol_engine/commands/aspirate.py,sha256=zOh7wqqFlAdkQCUC1-pp0-Zi-6QEpg3ntXDTpzlgc4Y,6137
284
- opentrons/protocol_engine/commands/aspirate_in_place.py,sha256=pWU3Rfgi3i1vHG8_cKFmkot1sYKAYSxR-iQJlMpjTo4,5999
284
+ opentrons/protocol_engine/commands/aspirate_in_place.py,sha256=0m3V2IMZm4PgekIPHkF9f7v52j3ngDNJuoppmF0p4xU,6003
285
285
  opentrons/protocol_engine/commands/blow_out.py,sha256=qCxq_wa5spsr7kARCR1lRIODF4WQDCsZFJ4rhtJ4FXw,4191
286
286
  opentrons/protocol_engine/commands/blow_out_in_place.py,sha256=uJ6x8cXM1WcIKk6771FlVRLnO9-p5C8_FBCq0aGralk,3809
287
- opentrons/protocol_engine/commands/command.py,sha256=LmZQAGRw_QnB77QNo242nonefqk1chg9A-MQ75F6GPs,9952
287
+ opentrons/protocol_engine/commands/command.py,sha256=xBJBC2N40Ljkyp7hh5riXAu_2BWrgajU95uRVNvA3GI,9780
288
288
  opentrons/protocol_engine/commands/command_unions.py,sha256=30mrXVFxikW24rs3MeVBhpCevEbxs8NZ7EygLfi7O1M,20402
289
289
  opentrons/protocol_engine/commands/comment.py,sha256=yo2MpBEkILZ0R501eBW0-UACi15daH4COmghdDPz_FQ,1631
290
290
  opentrons/protocol_engine/commands/configure_for_volume.py,sha256=ZAZMWpFDU8C4GNRO-AEuMk1J2um11U5-iY3s3AaNi_M,3293
291
291
  opentrons/protocol_engine/commands/configure_nozzle_layout.py,sha256=86cYz78pVPtIiZu71TegHBIH9Gzz3Rz3LxI5-9bUJ5w,3802
292
292
  opentrons/protocol_engine/commands/custom.py,sha256=Gdhg8QrQ-PKphW1j8j3O2JEeCTQSQldldtNE-3YIdLU,2187
293
293
  opentrons/protocol_engine/commands/dispense.py,sha256=LcOjG9kzf0yUcnCBLGV6OmTur1Y_6B6ydUUvo3LFFok,5033
294
- opentrons/protocol_engine/commands/dispense_in_place.py,sha256=oiek-Xu3TvGv2tQY6BHcp4r1LW4bu1mAB58Nyr3FKWI,5183
295
- opentrons/protocol_engine/commands/drop_tip.py,sha256=rjR7lAf20OvaFSRVgl78fFq_9dUW6U7-N7eHsq3hoK0,6338
296
- opentrons/protocol_engine/commands/drop_tip_in_place.py,sha256=qTPwqXWkMW4rIQznxi3anRjCBH2UQE_WlcIHCPXypvc,4158
294
+ opentrons/protocol_engine/commands/dispense_in_place.py,sha256=uJP947lhql7OrJtfcZUhiSN7nKnJsTGtDVkGp4aCpSI,5187
295
+ opentrons/protocol_engine/commands/drop_tip.py,sha256=DdRPYbafoahQLkrgBG7X9GvzDxuyuz7oLbUeLcBC-Ko,6272
296
+ opentrons/protocol_engine/commands/drop_tip_in_place.py,sha256=_FUBZ-FcmOoK57zZLrjCl_FSRk0RzUY_M1mGL2Js9vU,3914
297
297
  opentrons/protocol_engine/commands/generate_command_schema.py,sha256=w5RsTJV4HtFpS58-xfVQ2O52h1R0zVTJkpLapN4uo9Y,1352
298
298
  opentrons/protocol_engine/commands/get_tip_presence.py,sha256=igvMiKJWzdetWBXlIaYp4Tfk57gfACon34CWzUWynno,2536
299
299
  opentrons/protocol_engine/commands/hash_command_params.py,sha256=obWy4TbVH97SyhNqrSD6iP1wgZ20JoaH1rilZCjXxIs,1530
@@ -309,8 +309,8 @@ opentrons/protocol_engine/commands/move_to_addressable_area.py,sha256=cJRXXRLkaw
309
309
  opentrons/protocol_engine/commands/move_to_addressable_area_for_drop_tip.py,sha256=5BAisk0npPcesI6bMQxKH2Xxz641uyR6RbtU9RiD5NM,7134
310
310
  opentrons/protocol_engine/commands/move_to_coordinates.py,sha256=FQ1wQ9V3OcM4nSn-hWYWrxefcLMLZOw8WW6yARiRqDg,3051
311
311
  opentrons/protocol_engine/commands/move_to_well.py,sha256=0w5TsY51m5rmp-H7bd9EKWjTzJiz3ztyW647N5NxdHI,3292
312
- opentrons/protocol_engine/commands/pick_up_tip.py,sha256=1yzOenpKUDIQh_xrkea5hhD_0kxd00DmXpoIrvr6kuo,6874
313
- opentrons/protocol_engine/commands/pipetting_common.py,sha256=JW_QzmBhwOXq_xONiSNyeHdLzFn2r--H6pDu05JNSJE,6879
312
+ opentrons/protocol_engine/commands/pick_up_tip.py,sha256=Qd7ZZEKNT1cwlNZUZgZqtjnwJ7Iqgpf4dhIcbuf_0W0,6875
313
+ opentrons/protocol_engine/commands/pipetting_common.py,sha256=Ds5FsMpBIxq2Y-2_ntGTsjC0eFZReXDSmVdk37LJOSI,6672
314
314
  opentrons/protocol_engine/commands/prepare_to_aspirate.py,sha256=061KttjjIM4u5WejUViLwnIqrj97mr8V-4UjkbTbitU,3710
315
315
  opentrons/protocol_engine/commands/reload_labware.py,sha256=XPSQ1AHykiChI1CotwE73eF7FbULUqDQ1pUpOtEwrXc,3408
316
316
  opentrons/protocol_engine/commands/retract_axis.py,sha256=bMPJxQSYK9VsxraNl_SErXH9Dj4pBqrbx2gtTIg0MMw,2882
@@ -323,9 +323,9 @@ opentrons/protocol_engine/commands/wait_for_duration.py,sha256=DIATqpdBStGQWnLAb
323
323
  opentrons/protocol_engine/commands/wait_for_resume.py,sha256=yFNpYDJO5mgAhIpMb1i7Epo7ZhO15Ot9RsSUdW8AjUg,2178
324
324
  opentrons/protocol_engine/commands/absorbance_reader/__init__.py,sha256=umS98LlkBEAToRCvxLpr4k43tRPPTfkYu-81-bLy5DU,1251
325
325
  opentrons/protocol_engine/commands/absorbance_reader/close_lid.py,sha256=i6kggql8hJgTxpUbc5dmdMdHDsYWiczfMvZNA72FmvI,5540
326
- opentrons/protocol_engine/commands/absorbance_reader/initialize.py,sha256=bbs7FwfpGVNAa5UT_rMV7ImrRnmREN9kRhmG8xJsAaU,5373
326
+ opentrons/protocol_engine/commands/absorbance_reader/initialize.py,sha256=HKsgwCfv6LR4SJ06721eq9_NhKcxtVR5lYIdaZPL-_4,4760
327
327
  opentrons/protocol_engine/commands/absorbance_reader/open_lid.py,sha256=Ef5coWs4GGOzmZbrAFZXTKq8hZCC7rJc2DVCOU2PFJg,5531
328
- opentrons/protocol_engine/commands/absorbance_reader/read.py,sha256=QZ8zjjlKQPXprekxsEjgFxmvLns4Q0NpnZ6hbFAoq6k,8403
328
+ opentrons/protocol_engine/commands/absorbance_reader/read.py,sha256=xu5KijW_sSEtjdhNIEctYkQBZC8Baj650W6s8nXfTKw,8187
329
329
  opentrons/protocol_engine/commands/calibration/__init__.py,sha256=JjNnULLBM3j8VtpfHOvH51em9jVLR_ezyrUJUWqxuYI,1611
330
330
  opentrons/protocol_engine/commands/calibration/calibrate_gripper.py,sha256=1HgEsH-0ycGD-OlxdmCTIuBeSCzVTc1vepSjVirai-g,5570
331
331
  opentrons/protocol_engine/commands/calibration/calibrate_module.py,sha256=zjkgPgHHn5CM-ztvbcKcTaAMvj9zsMLNyykynwec0j0,4172
@@ -362,12 +362,12 @@ opentrons/protocol_engine/commands/unsafe/__init__.py,sha256=lx3TFW_78XK0bdtLFuG
362
362
  opentrons/protocol_engine/commands/unsafe/unsafe_blow_out_in_place.py,sha256=K1idiUT1RW_mWa_SIe3JOUaeuSsUbv12toWgAB1KSvM,3065
363
363
  opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py,sha256=v5h1sLxx_NMAhVCLbmECd7sD0PsecB4Dj-oaBEe0YBs,3635
364
364
  opentrons/protocol_engine/commands/unsafe/unsafe_engage_axes.py,sha256=hCRqFeBInC9Mxz9LqUgIrjTTAjuMEq5MJxCqqXwi3N4,2552
365
- opentrons/protocol_engine/commands/unsafe/unsafe_place_labware.py,sha256=etNdLxj0TtmBA5fTLR-OSfbnRNbXKDzE__aKRAkvWMM,7866
366
- opentrons/protocol_engine/commands/unsafe/unsafe_ungrip_labware.py,sha256=408KbcJgroOA7Qhs-qih-ce-2n-ixGKu6mhv33TplJ0,2454
367
- opentrons/protocol_engine/commands/unsafe/update_position_estimators.py,sha256=Jgds_cwEHBiiDyJVK6wL34VTWZikrSVYJSRUohnsod8,3044
368
- opentrons/protocol_engine/errors/__init__.py,sha256=4CEG_WmrdSmESVkSkwfLlbNwW_r8TlMbD_fEXzcn5qg,5232
369
- opentrons/protocol_engine/errors/error_occurrence.py,sha256=Uoa0tqJ4C-oosDUwk-XXf0NxgWVnVnnhTFOqJAT1J_o,7896
370
- opentrons/protocol_engine/errors/exceptions.py,sha256=yHLqtkKQbJev80zZYvZz8gjw8luXxWRrcJe3TEcIj88,40604
365
+ opentrons/protocol_engine/commands/unsafe/unsafe_place_labware.py,sha256=HnYnFViUtPx2p3UXntdMa5LyBLE2AYLjskvnIIWYZ24,7576
366
+ opentrons/protocol_engine/commands/unsafe/unsafe_ungrip_labware.py,sha256=MSYftVeLHqnIyX0n9IJLq6XOb7P835EQg7KR3n3PU6c,2397
367
+ opentrons/protocol_engine/commands/unsafe/update_position_estimators.py,sha256=pXew4UsDB4Kh7z9r2l7-S3D8bICNmdDr8lNkNEnByYE,2938
368
+ opentrons/protocol_engine/errors/__init__.py,sha256=rwpfKoEIZUN7c5kf0T9b0MHCJdDxZiUTCvQs64jPtVI,5174
369
+ opentrons/protocol_engine/errors/error_occurrence.py,sha256=PM_bxIxLYKtsRl_cGMiCtXVVMEb88hkLFEWcafwqLf8,7542
370
+ opentrons/protocol_engine/errors/exceptions.py,sha256=bLZ5ZYUgUH-CjGtflbDBbmWCqUPr6MGcpE1Yiip3ll4,40153
371
371
  opentrons/protocol_engine/execution/__init__.py,sha256=X8qTYYOc1v84JIDM1xYpIo3VG_BPnsrfl2jm9UUQGwQ,1384
372
372
  opentrons/protocol_engine/execution/command_executor.py,sha256=F1V7H_Y7mqc4hJMfs79aNZ7qG0NFh-xj2BHt4fSUK-4,8202
373
373
  opentrons/protocol_engine/execution/create_queue_worker.py,sha256=6hMuOqbqwfMn63idsrAgro0NJZoyX4VVH7AV3le2EWM,3372
@@ -412,7 +412,7 @@ opentrons/protocol_engine/state/frustum_helpers.py,sha256=OMa7_3INieaNhkFb6wVC6l
412
412
  opentrons/protocol_engine/state/geometry.py,sha256=-yEsGHPfjUVNgVWJKeBiJyzl65wAzSvjS7W-kOxukCQ,67902
413
413
  opentrons/protocol_engine/state/labware.py,sha256=Ns_GoUKxL55P6J2YEch5GZCVvTbQZS0h4CbZwCr7Frc,44758
414
414
  opentrons/protocol_engine/state/liquids.py,sha256=TwchzB7xNt7CAd3wX3BA_5DXrQhGwj_uFQsv0FWOXXk,1886
415
- opentrons/protocol_engine/state/modules.py,sha256=NCx6s9WhFnv-XXIcnfnJ_rqLelI7pzqIv8v5ACrG2xE,54110
415
+ opentrons/protocol_engine/state/modules.py,sha256=8d5YOPhGs8jnw5mDQiGSrhtvozZkCtcRQd49YesVmds,53936
416
416
  opentrons/protocol_engine/state/motion.py,sha256=1KEm1HXdkuFKNe2lElZnNfJedml4afMFnmcDvG-3fLA,14937
417
417
  opentrons/protocol_engine/state/pipettes.py,sha256=jXhPGLHT1Ypc_tt8UkWZz51sCZ9ld4umr7AyuhlvxoU,30861
418
418
  opentrons/protocol_engine/state/state.py,sha256=HbkGfTLYNPlb9yu2sCi4UOJQrgXedi3w8xbYc0QCn-w,14550
@@ -446,7 +446,7 @@ opentrons/protocol_runner/legacy_command_mapper.py,sha256=N6Ubuz8VHHh0Ga3JgHVhBx
446
446
  opentrons/protocol_runner/legacy_context_plugin.py,sha256=G_qpeyaLvsCjb72_n96Luy8CPSfgPZpt0QKVzKc6LKY,4730
447
447
  opentrons/protocol_runner/protocol_runner.py,sha256=VtgqbcrcKhvWwGyl-LeX-0LjcQw3_frvwyi3d3UlzR8,20732
448
448
  opentrons/protocol_runner/python_protocol_wrappers.py,sha256=2eIGAlKCLfVSUjO5hhd_UKCEBQX_nS4Y9E5wXm2WvhY,6505
449
- opentrons/protocol_runner/run_orchestrator.py,sha256=d--Ezeo2M8hEk0Vjp2tZMvJFqaNKFkrQNB24F03DACo,18864
449
+ opentrons/protocol_runner/run_orchestrator.py,sha256=H_1oryOKooKVmDaKukP9htm0JmgDTJJ6iRs-uEp8jxc,18324
450
450
  opentrons/protocol_runner/task_queue.py,sha256=YH8_lvuLBYjfzXAOJU8DYXizQcbaxGmUiAPmd7kHERw,2581
451
451
  opentrons/protocols/__init__.py,sha256=cOUxilkIvdlqGvN4nYJQYr0TGdIWnzxBaTfoz3svmw8,245
452
452
  opentrons/protocols/bundle.py,sha256=QW_2kwnxgdG_nNPl2e110A5ehOH9Ej63-9TBx-F9Yvw,3666
@@ -485,7 +485,7 @@ opentrons/protocols/models/__init__.py,sha256=KePRAkkKzFoc0lAz8y89cWnxru8ofe3mow
485
485
  opentrons/protocols/models/json_protocol.py,sha256=lteWlIBXgRM86k-wO1dKsx02G2_4kustSDeSoyc5N5U,20128
486
486
  opentrons/protocols/parameters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
487
487
  opentrons/protocols/parameters/csv_parameter_definition.py,sha256=xZhGtdfH2vXSWFK-aGET07_L0LODvHWkfNxf7pQoOmo,2762
488
- opentrons/protocols/parameters/csv_parameter_interface.py,sha256=lcELoVQi3PRIDFd4Dw7bi4wODi1tjGuMb2F5X4c4m6Y,4086
488
+ opentrons/protocols/parameters/csv_parameter_interface.py,sha256=S7fdY39TxXqXO-jnaTZFLFI62n0HGc_XjYScWGB44VY,3945
489
489
  opentrons/protocols/parameters/exceptions.py,sha256=vQUeyy8Yk_fzP4bvT0r_zu3s7Aty3LM7PzTV6k2iXu0,1092
490
490
  opentrons/protocols/parameters/parameter_definition.py,sha256=OMtUCPKyFx5ZH3Jfcw05aF8pptWQ7XYzYttGMuSPu9k,9529
491
491
  opentrons/protocols/parameters/types.py,sha256=h7vaNmKbDHc1q_FzbZoIgoSVo0mvS64FeiLZDnv7xnQ,489
@@ -512,9 +512,9 @@ opentrons/util/helpers.py,sha256=3hr801bWGbxEcOFAS7f-iOhmnUhoK5qahbB8SIvaCfY,165
512
512
  opentrons/util/linal.py,sha256=IlKAP9HkNBBgULeSf4YVwSKHdx9jnCjSr7nvDvlRALg,5753
513
513
  opentrons/util/logging_config.py,sha256=t3xRxQ5zfXQsU8S4gl6yvrtqx6dxOGyBwIM43CGRyjE,6887
514
514
  opentrons/util/performance_helpers.py,sha256=ew7H8XD20iS6-2TJAzbQeyzStZkkE6PzHt_Adx3wbZQ,5172
515
- opentrons-8.2.0.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
516
- opentrons-8.2.0.dist-info/METADATA,sha256=B7P2hHw5zLWPE1djYqdhELVflN-mm9Woawd1bLTpyeU,5011
517
- opentrons-8.2.0.dist-info/WHEEL,sha256=_4XEmVmaBFWtekSGrbfOGNjC2I5lUr0lZSRblBllIFA,109
518
- opentrons-8.2.0.dist-info/entry_points.txt,sha256=fTa6eGCYkvOtv0ov-KVE8LLGetgb35LQLF9x85OWPVw,106
519
- opentrons-8.2.0.dist-info/top_level.txt,sha256=wk6whpbMZdBQpcK0Fg0YVfUGrAgVOFON7oQAhOMGMW8,10
520
- opentrons-8.2.0.dist-info/RECORD,,
515
+ opentrons-8.2.0a1.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
516
+ opentrons-8.2.0a1.dist-info/METADATA,sha256=1X3bpJiJdC2f93wQJUlj-jC0LTujfDRA2Rdrk4895lw,5019
517
+ opentrons-8.2.0a1.dist-info/WHEEL,sha256=_4XEmVmaBFWtekSGrbfOGNjC2I5lUr0lZSRblBllIFA,109
518
+ opentrons-8.2.0a1.dist-info/entry_points.txt,sha256=fTa6eGCYkvOtv0ov-KVE8LLGetgb35LQLF9x85OWPVw,106
519
+ opentrons-8.2.0a1.dist-info/top_level.txt,sha256=wk6whpbMZdBQpcK0Fg0YVfUGrAgVOFON7oQAhOMGMW8,10
520
+ opentrons-8.2.0a1.dist-info/RECORD,,