opentrons 8.3.0a0__py2.py3-none-any.whl → 8.3.0a2__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/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 +28 -20
- opentrons/hardware_control/backends/flex_protocol.py +4 -6
- opentrons/hardware_control/backends/ot3controller.py +177 -59
- opentrons/hardware_control/backends/ot3simulator.py +10 -8
- opentrons/hardware_control/backends/ot3utils.py +3 -13
- opentrons/hardware_control/dev_types.py +2 -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 +9 -21
- 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 +13 -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 +34 -22
- 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 +18 -0
- opentrons/hardware_control/protocols/motion_controller.py +6 -0
- opentrons/hardware_control/robot_calibration.py +1 -1
- opentrons/hardware_control/types.py +61 -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 +67 -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 +42 -4
- opentrons/protocol_api/core/labware.py +13 -4
- opentrons/protocol_api/core/legacy/legacy_instrument_core.py +34 -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 +34 -3
- opentrons/protocol_api/core/protocol.py +34 -1
- opentrons/protocol_api/core/robot.py +51 -0
- opentrons/protocol_api/instrument_context.py +145 -43
- opentrons/protocol_api/labware.py +231 -7
- 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 +261 -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 +81 -0
- opentrons/protocol_engine/commands/absorbance_reader/close_lid.py +0 -2
- opentrons/protocol_engine/commands/absorbance_reader/initialize.py +19 -5
- opentrons/protocol_engine/commands/absorbance_reader/open_lid.py +0 -1
- opentrons/protocol_engine/commands/absorbance_reader/read.py +32 -9
- 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 +101 -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 +13 -3
- 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 +60 -25
- opentrons/protocol_engine/commands/load_labware.py +29 -7
- 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 +19 -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 +8 -2
- 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 +4 -1
- opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py +12 -3
- opentrons/protocol_engine/commands/unsafe/unsafe_engage_axes.py +1 -4
- opentrons/protocol_engine/commands/unsafe/update_position_estimators.py +1 -4
- 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 +8 -0
- opentrons/protocol_engine/errors/error_occurrence.py +19 -20
- opentrons/protocol_engine/errors/exceptions.py +50 -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 +364 -8
- opentrons/protocol_engine/execution/movement.py +27 -0
- opentrons/protocol_engine/execution/pipetting.py +5 -1
- opentrons/protocol_engine/execution/tip_handler.py +4 -6
- 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 +5 -0
- opentrons/protocol_engine/resources/module_data_provider.py +1 -1
- opentrons/protocol_engine/resources/pipette_data_provider.py +12 -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 +17 -13
- opentrons/protocol_engine/state/files.py +10 -12
- opentrons/protocol_engine/state/fluid_stack.py +138 -0
- opentrons/protocol_engine/state/frustum_helpers.py +57 -32
- opentrons/protocol_engine/state/geometry.py +47 -1
- opentrons/protocol_engine/state/labware.py +79 -25
- opentrons/protocol_engine/state/liquid_classes.py +82 -0
- opentrons/protocol_engine/state/liquids.py +16 -4
- opentrons/protocol_engine/state/modules.py +52 -70
- opentrons/protocol_engine/state/motion.py +6 -1
- opentrons/protocol_engine/state/pipettes.py +135 -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.3.0a0.dist-info → opentrons-8.3.0a2.dist-info}/METADATA +16 -15
- {opentrons-8.3.0a0.dist-info → opentrons-8.3.0a2.dist-info}/RECORD +229 -202
- {opentrons-8.3.0a0.dist-info → opentrons-8.3.0a2.dist-info}/WHEEL +1 -1
- {opentrons-8.3.0a0.dist-info → opentrons-8.3.0a2.dist-info}/LICENSE +0 -0
- {opentrons-8.3.0a0.dist-info → opentrons-8.3.0a2.dist-info}/entry_points.txt +0 -0
- {opentrons-8.3.0a0.dist-info → opentrons-8.3.0a2.dist-info}/top_level.txt +0 -0
|
@@ -46,7 +46,6 @@ from opentrons.config.types import (
|
|
|
46
46
|
LiquidProbeSettings,
|
|
47
47
|
)
|
|
48
48
|
from opentrons.drivers.rpi_drivers.types import USBPort, PortGroup
|
|
49
|
-
from opentrons.hardware_control.nozzle_manager import NozzleConfigurationType
|
|
50
49
|
from opentrons_shared_data.errors.exceptions import (
|
|
51
50
|
EnumeratedError,
|
|
52
51
|
PythonException,
|
|
@@ -99,6 +98,7 @@ from .types import (
|
|
|
99
98
|
EstopState,
|
|
100
99
|
HardwareFeatureFlags,
|
|
101
100
|
FailedTipStateCheck,
|
|
101
|
+
PipetteSensorResponseQueue,
|
|
102
102
|
)
|
|
103
103
|
from .errors import (
|
|
104
104
|
UpdateOngoingError,
|
|
@@ -144,8 +144,6 @@ from .backends.types import HWStopCondition
|
|
|
144
144
|
from .backends.flex_protocol import FlexBackend
|
|
145
145
|
from .backends.ot3simulator import OT3Simulator
|
|
146
146
|
from .backends.errors import SubsystemUpdating
|
|
147
|
-
from opentrons_hardware.firmware_bindings.constants import SensorId
|
|
148
|
-
from opentrons_hardware.sensors.types import SensorDataType
|
|
149
147
|
|
|
150
148
|
mod_log = logging.getLogger(__name__)
|
|
151
149
|
|
|
@@ -357,7 +355,9 @@ class OT3API(
|
|
|
357
355
|
def _reset_last_mount(self) -> None:
|
|
358
356
|
self._last_moved_mount = None
|
|
359
357
|
|
|
360
|
-
def
|
|
358
|
+
def get_deck_from_machine(
|
|
359
|
+
self, machine_pos: Dict[Axis, float]
|
|
360
|
+
) -> Dict[Axis, float]:
|
|
361
361
|
return deck_from_machine(
|
|
362
362
|
machine_pos=machine_pos,
|
|
363
363
|
attitude=self._robot_calibration.deck_calibration.attitude,
|
|
@@ -800,6 +800,8 @@ class OT3API(
|
|
|
800
800
|
"""
|
|
801
801
|
Function to update motor estimation for a set of axes
|
|
802
802
|
"""
|
|
803
|
+
await self._backend.update_motor_status()
|
|
804
|
+
|
|
803
805
|
if axes is None:
|
|
804
806
|
axes = [ax for ax in Axis]
|
|
805
807
|
|
|
@@ -968,8 +970,8 @@ class OT3API(
|
|
|
968
970
|
):
|
|
969
971
|
# move toward home until a safe distance
|
|
970
972
|
await self._backend.tip_action(
|
|
971
|
-
origin=
|
|
972
|
-
targets=[(
|
|
973
|
+
origin=current_pos_float,
|
|
974
|
+
targets=[(self._config.safe_home_distance, 400)],
|
|
973
975
|
)
|
|
974
976
|
|
|
975
977
|
# update current position
|
|
@@ -1046,14 +1048,14 @@ class OT3API(
|
|
|
1046
1048
|
|
|
1047
1049
|
async def _cache_current_position(self) -> Dict[Axis, float]:
|
|
1048
1050
|
"""Cache current position from backend and return in absolute deck coords."""
|
|
1049
|
-
self._current_position = self.
|
|
1051
|
+
self._current_position = self.get_deck_from_machine(
|
|
1050
1052
|
await self._backend.update_position()
|
|
1051
1053
|
)
|
|
1052
1054
|
return self._current_position
|
|
1053
1055
|
|
|
1054
1056
|
async def _cache_encoder_position(self) -> Dict[Axis, float]:
|
|
1055
1057
|
"""Cache encoder position from backend and return in absolute deck coords."""
|
|
1056
|
-
self._encoder_position = self.
|
|
1058
|
+
self._encoder_position = self.get_deck_from_machine(
|
|
1057
1059
|
await self._backend.update_encoder_position()
|
|
1058
1060
|
)
|
|
1059
1061
|
if self.has_gripper():
|
|
@@ -1253,7 +1255,9 @@ class OT3API(
|
|
|
1253
1255
|
message=f"{axis} is not present", detail={"axis": str(axis)}
|
|
1254
1256
|
)
|
|
1255
1257
|
|
|
1258
|
+
self._log.info(f"Attempting to move {position} with speed {speed}.")
|
|
1256
1259
|
if not self._backend.check_encoder_status(list(position.keys())):
|
|
1260
|
+
self._log.info("Calling home in move_axes")
|
|
1257
1261
|
await self.home()
|
|
1258
1262
|
self._assert_motor_ok(list(position.keys()))
|
|
1259
1263
|
|
|
@@ -1464,6 +1468,10 @@ class OT3API(
|
|
|
1464
1468
|
check_motion_bounds(to_check, target_position, bounds, check_bounds)
|
|
1465
1469
|
self._log.info(f"Move: deck {target_position} becomes machine {machine_pos}")
|
|
1466
1470
|
origin = await self._backend.update_position()
|
|
1471
|
+
|
|
1472
|
+
if self._gantry_load == GantryLoad.HIGH_THROUGHPUT:
|
|
1473
|
+
origin[Axis.Q] = self._backend.gear_motor_position or 0.0
|
|
1474
|
+
|
|
1467
1475
|
async with contextlib.AsyncExitStack() as stack:
|
|
1468
1476
|
if acquire_lock:
|
|
1469
1477
|
await stack.enter_async_context(self._motion_lock)
|
|
@@ -1665,7 +1673,12 @@ class OT3API(
|
|
|
1665
1673
|
await self._backend.disengage_axes(which)
|
|
1666
1674
|
|
|
1667
1675
|
async def engage_axes(self, which: List[Axis]) -> None:
|
|
1668
|
-
await self._backend.engage_axes(
|
|
1676
|
+
await self._backend.engage_axes(
|
|
1677
|
+
[axis for axis in which if self._backend.axis_is_present(axis)]
|
|
1678
|
+
)
|
|
1679
|
+
|
|
1680
|
+
def axis_is_present(self, axis: Axis) -> bool:
|
|
1681
|
+
return self._backend.axis_is_present(axis)
|
|
1669
1682
|
|
|
1670
1683
|
async def get_limit_switches(self) -> Dict[Axis, bool]:
|
|
1671
1684
|
res = await self._backend.get_limit_switches()
|
|
@@ -1851,7 +1864,7 @@ class OT3API(
|
|
|
1851
1864
|
if (
|
|
1852
1865
|
self.gantry_load == GantryLoad.HIGH_THROUGHPUT
|
|
1853
1866
|
and instrument.nozzle_manager.current_configuration.configuration
|
|
1854
|
-
== NozzleConfigurationType.FULL
|
|
1867
|
+
== top_types.NozzleConfigurationType.FULL
|
|
1855
1868
|
):
|
|
1856
1869
|
spec = self._pipette_handler.plan_ht_pick_up_tip(
|
|
1857
1870
|
instrument.nozzle_manager.current_configuration.tip_count
|
|
@@ -2181,8 +2194,8 @@ class OT3API(
|
|
|
2181
2194
|
# only move tip motors if they are not already below the sensor
|
|
2182
2195
|
if tip_motor_pos_float < tip_presence_check_target:
|
|
2183
2196
|
await self._backend.tip_action(
|
|
2184
|
-
origin=
|
|
2185
|
-
targets=[(
|
|
2197
|
+
origin=tip_motor_pos_float,
|
|
2198
|
+
targets=[(tip_presence_check_target, 400)],
|
|
2186
2199
|
)
|
|
2187
2200
|
try:
|
|
2188
2201
|
yield
|
|
@@ -2253,11 +2266,11 @@ class OT3API(
|
|
|
2253
2266
|
gear_origin_float = self._backend.gear_motor_position or 0.0
|
|
2254
2267
|
|
|
2255
2268
|
move_targets = [
|
|
2256
|
-
(
|
|
2269
|
+
(move_segment.distance, move_segment.speed or 400)
|
|
2257
2270
|
for move_segment in pipette_spec
|
|
2258
2271
|
]
|
|
2259
2272
|
await self._backend.tip_action(
|
|
2260
|
-
origin=
|
|
2273
|
+
origin=gear_origin_float, targets=move_targets
|
|
2261
2274
|
)
|
|
2262
2275
|
await self.home_gear_motors()
|
|
2263
2276
|
|
|
@@ -2582,7 +2595,7 @@ class OT3API(
|
|
|
2582
2595
|
mount: Union[top_types.Mount, OT3Mount],
|
|
2583
2596
|
critical_point: Optional[CriticalPoint] = None,
|
|
2584
2597
|
) -> float:
|
|
2585
|
-
carriage_pos = self.
|
|
2598
|
+
carriage_pos = self.get_deck_from_machine(self._backend.home_position())
|
|
2586
2599
|
pos_at_home = self._effector_pos_from_carriage_pos(
|
|
2587
2600
|
OT3Mount.from_mount(mount), carriage_pos, critical_point
|
|
2588
2601
|
)
|
|
@@ -2664,10 +2677,9 @@ class OT3API(
|
|
|
2664
2677
|
probe_settings: LiquidProbeSettings,
|
|
2665
2678
|
probe: InstrumentProbeType,
|
|
2666
2679
|
p_travel: float,
|
|
2680
|
+
z_offset_for_plunger_prep: float,
|
|
2667
2681
|
force_both_sensors: bool = False,
|
|
2668
|
-
response_queue: Optional[
|
|
2669
|
-
asyncio.Queue[Dict[SensorId, List[SensorDataType]]]
|
|
2670
|
-
] = None,
|
|
2682
|
+
response_queue: Optional[PipetteSensorResponseQueue] = None,
|
|
2671
2683
|
) -> float:
|
|
2672
2684
|
plunger_direction = -1 if probe_settings.aspirate_while_sensing else 1
|
|
2673
2685
|
end_z = await self._backend.liquid_probe(
|
|
@@ -2678,13 +2690,14 @@ class OT3API(
|
|
|
2678
2690
|
probe_settings.sensor_threshold_pascals,
|
|
2679
2691
|
probe_settings.plunger_impulse_time,
|
|
2680
2692
|
probe_settings.samples_for_baselining,
|
|
2693
|
+
z_offset_for_plunger_prep,
|
|
2681
2694
|
probe=probe,
|
|
2682
2695
|
force_both_sensors=force_both_sensors,
|
|
2683
2696
|
response_queue=response_queue,
|
|
2684
2697
|
)
|
|
2685
2698
|
machine_pos = await self._backend.update_position()
|
|
2686
2699
|
machine_pos[Axis.by_mount(mount)] = end_z
|
|
2687
|
-
deck_end_z = self.
|
|
2700
|
+
deck_end_z = self.get_deck_from_machine(machine_pos)[Axis.by_mount(mount)]
|
|
2688
2701
|
offset = offset_for_mount(
|
|
2689
2702
|
mount,
|
|
2690
2703
|
top_types.Point(*self._config.left_mount_offset),
|
|
@@ -2701,9 +2714,7 @@ class OT3API(
|
|
|
2701
2714
|
probe_settings: Optional[LiquidProbeSettings] = None,
|
|
2702
2715
|
probe: Optional[InstrumentProbeType] = None,
|
|
2703
2716
|
force_both_sensors: bool = False,
|
|
2704
|
-
response_queue: Optional[
|
|
2705
|
-
asyncio.Queue[Dict[SensorId, List[SensorDataType]]]
|
|
2706
|
-
] = None,
|
|
2717
|
+
response_queue: Optional[PipetteSensorResponseQueue] = None,
|
|
2707
2718
|
) -> float:
|
|
2708
2719
|
"""Search for and return liquid level height.
|
|
2709
2720
|
|
|
@@ -2829,6 +2840,7 @@ class OT3API(
|
|
|
2829
2840
|
probe_settings,
|
|
2830
2841
|
checked_probe,
|
|
2831
2842
|
plunger_travel_mm + sensor_baseline_plunger_move_mm,
|
|
2843
|
+
z_offset_for_plunger_prep,
|
|
2832
2844
|
force_both_sensors,
|
|
2833
2845
|
response_queue,
|
|
2834
2846
|
)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from typing import Dict, Optional
|
|
2
2
|
from typing_extensions import Protocol
|
|
3
3
|
|
|
4
|
-
from ..types import SubSystem, SubSystemState
|
|
4
|
+
from ..types import SubSystem, SubSystemState, Axis
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class HardwareManager(Protocol):
|
|
@@ -45,3 +45,7 @@ class HardwareManager(Protocol):
|
|
|
45
45
|
async def get_serial_number(self) -> Optional[str]:
|
|
46
46
|
"""Get the robot serial number, if provisioned. If not provisioned, will be None."""
|
|
47
47
|
...
|
|
48
|
+
|
|
49
|
+
def axis_is_present(self, axis: Axis) -> bool:
|
|
50
|
+
"""Get whether a motor axis is present on the machine."""
|
|
51
|
+
...
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
from typing import Optional
|
|
2
2
|
from typing_extensions import Protocol
|
|
3
3
|
|
|
4
|
+
from opentrons.types import Point
|
|
5
|
+
from opentrons.hardware_control.types import CriticalPoint
|
|
4
6
|
from .types import MountArgType, CalibrationType, ConfigType
|
|
5
7
|
|
|
6
8
|
from .instrument_configurer import InstrumentConfigurer
|
|
@@ -16,6 +18,22 @@ class LiquidHandler(
|
|
|
16
18
|
Calibratable[CalibrationType],
|
|
17
19
|
Protocol[CalibrationType, MountArgType, ConfigType],
|
|
18
20
|
):
|
|
21
|
+
def critical_point_for(
|
|
22
|
+
self,
|
|
23
|
+
mount: MountArgType,
|
|
24
|
+
cp_override: Optional[CriticalPoint] = None,
|
|
25
|
+
) -> Point:
|
|
26
|
+
"""
|
|
27
|
+
Determine the current critical point for the specified mount.
|
|
28
|
+
|
|
29
|
+
:param mount: A robot mount that the instrument is on.
|
|
30
|
+
:param cp_override: The critical point override to use.
|
|
31
|
+
|
|
32
|
+
If no critical point override is specified, the robot defaults to nozzle location `A1` or the mount critical point.
|
|
33
|
+
:return: Point.
|
|
34
|
+
"""
|
|
35
|
+
...
|
|
36
|
+
|
|
19
37
|
async def update_nozzle_configuration_for_mount(
|
|
20
38
|
self,
|
|
21
39
|
mount: MountArgType,
|
|
@@ -9,6 +9,12 @@ from .types import MountArgType
|
|
|
9
9
|
class MotionController(Protocol[MountArgType]):
|
|
10
10
|
"""Protocol specifying fundamental motion controls."""
|
|
11
11
|
|
|
12
|
+
def get_deck_from_machine(
|
|
13
|
+
self, machine_pos: Dict[Axis, float]
|
|
14
|
+
) -> Dict[Axis, float]:
|
|
15
|
+
"""Convert machine coordinates to deck coordinates."""
|
|
16
|
+
...
|
|
17
|
+
|
|
12
18
|
async def halt(self, disengage_before_stopping: bool = False) -> None:
|
|
13
19
|
"""Immediately stop motion.
|
|
14
20
|
|
|
@@ -154,7 +154,7 @@ def load_attitude_matrix() -> DeckCalibration:
|
|
|
154
154
|
return DeckCalibration(
|
|
155
155
|
attitude=calibration_data.attitude,
|
|
156
156
|
source=calibration_data.source,
|
|
157
|
-
status=types.CalibrationStatus(**calibration_data.status.
|
|
157
|
+
status=types.CalibrationStatus(**calibration_data.status.model_dump()),
|
|
158
158
|
last_modified=calibration_data.last_modified,
|
|
159
159
|
pipette_calibrated_with=calibration_data.pipette_calibrated_with,
|
|
160
160
|
tiprack=calibration_data.tiprack,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from asyncio import Queue
|
|
1
2
|
import enum
|
|
2
3
|
import logging
|
|
3
4
|
from dataclasses import dataclass
|
|
@@ -712,3 +713,63 @@ class FailedTipStateCheck(RuntimeError):
|
|
|
712
713
|
super().__init__(
|
|
713
714
|
f"Expected tip state {expected_state}, but received {actual_state}."
|
|
714
715
|
)
|
|
716
|
+
|
|
717
|
+
|
|
718
|
+
@enum.unique
|
|
719
|
+
class PipetteSensorId(int, enum.Enum):
|
|
720
|
+
"""Sensor IDs available.
|
|
721
|
+
|
|
722
|
+
Not to be confused with SensorType. This is the ID value that separate
|
|
723
|
+
two or more of the same type of sensor within a system.
|
|
724
|
+
|
|
725
|
+
Note that this is a copy of an enum defined in opentrons_hardware.firmware_bindings.constants. That version
|
|
726
|
+
is authoritative; this version is here because this data is exposed above the hardware control layer and
|
|
727
|
+
therefore needs a typing source here so that we don't create a dependency on the internal hardware package.
|
|
728
|
+
"""
|
|
729
|
+
|
|
730
|
+
S0 = 0x0
|
|
731
|
+
S1 = 0x1
|
|
732
|
+
UNUSED = 0x2
|
|
733
|
+
BOTH = 0x3
|
|
734
|
+
|
|
735
|
+
|
|
736
|
+
@enum.unique
|
|
737
|
+
class PipetteSensorType(int, enum.Enum):
|
|
738
|
+
"""Sensor types available.
|
|
739
|
+
|
|
740
|
+
Note that this is a copy of an enum defined in opentrons_hardware.firmware_bindings.constants. That version
|
|
741
|
+
is authoritative; this version is here because this data is exposed above the hardware control layer and
|
|
742
|
+
therefore needs a typing source here so that we don't create a dependency on the internal hardware package.
|
|
743
|
+
"""
|
|
744
|
+
|
|
745
|
+
tip = 0x00
|
|
746
|
+
capacitive = 0x01
|
|
747
|
+
environment = 0x02
|
|
748
|
+
pressure = 0x03
|
|
749
|
+
pressure_temperature = 0x04
|
|
750
|
+
humidity = 0x05
|
|
751
|
+
temperature = 0x06
|
|
752
|
+
|
|
753
|
+
|
|
754
|
+
@dataclass(frozen=True)
|
|
755
|
+
class PipetteSensorData:
|
|
756
|
+
"""Sensor data from a monitored sensor.
|
|
757
|
+
|
|
758
|
+
Note that this is a copy of an enum defined in opentrons_hardware.firmware_bindings.constants. That version
|
|
759
|
+
is authoritative; this version is here because this data is exposed above the hardware control layer and
|
|
760
|
+
therefore needs a typing source here so that we don't create a dependency on the internal hardware package.
|
|
761
|
+
"""
|
|
762
|
+
|
|
763
|
+
sensor_type: PipetteSensorType
|
|
764
|
+
_as_int: int
|
|
765
|
+
_as_float: float
|
|
766
|
+
|
|
767
|
+
def to_float(self) -> float:
|
|
768
|
+
return self._as_float
|
|
769
|
+
|
|
770
|
+
@property
|
|
771
|
+
def to_int(self) -> int:
|
|
772
|
+
return self._as_int
|
|
773
|
+
|
|
774
|
+
|
|
775
|
+
PipetteSensorResponseQueue = Queue[Dict[PipetteSensorId, List[PipetteSensorData]]]
|
|
@@ -30,7 +30,16 @@ from .module_contexts import (
|
|
|
30
30
|
)
|
|
31
31
|
from .disposal_locations import TrashBin, WasteChute
|
|
32
32
|
from ._liquid import Liquid, LiquidClass
|
|
33
|
-
from ._types import
|
|
33
|
+
from ._types import (
|
|
34
|
+
OFF_DECK,
|
|
35
|
+
PLUNGER_BLOWOUT,
|
|
36
|
+
PLUNGER_TOP,
|
|
37
|
+
PLUNGER_BOTTOM,
|
|
38
|
+
PLUNGER_DROPTIP,
|
|
39
|
+
ASPIRATE_ACTION,
|
|
40
|
+
DISPENSE_ACTION,
|
|
41
|
+
BLOWOUT_ACTION,
|
|
42
|
+
)
|
|
34
43
|
from ._nozzle_layout import (
|
|
35
44
|
COLUMN,
|
|
36
45
|
PARTIAL_COLUMN,
|
|
@@ -69,12 +78,22 @@ __all__ = [
|
|
|
69
78
|
"Liquid",
|
|
70
79
|
"LiquidClass",
|
|
71
80
|
"Parameters",
|
|
81
|
+
# Partial Tip types
|
|
72
82
|
"COLUMN",
|
|
73
83
|
"PARTIAL_COLUMN",
|
|
74
84
|
"SINGLE",
|
|
75
85
|
"ROW",
|
|
76
86
|
"ALL",
|
|
87
|
+
# Deck location types
|
|
77
88
|
"OFF_DECK",
|
|
89
|
+
# Pipette plunger types
|
|
90
|
+
"PLUNGER_BLOWOUT",
|
|
91
|
+
"PLUNGER_TOP",
|
|
92
|
+
"PLUNGER_BOTTOM",
|
|
93
|
+
"PLUNGER_DROPTIP",
|
|
94
|
+
"ASPIRATE_ACTION",
|
|
95
|
+
"DISPENSE_ACTION",
|
|
96
|
+
"BLOWOUT_ACTION",
|
|
78
97
|
"RuntimeParameterRequiredError",
|
|
79
98
|
"CSVParameter",
|
|
80
99
|
# For internal Opentrons use only:
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
from dataclasses import dataclass
|
|
2
|
-
from typing import Optional,
|
|
4
|
+
from typing import Optional, Dict
|
|
3
5
|
|
|
4
6
|
from opentrons_shared_data.liquid_classes.liquid_class_definition import (
|
|
5
7
|
LiquidClassSchemaV1,
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
from ._liquid_properties import (
|
|
11
|
+
TransferProperties,
|
|
12
|
+
build_transfer_properties,
|
|
11
13
|
)
|
|
12
14
|
|
|
13
15
|
|
|
@@ -29,46 +31,29 @@ class Liquid:
|
|
|
29
31
|
display_color: Optional[str]
|
|
30
32
|
|
|
31
33
|
|
|
32
|
-
# TODO (spp, 2024-10-17): create PAPI-equivalent types for all the properties
|
|
33
|
-
# and have validation on value updates with user-facing error messages
|
|
34
|
-
@dataclass
|
|
35
|
-
class TransferProperties:
|
|
36
|
-
_aspirate: AspirateProperties
|
|
37
|
-
_dispense: SingleDispenseProperties
|
|
38
|
-
_multi_dispense: Optional[MultiDispenseProperties]
|
|
39
|
-
|
|
40
|
-
@property
|
|
41
|
-
def aspirate(self) -> AspirateProperties:
|
|
42
|
-
"""Aspirate properties."""
|
|
43
|
-
return self._aspirate
|
|
44
|
-
|
|
45
|
-
@property
|
|
46
|
-
def dispense(self) -> SingleDispenseProperties:
|
|
47
|
-
"""Single dispense properties."""
|
|
48
|
-
return self._dispense
|
|
49
|
-
|
|
50
|
-
@property
|
|
51
|
-
def multi_dispense(self) -> Optional[MultiDispenseProperties]:
|
|
52
|
-
"""Multi dispense properties."""
|
|
53
|
-
return self._multi_dispense
|
|
54
|
-
|
|
55
|
-
|
|
56
34
|
@dataclass
|
|
57
35
|
class LiquidClass:
|
|
58
36
|
"""A data class that contains properties of a specific class of liquids."""
|
|
59
37
|
|
|
60
38
|
_name: str
|
|
61
39
|
_display_name: str
|
|
62
|
-
_by_pipette_setting:
|
|
40
|
+
_by_pipette_setting: Dict[str, Dict[str, TransferProperties]]
|
|
63
41
|
|
|
64
42
|
@classmethod
|
|
65
43
|
def create(cls, liquid_class_definition: LiquidClassSchemaV1) -> "LiquidClass":
|
|
66
44
|
"""Liquid class factory method."""
|
|
67
45
|
|
|
46
|
+
by_pipette_settings: Dict[str, Dict[str, TransferProperties]] = {}
|
|
47
|
+
for by_pipette in liquid_class_definition.byPipette:
|
|
48
|
+
tip_settings: Dict[str, TransferProperties] = {}
|
|
49
|
+
for tip_type in by_pipette.byTipType:
|
|
50
|
+
tip_settings[tip_type.tiprack] = build_transfer_properties(tip_type)
|
|
51
|
+
by_pipette_settings[by_pipette.pipetteModel] = tip_settings
|
|
52
|
+
|
|
68
53
|
return cls(
|
|
69
54
|
_name=liquid_class_definition.liquidClassName,
|
|
70
55
|
_display_name=liquid_class_definition.displayName,
|
|
71
|
-
_by_pipette_setting=
|
|
56
|
+
_by_pipette_setting=by_pipette_settings,
|
|
72
57
|
)
|
|
73
58
|
|
|
74
59
|
@property
|
|
@@ -81,26 +66,16 @@ class LiquidClass:
|
|
|
81
66
|
|
|
82
67
|
def get_for(self, pipette: str, tiprack: str) -> TransferProperties:
|
|
83
68
|
"""Get liquid class transfer properties for the specified pipette and tip."""
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
if pip_setting.pipetteModel == pipette
|
|
88
|
-
]
|
|
89
|
-
if len(settings_for_pipette) == 0:
|
|
69
|
+
try:
|
|
70
|
+
settings_for_pipette = self._by_pipette_setting[pipette]
|
|
71
|
+
except KeyError:
|
|
90
72
|
raise ValueError(
|
|
91
73
|
f"No properties found for {pipette} in {self._name} liquid class"
|
|
92
74
|
)
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
if tip_setting.tiprack == tiprack
|
|
97
|
-
]
|
|
98
|
-
if len(settings_for_tip) == 0:
|
|
75
|
+
try:
|
|
76
|
+
transfer_properties = settings_for_pipette[tiprack]
|
|
77
|
+
except KeyError:
|
|
99
78
|
raise ValueError(
|
|
100
79
|
f"No properties found for {tiprack} in {self._name} liquid class"
|
|
101
80
|
)
|
|
102
|
-
return
|
|
103
|
-
_aspirate=settings_for_tip[0].aspirate,
|
|
104
|
-
_dispense=settings_for_tip[0].singleDispense,
|
|
105
|
-
_multi_dispense=settings_for_tip[0].multiDispense,
|
|
106
|
-
)
|
|
81
|
+
return transfer_properties
|