opentrons 8.2.0a3__py2.py3-none-any.whl → 8.3.0__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.
- opentrons/calibration_storage/deck_configuration.py +3 -3
- opentrons/calibration_storage/file_operators.py +3 -3
- opentrons/calibration_storage/helpers.py +3 -1
- opentrons/calibration_storage/ot2/models/v1.py +16 -29
- opentrons/calibration_storage/ot2/tip_length.py +7 -4
- opentrons/calibration_storage/ot3/models/v1.py +14 -23
- opentrons/cli/analyze.py +18 -6
- opentrons/config/defaults_ot3.py +1 -0
- opentrons/drivers/asyncio/communication/__init__.py +2 -0
- opentrons/drivers/asyncio/communication/errors.py +16 -3
- opentrons/drivers/asyncio/communication/serial_connection.py +24 -9
- opentrons/drivers/command_builder.py +2 -2
- opentrons/drivers/flex_stacker/__init__.py +9 -0
- opentrons/drivers/flex_stacker/abstract.py +89 -0
- opentrons/drivers/flex_stacker/driver.py +260 -0
- opentrons/drivers/flex_stacker/simulator.py +109 -0
- opentrons/drivers/flex_stacker/types.py +138 -0
- opentrons/drivers/heater_shaker/driver.py +18 -3
- opentrons/drivers/temp_deck/driver.py +13 -3
- opentrons/drivers/thermocycler/driver.py +17 -3
- opentrons/execute.py +3 -1
- opentrons/hardware_control/__init__.py +1 -2
- opentrons/hardware_control/api.py +33 -21
- opentrons/hardware_control/backends/flex_protocol.py +17 -7
- opentrons/hardware_control/backends/ot3controller.py +213 -63
- opentrons/hardware_control/backends/ot3simulator.py +18 -9
- opentrons/hardware_control/backends/ot3utils.py +43 -15
- opentrons/hardware_control/dev_types.py +4 -0
- opentrons/hardware_control/emulation/heater_shaker.py +4 -0
- opentrons/hardware_control/emulation/module_server/client.py +1 -1
- opentrons/hardware_control/emulation/module_server/server.py +5 -3
- opentrons/hardware_control/emulation/settings.py +3 -4
- opentrons/hardware_control/instruments/ot2/instrument_calibration.py +2 -1
- opentrons/hardware_control/instruments/ot2/pipette.py +15 -22
- opentrons/hardware_control/instruments/ot2/pipette_handler.py +8 -1
- opentrons/hardware_control/instruments/ot3/gripper.py +2 -2
- opentrons/hardware_control/instruments/ot3/pipette.py +23 -22
- opentrons/hardware_control/instruments/ot3/pipette_handler.py +10 -1
- opentrons/hardware_control/modules/mod_abc.py +2 -2
- opentrons/hardware_control/motion_utilities.py +68 -0
- opentrons/hardware_control/nozzle_manager.py +39 -41
- opentrons/hardware_control/ot3_calibration.py +1 -1
- opentrons/hardware_control/ot3api.py +78 -31
- opentrons/hardware_control/protocols/gripper_controller.py +3 -0
- opentrons/hardware_control/protocols/hardware_manager.py +5 -1
- opentrons/hardware_control/protocols/liquid_handler.py +22 -1
- opentrons/hardware_control/protocols/motion_controller.py +7 -0
- opentrons/hardware_control/robot_calibration.py +1 -1
- opentrons/hardware_control/types.py +61 -0
- opentrons/legacy_commands/commands.py +37 -0
- opentrons/legacy_commands/types.py +39 -0
- opentrons/protocol_api/__init__.py +20 -1
- opentrons/protocol_api/_liquid.py +24 -49
- opentrons/protocol_api/_liquid_properties.py +754 -0
- opentrons/protocol_api/_types.py +24 -0
- opentrons/protocol_api/core/common.py +2 -0
- opentrons/protocol_api/core/engine/instrument.py +191 -10
- opentrons/protocol_api/core/engine/labware.py +29 -7
- opentrons/protocol_api/core/engine/protocol.py +130 -5
- opentrons/protocol_api/core/engine/robot.py +139 -0
- opentrons/protocol_api/core/engine/well.py +4 -1
- opentrons/protocol_api/core/instrument.py +73 -4
- opentrons/protocol_api/core/labware.py +13 -4
- opentrons/protocol_api/core/legacy/legacy_instrument_core.py +87 -3
- opentrons/protocol_api/core/legacy/legacy_labware_core.py +13 -4
- opentrons/protocol_api/core/legacy/legacy_protocol_core.py +32 -1
- opentrons/protocol_api/core/legacy/legacy_robot_core.py +0 -0
- opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py +61 -3
- opentrons/protocol_api/core/protocol.py +34 -1
- opentrons/protocol_api/core/robot.py +51 -0
- opentrons/protocol_api/instrument_context.py +299 -44
- opentrons/protocol_api/labware.py +248 -9
- opentrons/protocol_api/module_contexts.py +21 -17
- opentrons/protocol_api/protocol_context.py +125 -4
- opentrons/protocol_api/robot_context.py +204 -32
- opentrons/protocol_api/validation.py +262 -3
- opentrons/protocol_engine/__init__.py +4 -0
- opentrons/protocol_engine/actions/actions.py +2 -3
- opentrons/protocol_engine/clients/sync_client.py +18 -0
- opentrons/protocol_engine/commands/__init__.py +121 -0
- opentrons/protocol_engine/commands/absorbance_reader/close_lid.py +1 -3
- opentrons/protocol_engine/commands/absorbance_reader/initialize.py +20 -6
- opentrons/protocol_engine/commands/absorbance_reader/open_lid.py +1 -2
- opentrons/protocol_engine/commands/absorbance_reader/read.py +40 -10
- opentrons/protocol_engine/commands/air_gap_in_place.py +160 -0
- opentrons/protocol_engine/commands/aspirate.py +103 -53
- opentrons/protocol_engine/commands/aspirate_in_place.py +55 -51
- opentrons/protocol_engine/commands/blow_out.py +44 -39
- opentrons/protocol_engine/commands/blow_out_in_place.py +21 -32
- opentrons/protocol_engine/commands/calibration/calibrate_gripper.py +13 -6
- opentrons/protocol_engine/commands/calibration/calibrate_module.py +1 -1
- opentrons/protocol_engine/commands/calibration/calibrate_pipette.py +3 -3
- opentrons/protocol_engine/commands/calibration/move_to_maintenance_position.py +1 -1
- opentrons/protocol_engine/commands/command.py +73 -66
- opentrons/protocol_engine/commands/command_unions.py +140 -1
- opentrons/protocol_engine/commands/comment.py +1 -1
- opentrons/protocol_engine/commands/configure_for_volume.py +10 -3
- opentrons/protocol_engine/commands/configure_nozzle_layout.py +6 -4
- opentrons/protocol_engine/commands/custom.py +6 -12
- opentrons/protocol_engine/commands/dispense.py +82 -48
- opentrons/protocol_engine/commands/dispense_in_place.py +71 -51
- opentrons/protocol_engine/commands/drop_tip.py +52 -31
- opentrons/protocol_engine/commands/drop_tip_in_place.py +79 -8
- opentrons/protocol_engine/commands/evotip_dispense.py +156 -0
- opentrons/protocol_engine/commands/evotip_seal_pipette.py +331 -0
- opentrons/protocol_engine/commands/evotip_unseal_pipette.py +160 -0
- opentrons/protocol_engine/commands/generate_command_schema.py +4 -11
- opentrons/protocol_engine/commands/get_next_tip.py +134 -0
- opentrons/protocol_engine/commands/get_tip_presence.py +1 -1
- opentrons/protocol_engine/commands/heater_shaker/close_labware_latch.py +1 -1
- opentrons/protocol_engine/commands/heater_shaker/deactivate_heater.py +1 -1
- opentrons/protocol_engine/commands/heater_shaker/deactivate_shaker.py +1 -1
- opentrons/protocol_engine/commands/heater_shaker/open_labware_latch.py +1 -1
- opentrons/protocol_engine/commands/heater_shaker/set_and_wait_for_shake_speed.py +1 -1
- opentrons/protocol_engine/commands/heater_shaker/set_target_temperature.py +1 -1
- opentrons/protocol_engine/commands/heater_shaker/wait_for_temperature.py +10 -4
- opentrons/protocol_engine/commands/home.py +13 -4
- opentrons/protocol_engine/commands/liquid_probe.py +125 -31
- opentrons/protocol_engine/commands/load_labware.py +33 -6
- opentrons/protocol_engine/commands/load_lid.py +146 -0
- opentrons/protocol_engine/commands/load_lid_stack.py +189 -0
- opentrons/protocol_engine/commands/load_liquid.py +12 -4
- opentrons/protocol_engine/commands/load_liquid_class.py +144 -0
- opentrons/protocol_engine/commands/load_module.py +31 -10
- opentrons/protocol_engine/commands/load_pipette.py +19 -8
- opentrons/protocol_engine/commands/magnetic_module/disengage.py +1 -1
- opentrons/protocol_engine/commands/magnetic_module/engage.py +1 -1
- opentrons/protocol_engine/commands/move_labware.py +28 -6
- opentrons/protocol_engine/commands/move_relative.py +35 -25
- opentrons/protocol_engine/commands/move_to_addressable_area.py +40 -27
- opentrons/protocol_engine/commands/move_to_addressable_area_for_drop_tip.py +53 -32
- opentrons/protocol_engine/commands/move_to_coordinates.py +36 -22
- opentrons/protocol_engine/commands/move_to_well.py +40 -24
- opentrons/protocol_engine/commands/movement_common.py +338 -0
- opentrons/protocol_engine/commands/pick_up_tip.py +49 -27
- opentrons/protocol_engine/commands/pipetting_common.py +169 -87
- opentrons/protocol_engine/commands/prepare_to_aspirate.py +24 -33
- opentrons/protocol_engine/commands/reload_labware.py +1 -1
- opentrons/protocol_engine/commands/retract_axis.py +1 -1
- opentrons/protocol_engine/commands/robot/__init__.py +69 -0
- opentrons/protocol_engine/commands/robot/close_gripper_jaw.py +86 -0
- opentrons/protocol_engine/commands/robot/common.py +18 -0
- opentrons/protocol_engine/commands/robot/move_axes_relative.py +101 -0
- opentrons/protocol_engine/commands/robot/move_axes_to.py +100 -0
- opentrons/protocol_engine/commands/robot/move_to.py +94 -0
- opentrons/protocol_engine/commands/robot/open_gripper_jaw.py +77 -0
- opentrons/protocol_engine/commands/save_position.py +14 -5
- opentrons/protocol_engine/commands/set_rail_lights.py +1 -1
- opentrons/protocol_engine/commands/set_status_bar.py +1 -1
- opentrons/protocol_engine/commands/temperature_module/deactivate.py +1 -1
- opentrons/protocol_engine/commands/temperature_module/set_target_temperature.py +1 -1
- opentrons/protocol_engine/commands/temperature_module/wait_for_temperature.py +10 -4
- opentrons/protocol_engine/commands/thermocycler/close_lid.py +1 -1
- opentrons/protocol_engine/commands/thermocycler/deactivate_block.py +1 -1
- opentrons/protocol_engine/commands/thermocycler/deactivate_lid.py +1 -1
- opentrons/protocol_engine/commands/thermocycler/open_lid.py +1 -1
- opentrons/protocol_engine/commands/thermocycler/run_extended_profile.py +9 -3
- opentrons/protocol_engine/commands/thermocycler/run_profile.py +9 -3
- opentrons/protocol_engine/commands/thermocycler/set_target_block_temperature.py +11 -4
- opentrons/protocol_engine/commands/thermocycler/set_target_lid_temperature.py +1 -1
- opentrons/protocol_engine/commands/thermocycler/wait_for_block_temperature.py +1 -1
- opentrons/protocol_engine/commands/thermocycler/wait_for_lid_temperature.py +1 -1
- opentrons/protocol_engine/commands/touch_tip.py +65 -16
- opentrons/protocol_engine/commands/unsafe/unsafe_blow_out_in_place.py +5 -2
- opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py +13 -4
- opentrons/protocol_engine/commands/unsafe/unsafe_engage_axes.py +2 -5
- opentrons/protocol_engine/commands/unsafe/unsafe_place_labware.py +1 -1
- opentrons/protocol_engine/commands/unsafe/unsafe_ungrip_labware.py +4 -2
- opentrons/protocol_engine/commands/unsafe/update_position_estimators.py +2 -5
- opentrons/protocol_engine/commands/verify_tip_presence.py +11 -4
- opentrons/protocol_engine/commands/wait_for_duration.py +10 -3
- opentrons/protocol_engine/commands/wait_for_resume.py +10 -3
- opentrons/protocol_engine/errors/__init__.py +12 -0
- opentrons/protocol_engine/errors/error_occurrence.py +19 -20
- opentrons/protocol_engine/errors/exceptions.py +76 -0
- opentrons/protocol_engine/execution/command_executor.py +1 -1
- opentrons/protocol_engine/execution/equipment.py +73 -5
- opentrons/protocol_engine/execution/gantry_mover.py +369 -8
- opentrons/protocol_engine/execution/hardware_stopper.py +7 -7
- opentrons/protocol_engine/execution/movement.py +27 -0
- opentrons/protocol_engine/execution/pipetting.py +5 -1
- opentrons/protocol_engine/execution/tip_handler.py +34 -15
- opentrons/protocol_engine/notes/notes.py +1 -1
- opentrons/protocol_engine/protocol_engine.py +7 -6
- opentrons/protocol_engine/resources/labware_data_provider.py +1 -1
- opentrons/protocol_engine/resources/labware_validation.py +18 -0
- opentrons/protocol_engine/resources/module_data_provider.py +1 -1
- opentrons/protocol_engine/resources/pipette_data_provider.py +26 -0
- opentrons/protocol_engine/slot_standardization.py +9 -9
- opentrons/protocol_engine/state/_move_types.py +9 -5
- opentrons/protocol_engine/state/_well_math.py +193 -0
- opentrons/protocol_engine/state/addressable_areas.py +25 -61
- opentrons/protocol_engine/state/command_history.py +12 -0
- opentrons/protocol_engine/state/commands.py +22 -14
- opentrons/protocol_engine/state/files.py +10 -12
- opentrons/protocol_engine/state/fluid_stack.py +138 -0
- opentrons/protocol_engine/state/frustum_helpers.py +63 -69
- opentrons/protocol_engine/state/geometry.py +47 -1
- opentrons/protocol_engine/state/labware.py +92 -26
- opentrons/protocol_engine/state/liquid_classes.py +82 -0
- opentrons/protocol_engine/state/liquids.py +16 -4
- opentrons/protocol_engine/state/modules.py +56 -71
- opentrons/protocol_engine/state/motion.py +6 -1
- opentrons/protocol_engine/state/pipettes.py +149 -58
- opentrons/protocol_engine/state/state.py +21 -2
- opentrons/protocol_engine/state/state_summary.py +4 -2
- opentrons/protocol_engine/state/tips.py +11 -44
- opentrons/protocol_engine/state/update_types.py +343 -48
- opentrons/protocol_engine/state/wells.py +19 -11
- opentrons/protocol_engine/types.py +176 -28
- opentrons/protocol_reader/extract_labware_definitions.py +5 -2
- opentrons/protocol_reader/file_format_validator.py +5 -5
- opentrons/protocol_runner/json_file_reader.py +9 -3
- opentrons/protocol_runner/json_translator.py +51 -25
- opentrons/protocol_runner/legacy_command_mapper.py +66 -64
- opentrons/protocol_runner/protocol_runner.py +35 -4
- opentrons/protocol_runner/python_protocol_wrappers.py +1 -1
- opentrons/protocol_runner/run_orchestrator.py +13 -3
- opentrons/protocols/advanced_control/common.py +38 -0
- opentrons/protocols/advanced_control/mix.py +1 -1
- opentrons/protocols/advanced_control/transfers/__init__.py +0 -0
- opentrons/protocols/advanced_control/transfers/common.py +56 -0
- opentrons/protocols/advanced_control/{transfers.py → transfers/transfer.py} +10 -85
- opentrons/protocols/api_support/definitions.py +1 -1
- opentrons/protocols/api_support/instrument.py +1 -1
- opentrons/protocols/api_support/util.py +10 -0
- opentrons/protocols/labware.py +70 -8
- opentrons/protocols/models/json_protocol.py +5 -9
- opentrons/simulate.py +3 -1
- opentrons/types.py +162 -2
- opentrons/util/entrypoint_util.py +2 -5
- opentrons/util/logging_config.py +1 -1
- {opentrons-8.2.0a3.dist-info → opentrons-8.3.0.dist-info}/METADATA +16 -15
- {opentrons-8.2.0a3.dist-info → opentrons-8.3.0.dist-info}/RECORD +238 -208
- {opentrons-8.2.0a3.dist-info → opentrons-8.3.0.dist-info}/WHEEL +1 -1
- {opentrons-8.2.0a3.dist-info → opentrons-8.3.0.dist-info}/LICENSE +0 -0
- {opentrons-8.2.0a3.dist-info → opentrons-8.3.0.dist-info}/entry_points.txt +0 -0
- {opentrons-8.2.0a3.dist-info → opentrons-8.3.0.dist-info}/top_level.txt +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Pick up tip command request, result, and implementation models."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
4
|
from opentrons_shared_data.errors import ErrorCodes
|
|
4
5
|
from pydantic import Field
|
|
@@ -9,10 +10,14 @@ from typing_extensions import Literal
|
|
|
9
10
|
from ..errors import ErrorOccurrence, PickUpTipTipNotAttachedError
|
|
10
11
|
from ..resources import ModelUtils
|
|
11
12
|
from ..state import update_types
|
|
12
|
-
from ..types import PickUpTipWellLocation
|
|
13
|
+
from ..types import PickUpTipWellLocation
|
|
13
14
|
from .pipetting_common import (
|
|
14
15
|
PipetteIdMixin,
|
|
16
|
+
)
|
|
17
|
+
from .movement_common import (
|
|
15
18
|
DestinationPositionResult,
|
|
19
|
+
StallOrCollisionError,
|
|
20
|
+
move_to_well,
|
|
16
21
|
)
|
|
17
22
|
from .command import (
|
|
18
23
|
AbstractCommandImpl,
|
|
@@ -87,7 +92,8 @@ class TipPhysicallyMissingError(ErrorOccurrence):
|
|
|
87
92
|
|
|
88
93
|
_ExecuteReturn = Union[
|
|
89
94
|
SuccessData[PickUpTipResult],
|
|
90
|
-
DefinedErrorData[TipPhysicallyMissingError]
|
|
95
|
+
DefinedErrorData[TipPhysicallyMissingError]
|
|
96
|
+
| DefinedErrorData[StallOrCollisionError],
|
|
91
97
|
]
|
|
92
98
|
|
|
93
99
|
|
|
@@ -115,24 +121,19 @@ class PickUpTipImplementation(AbstractCommandImpl[PickUpTipParams, _ExecuteRetur
|
|
|
115
121
|
labware_id = params.labwareId
|
|
116
122
|
well_name = params.wellName
|
|
117
123
|
|
|
118
|
-
state_update = update_types.StateUpdate()
|
|
119
|
-
|
|
120
124
|
well_location = self._state_view.geometry.convert_pick_up_tip_well_location(
|
|
121
125
|
well_location=params.wellLocation
|
|
122
126
|
)
|
|
123
|
-
|
|
127
|
+
move_result = await move_to_well(
|
|
128
|
+
movement=self._movement,
|
|
129
|
+
model_utils=self._model_utils,
|
|
124
130
|
pipette_id=pipette_id,
|
|
125
131
|
labware_id=labware_id,
|
|
126
132
|
well_name=well_name,
|
|
127
133
|
well_location=well_location,
|
|
128
134
|
)
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
pipette_id=pipette_id,
|
|
132
|
-
new_labware_id=labware_id,
|
|
133
|
-
new_well_name=well_name,
|
|
134
|
-
new_deck_point=deck_point,
|
|
135
|
-
)
|
|
135
|
+
if isinstance(move_result, DefinedErrorData):
|
|
136
|
+
return move_result
|
|
136
137
|
|
|
137
138
|
try:
|
|
138
139
|
tip_geometry = await self._tip_handler.pick_up_tip(
|
|
@@ -141,13 +142,27 @@ class PickUpTipImplementation(AbstractCommandImpl[PickUpTipParams, _ExecuteRetur
|
|
|
141
142
|
well_name=well_name,
|
|
142
143
|
)
|
|
143
144
|
except PickUpTipTipNotAttachedError as e:
|
|
144
|
-
state_update_if_false_positive =
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
145
|
+
state_update_if_false_positive = (
|
|
146
|
+
update_types.StateUpdate.reduce(
|
|
147
|
+
update_types.StateUpdate(), move_result.state_update
|
|
148
|
+
)
|
|
149
|
+
.update_pipette_tip_state(
|
|
150
|
+
pipette_id=pipette_id,
|
|
151
|
+
tip_geometry=e.tip_geometry,
|
|
152
|
+
)
|
|
153
|
+
.set_fluid_empty(pipette_id=pipette_id)
|
|
154
|
+
.mark_tips_as_used(
|
|
155
|
+
pipette_id=pipette_id, labware_id=labware_id, well_name=well_name
|
|
156
|
+
)
|
|
148
157
|
)
|
|
149
|
-
state_update
|
|
150
|
-
|
|
158
|
+
state_update = (
|
|
159
|
+
update_types.StateUpdate.reduce(
|
|
160
|
+
update_types.StateUpdate(), move_result.state_update
|
|
161
|
+
)
|
|
162
|
+
.mark_tips_as_used(
|
|
163
|
+
pipette_id=pipette_id, labware_id=labware_id, well_name=well_name
|
|
164
|
+
)
|
|
165
|
+
.set_fluid_unknown(pipette_id=pipette_id)
|
|
151
166
|
)
|
|
152
167
|
return DefinedErrorData(
|
|
153
168
|
public=TipPhysicallyMissingError(
|
|
@@ -165,32 +180,39 @@ class PickUpTipImplementation(AbstractCommandImpl[PickUpTipParams, _ExecuteRetur
|
|
|
165
180
|
state_update_if_false_positive=state_update_if_false_positive,
|
|
166
181
|
)
|
|
167
182
|
else:
|
|
168
|
-
state_update
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
183
|
+
state_update = (
|
|
184
|
+
move_result.state_update.update_pipette_tip_state(
|
|
185
|
+
pipette_id=pipette_id,
|
|
186
|
+
tip_geometry=tip_geometry,
|
|
187
|
+
)
|
|
188
|
+
.mark_tips_as_used(
|
|
189
|
+
pipette_id=pipette_id, labware_id=labware_id, well_name=well_name
|
|
190
|
+
)
|
|
191
|
+
.set_fluid_empty(pipette_id=pipette_id)
|
|
174
192
|
)
|
|
175
193
|
return SuccessData(
|
|
176
194
|
public=PickUpTipResult(
|
|
177
195
|
tipVolume=tip_geometry.volume,
|
|
178
196
|
tipLength=tip_geometry.length,
|
|
179
197
|
tipDiameter=tip_geometry.diameter,
|
|
180
|
-
position=
|
|
198
|
+
position=move_result.public.position,
|
|
181
199
|
),
|
|
182
200
|
state_update=state_update,
|
|
183
201
|
)
|
|
184
202
|
|
|
185
203
|
|
|
186
204
|
class PickUpTip(
|
|
187
|
-
BaseCommand[
|
|
205
|
+
BaseCommand[
|
|
206
|
+
PickUpTipParams,
|
|
207
|
+
PickUpTipResult,
|
|
208
|
+
TipPhysicallyMissingError | StallOrCollisionError,
|
|
209
|
+
]
|
|
188
210
|
):
|
|
189
211
|
"""Pick up tip command model."""
|
|
190
212
|
|
|
191
213
|
commandType: PickUpTipCommandType = "pickUpTip"
|
|
192
214
|
params: PickUpTipParams
|
|
193
|
-
result: Optional[PickUpTipResult]
|
|
215
|
+
result: Optional[PickUpTipResult] = None
|
|
194
216
|
|
|
195
217
|
_ImplementationCls: Type[PickUpTipImplementation] = PickUpTipImplementation
|
|
196
218
|
|
|
@@ -1,11 +1,23 @@
|
|
|
1
1
|
"""Common pipetting command base models."""
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from typing import Literal, Tuple, TYPE_CHECKING
|
|
5
|
+
|
|
6
|
+
from typing_extensions import TypedDict
|
|
3
7
|
from pydantic import BaseModel, Field
|
|
4
|
-
from typing import Literal, Optional, Tuple, TypedDict
|
|
5
8
|
|
|
9
|
+
from opentrons_shared_data.errors import ErrorCodes
|
|
6
10
|
from opentrons.protocol_engine.errors.error_occurrence import ErrorOccurrence
|
|
11
|
+
from opentrons.protocol_engine.types import AspiratedFluid, FluidKind
|
|
12
|
+
from opentrons_shared_data.errors.exceptions import PipetteOverpressureError
|
|
13
|
+
from .command import DefinedErrorData, SuccessData
|
|
14
|
+
from opentrons.protocol_engine.state.update_types import StateUpdate
|
|
7
15
|
|
|
8
|
-
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from ..execution.pipetting import PipettingHandler
|
|
19
|
+
from ..resources import ModelUtils
|
|
20
|
+
from ..notes import CommandNoteAdder
|
|
9
21
|
|
|
10
22
|
|
|
11
23
|
class PipetteIdMixin(BaseModel):
|
|
@@ -51,72 +63,6 @@ class FlowRateMixin(BaseModel):
|
|
|
51
63
|
)
|
|
52
64
|
|
|
53
65
|
|
|
54
|
-
class WellLocationMixin(BaseModel):
|
|
55
|
-
"""Mixin for command requests that take a location that's somewhere in a well."""
|
|
56
|
-
|
|
57
|
-
labwareId: str = Field(
|
|
58
|
-
...,
|
|
59
|
-
description="Identifier of labware to use.",
|
|
60
|
-
)
|
|
61
|
-
wellName: str = Field(
|
|
62
|
-
...,
|
|
63
|
-
description="Name of well to use in labware.",
|
|
64
|
-
)
|
|
65
|
-
wellLocation: WellLocation = Field(
|
|
66
|
-
default_factory=WellLocation,
|
|
67
|
-
description="Relative well location at which to perform the operation",
|
|
68
|
-
)
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
class LiquidHandlingWellLocationMixin(BaseModel):
|
|
72
|
-
"""Mixin for command requests that take a location that's somewhere in a well."""
|
|
73
|
-
|
|
74
|
-
labwareId: str = Field(
|
|
75
|
-
...,
|
|
76
|
-
description="Identifier of labware to use.",
|
|
77
|
-
)
|
|
78
|
-
wellName: str = Field(
|
|
79
|
-
...,
|
|
80
|
-
description="Name of well to use in labware.",
|
|
81
|
-
)
|
|
82
|
-
wellLocation: LiquidHandlingWellLocation = Field(
|
|
83
|
-
default_factory=LiquidHandlingWellLocation,
|
|
84
|
-
description="Relative well location at which to perform the operation",
|
|
85
|
-
)
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
class MovementMixin(BaseModel):
|
|
89
|
-
"""Mixin for command requests that move a pipette."""
|
|
90
|
-
|
|
91
|
-
minimumZHeight: Optional[float] = Field(
|
|
92
|
-
None,
|
|
93
|
-
description=(
|
|
94
|
-
"Optional minimal Z margin in mm."
|
|
95
|
-
" If this is larger than the API's default safe Z margin,"
|
|
96
|
-
" it will make the arc higher. If it's smaller, it will have no effect."
|
|
97
|
-
),
|
|
98
|
-
)
|
|
99
|
-
|
|
100
|
-
forceDirect: bool = Field(
|
|
101
|
-
False,
|
|
102
|
-
description=(
|
|
103
|
-
"If true, moving from one labware/well to another"
|
|
104
|
-
" will not arc to the default safe z,"
|
|
105
|
-
" but instead will move directly to the specified location."
|
|
106
|
-
" This will also force the `minimumZHeight` param to be ignored."
|
|
107
|
-
" A 'direct' movement is in X/Y/Z simultaneously."
|
|
108
|
-
),
|
|
109
|
-
)
|
|
110
|
-
|
|
111
|
-
speed: Optional[float] = Field(
|
|
112
|
-
None,
|
|
113
|
-
description=(
|
|
114
|
-
"Override the travel speed in mm/s."
|
|
115
|
-
" This controls the straight linear speed of motion."
|
|
116
|
-
),
|
|
117
|
-
)
|
|
118
|
-
|
|
119
|
-
|
|
120
66
|
class BaseLiquidHandlingResult(BaseModel):
|
|
121
67
|
"""Base properties of a liquid handling result."""
|
|
122
68
|
|
|
@@ -127,24 +73,8 @@ class BaseLiquidHandlingResult(BaseModel):
|
|
|
127
73
|
)
|
|
128
74
|
|
|
129
75
|
|
|
130
|
-
class
|
|
131
|
-
"""
|
|
132
|
-
|
|
133
|
-
# todo(mm, 2024-08-02): Consider deprecating or redefining this.
|
|
134
|
-
#
|
|
135
|
-
# This is here because opentrons.protocol_engine needed it for internal bookkeeping
|
|
136
|
-
# and, at the time, we didn't have a way to do that without adding this to the
|
|
137
|
-
# public command results. Its usefulness to callers outside
|
|
138
|
-
# opentrons.protocol_engine is questionable because they would need to know which
|
|
139
|
-
# critical point is in play, and I think that can change depending on obscure
|
|
140
|
-
# things like labware quirks.
|
|
141
|
-
position: DeckPoint = Field(
|
|
142
|
-
DeckPoint(x=0, y=0, z=0),
|
|
143
|
-
description=(
|
|
144
|
-
"The (x,y,z) coordinates of the pipette's critical point in deck space"
|
|
145
|
-
" after the move was completed."
|
|
146
|
-
),
|
|
147
|
-
)
|
|
76
|
+
class EmptyResult(BaseModel):
|
|
77
|
+
"""A result with no data."""
|
|
148
78
|
|
|
149
79
|
|
|
150
80
|
class ErrorLocationInfo(TypedDict):
|
|
@@ -208,3 +138,155 @@ class TipPhysicallyAttachedError(ErrorOccurrence):
|
|
|
208
138
|
detail: str = ErrorCodes.TIP_DROP_FAILED.value.detail
|
|
209
139
|
|
|
210
140
|
errorInfo: ErrorLocationInfo
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
async def prepare_for_aspirate(
|
|
144
|
+
pipette_id: str,
|
|
145
|
+
pipetting: PipettingHandler,
|
|
146
|
+
model_utils: ModelUtils,
|
|
147
|
+
location_if_error: ErrorLocationInfo,
|
|
148
|
+
) -> SuccessData[EmptyResult] | DefinedErrorData[OverpressureError]:
|
|
149
|
+
"""Execute pipetting.prepare_for_aspirate, handle errors, and marshal success."""
|
|
150
|
+
try:
|
|
151
|
+
await pipetting.prepare_for_aspirate(pipette_id)
|
|
152
|
+
except PipetteOverpressureError as e:
|
|
153
|
+
return DefinedErrorData(
|
|
154
|
+
public=OverpressureError(
|
|
155
|
+
id=model_utils.generate_id(),
|
|
156
|
+
createdAt=model_utils.get_timestamp(),
|
|
157
|
+
wrappedErrors=[
|
|
158
|
+
ErrorOccurrence.from_failed(
|
|
159
|
+
id=model_utils.generate_id(),
|
|
160
|
+
createdAt=model_utils.get_timestamp(),
|
|
161
|
+
error=e,
|
|
162
|
+
)
|
|
163
|
+
],
|
|
164
|
+
errorInfo=location_if_error,
|
|
165
|
+
),
|
|
166
|
+
state_update=StateUpdate().set_fluid_unknown(pipette_id=pipette_id),
|
|
167
|
+
)
|
|
168
|
+
else:
|
|
169
|
+
return SuccessData(
|
|
170
|
+
public=EmptyResult(),
|
|
171
|
+
state_update=StateUpdate().set_fluid_empty(pipette_id=pipette_id),
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
async def aspirate_in_place(
|
|
176
|
+
pipette_id: str,
|
|
177
|
+
volume: float,
|
|
178
|
+
flow_rate: float,
|
|
179
|
+
location_if_error: ErrorLocationInfo,
|
|
180
|
+
command_note_adder: CommandNoteAdder,
|
|
181
|
+
pipetting: PipettingHandler,
|
|
182
|
+
model_utils: ModelUtils,
|
|
183
|
+
) -> SuccessData[BaseLiquidHandlingResult] | DefinedErrorData[OverpressureError]:
|
|
184
|
+
"""Execute an aspirate in place microoperation."""
|
|
185
|
+
try:
|
|
186
|
+
volume_aspirated = await pipetting.aspirate_in_place(
|
|
187
|
+
pipette_id=pipette_id,
|
|
188
|
+
volume=volume,
|
|
189
|
+
flow_rate=flow_rate,
|
|
190
|
+
command_note_adder=command_note_adder,
|
|
191
|
+
)
|
|
192
|
+
except PipetteOverpressureError as e:
|
|
193
|
+
return DefinedErrorData(
|
|
194
|
+
public=OverpressureError(
|
|
195
|
+
id=model_utils.generate_id(),
|
|
196
|
+
createdAt=model_utils.get_timestamp(),
|
|
197
|
+
wrappedErrors=[
|
|
198
|
+
ErrorOccurrence.from_failed(
|
|
199
|
+
id=model_utils.generate_id(),
|
|
200
|
+
createdAt=model_utils.get_timestamp(),
|
|
201
|
+
error=e,
|
|
202
|
+
)
|
|
203
|
+
],
|
|
204
|
+
errorInfo=location_if_error,
|
|
205
|
+
),
|
|
206
|
+
state_update=StateUpdate().set_fluid_unknown(pipette_id=pipette_id),
|
|
207
|
+
)
|
|
208
|
+
else:
|
|
209
|
+
return SuccessData(
|
|
210
|
+
public=BaseLiquidHandlingResult(
|
|
211
|
+
volume=volume_aspirated,
|
|
212
|
+
),
|
|
213
|
+
state_update=StateUpdate().set_fluid_aspirated(
|
|
214
|
+
pipette_id=pipette_id,
|
|
215
|
+
fluid=AspiratedFluid(kind=FluidKind.LIQUID, volume=volume_aspirated),
|
|
216
|
+
),
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
async def dispense_in_place(
|
|
221
|
+
pipette_id: str,
|
|
222
|
+
volume: float,
|
|
223
|
+
flow_rate: float,
|
|
224
|
+
push_out: float | None,
|
|
225
|
+
location_if_error: ErrorLocationInfo,
|
|
226
|
+
pipetting: PipettingHandler,
|
|
227
|
+
model_utils: ModelUtils,
|
|
228
|
+
) -> SuccessData[BaseLiquidHandlingResult] | DefinedErrorData[OverpressureError]:
|
|
229
|
+
"""Dispense-in-place as a microoperation."""
|
|
230
|
+
try:
|
|
231
|
+
volume = await pipetting.dispense_in_place(
|
|
232
|
+
pipette_id=pipette_id,
|
|
233
|
+
volume=volume,
|
|
234
|
+
flow_rate=flow_rate,
|
|
235
|
+
push_out=push_out,
|
|
236
|
+
)
|
|
237
|
+
except PipetteOverpressureError as e:
|
|
238
|
+
return DefinedErrorData(
|
|
239
|
+
public=OverpressureError(
|
|
240
|
+
id=model_utils.generate_id(),
|
|
241
|
+
createdAt=model_utils.get_timestamp(),
|
|
242
|
+
wrappedErrors=[
|
|
243
|
+
ErrorOccurrence.from_failed(
|
|
244
|
+
id=model_utils.generate_id(),
|
|
245
|
+
createdAt=model_utils.get_timestamp(),
|
|
246
|
+
error=e,
|
|
247
|
+
)
|
|
248
|
+
],
|
|
249
|
+
errorInfo=location_if_error,
|
|
250
|
+
),
|
|
251
|
+
state_update=StateUpdate().set_fluid_unknown(pipette_id=pipette_id),
|
|
252
|
+
)
|
|
253
|
+
else:
|
|
254
|
+
return SuccessData(
|
|
255
|
+
public=BaseLiquidHandlingResult(volume=volume),
|
|
256
|
+
state_update=StateUpdate().set_fluid_ejected(
|
|
257
|
+
pipette_id=pipette_id, volume=volume
|
|
258
|
+
),
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
async def blow_out_in_place(
|
|
263
|
+
pipette_id: str,
|
|
264
|
+
flow_rate: float,
|
|
265
|
+
location_if_error: ErrorLocationInfo,
|
|
266
|
+
pipetting: PipettingHandler,
|
|
267
|
+
model_utils: ModelUtils,
|
|
268
|
+
) -> SuccessData[EmptyResult] | DefinedErrorData[OverpressureError]:
|
|
269
|
+
"""Execute a blow-out-in-place micro-operation."""
|
|
270
|
+
try:
|
|
271
|
+
await pipetting.blow_out_in_place(pipette_id=pipette_id, flow_rate=flow_rate)
|
|
272
|
+
except PipetteOverpressureError as e:
|
|
273
|
+
return DefinedErrorData(
|
|
274
|
+
public=OverpressureError(
|
|
275
|
+
id=model_utils.generate_id(),
|
|
276
|
+
createdAt=model_utils.get_timestamp(),
|
|
277
|
+
wrappedErrors=[
|
|
278
|
+
ErrorOccurrence.from_failed(
|
|
279
|
+
id=model_utils.generate_id(),
|
|
280
|
+
createdAt=model_utils.get_timestamp(),
|
|
281
|
+
error=e,
|
|
282
|
+
)
|
|
283
|
+
],
|
|
284
|
+
errorInfo=location_if_error,
|
|
285
|
+
),
|
|
286
|
+
state_update=StateUpdate().set_fluid_unknown(pipette_id=pipette_id),
|
|
287
|
+
)
|
|
288
|
+
else:
|
|
289
|
+
return SuccessData(
|
|
290
|
+
public=EmptyResult(),
|
|
291
|
+
state_update=StateUpdate().set_fluid_empty(pipette_id=pipette_id),
|
|
292
|
+
)
|
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
"""Prepare to aspirate command request, result, and implementation models."""
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
|
-
from opentrons_shared_data.errors.exceptions import PipetteOverpressureError
|
|
5
4
|
from pydantic import BaseModel
|
|
6
5
|
from typing import TYPE_CHECKING, Optional, Type, Union
|
|
7
6
|
from typing_extensions import Literal
|
|
8
7
|
|
|
9
|
-
from .pipetting_common import
|
|
10
|
-
OverpressureError,
|
|
11
|
-
PipetteIdMixin,
|
|
12
|
-
)
|
|
8
|
+
from .pipetting_common import OverpressureError, PipetteIdMixin, prepare_for_aspirate
|
|
13
9
|
from .command import (
|
|
14
10
|
AbstractCommandImpl,
|
|
15
11
|
BaseCommand,
|
|
@@ -61,39 +57,34 @@ class PrepareToAspirateImplementation(
|
|
|
61
57
|
self._model_utils = model_utils
|
|
62
58
|
self._gantry_mover = gantry_mover
|
|
63
59
|
|
|
60
|
+
def _transform_result(
|
|
61
|
+
self, result: SuccessData[BaseModel]
|
|
62
|
+
) -> SuccessData[PrepareToAspirateResult]:
|
|
63
|
+
return SuccessData(
|
|
64
|
+
public=PrepareToAspirateResult(), state_update=result.state_update
|
|
65
|
+
)
|
|
66
|
+
|
|
64
67
|
async def execute(self, params: PrepareToAspirateParams) -> _ExecuteReturn:
|
|
65
68
|
"""Prepare the pipette to aspirate."""
|
|
66
69
|
current_position = await self._gantry_mover.get_position(params.pipetteId)
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
)
|
|
82
|
-
],
|
|
83
|
-
errorInfo=(
|
|
84
|
-
{
|
|
85
|
-
"retryLocation": (
|
|
86
|
-
current_position.x,
|
|
87
|
-
current_position.y,
|
|
88
|
-
current_position.z,
|
|
89
|
-
)
|
|
90
|
-
}
|
|
91
|
-
),
|
|
92
|
-
),
|
|
93
|
-
)
|
|
70
|
+
prepare_result = await prepare_for_aspirate(
|
|
71
|
+
pipette_id=params.pipetteId,
|
|
72
|
+
pipetting=self._pipetting_handler,
|
|
73
|
+
model_utils=self._model_utils,
|
|
74
|
+
location_if_error={
|
|
75
|
+
"retryLocation": (
|
|
76
|
+
current_position.x,
|
|
77
|
+
current_position.y,
|
|
78
|
+
current_position.z,
|
|
79
|
+
)
|
|
80
|
+
},
|
|
81
|
+
)
|
|
82
|
+
if isinstance(prepare_result, DefinedErrorData):
|
|
83
|
+
return prepare_result
|
|
94
84
|
else:
|
|
95
85
|
return SuccessData(
|
|
96
86
|
public=PrepareToAspirateResult(),
|
|
87
|
+
state_update=prepare_result.state_update,
|
|
97
88
|
)
|
|
98
89
|
|
|
99
90
|
|
|
@@ -104,7 +95,7 @@ class PrepareToAspirate(
|
|
|
104
95
|
|
|
105
96
|
commandType: PrepareToAspirateCommandType = "prepareToAspirate"
|
|
106
97
|
params: PrepareToAspirateParams
|
|
107
|
-
result: Optional[PrepareToAspirateResult]
|
|
98
|
+
result: Optional[PrepareToAspirateResult] = None
|
|
108
99
|
|
|
109
100
|
_ImplementationCls: Type[
|
|
110
101
|
PrepareToAspirateImplementation
|
|
@@ -89,7 +89,7 @@ class ReloadLabware(
|
|
|
89
89
|
|
|
90
90
|
commandType: ReloadLabwareCommandType = "reloadLabware"
|
|
91
91
|
params: ReloadLabwareParams
|
|
92
|
-
result: Optional[ReloadLabwareResult]
|
|
92
|
+
result: Optional[ReloadLabwareResult] = None
|
|
93
93
|
|
|
94
94
|
_ImplementationCls: Type[ReloadLabwareImplementation] = ReloadLabwareImplementation
|
|
95
95
|
|
|
@@ -61,7 +61,7 @@ class RetractAxis(BaseCommand[RetractAxisParams, RetractAxisResult, ErrorOccurre
|
|
|
61
61
|
|
|
62
62
|
commandType: RetractAxisCommandType = "retractAxis"
|
|
63
63
|
params: RetractAxisParams
|
|
64
|
-
result: Optional[RetractAxisResult]
|
|
64
|
+
result: Optional[RetractAxisResult] = None
|
|
65
65
|
|
|
66
66
|
_ImplementationCls: Type[RetractAxisImplementation] = RetractAxisImplementation
|
|
67
67
|
|
|
@@ -1 +1,70 @@
|
|
|
1
1
|
"""Robot movement commands."""
|
|
2
|
+
|
|
3
|
+
from .move_to import (
|
|
4
|
+
MoveTo,
|
|
5
|
+
MoveToCreate,
|
|
6
|
+
MoveToParams,
|
|
7
|
+
MoveToResult,
|
|
8
|
+
MoveToCommandType,
|
|
9
|
+
)
|
|
10
|
+
from .move_axes_to import (
|
|
11
|
+
MoveAxesTo,
|
|
12
|
+
MoveAxesToCreate,
|
|
13
|
+
MoveAxesToParams,
|
|
14
|
+
MoveAxesToResult,
|
|
15
|
+
MoveAxesToCommandType,
|
|
16
|
+
)
|
|
17
|
+
from .move_axes_relative import (
|
|
18
|
+
MoveAxesRelative,
|
|
19
|
+
MoveAxesRelativeCreate,
|
|
20
|
+
MoveAxesRelativeParams,
|
|
21
|
+
MoveAxesRelativeResult,
|
|
22
|
+
MoveAxesRelativeCommandType,
|
|
23
|
+
)
|
|
24
|
+
from .open_gripper_jaw import (
|
|
25
|
+
openGripperJaw,
|
|
26
|
+
openGripperJawCreate,
|
|
27
|
+
openGripperJawParams,
|
|
28
|
+
openGripperJawResult,
|
|
29
|
+
openGripperJawCommandType,
|
|
30
|
+
)
|
|
31
|
+
from .close_gripper_jaw import (
|
|
32
|
+
closeGripperJaw,
|
|
33
|
+
closeGripperJawCreate,
|
|
34
|
+
closeGripperJawParams,
|
|
35
|
+
closeGripperJawResult,
|
|
36
|
+
closeGripperJawCommandType,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
__all__ = [
|
|
40
|
+
# robot/moveTo
|
|
41
|
+
"MoveTo",
|
|
42
|
+
"MoveToCreate",
|
|
43
|
+
"MoveToParams",
|
|
44
|
+
"MoveToResult",
|
|
45
|
+
"MoveToCommandType",
|
|
46
|
+
# robot/moveAxesTo
|
|
47
|
+
"MoveAxesTo",
|
|
48
|
+
"MoveAxesToCreate",
|
|
49
|
+
"MoveAxesToParams",
|
|
50
|
+
"MoveAxesToResult",
|
|
51
|
+
"MoveAxesToCommandType",
|
|
52
|
+
# robot/moveAxesRelative
|
|
53
|
+
"MoveAxesRelative",
|
|
54
|
+
"MoveAxesRelativeCreate",
|
|
55
|
+
"MoveAxesRelativeParams",
|
|
56
|
+
"MoveAxesRelativeResult",
|
|
57
|
+
"MoveAxesRelativeCommandType",
|
|
58
|
+
# robot/openGripperJaw
|
|
59
|
+
"openGripperJaw",
|
|
60
|
+
"openGripperJawCreate",
|
|
61
|
+
"openGripperJawParams",
|
|
62
|
+
"openGripperJawResult",
|
|
63
|
+
"openGripperJawCommandType",
|
|
64
|
+
# robot/closeGripperJaw
|
|
65
|
+
"closeGripperJaw",
|
|
66
|
+
"closeGripperJawCreate",
|
|
67
|
+
"closeGripperJawParams",
|
|
68
|
+
"closeGripperJawResult",
|
|
69
|
+
"closeGripperJawCommandType",
|
|
70
|
+
]
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"""Command models for opening a gripper jaw."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
from typing import Literal, Type, Optional, Any
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel, Field
|
|
6
|
+
from pydantic.json_schema import SkipJsonSchema
|
|
7
|
+
|
|
8
|
+
from opentrons.hardware_control import HardwareControlAPI
|
|
9
|
+
from opentrons.protocol_engine.resources import ensure_ot3_hardware
|
|
10
|
+
|
|
11
|
+
from ..command import (
|
|
12
|
+
AbstractCommandImpl,
|
|
13
|
+
BaseCommand,
|
|
14
|
+
BaseCommandCreate,
|
|
15
|
+
SuccessData,
|
|
16
|
+
)
|
|
17
|
+
from opentrons.protocol_engine.errors.error_occurrence import ErrorOccurrence
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
closeGripperJawCommandType = Literal["robot/closeGripperJaw"]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _remove_default(s: dict[str, Any]) -> None:
|
|
24
|
+
s.pop("default", None)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class closeGripperJawParams(BaseModel):
|
|
28
|
+
"""Payload required to close a gripper."""
|
|
29
|
+
|
|
30
|
+
force: float | SkipJsonSchema[None] = Field(
|
|
31
|
+
default=None,
|
|
32
|
+
description="The force the gripper should use to hold the jaws, falls to default if none is provided.",
|
|
33
|
+
json_schema_extra=_remove_default,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class closeGripperJawResult(BaseModel):
|
|
38
|
+
"""Result data from the execution of a closeGripperJaw command."""
|
|
39
|
+
|
|
40
|
+
pass
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class closeGripperJawImplementation(
|
|
44
|
+
AbstractCommandImpl[closeGripperJawParams, SuccessData[closeGripperJawResult]]
|
|
45
|
+
):
|
|
46
|
+
"""closeGripperJaw command implementation."""
|
|
47
|
+
|
|
48
|
+
def __init__(
|
|
49
|
+
self,
|
|
50
|
+
hardware_api: HardwareControlAPI,
|
|
51
|
+
**kwargs: object,
|
|
52
|
+
) -> None:
|
|
53
|
+
self._hardware_api = hardware_api
|
|
54
|
+
|
|
55
|
+
async def execute(
|
|
56
|
+
self, params: closeGripperJawParams
|
|
57
|
+
) -> SuccessData[closeGripperJawResult]:
|
|
58
|
+
"""Release the gripper."""
|
|
59
|
+
ot3_hardware_api = ensure_ot3_hardware(self._hardware_api)
|
|
60
|
+
await ot3_hardware_api.grip(force_newtons=params.force)
|
|
61
|
+
return SuccessData(
|
|
62
|
+
public=closeGripperJawResult(),
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class closeGripperJaw(
|
|
67
|
+
BaseCommand[closeGripperJawParams, closeGripperJawResult, ErrorOccurrence]
|
|
68
|
+
):
|
|
69
|
+
"""closeGripperJaw command model."""
|
|
70
|
+
|
|
71
|
+
commandType: closeGripperJawCommandType = "robot/closeGripperJaw"
|
|
72
|
+
params: closeGripperJawParams
|
|
73
|
+
result: Optional[closeGripperJawResult] = None
|
|
74
|
+
|
|
75
|
+
_ImplementationCls: Type[
|
|
76
|
+
closeGripperJawImplementation
|
|
77
|
+
] = closeGripperJawImplementation
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class closeGripperJawCreate(BaseCommandCreate[closeGripperJawParams]):
|
|
81
|
+
"""closeGripperJaw command request model."""
|
|
82
|
+
|
|
83
|
+
commandType: closeGripperJawCommandType = "robot/closeGripperJaw"
|
|
84
|
+
params: closeGripperJawParams
|
|
85
|
+
|
|
86
|
+
_CommandCls: Type[closeGripperJaw] = closeGripperJaw
|