opentrons 8.2.0a4__py2.py3-none-any.whl → 8.3.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.
- opentrons/config/defaults_ot3.py +1 -0
- opentrons/hardware_control/backends/flex_protocol.py +13 -1
- opentrons/hardware_control/backends/ot3controller.py +36 -4
- opentrons/hardware_control/backends/ot3simulator.py +8 -1
- opentrons/hardware_control/backends/ot3utils.py +40 -2
- opentrons/hardware_control/dev_types.py +2 -0
- opentrons/hardware_control/instruments/ot2/pipette.py +6 -1
- opentrons/hardware_control/instruments/ot3/pipette.py +10 -0
- opentrons/hardware_control/ot3api.py +26 -1
- opentrons/protocol_api/core/engine/instrument.py +15 -0
- opentrons/protocol_api/core/instrument.py +4 -0
- opentrons/protocol_api/core/legacy/legacy_instrument_core.py +3 -0
- opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py +3 -0
- opentrons/protocol_api/instrument_context.py +13 -1
- opentrons/protocol_api/validation.py +1 -0
- opentrons/protocol_engine/commands/liquid_probe.py +8 -0
- opentrons/protocol_engine/resources/pipette_data_provider.py +14 -0
- opentrons/protocol_engine/state/pipettes.py +9 -0
- {opentrons-8.2.0a4.dist-info → opentrons-8.3.0a0.dist-info}/METADATA +4 -4
- {opentrons-8.2.0a4.dist-info → opentrons-8.3.0a0.dist-info}/RECORD +24 -24
- {opentrons-8.2.0a4.dist-info → opentrons-8.3.0a0.dist-info}/LICENSE +0 -0
- {opentrons-8.2.0a4.dist-info → opentrons-8.3.0a0.dist-info}/WHEEL +0 -0
- {opentrons-8.2.0a4.dist-info → opentrons-8.3.0a0.dist-info}/entry_points.txt +0 -0
- {opentrons-8.2.0a4.dist-info → opentrons-8.3.0a0.dist-info}/top_level.txt +0 -0
opentrons/config/defaults_ot3.py
CHANGED
|
@@ -75,6 +75,7 @@ DEFAULT_RIGHT_MOUNT_OFFSET: Final[Offset] = (40.5, -60.5, 255.675)
|
|
|
75
75
|
DEFAULT_GRIPPER_MOUNT_OFFSET: Final[Offset] = (84.55, -12.75, 93.85)
|
|
76
76
|
DEFAULT_SAFE_HOME_DISTANCE: Final = 5
|
|
77
77
|
DEFAULT_CALIBRATION_AXIS_MAX_SPEED: Final = 30
|
|
78
|
+
DEFAULT_EMULSIFYING_PIPETTE_AXIS_MAX_SPEED: Final = 90
|
|
78
79
|
|
|
79
80
|
DEFAULT_MAX_SPEEDS: Final[ByGantryLoad[Dict[OT3AxisKind, float]]] = ByGantryLoad(
|
|
80
81
|
high_throughput={
|
|
@@ -60,6 +60,14 @@ class FlexBackend(Protocol):
|
|
|
60
60
|
def grab_pressure(self, channels: int, mount: OT3Mount) -> AsyncIterator[None]:
|
|
61
61
|
...
|
|
62
62
|
|
|
63
|
+
def set_pressure_sensor_available(
|
|
64
|
+
self, pipette_axis: Axis, available: bool
|
|
65
|
+
) -> None:
|
|
66
|
+
...
|
|
67
|
+
|
|
68
|
+
def get_pressure_sensor_available(self, pipette_axis: Axis) -> bool:
|
|
69
|
+
...
|
|
70
|
+
|
|
63
71
|
def update_constraints_for_gantry_load(self, gantry_load: GantryLoad) -> None:
|
|
64
72
|
...
|
|
65
73
|
|
|
@@ -70,7 +78,11 @@ class FlexBackend(Protocol):
|
|
|
70
78
|
...
|
|
71
79
|
|
|
72
80
|
def update_constraints_for_plunger_acceleration(
|
|
73
|
-
self,
|
|
81
|
+
self,
|
|
82
|
+
mount: OT3Mount,
|
|
83
|
+
acceleration: float,
|
|
84
|
+
gantry_load: GantryLoad,
|
|
85
|
+
high_speed_pipette: bool = False,
|
|
74
86
|
) -> None:
|
|
75
87
|
...
|
|
76
88
|
|
|
@@ -197,6 +197,7 @@ from opentrons_shared_data.errors.exceptions import (
|
|
|
197
197
|
PipetteLiquidNotFoundError,
|
|
198
198
|
CommunicationError,
|
|
199
199
|
PythonException,
|
|
200
|
+
UnsupportedHardwareCommand,
|
|
200
201
|
)
|
|
201
202
|
|
|
202
203
|
from .subsystem_manager import SubsystemManager
|
|
@@ -362,6 +363,7 @@ class OT3Controller(FlexBackend):
|
|
|
362
363
|
self._configuration.motion_settings, GantryLoad.LOW_THROUGHPUT
|
|
363
364
|
)
|
|
364
365
|
)
|
|
366
|
+
self._pressure_sensor_available: Dict[NodeId, bool] = {}
|
|
365
367
|
|
|
366
368
|
@asynccontextmanager
|
|
367
369
|
async def restore_system_constraints(self) -> AsyncIterator[None]:
|
|
@@ -380,6 +382,16 @@ class OT3Controller(FlexBackend):
|
|
|
380
382
|
async with grab_pressure(channels, tool, self._messenger):
|
|
381
383
|
yield
|
|
382
384
|
|
|
385
|
+
def set_pressure_sensor_available(
|
|
386
|
+
self, pipette_axis: Axis, available: bool
|
|
387
|
+
) -> None:
|
|
388
|
+
pip_node = axis_to_node(pipette_axis)
|
|
389
|
+
self._pressure_sensor_available[pip_node] = available
|
|
390
|
+
|
|
391
|
+
def get_pressure_sensor_available(self, pipette_axis: Axis) -> bool:
|
|
392
|
+
pip_node = axis_to_node(pipette_axis)
|
|
393
|
+
return self._pressure_sensor_available[pip_node]
|
|
394
|
+
|
|
383
395
|
def update_constraints_for_calibration_with_gantry_load(
|
|
384
396
|
self,
|
|
385
397
|
gantry_load: GantryLoad,
|
|
@@ -399,10 +411,18 @@ class OT3Controller(FlexBackend):
|
|
|
399
411
|
)
|
|
400
412
|
|
|
401
413
|
def update_constraints_for_plunger_acceleration(
|
|
402
|
-
self,
|
|
414
|
+
self,
|
|
415
|
+
mount: OT3Mount,
|
|
416
|
+
acceleration: float,
|
|
417
|
+
gantry_load: GantryLoad,
|
|
418
|
+
high_speed_pipette: bool = False,
|
|
403
419
|
) -> None:
|
|
404
420
|
new_constraints = get_system_constraints_for_plunger_acceleration(
|
|
405
|
-
self._configuration.motion_settings,
|
|
421
|
+
self._configuration.motion_settings,
|
|
422
|
+
gantry_load,
|
|
423
|
+
mount,
|
|
424
|
+
acceleration,
|
|
425
|
+
high_speed_pipette,
|
|
406
426
|
)
|
|
407
427
|
self._move_manager.update_constraints(new_constraints)
|
|
408
428
|
|
|
@@ -679,7 +699,8 @@ class OT3Controller(FlexBackend):
|
|
|
679
699
|
|
|
680
700
|
pipettes_moving = moving_pipettes_in_move_group(move_group)
|
|
681
701
|
|
|
682
|
-
|
|
702
|
+
checked_moving_pipettes = self._pipettes_to_monitor_pressure(pipettes_moving)
|
|
703
|
+
async with self._monitor_overpressure(checked_moving_pipettes):
|
|
683
704
|
positions = await runner.run(can_messenger=self._messenger)
|
|
684
705
|
self._handle_motor_status_response(positions)
|
|
685
706
|
|
|
@@ -786,7 +807,8 @@ class OT3Controller(FlexBackend):
|
|
|
786
807
|
moving_pipettes = [
|
|
787
808
|
axis_to_node(ax) for ax in checked_axes if ax in Axis.pipette_axes()
|
|
788
809
|
]
|
|
789
|
-
|
|
810
|
+
checked_moving_pipettes = self._pipettes_to_monitor_pressure(moving_pipettes)
|
|
811
|
+
async with self._monitor_overpressure(checked_moving_pipettes):
|
|
790
812
|
positions = await asyncio.gather(*coros)
|
|
791
813
|
# TODO(CM): default gear motor homing routine to have some acceleration
|
|
792
814
|
if Axis.Q in checked_axes:
|
|
@@ -800,6 +822,9 @@ class OT3Controller(FlexBackend):
|
|
|
800
822
|
self._handle_motor_status_response(position)
|
|
801
823
|
return axis_convert(self._position, 0.0)
|
|
802
824
|
|
|
825
|
+
def _pipettes_to_monitor_pressure(self, pipettes: List[NodeId]) -> List[NodeId]:
|
|
826
|
+
return [pip for pip in pipettes if self._pressure_sensor_available[pip]]
|
|
827
|
+
|
|
803
828
|
def _filter_move_group(self, move_group: MoveGroup) -> MoveGroup:
|
|
804
829
|
new_group: MoveGroup = []
|
|
805
830
|
for step in move_group:
|
|
@@ -915,6 +940,7 @@ class OT3Controller(FlexBackend):
|
|
|
915
940
|
lookup_name = {
|
|
916
941
|
FirmwarePipetteName.p1000_single: "P1KS",
|
|
917
942
|
FirmwarePipetteName.p1000_multi: "P1KM",
|
|
943
|
+
FirmwarePipetteName.p1000_multi_em: "P1KP",
|
|
918
944
|
FirmwarePipetteName.p50_single: "P50S",
|
|
919
945
|
FirmwarePipetteName.p50_multi: "P50M",
|
|
920
946
|
FirmwarePipetteName.p1000_96: "P1KH",
|
|
@@ -949,6 +975,7 @@ class OT3Controller(FlexBackend):
|
|
|
949
975
|
converted_name.pipette_type,
|
|
950
976
|
converted_name.pipette_channels,
|
|
951
977
|
converted_name.pipette_version,
|
|
978
|
+
converted_name.oem_type,
|
|
952
979
|
),
|
|
953
980
|
"id": OT3Controller._combine_serial_number(attached),
|
|
954
981
|
}
|
|
@@ -1378,6 +1405,11 @@ class OT3Controller(FlexBackend):
|
|
|
1378
1405
|
) -> float:
|
|
1379
1406
|
head_node = axis_to_node(Axis.by_mount(mount))
|
|
1380
1407
|
tool = sensor_node_for_pipette(OT3Mount(mount.value))
|
|
1408
|
+
if tool not in self._pipettes_to_monitor_pressure([tool]):
|
|
1409
|
+
raise UnsupportedHardwareCommand(
|
|
1410
|
+
"Liquid Presence Detection not available on this pipette."
|
|
1411
|
+
)
|
|
1412
|
+
|
|
1381
1413
|
positions = await liquid_probe(
|
|
1382
1414
|
messenger=self._messenger,
|
|
1383
1415
|
tool=tool,
|
|
@@ -235,7 +235,11 @@ class OT3Simulator(FlexBackend):
|
|
|
235
235
|
self._sim_gantry_load = gantry_load
|
|
236
236
|
|
|
237
237
|
def update_constraints_for_plunger_acceleration(
|
|
238
|
-
self,
|
|
238
|
+
self,
|
|
239
|
+
mount: OT3Mount,
|
|
240
|
+
acceleration: float,
|
|
241
|
+
gantry_load: GantryLoad,
|
|
242
|
+
high_speed_pipette: bool = False,
|
|
239
243
|
) -> None:
|
|
240
244
|
self._sim_gantry_load = gantry_load
|
|
241
245
|
|
|
@@ -505,6 +509,7 @@ class OT3Simulator(FlexBackend):
|
|
|
505
509
|
converted_name.pipette_type,
|
|
506
510
|
converted_name.pipette_channels,
|
|
507
511
|
converted_name.pipette_version,
|
|
512
|
+
converted_name.oem_type,
|
|
508
513
|
),
|
|
509
514
|
"id": None,
|
|
510
515
|
}
|
|
@@ -527,6 +532,7 @@ class OT3Simulator(FlexBackend):
|
|
|
527
532
|
converted_name.pipette_type,
|
|
528
533
|
converted_name.pipette_channels,
|
|
529
534
|
converted_name.pipette_version,
|
|
535
|
+
converted_name.oem_type,
|
|
530
536
|
),
|
|
531
537
|
"id": init_instr["id"],
|
|
532
538
|
}
|
|
@@ -538,6 +544,7 @@ class OT3Simulator(FlexBackend):
|
|
|
538
544
|
converted_name.pipette_type,
|
|
539
545
|
converted_name.pipette_channels,
|
|
540
546
|
converted_name.pipette_version,
|
|
547
|
+
converted_name.oem_type,
|
|
541
548
|
),
|
|
542
549
|
"id": None,
|
|
543
550
|
}
|
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
from typing import Dict, Iterable, List, Set, Tuple, TypeVar, cast, Sequence, Optional
|
|
3
3
|
from typing_extensions import Literal
|
|
4
4
|
from logging import getLogger
|
|
5
|
-
from opentrons.config.defaults_ot3 import
|
|
5
|
+
from opentrons.config.defaults_ot3 import (
|
|
6
|
+
DEFAULT_CALIBRATION_AXIS_MAX_SPEED,
|
|
7
|
+
DEFAULT_EMULSIFYING_PIPETTE_AXIS_MAX_SPEED,
|
|
8
|
+
)
|
|
6
9
|
from opentrons.config.types import OT3MotionSettings, OT3CurrentSettings, GantryLoad
|
|
7
10
|
from opentrons.hardware_control.types import (
|
|
8
11
|
Axis,
|
|
@@ -281,12 +284,22 @@ def get_system_constraints_for_plunger_acceleration(
|
|
|
281
284
|
gantry_load: GantryLoad,
|
|
282
285
|
mount: OT3Mount,
|
|
283
286
|
acceleration: float,
|
|
287
|
+
high_speed_pipette: bool = False,
|
|
284
288
|
) -> "SystemConstraints[Axis]":
|
|
285
289
|
old_constraints = config.by_gantry_load(gantry_load)
|
|
286
290
|
new_constraints = {}
|
|
287
291
|
axis_kinds = set([k for _, v in old_constraints.items() for k in v.keys()])
|
|
292
|
+
|
|
293
|
+
def _get_axis_max_speed(ax: Axis) -> float:
|
|
294
|
+
if ax == Axis.of_main_tool_actuator(mount) and high_speed_pipette:
|
|
295
|
+
_max_speed = float(DEFAULT_EMULSIFYING_PIPETTE_AXIS_MAX_SPEED)
|
|
296
|
+
else:
|
|
297
|
+
_max_speed = old_constraints["default_max_speed"][axis_kind]
|
|
298
|
+
return _max_speed
|
|
299
|
+
|
|
288
300
|
for axis_kind in axis_kinds:
|
|
289
301
|
for axis in Axis.of_kind(axis_kind):
|
|
302
|
+
_default_max_speed = _get_axis_max_speed(axis)
|
|
290
303
|
if axis == Axis.of_main_tool_actuator(mount):
|
|
291
304
|
_accel = acceleration
|
|
292
305
|
else:
|
|
@@ -295,7 +308,32 @@ def get_system_constraints_for_plunger_acceleration(
|
|
|
295
308
|
_accel,
|
|
296
309
|
old_constraints["max_speed_discontinuity"][axis_kind],
|
|
297
310
|
old_constraints["direction_change_speed_discontinuity"][axis_kind],
|
|
298
|
-
|
|
311
|
+
_default_max_speed,
|
|
312
|
+
)
|
|
313
|
+
return new_constraints
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
def get_system_constraints_for_emulsifying_pipette(
|
|
317
|
+
config: OT3MotionSettings,
|
|
318
|
+
gantry_load: GantryLoad,
|
|
319
|
+
mount: OT3Mount,
|
|
320
|
+
) -> "SystemConstraints[Axis]":
|
|
321
|
+
old_constraints = config.by_gantry_load(gantry_load)
|
|
322
|
+
new_constraints = {}
|
|
323
|
+
axis_kinds = set([k for _, v in old_constraints.items() for k in v.keys()])
|
|
324
|
+
for axis_kind in axis_kinds:
|
|
325
|
+
for axis in Axis.of_kind(axis_kind):
|
|
326
|
+
if axis == Axis.of_main_tool_actuator(mount):
|
|
327
|
+
_max_speed = float(DEFAULT_EMULSIFYING_PIPETTE_AXIS_MAX_SPEED)
|
|
328
|
+
else:
|
|
329
|
+
_max_speed = old_constraints["default_max_speed"][axis_kind]
|
|
330
|
+
new_constraints[axis] = AxisConstraints.build(
|
|
331
|
+
max_acceleration=old_constraints["acceleration"][axis_kind],
|
|
332
|
+
max_speed_discont=old_constraints["max_speed_discontinuity"][axis_kind],
|
|
333
|
+
max_direction_change_speed_discont=old_constraints[
|
|
334
|
+
"direction_change_speed_discontinuity"
|
|
335
|
+
][axis_kind],
|
|
336
|
+
max_speed=_max_speed,
|
|
299
337
|
)
|
|
300
338
|
return new_constraints
|
|
301
339
|
|
|
@@ -20,6 +20,7 @@ from opentrons_shared_data.pipette.pipette_definition import (
|
|
|
20
20
|
PipetteConfigurations,
|
|
21
21
|
SupportedTipsDefinition,
|
|
22
22
|
PipetteBoundingBoxOffsetDefinition,
|
|
23
|
+
AvailableSensorDefinition,
|
|
23
24
|
)
|
|
24
25
|
from opentrons_shared_data.gripper import (
|
|
25
26
|
GripperModel,
|
|
@@ -100,6 +101,7 @@ class PipetteDict(InstrumentDict):
|
|
|
100
101
|
pipette_bounding_box_offsets: PipetteBoundingBoxOffsetDefinition
|
|
101
102
|
current_nozzle_map: NozzleMap
|
|
102
103
|
lld_settings: Optional[Dict[str, Dict[str, float]]]
|
|
104
|
+
available_sensors: AvailableSensorDefinition
|
|
103
105
|
|
|
104
106
|
|
|
105
107
|
class PipetteStateDict(TypedDict):
|
|
@@ -56,6 +56,7 @@ from opentrons_shared_data.pipette.types import (
|
|
|
56
56
|
UlPerMmAction,
|
|
57
57
|
PipetteName,
|
|
58
58
|
PipetteModel,
|
|
59
|
+
PipetteOEMType,
|
|
59
60
|
)
|
|
60
61
|
from opentrons.hardware_control.dev_types import InstrumentHardwareConfigs
|
|
61
62
|
|
|
@@ -112,17 +113,20 @@ class Pipette(AbstractInstrument[PipetteConfigurations]):
|
|
|
112
113
|
pipette_type=config.pipette_type,
|
|
113
114
|
pipette_channels=config.channels,
|
|
114
115
|
pipette_generation=config.display_category,
|
|
116
|
+
oem_type=PipetteOEMType.OT,
|
|
115
117
|
)
|
|
116
118
|
self._acting_as = self._pipette_name
|
|
117
119
|
self._pipette_model = PipetteModelVersionType(
|
|
118
120
|
pipette_type=config.pipette_type,
|
|
119
121
|
pipette_channels=config.channels,
|
|
120
122
|
pipette_version=config.version,
|
|
123
|
+
oem_type=PipetteOEMType.OT,
|
|
121
124
|
)
|
|
122
125
|
self._valid_nozzle_maps = load_pipette_data.load_valid_nozzle_maps(
|
|
123
126
|
self._pipette_model.pipette_type,
|
|
124
127
|
self._pipette_model.pipette_channels,
|
|
125
128
|
self._pipette_model.pipette_version,
|
|
129
|
+
PipetteOEMType.OT,
|
|
126
130
|
)
|
|
127
131
|
self._nozzle_offset = self._config.nozzle_offset
|
|
128
132
|
self._nozzle_manager = (
|
|
@@ -189,7 +193,7 @@ class Pipette(AbstractInstrument[PipetteConfigurations]):
|
|
|
189
193
|
], f"{self.name} is not back-compatible with {name}"
|
|
190
194
|
|
|
191
195
|
liquid_model = load_pipette_data.load_liquid_model(
|
|
192
|
-
name.pipette_type, name.pipette_channels, name.get_version()
|
|
196
|
+
name.pipette_type, name.pipette_channels, name.get_version(), name.oem_type
|
|
193
197
|
)
|
|
194
198
|
# TODO need to grab name config here to deal with act as test
|
|
195
199
|
self._liquid_class.max_volume = liquid_model["default"].max_volume
|
|
@@ -280,6 +284,7 @@ class Pipette(AbstractInstrument[PipetteConfigurations]):
|
|
|
280
284
|
self._pipette_model.pipette_type,
|
|
281
285
|
self._pipette_model.pipette_channels,
|
|
282
286
|
self._pipette_model.pipette_version,
|
|
287
|
+
self._pipette_model.oem_type,
|
|
283
288
|
)
|
|
284
289
|
self._config_as_dict = self._config.dict()
|
|
285
290
|
|
|
@@ -41,6 +41,8 @@ from opentrons_shared_data.pipette.types import (
|
|
|
41
41
|
UlPerMmAction,
|
|
42
42
|
PipetteName,
|
|
43
43
|
PipetteModel,
|
|
44
|
+
Quirks,
|
|
45
|
+
PipetteOEMType,
|
|
44
46
|
)
|
|
45
47
|
from opentrons_shared_data.pipette import (
|
|
46
48
|
load_data as load_pipette_data,
|
|
@@ -92,22 +94,26 @@ class Pipette(AbstractInstrument[PipetteConfigurations]):
|
|
|
92
94
|
self._liquid_class_name = pip_types.LiquidClasses.default
|
|
93
95
|
self._liquid_class = self._config.liquid_properties[self._liquid_class_name]
|
|
94
96
|
|
|
97
|
+
oem = PipetteOEMType.get_oem_from_quirks(config.quirks)
|
|
95
98
|
# TODO (lc 12-05-2022) figure out how we can safely deprecate "name" and "model"
|
|
96
99
|
self._pipette_name = PipetteNameType(
|
|
97
100
|
pipette_type=config.pipette_type,
|
|
98
101
|
pipette_channels=config.channels,
|
|
99
102
|
pipette_generation=config.display_category,
|
|
103
|
+
oem_type=oem,
|
|
100
104
|
)
|
|
101
105
|
self._acting_as = self._pipette_name
|
|
102
106
|
self._pipette_model = PipetteModelVersionType(
|
|
103
107
|
pipette_type=config.pipette_type,
|
|
104
108
|
pipette_channels=config.channels,
|
|
105
109
|
pipette_version=config.version,
|
|
110
|
+
oem_type=oem,
|
|
106
111
|
)
|
|
107
112
|
self._valid_nozzle_maps = load_pipette_data.load_valid_nozzle_maps(
|
|
108
113
|
self._pipette_model.pipette_type,
|
|
109
114
|
self._pipette_model.pipette_channels,
|
|
110
115
|
self._pipette_model.pipette_version,
|
|
116
|
+
self._pipette_model.oem_type,
|
|
111
117
|
)
|
|
112
118
|
self._nozzle_offset = self._config.nozzle_offset
|
|
113
119
|
self._nozzle_manager = (
|
|
@@ -225,6 +231,9 @@ class Pipette(AbstractInstrument[PipetteConfigurations]):
|
|
|
225
231
|
def push_out_volume(self) -> float:
|
|
226
232
|
return self._active_tip_settings.default_push_out_volume
|
|
227
233
|
|
|
234
|
+
def is_high_speed_pipette(self) -> bool:
|
|
235
|
+
return Quirks.highSpeed in self._config.quirks
|
|
236
|
+
|
|
228
237
|
def act_as(self, name: PipetteName) -> None:
|
|
229
238
|
"""Reconfigure to act as ``name``. ``name`` must be either the
|
|
230
239
|
actual name of the pipette, or a name in its back-compatibility
|
|
@@ -246,6 +255,7 @@ class Pipette(AbstractInstrument[PipetteConfigurations]):
|
|
|
246
255
|
self._pipette_model.pipette_type,
|
|
247
256
|
self._pipette_model.pipette_channels,
|
|
248
257
|
self._pipette_model.pipette_version,
|
|
258
|
+
self._pipette_model.oem_type,
|
|
249
259
|
)
|
|
250
260
|
self._config_as_dict = self._config.dict()
|
|
251
261
|
|
|
@@ -32,6 +32,7 @@ from opentrons_shared_data.pipette.types import (
|
|
|
32
32
|
)
|
|
33
33
|
from opentrons_shared_data.pipette import (
|
|
34
34
|
pipette_load_name_conversions as pipette_load_name,
|
|
35
|
+
pipette_definition,
|
|
35
36
|
)
|
|
36
37
|
from opentrons_shared_data.robot.types import RobotType
|
|
37
38
|
|
|
@@ -299,8 +300,11 @@ class OT3API(
|
|
|
299
300
|
async def set_system_constraints_for_plunger_acceleration(
|
|
300
301
|
self, mount: OT3Mount, acceleration: float
|
|
301
302
|
) -> None:
|
|
303
|
+
high_speed_pipette = self._pipette_handler.get_pipette(
|
|
304
|
+
mount
|
|
305
|
+
).is_high_speed_pipette()
|
|
302
306
|
self._backend.update_constraints_for_plunger_acceleration(
|
|
303
|
-
mount, acceleration, self._gantry_load
|
|
307
|
+
mount, acceleration, self._gantry_load, high_speed_pipette
|
|
304
308
|
)
|
|
305
309
|
|
|
306
310
|
@contextlib.asynccontextmanager
|
|
@@ -633,10 +637,31 @@ class OT3API(
|
|
|
633
637
|
self._feature_flags.use_old_aspiration_functions,
|
|
634
638
|
)
|
|
635
639
|
self._pipette_handler.hardware_instruments[mount] = p
|
|
640
|
+
|
|
641
|
+
if config is not None:
|
|
642
|
+
self._set_pressure_sensor_available(mount, instrument_config=config)
|
|
643
|
+
|
|
636
644
|
# TODO (lc 12-5-2022) Properly support backwards compatibility
|
|
637
645
|
# when applicable
|
|
638
646
|
return skipped
|
|
639
647
|
|
|
648
|
+
def get_pressure_sensor_available(self, mount: OT3Mount) -> bool:
|
|
649
|
+
pip_axis = Axis.of_main_tool_actuator(mount)
|
|
650
|
+
return self._backend.get_pressure_sensor_available(pip_axis)
|
|
651
|
+
|
|
652
|
+
def _set_pressure_sensor_available(
|
|
653
|
+
self,
|
|
654
|
+
mount: OT3Mount,
|
|
655
|
+
instrument_config: pipette_definition.PipetteConfigurations,
|
|
656
|
+
) -> None:
|
|
657
|
+
pressure_sensor_available = (
|
|
658
|
+
"pressure" in instrument_config.available_sensors.sensors
|
|
659
|
+
)
|
|
660
|
+
pip_axis = Axis.of_main_tool_actuator(mount)
|
|
661
|
+
self._backend.set_pressure_sensor_available(
|
|
662
|
+
pipette_axis=pip_axis, available=pressure_sensor_available
|
|
663
|
+
)
|
|
664
|
+
|
|
640
665
|
async def cache_gripper(self, instrument_data: AttachedGripper) -> bool:
|
|
641
666
|
"""Set up gripper based on scanned information."""
|
|
642
667
|
grip_cal = load_gripper_calibration_offset(instrument_data.get("id"))
|
|
@@ -31,6 +31,9 @@ from opentrons.protocol_engine.errors.exceptions import TipNotAttachedError
|
|
|
31
31
|
from opentrons.protocol_engine.clients import SyncClient as EngineClient
|
|
32
32
|
from opentrons.protocols.api_support.definitions import MAX_SUPPORTED_VERSION
|
|
33
33
|
from opentrons_shared_data.pipette.types import PipetteNameType
|
|
34
|
+
from opentrons_shared_data.errors.exceptions import (
|
|
35
|
+
UnsupportedHardwareCommand,
|
|
36
|
+
)
|
|
34
37
|
from opentrons.protocol_api._nozzle_layout import NozzleLayout
|
|
35
38
|
from opentrons.hardware_control.nozzle_manager import NozzleConfigurationType
|
|
36
39
|
from opentrons.hardware_control.nozzle_manager import NozzleMap
|
|
@@ -86,6 +89,13 @@ class InstrumentCore(AbstractInstrument[WellCore]):
|
|
|
86
89
|
self._liquid_presence_detection = bool(
|
|
87
90
|
self._engine_client.state.pipettes.get_liquid_presence_detection(pipette_id)
|
|
88
91
|
)
|
|
92
|
+
if (
|
|
93
|
+
self._liquid_presence_detection
|
|
94
|
+
and not self._pressure_supported_by_pipette()
|
|
95
|
+
):
|
|
96
|
+
raise UnsupportedHardwareCommand(
|
|
97
|
+
"Pressure sensor not available for this pipette"
|
|
98
|
+
)
|
|
89
99
|
|
|
90
100
|
@property
|
|
91
101
|
def pipette_id(self) -> str:
|
|
@@ -847,6 +857,11 @@ class InstrumentCore(AbstractInstrument[WellCore]):
|
|
|
847
857
|
z_axis = self._engine_client.state.pipettes.get_z_axis(self._pipette_id)
|
|
848
858
|
self._engine_client.execute_command(cmd.HomeParams(axes=[z_axis]))
|
|
849
859
|
|
|
860
|
+
def _pressure_supported_by_pipette(self) -> bool:
|
|
861
|
+
return self._engine_client.state.pipettes.get_pipette_supports_pressure(
|
|
862
|
+
self.pipette_id
|
|
863
|
+
)
|
|
864
|
+
|
|
850
865
|
def detect_liquid_presence(self, well_core: WellCore, loc: Location) -> bool:
|
|
851
866
|
labware_id = well_core.labware_id
|
|
852
867
|
well_name = well_core.get_name()
|
|
@@ -253,6 +253,10 @@ class AbstractInstrument(ABC, Generic[WellCoreType]):
|
|
|
253
253
|
def get_liquid_presence_detection(self) -> bool:
|
|
254
254
|
...
|
|
255
255
|
|
|
256
|
+
@abstractmethod
|
|
257
|
+
def _pressure_supported_by_pipette(self) -> bool:
|
|
258
|
+
...
|
|
259
|
+
|
|
256
260
|
@abstractmethod
|
|
257
261
|
def set_liquid_presence_detection(self, enable: bool) -> None:
|
|
258
262
|
...
|
|
@@ -583,3 +583,6 @@ class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore]):
|
|
|
583
583
|
) -> float:
|
|
584
584
|
"""This will never be called because it was added in API 2.20."""
|
|
585
585
|
assert False, "liquid_probe_without_recovery only supported in API 2.20 & later"
|
|
586
|
+
|
|
587
|
+
def _pressure_supported_by_pipette(self) -> bool:
|
|
588
|
+
return False
|
|
@@ -501,3 +501,6 @@ class LegacyInstrumentCoreSimulator(AbstractInstrument[LegacyWellCore]):
|
|
|
501
501
|
) -> float:
|
|
502
502
|
"""This will never be called because it was added in API 2.20."""
|
|
503
503
|
assert False, "liquid_probe_without_recovery only supported in API 2.20 & later"
|
|
504
|
+
|
|
505
|
+
def _pressure_supported_by_pipette(self) -> bool:
|
|
506
|
+
return False
|
|
@@ -7,6 +7,7 @@ from opentrons_shared_data.errors.exceptions import (
|
|
|
7
7
|
CommandPreconditionViolated,
|
|
8
8
|
CommandParameterLimitViolated,
|
|
9
9
|
UnexpectedTipRemovalError,
|
|
10
|
+
UnsupportedHardwareCommand,
|
|
10
11
|
)
|
|
11
12
|
from opentrons.legacy_broker import LegacyBroker
|
|
12
13
|
from opentrons.hardware_control.dev_types import PipetteDict
|
|
@@ -260,6 +261,7 @@ class InstrumentContext(publisher.CommandPublisher):
|
|
|
260
261
|
and self._96_tip_config_valid()
|
|
261
262
|
and self._core.get_current_volume() == 0
|
|
262
263
|
):
|
|
264
|
+
self._raise_if_pressure_not_supported_by_pipette()
|
|
263
265
|
self.require_liquid_presence(well=well)
|
|
264
266
|
|
|
265
267
|
with publisher.publish_context(
|
|
@@ -1694,6 +1696,8 @@ class InstrumentContext(publisher.CommandPublisher):
|
|
|
1694
1696
|
@liquid_presence_detection.setter
|
|
1695
1697
|
@requires_version(2, 20)
|
|
1696
1698
|
def liquid_presence_detection(self, enable: bool) -> None:
|
|
1699
|
+
if enable:
|
|
1700
|
+
self._raise_if_pressure_not_supported_by_pipette()
|
|
1697
1701
|
self._core.set_liquid_presence_detection(enable)
|
|
1698
1702
|
|
|
1699
1703
|
@property
|
|
@@ -2143,6 +2147,7 @@ class InstrumentContext(publisher.CommandPublisher):
|
|
|
2143
2147
|
.. note::
|
|
2144
2148
|
The pressure sensors for the Flex 8-channel pipette are on channels 1 and 8 (positions A1 and H1). For the Flex 96-channel pipette, the pressure sensors are on channels 1 and 96 (positions A1 and H12). Other channels on multi-channel pipettes do not have sensors and cannot detect liquid.
|
|
2145
2149
|
"""
|
|
2150
|
+
self._raise_if_pressure_not_supported_by_pipette()
|
|
2146
2151
|
loc = well.top()
|
|
2147
2152
|
self._96_tip_config_valid()
|
|
2148
2153
|
return self._core.detect_liquid_presence(well._core, loc)
|
|
@@ -2156,6 +2161,7 @@ class InstrumentContext(publisher.CommandPublisher):
|
|
|
2156
2161
|
.. note::
|
|
2157
2162
|
The pressure sensors for the Flex 8-channel pipette are on channels 1 and 8 (positions A1 and H1). For the Flex 96-channel pipette, the pressure sensors are on channels 1 and 96 (positions A1 and H12). Other channels on multi-channel pipettes do not have sensors and cannot detect liquid.
|
|
2158
2163
|
"""
|
|
2164
|
+
self._raise_if_pressure_not_supported_by_pipette()
|
|
2159
2165
|
loc = well.top()
|
|
2160
2166
|
self._96_tip_config_valid()
|
|
2161
2167
|
self._core.liquid_probe_with_recovery(well._core, loc)
|
|
@@ -2170,7 +2176,7 @@ class InstrumentContext(publisher.CommandPublisher):
|
|
|
2170
2176
|
|
|
2171
2177
|
This is intended for Opentrons internal use only and is not a guaranteed API.
|
|
2172
2178
|
"""
|
|
2173
|
-
|
|
2179
|
+
self._raise_if_pressure_not_supported_by_pipette()
|
|
2174
2180
|
loc = well.top()
|
|
2175
2181
|
self._96_tip_config_valid()
|
|
2176
2182
|
height = self._core.liquid_probe_without_recovery(well._core, loc)
|
|
@@ -2192,6 +2198,12 @@ class InstrumentContext(publisher.CommandPublisher):
|
|
|
2192
2198
|
)
|
|
2193
2199
|
# SINGLE, QUADRANT and ALL are supported by all pipettes
|
|
2194
2200
|
|
|
2201
|
+
def _raise_if_pressure_not_supported_by_pipette(self) -> None:
|
|
2202
|
+
if not self._core._pressure_supported_by_pipette():
|
|
2203
|
+
raise UnsupportedHardwareCommand(
|
|
2204
|
+
"Pressure sensor not available for this pipette"
|
|
2205
|
+
)
|
|
2206
|
+
|
|
2195
2207
|
def _handle_aspirate_target(
|
|
2196
2208
|
self, target: validation.ValidTarget
|
|
2197
2209
|
) -> tuple[types.Location, Optional[labware.Well], Optional[bool]]:
|
|
@@ -63,6 +63,7 @@ _PIPETTE_NAMES_MAP = {
|
|
|
63
63
|
"flex_8channel_50": PipetteNameType.P50_MULTI_FLEX,
|
|
64
64
|
"flex_1channel_1000": PipetteNameType.P1000_SINGLE_FLEX,
|
|
65
65
|
"flex_8channel_1000": PipetteNameType.P1000_MULTI_FLEX,
|
|
66
|
+
"flex_8channel_1000_em": PipetteNameType.P1000_MULTI_EM,
|
|
66
67
|
"flex_96channel_1000": PipetteNameType.P1000_96,
|
|
67
68
|
}
|
|
68
69
|
|
|
@@ -16,6 +16,7 @@ from opentrons.protocol_engine.errors.exceptions import (
|
|
|
16
16
|
from opentrons.types import MountType
|
|
17
17
|
from opentrons_shared_data.errors.exceptions import (
|
|
18
18
|
PipetteLiquidNotFoundError,
|
|
19
|
+
UnsupportedHardwareCommand,
|
|
19
20
|
)
|
|
20
21
|
|
|
21
22
|
from ..types import DeckPoint
|
|
@@ -113,6 +114,13 @@ async def _execute_common(
|
|
|
113
114
|
well_name = params.wellName
|
|
114
115
|
|
|
115
116
|
state_update = update_types.StateUpdate()
|
|
117
|
+
if (
|
|
118
|
+
"pressure"
|
|
119
|
+
not in state_view.pipettes.get_config(pipette_id).available_sensors.sensors
|
|
120
|
+
):
|
|
121
|
+
raise UnsupportedHardwareCommand(
|
|
122
|
+
"Pressure sensor not available for this pipette"
|
|
123
|
+
)
|
|
116
124
|
|
|
117
125
|
# May raise TipNotAttachedError.
|
|
118
126
|
aspirated_volume = state_view.pipettes.get_aspirated_volume(pipette_id)
|
|
@@ -67,6 +67,7 @@ class LoadedStaticPipetteData:
|
|
|
67
67
|
back_left_corner_offset: Point
|
|
68
68
|
front_right_corner_offset: Point
|
|
69
69
|
pipette_lld_settings: Optional[Dict[str, Dict[str, float]]]
|
|
70
|
+
available_sensors: pipette_definition.AvailableSensorDefinition
|
|
70
71
|
|
|
71
72
|
|
|
72
73
|
class VirtualPipetteDataProvider:
|
|
@@ -95,6 +96,7 @@ class VirtualPipetteDataProvider:
|
|
|
95
96
|
config.pipette_type,
|
|
96
97
|
config.channels,
|
|
97
98
|
config.version,
|
|
99
|
+
pip_types.PipetteOEMType.OT,
|
|
98
100
|
)
|
|
99
101
|
new_nozzle_manager = NozzleConfigurationManager.build_from_config(
|
|
100
102
|
config, valid_nozzle_maps
|
|
@@ -127,6 +129,7 @@ class VirtualPipetteDataProvider:
|
|
|
127
129
|
pipette_model.pipette_type,
|
|
128
130
|
pipette_model.pipette_channels,
|
|
129
131
|
pipette_model.pipette_version,
|
|
132
|
+
pipette_model.oem_type,
|
|
130
133
|
)
|
|
131
134
|
|
|
132
135
|
liquid_class = pipette_definition.liquid_class_for_volume_between_default_and_defaultlowvolume(
|
|
@@ -160,6 +163,7 @@ class VirtualPipetteDataProvider:
|
|
|
160
163
|
pipette_model.pipette_type,
|
|
161
164
|
pipette_model.pipette_channels,
|
|
162
165
|
pipette_model.pipette_version,
|
|
166
|
+
pipette_model.oem_type,
|
|
163
167
|
)
|
|
164
168
|
|
|
165
169
|
def _get_virtual_pipette_static_config_by_model( # noqa: C901
|
|
@@ -176,6 +180,7 @@ class VirtualPipetteDataProvider:
|
|
|
176
180
|
pipette_model.pipette_type,
|
|
177
181
|
pipette_model.pipette_channels,
|
|
178
182
|
pipette_model.pipette_version,
|
|
183
|
+
pipette_model.oem_type,
|
|
179
184
|
)
|
|
180
185
|
try:
|
|
181
186
|
tip_type = pip_types.PipetteTipType(
|
|
@@ -192,6 +197,7 @@ class VirtualPipetteDataProvider:
|
|
|
192
197
|
pipette_model.pipette_type,
|
|
193
198
|
pipette_model.pipette_channels,
|
|
194
199
|
pipette_model.pipette_version,
|
|
200
|
+
pipette_model.oem_type,
|
|
195
201
|
)
|
|
196
202
|
if pipette_id not in self._nozzle_manager_layout_by_id:
|
|
197
203
|
nozzle_manager = NozzleConfigurationManager.build_from_config(
|
|
@@ -280,6 +286,8 @@ class VirtualPipetteDataProvider:
|
|
|
280
286
|
pip_front_right[0], pip_front_right[1], pip_front_right[2]
|
|
281
287
|
),
|
|
282
288
|
pipette_lld_settings=config.lld_settings,
|
|
289
|
+
available_sensors=config.available_sensors
|
|
290
|
+
or pipette_definition.AvailableSensorDefinition(sensors=[]),
|
|
283
291
|
)
|
|
284
292
|
|
|
285
293
|
def get_virtual_pipette_static_config(
|
|
@@ -298,6 +306,11 @@ def get_pipette_static_config(
|
|
|
298
306
|
"""Get the config for a pipette, given the state/config object from the HW API."""
|
|
299
307
|
back_left_offset = pipette_dict["pipette_bounding_box_offsets"].back_left_corner
|
|
300
308
|
front_right_offset = pipette_dict["pipette_bounding_box_offsets"].front_right_corner
|
|
309
|
+
available_sensors = (
|
|
310
|
+
pipette_dict["available_sensors"]
|
|
311
|
+
if "available_sensors" in pipette_dict.keys()
|
|
312
|
+
else pipette_definition.AvailableSensorDefinition(sensors=[])
|
|
313
|
+
)
|
|
301
314
|
return LoadedStaticPipetteData(
|
|
302
315
|
model=pipette_dict["model"],
|
|
303
316
|
display_name=pipette_dict["display_name"],
|
|
@@ -327,6 +340,7 @@ def get_pipette_static_config(
|
|
|
327
340
|
front_right_offset[0], front_right_offset[1], front_right_offset[2]
|
|
328
341
|
),
|
|
329
342
|
pipette_lld_settings=pipette_dict["lld_settings"],
|
|
343
|
+
available_sensors=available_sensors,
|
|
330
344
|
)
|
|
331
345
|
|
|
332
346
|
|
|
@@ -98,6 +98,7 @@ class StaticPipetteConfig:
|
|
|
98
98
|
bounding_nozzle_offsets: BoundingNozzlesOffsets
|
|
99
99
|
default_nozzle_map: NozzleMap # todo(mm, 2024-10-14): unused, remove?
|
|
100
100
|
lld_settings: Optional[Dict[str, Dict[str, float]]]
|
|
101
|
+
available_sensors: pipette_definition.AvailableSensorDefinition
|
|
101
102
|
|
|
102
103
|
|
|
103
104
|
@dataclasses.dataclass
|
|
@@ -292,6 +293,7 @@ class PipetteStore(HasState[PipetteState], HandlesActions):
|
|
|
292
293
|
),
|
|
293
294
|
default_nozzle_map=config.nozzle_map,
|
|
294
295
|
lld_settings=config.pipette_lld_settings,
|
|
296
|
+
available_sensors=config.available_sensors,
|
|
295
297
|
)
|
|
296
298
|
self._state.flow_rates_by_id[
|
|
297
299
|
state_update.pipette_config.pipette_id
|
|
@@ -723,6 +725,13 @@ class PipetteView(HasState[PipetteState]):
|
|
|
723
725
|
pip_front_left_bound,
|
|
724
726
|
)
|
|
725
727
|
|
|
728
|
+
def get_pipette_supports_pressure(self, pipette_id: str) -> bool:
|
|
729
|
+
"""Return if this pipette supports a pressure sensor."""
|
|
730
|
+
return (
|
|
731
|
+
"pressure"
|
|
732
|
+
in self._state.static_config_by_id[pipette_id].available_sensors.sensors
|
|
733
|
+
)
|
|
734
|
+
|
|
726
735
|
def get_liquid_presence_detection(self, pipette_id: str) -> bool:
|
|
727
736
|
"""Determine if liquid presence detection is enabled for this pipette."""
|
|
728
737
|
try:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: opentrons
|
|
3
|
-
Version: 8.
|
|
3
|
+
Version: 8.3.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.
|
|
24
|
+
Requires-Dist: opentrons-shared-data ==8.3.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.
|
|
37
|
+
Requires-Dist: opentrons-hardware[flex] ==8.3.0a0 ; extra == 'flex-hardware'
|
|
38
38
|
Provides-Extra: ot2-hardware
|
|
39
|
-
Requires-Dist: opentrons-hardware ==8.
|
|
39
|
+
Requires-Dist: opentrons-hardware ==8.3.0a0 ; extra == 'ot2-hardware'
|
|
40
40
|
|
|
41
41
|
.. _Full API Documentation: http://docs.opentrons.com
|
|
42
42
|
|
|
@@ -34,7 +34,7 @@ opentrons/cli/analyze.py,sha256=mKDVmrGgXtAHNN8im5XI-WGqbbXf7xeWN5tIqRgOcNo,1435
|
|
|
34
34
|
opentrons/config/__init__.py,sha256=B4kGZSsy6ESki_-K33sd0mRNrN_h2_bcZL8zEDOxHEg,21251
|
|
35
35
|
opentrons/config/advanced_settings.py,sha256=TAnzrGuZhSCokYii2efgW6SeJuAST2xyxO7hNlFxVUk,26560
|
|
36
36
|
opentrons/config/defaults_ot2.py,sha256=_l63QNW0aWTh0HGZcgF592ETJg8-W4M0XrQbbzkAPjA,6031
|
|
37
|
-
opentrons/config/defaults_ot3.py,sha256=
|
|
37
|
+
opentrons/config/defaults_ot3.py,sha256=T2NlloDzdwbZBM4Mev2cj7BWcJQbbYOb2OPonvi2gfc,14750
|
|
38
38
|
opentrons/config/feature_flags.py,sha256=aDWEOEQn9qQ0JcPpIgKq7IHLegbt2d7bMKSkt_5DbKo,2511
|
|
39
39
|
opentrons/config/gripper_config.py,sha256=ch3PtyP96KOCQi6otf4U6Okt04JrEYhqpQM0SkmP_cA,1721
|
|
40
40
|
opentrons/config/reset.py,sha256=5NNCfdUfV9_9CVLuXS8Ita1hrCbHbaSwZ7VnmyjBOEQ,6407
|
|
@@ -93,14 +93,14 @@ opentrons/hardware_control/__main__.py,sha256=DnlYdphZKLHiLCeXmnMDer6CclhberfTk_
|
|
|
93
93
|
opentrons/hardware_control/adapters.py,sha256=mm-gumoaF7CFrP0ad6W4xafbJRq6RaOD0GffSibWR-Q,3888
|
|
94
94
|
opentrons/hardware_control/api.py,sha256=Lv-Agio_nQ3axGjMbyXckkQRkl9rYfOV8L_Ul8bXGmY,50909
|
|
95
95
|
opentrons/hardware_control/constants.py,sha256=Ku-XABo7AN9JQ0tef8oPk-JlUuhQQLeP9S0h7kx5GEA,227
|
|
96
|
-
opentrons/hardware_control/dev_types.py,sha256=
|
|
96
|
+
opentrons/hardware_control/dev_types.py,sha256=P9AVjZ4yBN-XLOzRjoB3gS2A3MZ7dZRomo77K40cGbk,3379
|
|
97
97
|
opentrons/hardware_control/errors.py,sha256=NMF5_AvX22ENTHPpUlElgF-0aeaxEhYXnOq2lfIzuiM,1433
|
|
98
98
|
opentrons/hardware_control/execution_manager.py,sha256=WG3NF1OJgorAmRpkx8BRnqFeQsPUQ5w7H1kVK7pC-7A,5984
|
|
99
99
|
opentrons/hardware_control/module_control.py,sha256=u0RpbOgr5pV5exgKg3qvNQdwdVuy_9QkPpMZtWthsm8,12074
|
|
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=
|
|
103
|
+
opentrons/hardware_control/ot3api.py,sha256=i8Ei3rYwESkkLagdhnqV7dALkv1lDrv9SmJqukw4gIg,119009
|
|
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
|
|
@@ -113,10 +113,10 @@ opentrons/hardware_control/backends/__init__.py,sha256=u5Dg3AFZuvDV7hFqJ8I4F9D1d
|
|
|
113
113
|
opentrons/hardware_control/backends/controller.py,sha256=MOVMq9s1rY_jHhajHB1hQ1MgXXyY54-gMrrvAuMsOFg,14622
|
|
114
114
|
opentrons/hardware_control/backends/errors.py,sha256=ZiVP16exHMTWWOajxffnXEqI6NNfeTw-4RkhXE0EBJA,249
|
|
115
115
|
opentrons/hardware_control/backends/estop_state.py,sha256=_GYjI6OaD3CZNduWV2_RVeOtQ4K_Fg-SP8yU01ENhCY,6554
|
|
116
|
-
opentrons/hardware_control/backends/flex_protocol.py,sha256=
|
|
117
|
-
opentrons/hardware_control/backends/ot3controller.py,sha256=
|
|
118
|
-
opentrons/hardware_control/backends/ot3simulator.py,sha256=
|
|
119
|
-
opentrons/hardware_control/backends/ot3utils.py,sha256=
|
|
116
|
+
opentrons/hardware_control/backends/flex_protocol.py,sha256=fn18nbNYYtyicmzT12Zb4DM-6Dqam9MPnwz8fYnAwHo,12300
|
|
117
|
+
opentrons/hardware_control/backends/ot3controller.py,sha256=EgNDamZwJN3pF_3q-yAI9tXXS1sdoEuv_1lggwNrCV4,62302
|
|
118
|
+
opentrons/hardware_control/backends/ot3simulator.py,sha256=kPXTh8OtTPB0iB56X_MIrmQ4p_fTmQMLFZLP_iqcPv4,29708
|
|
119
|
+
opentrons/hardware_control/backends/ot3utils.py,sha256=Olxqly0LzQXTQKTvNuWbao9wLb3Csu5cqUFtxgQfGIw,23493
|
|
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
|
|
@@ -151,13 +151,13 @@ opentrons/hardware_control/instruments/__init__.py,sha256=wS7omegQYF7BQVmd-h4U6A
|
|
|
151
151
|
opentrons/hardware_control/instruments/instrument_abc.py,sha256=UqKb7_8E4ivlTV2tEXcnfY8AdyVaHcrRAI4LhXSFSrM,1074
|
|
152
152
|
opentrons/hardware_control/instruments/ot2/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
153
153
|
opentrons/hardware_control/instruments/ot2/instrument_calibration.py,sha256=llfCslA5iQp978S5KEOGH-SbFzZN7LY7PvDZnDWYUg8,4730
|
|
154
|
-
opentrons/hardware_control/instruments/ot2/pipette.py,sha256=
|
|
154
|
+
opentrons/hardware_control/instruments/ot2/pipette.py,sha256=uUiOQX1KNP-wzSDM4vSQ6oqK1655CKSxWi7QhCPy8Z8,28706
|
|
155
155
|
opentrons/hardware_control/instruments/ot2/pipette_handler.py,sha256=pu_pEdlrmStUfbJS8Yq4HuA7PfNZdbk_TEbxx3lrVIU,37673
|
|
156
156
|
opentrons/hardware_control/instruments/ot3/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
157
157
|
opentrons/hardware_control/instruments/ot3/gripper.py,sha256=h90Me-spIO4myXF_afgf4Fsjw_4uQsyMwwWxAD1gQ1U,13706
|
|
158
158
|
opentrons/hardware_control/instruments/ot3/gripper_handler.py,sha256=GVz6QreaYSo-Vt2b-NHnMV2ehjlDxJCWaqq5ufQYCYM,6055
|
|
159
159
|
opentrons/hardware_control/instruments/ot3/instrument_calibration.py,sha256=9ERAxnUHc2BBoLPloLwGoNDqssKsjzBQv1cOjwp8umk,5432
|
|
160
|
-
opentrons/hardware_control/instruments/ot3/pipette.py,sha256=
|
|
160
|
+
opentrons/hardware_control/instruments/ot3/pipette.py,sha256=oygUZaCVRfV58NuLAK-rJa0VdNSVBYuj53JXw9WDbaw,32826
|
|
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
163
|
opentrons/hardware_control/modules/absorbance_reader.py,sha256=Z6ikQiySpDi4tP1VxT-Q0WCNLUqfyzJ-iw7B7t-CUNI,13573
|
|
@@ -220,17 +220,17 @@ opentrons/protocol_api/config.py,sha256=r9lyvXjagTX_g3q5FGURPpcz2IA9sSF7Oa_1mKx-
|
|
|
220
220
|
opentrons/protocol_api/create_protocol_context.py,sha256=wwsZje0L__oDnu1Yrihau320_f-ASloR9eL1QCtkOh8,7612
|
|
221
221
|
opentrons/protocol_api/deck.py,sha256=94vFceg1SC1bAGd7TvC1ZpYwnJR-VlzurEZ6jkacYeg,8910
|
|
222
222
|
opentrons/protocol_api/disposal_locations.py,sha256=NRiSGmDR0LnbyEkWSOM-o64uR2fUoB1NWJG7Y7SsJSs,7920
|
|
223
|
-
opentrons/protocol_api/instrument_context.py,sha256=
|
|
223
|
+
opentrons/protocol_api/instrument_context.py,sha256=FvzLDaHzLI9XwO9Kq-8TanfYdJN4iICwHhYPNK__zZ0,97881
|
|
224
224
|
opentrons/protocol_api/labware.py,sha256=qwjAO1Au9Ujx5jyGNQ0-HLDBOXUygnXNSuv5696tGCw,48177
|
|
225
225
|
opentrons/protocol_api/module_contexts.py,sha256=qubmR4LrLwP8e-ONKQYBlLTRQ5gpB-H25fE3SV70sKI,42104
|
|
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
|
|
229
|
-
opentrons/protocol_api/validation.py,sha256=
|
|
229
|
+
opentrons/protocol_api/validation.py,sha256=wtmjgcn04q4SMBvtPOc7gRSTSVPN5kt0261hqLPOvyU,18458
|
|
230
230
|
opentrons/protocol_api/core/__init__.py,sha256=-g74o8OtBB0LmmOvwkRvPgrHt7fF7T8FRHDj-x_-Onk,736
|
|
231
231
|
opentrons/protocol_api/core/common.py,sha256=sXWlP8F4ZAEGcDh1WuavrVxkoi-FultBbpY6JW0_9ZY,1029
|
|
232
232
|
opentrons/protocol_api/core/core_map.py,sha256=gq3CIYPxuPvozf8yj8FprqBfs3e4ZJGQ6s0ViPbwV08,1757
|
|
233
|
-
opentrons/protocol_api/core/instrument.py,sha256=
|
|
233
|
+
opentrons/protocol_api/core/instrument.py,sha256=BLJbOwQCtQcwdI5YeHf067pzny-pEjRTTFTD2Aq3EwI,9561
|
|
234
234
|
opentrons/protocol_api/core/labware.py,sha256=SuHs0dP28F5pMWzeU1Ih0zzuD8h9Doyvmu2xIl14g7g,3946
|
|
235
235
|
opentrons/protocol_api/core/module.py,sha256=p02IstVzfSqTpwbfiCYkPv_xpeb78Hi__PQKJPePxNs,12548
|
|
236
236
|
opentrons/protocol_api/core/protocol.py,sha256=YUVZfbZvbRLOCLNZN5UKvmw8pwobiuL114GdMpmoLu4,7311
|
|
@@ -239,7 +239,7 @@ opentrons/protocol_api/core/well_grid.py,sha256=BU28DKaBgEU_JdZ6pEzrwNxmuh6TkO4z
|
|
|
239
239
|
opentrons/protocol_api/core/engine/__init__.py,sha256=B_5T7zgkWDb1mXPg4NbT-wBkQaK-WVokMMnJRNu7xiM,582
|
|
240
240
|
opentrons/protocol_api/core/engine/deck_conflict.py,sha256=0viwOidafVd0XhS8C7V72i68-ZYzHfDUNeqGozTA1G8,12012
|
|
241
241
|
opentrons/protocol_api/core/engine/exceptions.py,sha256=aZgNrmYEeuPZm21nX_KZYtvyjv5h_zPjxxgPkEV7_bw,725
|
|
242
|
-
opentrons/protocol_api/core/engine/instrument.py,sha256=
|
|
242
|
+
opentrons/protocol_api/core/engine/instrument.py,sha256=5MtrHVEGDl29HiRtPNcYRnKsV3ha8dwSm8NT__CRmJw,36588
|
|
243
243
|
opentrons/protocol_api/core/engine/labware.py,sha256=ra6leDHW9sEmvjPJIIx8iMVVIeFuAyJlLv3H92Ww7TM,7568
|
|
244
244
|
opentrons/protocol_api/core/engine/load_labware_params.py,sha256=cwbmGyYp5ZOyANtEm6KKwT_n8fnYc5RysBst9nRh7Ls,4607
|
|
245
245
|
opentrons/protocol_api/core/engine/module_core.py,sha256=TWqMqRgekBISMOEtlveDByJQI6JfSu-rvYOnqQbTgGY,26923
|
|
@@ -252,7 +252,7 @@ opentrons/protocol_api/core/engine/well.py,sha256=9rbu0YbCnIz9j7OU1T2LEIWcdCclCI
|
|
|
252
252
|
opentrons/protocol_api/core/legacy/__init__.py,sha256=_9jCJNKG3SlS_vljVu8HHkZmtLf4F-f-JHALLF5d5go,401
|
|
253
253
|
opentrons/protocol_api/core/legacy/deck.py,sha256=qHqcGo-Kdkl9L1aOE0pwrm9tsAnwkXbt4rIOr_VEP-s,13955
|
|
254
254
|
opentrons/protocol_api/core/legacy/labware_offset_provider.py,sha256=uNNeHecIz_A9u19QalpVKF7pxloHqLg27EFcD9dbYtc,3735
|
|
255
|
-
opentrons/protocol_api/core/legacy/legacy_instrument_core.py,sha256=
|
|
255
|
+
opentrons/protocol_api/core/legacy/legacy_instrument_core.py,sha256=UQl2VvtAhKN6bMqa_QjDgf5bFhRcSkLrXsCQhMWFWHg,22069
|
|
256
256
|
opentrons/protocol_api/core/legacy/legacy_labware_core.py,sha256=0LeoH2vIFTuPzXFdSSeddIWcnjdMRTPpOAEsuvLDtBU,7901
|
|
257
257
|
opentrons/protocol_api/core/legacy/legacy_module_core.py,sha256=tUhj88NKBMjCmCg6wjh1e2HX4d5hxjh8ZeJiYXaTaGY,23111
|
|
258
258
|
opentrons/protocol_api/core/legacy/legacy_protocol_core.py,sha256=zoD5kqOZ4TUdZeFx2OdRLhMq9M9i7yATdqhynR6KNcM,21490
|
|
@@ -261,7 +261,7 @@ opentrons/protocol_api/core/legacy/load_info.py,sha256=j-fzoUKwvXNS_5CQsE43XI5YO
|
|
|
261
261
|
opentrons/protocol_api/core/legacy/module_geometry.py,sha256=wbWeHomppdCDmp_nKrnNWbnRAapOamkhFMnaoY7ShTw,20886
|
|
262
262
|
opentrons/protocol_api/core/legacy/well_geometry.py,sha256=dCsDIpMbaIpb0AW_VrnSIJdRYi8ombyMpaA7n1X46Jg,4643
|
|
263
263
|
opentrons/protocol_api/core/legacy_simulator/__init__.py,sha256=m9bLHGDJ6LSYC2WPm8tpOuu0zWSOPIrlybQgjRQBw9k,647
|
|
264
|
-
opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py,sha256=
|
|
264
|
+
opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py,sha256=f5eGPuNwihDoYt-EOCWfAtHLqf3Zqsxu_iawuiSxVJo,18731
|
|
265
265
|
opentrons/protocol_api/core/legacy_simulator/legacy_protocol_core.py,sha256=28HrrHzeUfnGKXpZqQ-VM8WbPiadqVhKj2S9y33q6Lo,2910
|
|
266
266
|
opentrons/protocol_engine/__init__.py,sha256=35cWIWtg_0OO-9v6sgWNuiJ5siDM9y77K3KsuCY69K4,3253
|
|
267
267
|
opentrons/protocol_engine/create_protocol_engine.py,sha256=tfDIsC7_JKlRiCXPB_8tuxRsssU6o0ViRmWbGPtX9QA,7582
|
|
@@ -298,7 +298,7 @@ opentrons/protocol_engine/commands/generate_command_schema.py,sha256=w5RsTJV4HtF
|
|
|
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
|
|
300
300
|
opentrons/protocol_engine/commands/home.py,sha256=pmiul9vLcpVijHAOBwzkdHulW5tBCEiEcNey3bCXdAE,3075
|
|
301
|
-
opentrons/protocol_engine/commands/liquid_probe.py,sha256=
|
|
301
|
+
opentrons/protocol_engine/commands/liquid_probe.py,sha256=HjHdUtqj_A81KYA8zCU1uDyNLdpu0ntAcU4pnYINX-4,12332
|
|
302
302
|
opentrons/protocol_engine/commands/load_labware.py,sha256=UQSGj0dbfnkGjYxwPrQkVm2CNyrJYemu8L7g2xDhlt0,7584
|
|
303
303
|
opentrons/protocol_engine/commands/load_liquid.py,sha256=MIwzfqhzKR71DEALKvgcnykp1CbJ3kkssClLrT7jPrY,2781
|
|
304
304
|
opentrons/protocol_engine/commands/load_module.py,sha256=Vgu_O64tfDNgqAhVlVcjVrejt1TeKr_8ziar7L17-yw,7499
|
|
@@ -399,7 +399,7 @@ opentrons/protocol_engine/resources/labware_validation.py,sha256=3Rc--uqHJ6dSoT8
|
|
|
399
399
|
opentrons/protocol_engine/resources/model_utils.py,sha256=C3OHUi-OtuFUm3dS5rApSU3EJ0clnaCZEyBku5sTjzA,941
|
|
400
400
|
opentrons/protocol_engine/resources/module_data_provider.py,sha256=fU4l1Wkeb1odW6XekvC0_SS0KjzAOcHPJQ4dLMp74NU,1553
|
|
401
401
|
opentrons/protocol_engine/resources/ot3_validation.py,sha256=0x81JoZBXcj2xUVcOF7v5ETc8y5T_sbs-jTPxuSnooE,744
|
|
402
|
-
opentrons/protocol_engine/resources/pipette_data_provider.py,sha256=
|
|
402
|
+
opentrons/protocol_engine/resources/pipette_data_provider.py,sha256=FRKp7lRl6jaOUK-aQBcf2W8rjjAwsJjIcqe-AWClr-8,15416
|
|
403
403
|
opentrons/protocol_engine/state/__init__.py,sha256=hDdA4GjXbi9h7K_FMbQGT9tOw3YtRNn5LIryMdkotS8,36
|
|
404
404
|
opentrons/protocol_engine/state/_abstract_store.py,sha256=b5cqKZhI6ERZj6gyL0kDutD6ogdQngR3T-JmPATvhi8,631
|
|
405
405
|
opentrons/protocol_engine/state/_move_types.py,sha256=zSQj_qYHBi7_-wrpaZBKmX_O-wNZCpLZkCzagOwI-zY,2132
|
|
@@ -414,7 +414,7 @@ opentrons/protocol_engine/state/labware.py,sha256=Ns_GoUKxL55P6J2YEch5GZCVvTbQZS
|
|
|
414
414
|
opentrons/protocol_engine/state/liquids.py,sha256=TwchzB7xNt7CAd3wX3BA_5DXrQhGwj_uFQsv0FWOXXk,1886
|
|
415
415
|
opentrons/protocol_engine/state/modules.py,sha256=NCx6s9WhFnv-XXIcnfnJ_rqLelI7pzqIv8v5ACrG2xE,54110
|
|
416
416
|
opentrons/protocol_engine/state/motion.py,sha256=1KEm1HXdkuFKNe2lElZnNfJedml4afMFnmcDvG-3fLA,14937
|
|
417
|
-
opentrons/protocol_engine/state/pipettes.py,sha256=
|
|
417
|
+
opentrons/protocol_engine/state/pipettes.py,sha256=2PTtV1vkadi8m3XzjXomnhKSs_e6tfsxWaoAkYHPkNw,31260
|
|
418
418
|
opentrons/protocol_engine/state/state.py,sha256=HbkGfTLYNPlb9yu2sCi4UOJQrgXedi3w8xbYc0QCn-w,14550
|
|
419
419
|
opentrons/protocol_engine/state/state_summary.py,sha256=vTA4MLVtObroLSVEQFKspwE9hkKLfNHKacUA5QVIF5c,1058
|
|
420
420
|
opentrons/protocol_engine/state/tips.py,sha256=_1LZncAdhCavaKs2NBFKQAmTyExIorQw7vHOqomeb8g,20993
|
|
@@ -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.
|
|
516
|
-
opentrons-8.
|
|
517
|
-
opentrons-8.
|
|
518
|
-
opentrons-8.
|
|
519
|
-
opentrons-8.
|
|
520
|
-
opentrons-8.
|
|
515
|
+
opentrons-8.3.0a0.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
516
|
+
opentrons-8.3.0a0.dist-info/METADATA,sha256=9iQE3Sd4b1FTISPSJqyqy7PcntPkVpftdiMDRPi8ZdI,5019
|
|
517
|
+
opentrons-8.3.0a0.dist-info/WHEEL,sha256=_4XEmVmaBFWtekSGrbfOGNjC2I5lUr0lZSRblBllIFA,109
|
|
518
|
+
opentrons-8.3.0a0.dist-info/entry_points.txt,sha256=fTa6eGCYkvOtv0ov-KVE8LLGetgb35LQLF9x85OWPVw,106
|
|
519
|
+
opentrons-8.3.0a0.dist-info/top_level.txt,sha256=wk6whpbMZdBQpcK0Fg0YVfUGrAgVOFON7oQAhOMGMW8,10
|
|
520
|
+
opentrons-8.3.0a0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|