opentrons 8.4.0a13__py2.py3-none-any.whl → 8.5.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.
Potentially problematic release.
This version of opentrons might be problematic. Click here for more details.
- opentrons/config/defaults_ot3.py +1 -1
- opentrons/legacy_commands/commands.py +16 -4
- opentrons/legacy_commands/robot_commands.py +51 -0
- opentrons/legacy_commands/types.py +91 -2
- opentrons/protocol_api/_liquid.py +60 -15
- opentrons/protocol_api/_liquid_properties.py +137 -90
- opentrons/protocol_api/_transfer_liquid_validation.py +10 -6
- opentrons/protocol_api/core/engine/instrument.py +172 -75
- opentrons/protocol_api/core/engine/protocol.py +13 -14
- opentrons/protocol_api/core/engine/robot.py +2 -2
- opentrons/protocol_api/core/engine/transfer_components_executor.py +157 -126
- opentrons/protocol_api/core/engine/well.py +16 -0
- opentrons/protocol_api/core/instrument.py +2 -2
- opentrons/protocol_api/core/legacy/legacy_instrument_core.py +2 -2
- opentrons/protocol_api/core/legacy/legacy_protocol_core.py +1 -1
- opentrons/protocol_api/core/legacy/legacy_well_core.py +8 -0
- opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py +2 -2
- opentrons/protocol_api/core/protocol.py +2 -2
- opentrons/protocol_api/core/well.py +8 -0
- opentrons/protocol_api/instrument_context.py +377 -86
- opentrons/protocol_api/labware.py +10 -0
- opentrons/protocol_api/protocol_context.py +79 -4
- opentrons/protocol_api/robot_context.py +48 -6
- opentrons/protocol_api/validation.py +15 -8
- opentrons/protocol_engine/commands/command_unions.py +10 -10
- opentrons/protocol_engine/commands/generate_command_schema.py +1 -1
- opentrons/protocol_engine/commands/get_next_tip.py +2 -2
- opentrons/protocol_engine/commands/pick_up_tip.py +9 -3
- opentrons/protocol_engine/commands/robot/__init__.py +20 -20
- opentrons/protocol_engine/commands/robot/close_gripper_jaw.py +34 -24
- opentrons/protocol_engine/commands/robot/open_gripper_jaw.py +29 -20
- opentrons/protocol_engine/commands/seal_pipette_to_tip.py +1 -1
- opentrons/protocol_engine/commands/unsafe/__init__.py +17 -1
- opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py +1 -2
- opentrons/protocol_engine/execution/labware_movement.py +9 -2
- opentrons/protocol_engine/execution/movement.py +12 -9
- opentrons/protocol_engine/execution/queue_worker.py +8 -1
- opentrons/protocol_engine/execution/thermocycler_movement_flagger.py +52 -19
- opentrons/protocol_engine/state/_well_math.py +2 -2
- opentrons/protocol_engine/state/commands.py +14 -28
- opentrons/protocol_engine/state/frustum_helpers.py +11 -7
- opentrons/protocol_engine/state/modules.py +1 -1
- opentrons/protocol_engine/state/pipettes.py +8 -0
- opentrons/protocol_engine/state/tips.py +46 -83
- opentrons/protocol_engine/state/update_types.py +8 -23
- opentrons/protocol_runner/legacy_command_mapper.py +11 -4
- opentrons/protocol_runner/run_orchestrator.py +1 -1
- opentrons/protocols/advanced_control/transfers/common.py +54 -11
- opentrons/protocols/advanced_control/transfers/transfer_liquid_utils.py +1 -1
- opentrons/protocols/api_support/definitions.py +1 -1
- opentrons/types.py +6 -6
- {opentrons-8.4.0a13.dist-info → opentrons-8.5.0a1.dist-info}/METADATA +4 -4
- {opentrons-8.4.0a13.dist-info → opentrons-8.5.0a1.dist-info}/RECORD +57 -56
- {opentrons-8.4.0a13.dist-info → opentrons-8.5.0a1.dist-info}/LICENSE +0 -0
- {opentrons-8.4.0a13.dist-info → opentrons-8.5.0a1.dist-info}/WHEEL +0 -0
- {opentrons-8.4.0a13.dist-info → opentrons-8.5.0a1.dist-info}/entry_points.txt +0 -0
- {opentrons-8.4.0a13.dist-info → opentrons-8.5.0a1.dist-info}/top_level.txt +0 -0
|
@@ -346,6 +346,16 @@ class Well:
|
|
|
346
346
|
"""Get the current liquid volume in a well."""
|
|
347
347
|
return self._core.get_liquid_volume()
|
|
348
348
|
|
|
349
|
+
@requires_version(2, 24)
|
|
350
|
+
def volume_from_height(self, height: LiquidTrackingType) -> LiquidTrackingType:
|
|
351
|
+
"""Return the volume contained in a well at any height."""
|
|
352
|
+
return self._core.volume_from_height(height)
|
|
353
|
+
|
|
354
|
+
@requires_version(2, 24)
|
|
355
|
+
def height_from_volume(self, volume: LiquidTrackingType) -> LiquidTrackingType:
|
|
356
|
+
"""Return the height in a well corresponding to a given volume."""
|
|
357
|
+
return self._core.height_from_volume(volume)
|
|
358
|
+
|
|
349
359
|
@requires_version(2, 21)
|
|
350
360
|
def estimate_liquid_height_after_pipetting(
|
|
351
361
|
self,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
+
from copy import deepcopy
|
|
4
5
|
from typing import (
|
|
5
6
|
Callable,
|
|
6
7
|
Dict,
|
|
@@ -13,6 +14,11 @@ from typing import (
|
|
|
13
14
|
)
|
|
14
15
|
|
|
15
16
|
from opentrons_shared_data.labware.types import LabwareDefinition
|
|
17
|
+
from opentrons_shared_data.liquid_classes.liquid_class_definition import (
|
|
18
|
+
TransferProperties as SharedTransferProperties,
|
|
19
|
+
)
|
|
20
|
+
from opentrons_shared_data.liquid_classes import DEFAULT_LC_VERSION, definition_exists
|
|
21
|
+
from opentrons_shared_data.liquid_classes.types import TransferPropertiesDict
|
|
16
22
|
from opentrons_shared_data.pipette.types import PipetteNameType
|
|
17
23
|
|
|
18
24
|
from opentrons.types import Mount, Location, DeckLocation, DeckSlotName, StagingSlotName
|
|
@@ -48,6 +54,7 @@ from opentrons.protocols.api_support.util import (
|
|
|
48
54
|
)
|
|
49
55
|
from opentrons_shared_data.errors.exceptions import CommandPreconditionViolated
|
|
50
56
|
from opentrons.protocol_engine.errors import LabwareMovementNotAllowedError
|
|
57
|
+
from ._liquid_properties import build_transfer_properties
|
|
51
58
|
|
|
52
59
|
from ._types import OffDeckType
|
|
53
60
|
from .core.common import ModuleCore, LabwareCore, ProtocolCore
|
|
@@ -196,6 +203,7 @@ class ProtocolContext(CommandPublisher):
|
|
|
196
203
|
core=self._core.load_robot(),
|
|
197
204
|
protocol_core=self._core,
|
|
198
205
|
api_version=self._api_version,
|
|
206
|
+
broker=broker,
|
|
199
207
|
)
|
|
200
208
|
except APIVersionError:
|
|
201
209
|
self._robot = None
|
|
@@ -1189,9 +1197,16 @@ class ProtocolContext(CommandPublisher):
|
|
|
1189
1197
|
self._core.home()
|
|
1190
1198
|
|
|
1191
1199
|
@property
|
|
1192
|
-
def location_cache(self) -> Optional[Location]:
|
|
1193
|
-
"""The cache used by the robot to determine where it last was.
|
|
1194
|
-
|
|
1200
|
+
def location_cache(self) -> Optional[Union[Location, TrashBin, WasteChute]]:
|
|
1201
|
+
"""The cache used by the robot to determine where it last was.
|
|
1202
|
+
|
|
1203
|
+
.. versionchanged:: 2.24
|
|
1204
|
+
Can return a ``TrashBin`` or ``WasteChute`` object.
|
|
1205
|
+
"""
|
|
1206
|
+
last_loc = self._core.get_last_location()
|
|
1207
|
+
if isinstance(last_loc, Location) or self._api_version >= APIVersion(2, 24):
|
|
1208
|
+
return last_loc
|
|
1209
|
+
return None
|
|
1195
1210
|
|
|
1196
1211
|
@location_cache.setter
|
|
1197
1212
|
def location_cache(self, loc: Optional[Location]) -> None:
|
|
@@ -1368,7 +1383,67 @@ class ProtocolContext(CommandPublisher):
|
|
|
1368
1383
|
|
|
1369
1384
|
:meta private:
|
|
1370
1385
|
"""
|
|
1371
|
-
return self._core.define_liquid_class(name=name)
|
|
1386
|
+
return self._core.define_liquid_class(name=name, version=DEFAULT_LC_VERSION)
|
|
1387
|
+
|
|
1388
|
+
@requires_version(2, 24)
|
|
1389
|
+
def define_custom_liquid_class(
|
|
1390
|
+
self,
|
|
1391
|
+
name: str,
|
|
1392
|
+
properties: Dict[str, Dict[str, TransferPropertiesDict]],
|
|
1393
|
+
base_liquid_class: Optional[LiquidClass] = None,
|
|
1394
|
+
display_name: Optional[str] = None,
|
|
1395
|
+
) -> LiquidClass:
|
|
1396
|
+
"""Define a custom liquid class, either a completely new one or based on an existing one.
|
|
1397
|
+
|
|
1398
|
+
Args:
|
|
1399
|
+
name: The name to give to the new liquid class. Cannot use names of existing in-built liquid classes.
|
|
1400
|
+
properties: A dict of transfer properties per tip per pipette.
|
|
1401
|
+
Accepts a nested dictionary in the following format:
|
|
1402
|
+
|
|
1403
|
+
.. code-block:: python
|
|
1404
|
+
|
|
1405
|
+
{
|
|
1406
|
+
<pipette_name>: {
|
|
1407
|
+
<tiprack_uri>: <properties in the shape of TransferPropertiesDict>
|
|
1408
|
+
|
|
1409
|
+
# TransferPropertiesDict is a dictionary representation of the
|
|
1410
|
+
# transfer properties returned by the `LiquidClass.get_for(..)` function.
|
|
1411
|
+
}}
|
|
1412
|
+
|
|
1413
|
+
base_liquid_class: A LiquidClass to base this liquid class on. The properties
|
|
1414
|
+
specified in transfer_properties will override any existing ones
|
|
1415
|
+
for the specified pipettes & tips.
|
|
1416
|
+
display_name: An optional human-readable name for the liquid. If not provided,
|
|
1417
|
+
will default to title-cased name.
|
|
1418
|
+
|
|
1419
|
+
"""
|
|
1420
|
+
if definition_exists(name, DEFAULT_LC_VERSION):
|
|
1421
|
+
raise ValueError(
|
|
1422
|
+
f"Liquid class named {name} already exists. Please specify a different name."
|
|
1423
|
+
)
|
|
1424
|
+
new_liquid_class: LiquidClass
|
|
1425
|
+
if base_liquid_class:
|
|
1426
|
+
# If base liquid is provided, copy to new class
|
|
1427
|
+
# and replace the entries mentioned in transfer props arg
|
|
1428
|
+
new_liquid_class = deepcopy(base_liquid_class)
|
|
1429
|
+
else:
|
|
1430
|
+
new_liquid_class = LiquidClass.create_from(
|
|
1431
|
+
name=name,
|
|
1432
|
+
display_name=display_name or name.title(),
|
|
1433
|
+
by_pipette_setting={},
|
|
1434
|
+
)
|
|
1435
|
+
for pipette, by_tiprack_props in properties.items():
|
|
1436
|
+
for tiprack, transfer_props in by_tiprack_props.items():
|
|
1437
|
+
new_liquid_class.update_for(
|
|
1438
|
+
pipette=pipette,
|
|
1439
|
+
tip_rack=tiprack,
|
|
1440
|
+
transfer_properties=build_transfer_properties(
|
|
1441
|
+
transfer_properties=SharedTransferProperties.model_validate(
|
|
1442
|
+
transfer_props
|
|
1443
|
+
)
|
|
1444
|
+
),
|
|
1445
|
+
)
|
|
1446
|
+
return new_liquid_class
|
|
1372
1447
|
|
|
1373
1448
|
@property
|
|
1374
1449
|
@requires_version(2, 5)
|
|
@@ -9,6 +9,8 @@ from opentrons.types import (
|
|
|
9
9
|
AxisType,
|
|
10
10
|
StringAxisMap,
|
|
11
11
|
)
|
|
12
|
+
from opentrons.legacy_broker import LegacyBroker
|
|
13
|
+
from opentrons.legacy_commands import robot_commands as cmds
|
|
12
14
|
from opentrons.legacy_commands import publisher
|
|
13
15
|
from opentrons.hardware_control import SyncHardwareAPI
|
|
14
16
|
from opentrons.protocols.api_support.util import requires_version
|
|
@@ -49,8 +51,13 @@ class RobotContext(publisher.CommandPublisher):
|
|
|
49
51
|
"""
|
|
50
52
|
|
|
51
53
|
def __init__(
|
|
52
|
-
self,
|
|
54
|
+
self,
|
|
55
|
+
core: RobotCore,
|
|
56
|
+
protocol_core: ProtocolCore,
|
|
57
|
+
api_version: APIVersion,
|
|
58
|
+
broker: Optional[LegacyBroker] = None,
|
|
53
59
|
) -> None:
|
|
60
|
+
super().__init__(broker)
|
|
54
61
|
self._hardware = HardwareManager(hardware=protocol_core.get_hardware())
|
|
55
62
|
self._core = core
|
|
56
63
|
self._protocol_core = protocol_core
|
|
@@ -87,7 +94,16 @@ class RobotContext(publisher.CommandPublisher):
|
|
|
87
94
|
:param speed:
|
|
88
95
|
"""
|
|
89
96
|
mount = validation.ensure_instrument_mount(mount)
|
|
90
|
-
|
|
97
|
+
with publisher.publish_context(
|
|
98
|
+
broker=self.broker,
|
|
99
|
+
command=cmds.move_to(
|
|
100
|
+
# This needs to be called from protocol context and not the command for import loop reasons
|
|
101
|
+
mount=mount,
|
|
102
|
+
location=destination,
|
|
103
|
+
speed=speed,
|
|
104
|
+
),
|
|
105
|
+
):
|
|
106
|
+
self._core.move_to(mount, destination.point, speed)
|
|
91
107
|
|
|
92
108
|
@requires_version(2, 22)
|
|
93
109
|
def move_axes_to(
|
|
@@ -119,7 +135,15 @@ class RobotContext(publisher.CommandPublisher):
|
|
|
119
135
|
)
|
|
120
136
|
else:
|
|
121
137
|
critical_point = None
|
|
122
|
-
|
|
138
|
+
with publisher.publish_context(
|
|
139
|
+
broker=self.broker,
|
|
140
|
+
command=cmds.move_axis_to(
|
|
141
|
+
# This needs to be called from protocol context and not the command for import loop reasons
|
|
142
|
+
axis_map=axis_map,
|
|
143
|
+
speed=speed,
|
|
144
|
+
),
|
|
145
|
+
):
|
|
146
|
+
self._core.move_axes_to(axis_map, critical_point, speed)
|
|
123
147
|
|
|
124
148
|
@requires_version(2, 22)
|
|
125
149
|
def move_axes_relative(
|
|
@@ -142,15 +166,33 @@ class RobotContext(publisher.CommandPublisher):
|
|
|
142
166
|
axis_map = validation.ensure_axis_map_type(
|
|
143
167
|
axis_map, self._protocol_core.robot_type, is_96_channel
|
|
144
168
|
)
|
|
145
|
-
|
|
169
|
+
with publisher.publish_context(
|
|
170
|
+
broker=self.broker,
|
|
171
|
+
command=cmds.move_axis_relative(
|
|
172
|
+
# This needs to be called from protocol context and not the command for import loop reasons
|
|
173
|
+
axis_map=axis_map,
|
|
174
|
+
speed=speed,
|
|
175
|
+
),
|
|
176
|
+
):
|
|
177
|
+
self._core.move_axes_relative(axis_map, speed)
|
|
146
178
|
|
|
147
179
|
def close_gripper_jaw(self, force: Optional[float] = None) -> None:
|
|
148
180
|
"""Command the gripper closed with some force."""
|
|
149
|
-
|
|
181
|
+
with publisher.publish_context(
|
|
182
|
+
broker=self.broker,
|
|
183
|
+
command=cmds.close_gripper(
|
|
184
|
+
force=force,
|
|
185
|
+
),
|
|
186
|
+
):
|
|
187
|
+
self._core.close_gripper(force)
|
|
150
188
|
|
|
151
189
|
def open_gripper_jaw(self) -> None:
|
|
152
190
|
"""Command the gripper open."""
|
|
153
|
-
|
|
191
|
+
with publisher.publish_context(
|
|
192
|
+
broker=self.broker,
|
|
193
|
+
command=cmds.open_gripper(),
|
|
194
|
+
):
|
|
195
|
+
self._core.release_grip()
|
|
154
196
|
|
|
155
197
|
def axis_coordinates_for(
|
|
156
198
|
self,
|
|
@@ -545,6 +545,11 @@ class PointTarget(NamedTuple):
|
|
|
545
545
|
in_place: bool
|
|
546
546
|
|
|
547
547
|
|
|
548
|
+
class DisposalTarget(NamedTuple):
|
|
549
|
+
location: Union[TrashBin, WasteChute]
|
|
550
|
+
in_place: bool
|
|
551
|
+
|
|
552
|
+
|
|
548
553
|
class NoLocationError(ValueError):
|
|
549
554
|
"""Error representing that no location was supplied."""
|
|
550
555
|
|
|
@@ -553,12 +558,12 @@ class LocationTypeError(TypeError):
|
|
|
553
558
|
"""Error representing that the location supplied is of different expected type."""
|
|
554
559
|
|
|
555
560
|
|
|
556
|
-
ValidTarget = Union[WellTarget, PointTarget,
|
|
561
|
+
ValidTarget = Union[WellTarget, PointTarget, DisposalTarget]
|
|
557
562
|
|
|
558
563
|
|
|
559
564
|
def validate_location(
|
|
560
|
-
location: Union[Location, Well, TrashBin, WasteChute
|
|
561
|
-
last_location: Optional[Location],
|
|
565
|
+
location: Optional[Union[Location, Well, TrashBin, WasteChute]],
|
|
566
|
+
last_location: Optional[Union[Location, TrashBin, WasteChute]],
|
|
562
567
|
) -> ValidTarget:
|
|
563
568
|
"""Validate a given location for a liquid handling command.
|
|
564
569
|
|
|
@@ -569,9 +574,11 @@ def validate_location(
|
|
|
569
574
|
Returns:
|
|
570
575
|
A `WellTarget` if the input location represents a well.
|
|
571
576
|
A `PointTarget` if the input location is an x, y, z coordinate.
|
|
577
|
+
A `TrashBin` if the input location is a trash bin
|
|
578
|
+
A `WasteChute` if the input location is a waste chute
|
|
572
579
|
|
|
573
580
|
Raises:
|
|
574
|
-
NoLocationError:
|
|
581
|
+
NoLocationError: There is no input location and no cached location.
|
|
575
582
|
LocationTypeError: The location supplied is of unexpected type.
|
|
576
583
|
"""
|
|
577
584
|
from .labware import Well
|
|
@@ -586,11 +593,11 @@ def validate_location(
|
|
|
586
593
|
f"location should be a Well, Location, TrashBin or WasteChute, but it is {location}"
|
|
587
594
|
)
|
|
588
595
|
|
|
589
|
-
if isinstance(target_location, (TrashBin, WasteChute)):
|
|
590
|
-
return target_location
|
|
591
|
-
|
|
592
596
|
in_place = target_location == last_location
|
|
593
597
|
|
|
598
|
+
if isinstance(target_location, (TrashBin, WasteChute)):
|
|
599
|
+
return DisposalTarget(location=target_location, in_place=in_place)
|
|
600
|
+
|
|
594
601
|
if isinstance(target_location, Well):
|
|
595
602
|
return WellTarget(well=target_location, location=None, in_place=in_place)
|
|
596
603
|
|
|
@@ -662,7 +669,7 @@ def ensure_new_tip_policy(value: str) -> TransferTipPolicyV2:
|
|
|
662
669
|
except ValueError:
|
|
663
670
|
raise ValueError(
|
|
664
671
|
f"'{value}' is invalid value for 'new_tip'."
|
|
665
|
-
f" Acceptable value is either 'never', 'once', 'always' or 'per
|
|
672
|
+
f" Acceptable value is either 'never', 'once', 'always', 'per source' or 'per destination'."
|
|
666
673
|
)
|
|
667
674
|
|
|
668
675
|
|
|
@@ -498,8 +498,8 @@ Command = Annotated[
|
|
|
498
498
|
robot.MoveTo,
|
|
499
499
|
robot.MoveAxesRelative,
|
|
500
500
|
robot.MoveAxesTo,
|
|
501
|
-
robot.
|
|
502
|
-
robot.
|
|
501
|
+
robot.OpenGripperJaw,
|
|
502
|
+
robot.CloseGripperJaw,
|
|
503
503
|
],
|
|
504
504
|
Field(discriminator="commandType"),
|
|
505
505
|
]
|
|
@@ -599,8 +599,8 @@ CommandParams = Union[
|
|
|
599
599
|
robot.MoveAxesRelativeParams,
|
|
600
600
|
robot.MoveAxesToParams,
|
|
601
601
|
robot.MoveToParams,
|
|
602
|
-
robot.
|
|
603
|
-
robot.
|
|
602
|
+
robot.OpenGripperJawParams,
|
|
603
|
+
robot.CloseGripperJawParams,
|
|
604
604
|
]
|
|
605
605
|
|
|
606
606
|
CommandType = Union[
|
|
@@ -698,8 +698,8 @@ CommandType = Union[
|
|
|
698
698
|
robot.MoveAxesRelativeCommandType,
|
|
699
699
|
robot.MoveAxesToCommandType,
|
|
700
700
|
robot.MoveToCommandType,
|
|
701
|
-
robot.
|
|
702
|
-
robot.
|
|
701
|
+
robot.OpenGripperJawCommandType,
|
|
702
|
+
robot.CloseGripperJawCommandType,
|
|
703
703
|
]
|
|
704
704
|
|
|
705
705
|
CommandCreate = Annotated[
|
|
@@ -798,8 +798,8 @@ CommandCreate = Annotated[
|
|
|
798
798
|
robot.MoveAxesRelativeCreate,
|
|
799
799
|
robot.MoveAxesToCreate,
|
|
800
800
|
robot.MoveToCreate,
|
|
801
|
-
robot.
|
|
802
|
-
robot.
|
|
801
|
+
robot.OpenGripperJawCreate,
|
|
802
|
+
robot.CloseGripperJawCreate,
|
|
803
803
|
],
|
|
804
804
|
Field(discriminator="commandType"),
|
|
805
805
|
]
|
|
@@ -906,8 +906,8 @@ CommandResult = Union[
|
|
|
906
906
|
robot.MoveAxesRelativeResult,
|
|
907
907
|
robot.MoveAxesToResult,
|
|
908
908
|
robot.MoveToResult,
|
|
909
|
-
robot.
|
|
910
|
-
robot.
|
|
909
|
+
robot.OpenGripperJawResult,
|
|
910
|
+
robot.CloseGripperJawResult,
|
|
911
911
|
]
|
|
912
912
|
|
|
913
913
|
|
|
@@ -11,7 +11,7 @@ from opentrons_shared_data.load import get_shared_data_root
|
|
|
11
11
|
|
|
12
12
|
def generate_command_schema(version: str) -> str:
|
|
13
13
|
"""Generate a JSON Schema that all valid create commands can validate against."""
|
|
14
|
-
schema_as_dict = CommandCreateAdapter.json_schema(mode="validation")
|
|
14
|
+
schema_as_dict = CommandCreateAdapter.json_schema(mode="validation", by_alias=False)
|
|
15
15
|
schema_as_dict["$id"] = f"opentronsCommandSchemaV{version}"
|
|
16
16
|
schema_as_dict["$schema"] = "http://json-schema.org/draft-07/schema#"
|
|
17
17
|
return json.dumps(schema_as_dict, indent=2, sort_keys=True)
|
|
@@ -73,8 +73,8 @@ class GetNextTipImplementation(
|
|
|
73
73
|
pipette_id = params.pipetteId
|
|
74
74
|
starting_tip_name = params.startingTipWell
|
|
75
75
|
|
|
76
|
-
num_tips = self._state_view.
|
|
77
|
-
nozzle_map = self._state_view.
|
|
76
|
+
num_tips = self._state_view.pipettes.get_active_channels(pipette_id)
|
|
77
|
+
nozzle_map = self._state_view.pipettes.get_nozzle_configuration(pipette_id)
|
|
78
78
|
|
|
79
79
|
if (
|
|
80
80
|
starting_tip_name is not None
|
|
@@ -121,6 +121,12 @@ class PickUpTipImplementation(AbstractCommandImpl[PickUpTipParams, _ExecuteRetur
|
|
|
121
121
|
labware_id = params.labwareId
|
|
122
122
|
well_name = params.wellName
|
|
123
123
|
|
|
124
|
+
tips_to_mark_as_used = self._state_view.tips.compute_tips_to_mark_as_used(
|
|
125
|
+
labware_id=labware_id,
|
|
126
|
+
well_name=well_name,
|
|
127
|
+
nozzle_map=self._state_view.pipettes.get_nozzle_configuration(pipette_id),
|
|
128
|
+
)
|
|
129
|
+
|
|
124
130
|
well_location = self._state_view.geometry.convert_pick_up_tip_well_location(
|
|
125
131
|
well_location=params.wellLocation
|
|
126
132
|
)
|
|
@@ -152,7 +158,7 @@ class PickUpTipImplementation(AbstractCommandImpl[PickUpTipParams, _ExecuteRetur
|
|
|
152
158
|
)
|
|
153
159
|
.set_fluid_empty(pipette_id=pipette_id, clean_tip=True)
|
|
154
160
|
.mark_tips_as_used(
|
|
155
|
-
|
|
161
|
+
labware_id=labware_id, well_names=tips_to_mark_as_used
|
|
156
162
|
)
|
|
157
163
|
)
|
|
158
164
|
state_update = (
|
|
@@ -160,7 +166,7 @@ class PickUpTipImplementation(AbstractCommandImpl[PickUpTipParams, _ExecuteRetur
|
|
|
160
166
|
update_types.StateUpdate(), move_result.state_update
|
|
161
167
|
)
|
|
162
168
|
.mark_tips_as_used(
|
|
163
|
-
|
|
169
|
+
labware_id=labware_id, well_names=tips_to_mark_as_used
|
|
164
170
|
)
|
|
165
171
|
.set_fluid_unknown(pipette_id=pipette_id)
|
|
166
172
|
)
|
|
@@ -186,7 +192,7 @@ class PickUpTipImplementation(AbstractCommandImpl[PickUpTipParams, _ExecuteRetur
|
|
|
186
192
|
tip_geometry=tip_geometry,
|
|
187
193
|
)
|
|
188
194
|
.mark_tips_as_used(
|
|
189
|
-
|
|
195
|
+
labware_id=labware_id, well_names=tips_to_mark_as_used
|
|
190
196
|
)
|
|
191
197
|
.set_fluid_empty(pipette_id=pipette_id, clean_tip=True)
|
|
192
198
|
.set_pipette_ready_to_aspirate(
|
|
@@ -22,18 +22,18 @@ from .move_axes_relative import (
|
|
|
22
22
|
MoveAxesRelativeCommandType,
|
|
23
23
|
)
|
|
24
24
|
from .open_gripper_jaw import (
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
OpenGripperJaw,
|
|
26
|
+
OpenGripperJawCreate,
|
|
27
|
+
OpenGripperJawParams,
|
|
28
|
+
OpenGripperJawResult,
|
|
29
|
+
OpenGripperJawCommandType,
|
|
30
30
|
)
|
|
31
31
|
from .close_gripper_jaw import (
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
CloseGripperJaw,
|
|
33
|
+
CloseGripperJawCreate,
|
|
34
|
+
CloseGripperJawParams,
|
|
35
|
+
CloseGripperJawResult,
|
|
36
|
+
CloseGripperJawCommandType,
|
|
37
37
|
)
|
|
38
38
|
|
|
39
39
|
__all__ = [
|
|
@@ -56,15 +56,15 @@ __all__ = [
|
|
|
56
56
|
"MoveAxesRelativeResult",
|
|
57
57
|
"MoveAxesRelativeCommandType",
|
|
58
58
|
# robot/openGripperJaw
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
59
|
+
"OpenGripperJaw",
|
|
60
|
+
"OpenGripperJawCreate",
|
|
61
|
+
"OpenGripperJawParams",
|
|
62
|
+
"OpenGripperJawResult",
|
|
63
|
+
"OpenGripperJawCommandType",
|
|
64
64
|
# robot/closeGripperJaw
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"
|
|
65
|
+
"CloseGripperJaw",
|
|
66
|
+
"CloseGripperJawCreate",
|
|
67
|
+
"CloseGripperJawParams",
|
|
68
|
+
"CloseGripperJawResult",
|
|
69
|
+
"CloseGripperJawCommandType",
|
|
70
70
|
]
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""Command models for opening a gripper jaw."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
|
-
from typing import Literal, Type, Optional, Any
|
|
4
|
+
from typing import Literal, Type, Optional, Any, TYPE_CHECKING
|
|
4
5
|
|
|
5
6
|
from pydantic import BaseModel, Field
|
|
6
7
|
from pydantic.json_schema import SkipJsonSchema
|
|
@@ -16,15 +17,18 @@ from ..command import (
|
|
|
16
17
|
)
|
|
17
18
|
from opentrons.protocol_engine.errors.error_occurrence import ErrorOccurrence
|
|
18
19
|
|
|
20
|
+
if TYPE_CHECKING:
|
|
21
|
+
from ...state.state import StateView
|
|
22
|
+
|
|
19
23
|
|
|
20
|
-
|
|
24
|
+
CloseGripperJawCommandType = Literal["robot/closeGripperJaw"]
|
|
21
25
|
|
|
22
26
|
|
|
23
27
|
def _remove_default(s: dict[str, Any]) -> None:
|
|
24
28
|
s.pop("default", None)
|
|
25
29
|
|
|
26
30
|
|
|
27
|
-
class
|
|
31
|
+
class CloseGripperJawParams(BaseModel):
|
|
28
32
|
"""Payload required to close a gripper."""
|
|
29
33
|
|
|
30
34
|
force: float | SkipJsonSchema[None] = Field(
|
|
@@ -34,53 +38,59 @@ class closeGripperJawParams(BaseModel):
|
|
|
34
38
|
)
|
|
35
39
|
|
|
36
40
|
|
|
37
|
-
class
|
|
38
|
-
"""Result data from the execution of a
|
|
41
|
+
class CloseGripperJawResult(BaseModel):
|
|
42
|
+
"""Result data from the execution of a CloseGripperJaw command."""
|
|
39
43
|
|
|
40
44
|
pass
|
|
41
45
|
|
|
42
46
|
|
|
43
|
-
class
|
|
44
|
-
AbstractCommandImpl[
|
|
47
|
+
class CloseGripperJawImplementation(
|
|
48
|
+
AbstractCommandImpl[CloseGripperJawParams, SuccessData[CloseGripperJawResult]]
|
|
45
49
|
):
|
|
46
|
-
"""
|
|
50
|
+
"""CloseGripperJaw command implementation."""
|
|
47
51
|
|
|
48
52
|
def __init__(
|
|
49
53
|
self,
|
|
50
54
|
hardware_api: HardwareControlAPI,
|
|
55
|
+
state_view: StateView,
|
|
51
56
|
**kwargs: object,
|
|
52
57
|
) -> None:
|
|
53
58
|
self._hardware_api = hardware_api
|
|
59
|
+
self._state_view = state_view
|
|
54
60
|
|
|
55
61
|
async def execute(
|
|
56
|
-
self, params:
|
|
57
|
-
) -> SuccessData[
|
|
62
|
+
self, params: CloseGripperJawParams
|
|
63
|
+
) -> SuccessData[CloseGripperJawResult]:
|
|
58
64
|
"""Release the gripper."""
|
|
65
|
+
if self._state_view.config.use_virtual_gripper:
|
|
66
|
+
return SuccessData(
|
|
67
|
+
public=CloseGripperJawResult(),
|
|
68
|
+
)
|
|
59
69
|
ot3_hardware_api = ensure_ot3_hardware(self._hardware_api)
|
|
60
70
|
await ot3_hardware_api.grip(force_newtons=params.force)
|
|
61
71
|
return SuccessData(
|
|
62
|
-
public=
|
|
72
|
+
public=CloseGripperJawResult(),
|
|
63
73
|
)
|
|
64
74
|
|
|
65
75
|
|
|
66
|
-
class
|
|
67
|
-
BaseCommand[
|
|
76
|
+
class CloseGripperJaw(
|
|
77
|
+
BaseCommand[CloseGripperJawParams, CloseGripperJawResult, ErrorOccurrence]
|
|
68
78
|
):
|
|
69
|
-
"""
|
|
79
|
+
"""CloseGripperJaw command model."""
|
|
70
80
|
|
|
71
|
-
commandType:
|
|
72
|
-
params:
|
|
73
|
-
result: Optional[
|
|
81
|
+
commandType: CloseGripperJawCommandType = "robot/closeGripperJaw"
|
|
82
|
+
params: CloseGripperJawParams
|
|
83
|
+
result: Optional[CloseGripperJawResult] = None
|
|
74
84
|
|
|
75
85
|
_ImplementationCls: Type[
|
|
76
|
-
|
|
77
|
-
] =
|
|
86
|
+
CloseGripperJawImplementation
|
|
87
|
+
] = CloseGripperJawImplementation
|
|
78
88
|
|
|
79
89
|
|
|
80
|
-
class
|
|
81
|
-
"""
|
|
90
|
+
class CloseGripperJawCreate(BaseCommandCreate[CloseGripperJawParams]):
|
|
91
|
+
"""CloseGripperJaw command request model."""
|
|
82
92
|
|
|
83
|
-
commandType:
|
|
84
|
-
params:
|
|
93
|
+
commandType: CloseGripperJawCommandType = "robot/closeGripperJaw"
|
|
94
|
+
params: CloseGripperJawParams
|
|
85
95
|
|
|
86
|
-
_CommandCls: Type[
|
|
96
|
+
_CommandCls: Type[CloseGripperJaw] = CloseGripperJaw
|