Skip to content

Commit 10196b7

Browse files
committed
Merge branch 'chore_release-8.4.0' into lc-snapshot-protocols-96-happy-path
* chore_release-8.4.0: (30 commits) fix(api): make error message clearer for lld issues (#18005) chore(locize): sync for translations needed (#18009) chore(locize): sync translations (#18009) docs(api): API reference entries for liquid class methods (#17887) refactor(api): change the names of liquid classes based transfers (#18006) feat(app, labware-library): add evotip definition assets (#18007) fix(api, shared-data): Flex Stacker engine command optional fields (#17989) fix(shared-data): ethanol aspirate position reference (#17991) fix(app): Labware setup UI fixes (#17987) refactor(app): adjust protocol setup offsets table header (#17985) fix(app): do not show post run drop tip prompt if just handled in Error Recovery (#17981) fix(app): fix LPC disabled reasons not including fixture mismatch (#17979) refactor(app): adjust width on "calibrate now" button (#17978) fix(app): fix applying offsets implicitly when navigating on the desktop app (#17967) feat(robot-server): Populate `locationSequence` on old runs and make it faster to filter out deleted offsets (#17946) feat(app): add inline notification when setting default offsets with a 96ch (#17977) fix(app): ER tip selection crashes when trying to get labware def (#17975) feat(robot-server,system-server): Return server timing metrics in HTTP responses (#17970) fix(app): fix accumulating offsets on run record (#17969) fix(app): Fix local state issues when "resetting to default" in LPC (#17965) ...
2 parents 2d9b9bf + bcb87f6 commit 10196b7

File tree

175 files changed

+9035
-1270
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

175 files changed

+9035
-1270
lines changed

Diff for: .github/workflows/hardware-lint-test.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ jobs:
4141
lint-test:
4242
name: 'hardware package linting and tests'
4343
timeout-minutes: 20
44-
runs-on: 'ubuntu-20.04'
44+
runs-on: 'ubuntu-24.04'
4545
steps:
4646
- name: Checkout opentrons repo
4747
uses: 'actions/checkout@v4'

Diff for: .github/workflows/hardware-testing-protocols.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ jobs:
3535
lint-test:
3636
name: 'hardware-testing protocols'
3737
timeout-minutes: 20
38-
runs-on: 'ubuntu-20.04'
38+
runs-on: 'ubuntu-24.04'
3939
steps:
4040
- name: Checkout opentrons repo
4141
uses: 'actions/checkout@v4'

Diff for: .github/workflows/hardware-testing.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ jobs:
4040
lint-test:
4141
name: 'hardware--testing package linting and tests'
4242
timeout-minutes: 20
43-
runs-on: 'ubuntu-20.04'
43+
runs-on: 'ubuntu-24.04'
4444
steps:
4545
- name: Checkout opentrons repo
4646
uses: 'actions/checkout@v4'

Diff for: api/docs/v2/conf.py

+1
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,7 @@
445445
("py:class", r".*protocol_api\.config.*"),
446446
("py:class", r".*opentrons_shared_data.*"),
447447
("py:class", r".*protocol_api._parameters.Parameters.*"),
448+
("py:class", r".*protocol_api._liquid_properties.TransferProperties*"),
448449
("py:class", r".*RobotContext"), # shh it's a secret (for now)
449450
("py:class", r".*FlexStackerContext"), # ssh it's a secret (for now)
450451
(

Diff for: api/docs/v2/new_protocol_api.rst

+3
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ Wells and Liquids
4848

4949
.. autoclass:: opentrons.protocol_api.Liquid
5050

51+
.. autoclass:: opentrons.protocol_api.LiquidClass
52+
:members:
53+
5154
.. _protocol-api-modules:
5255

5356
Modules

Diff for: api/src/opentrons/hardware_control/backends/subsystem_manager.py

+4-5
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class SubsystemManager:
5858
_expected_core_targets: Set[FirmwareTarget]
5959
_present_tools: tools.types.ToolSummary
6060
_tool_task_condition: asyncio.Condition
61-
_tool_task_state: Union[bool, Exception]
61+
_tool_task_state: Union[bool, BaseException]
6262
_updates_required: Dict[FirmwareTarget, FirmwareUpdateRequirements]
6363
_updates_ongoing: Dict[SubSystem, UpdateStatus]
6464
_update_bag: FirmwareUpdate
@@ -370,7 +370,8 @@ def update_state(status: UpdateStatus) -> None:
370370
async def _tool_detection_task_main(self) -> None:
371371
try:
372372
await self._tool_detection_task_protected()
373-
except Exception as e:
373+
except BaseException as e:
374+
log.exception("Tool reader task failed")
374375
async with self._tool_task_condition:
375376
self._tool_task_state = e
376377
self._tool_task_condition.notify_all()
@@ -414,9 +415,7 @@ async def _tool_detection_task_protected(self) -> None:
414415
)
415416
self._present_tools = await self._tool_detector.resolve(to_resolve, 10.0)
416417
log.info(f"Present tools are now {self._present_tools}")
417-
await network.log_motor_usage_data(
418-
self._can_messenger, list(set(base_can_nodes + [t for t in tool_nodes]))
419-
)
418+
await network.log_motor_usage_data(self._can_messenger)
420419
async with self._tool_task_condition:
421420
self._tool_task_state = True
422421
self._tool_task_condition.notify_all()

Diff for: api/src/opentrons/protocol_api/core/engine/instrument.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -1141,7 +1141,7 @@ def get_next_tip(
11411141
result.nextTipInfo if isinstance(result.nextTipInfo, NextTipInfo) else None
11421142
)
11431143

1144-
def transfer_liquid( # noqa: C901
1144+
def transfer_with_liquid_class( # noqa: C901
11451145
self,
11461146
liquid_class: LiquidClass,
11471147
volume: float,
@@ -1335,7 +1335,7 @@ def _pick_up_tip() -> WellCore:
13351335
_drop_tip()
13361336

13371337
# TODO(spp, 2025-02-25): wire up return tip
1338-
def distribute_liquid( # noqa: C901
1338+
def distribute_with_liquid_class( # noqa: C901
13391339
self,
13401340
liquid_class: LiquidClass,
13411341
volume: float,
@@ -1417,7 +1417,7 @@ def distribute_liquid( # noqa: C901
14171417
tip_working_volume=working_volume,
14181418
)
14191419
):
1420-
self.transfer_liquid(
1420+
self.transfer_with_liquid_class(
14211421
liquid_class=liquid_class,
14221422
volume=volume,
14231423
source=[source for _ in range(len(dest))],
@@ -1657,7 +1657,7 @@ def _tip_can_hold_volume_for_multi_dispensing(
16571657
<= tip_working_volume
16581658
)
16591659

1660-
def consolidate_liquid( # noqa: C901
1660+
def consolidate_with_liquid_class( # noqa: C901
16611661
self,
16621662
liquid_class: LiquidClass,
16631663
volume: float,

Diff for: api/src/opentrons/protocol_api/core/instrument.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ def configure_nozzle_layout(
359359
...
360360

361361
@abstractmethod
362-
def transfer_liquid(
362+
def transfer_with_liquid_class(
363363
self,
364364
liquid_class: LiquidClass,
365365
volume: float,
@@ -374,7 +374,7 @@ def transfer_liquid(
374374
...
375375

376376
@abstractmethod
377-
def distribute_liquid(
377+
def distribute_with_liquid_class(
378378
self,
379379
liquid_class: LiquidClass,
380380
volume: float,
@@ -392,7 +392,7 @@ def distribute_liquid(
392392
...
393393

394394
@abstractmethod
395-
def consolidate_liquid(
395+
def consolidate_with_liquid_class(
396396
self,
397397
liquid_class: LiquidClass,
398398
volume: float,

Diff for: api/src/opentrons/protocol_api/core/legacy/legacy_instrument_core.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,7 @@ def configure_nozzle_layout(
624624
"""This will never be called because it was added in API 2.16."""
625625
pass
626626

627-
def transfer_liquid(
627+
def transfer_with_liquid_class(
628628
self,
629629
liquid_class: LiquidClass,
630630
volume: float,
@@ -638,7 +638,7 @@ def transfer_liquid(
638638
"""This will never be called because it was added in API 2.23"""
639639
assert False, "transfer_liquid is not supported in legacy context"
640640

641-
def distribute_liquid(
641+
def distribute_with_liquid_class(
642642
self,
643643
liquid_class: LiquidClass,
644644
volume: float,
@@ -652,7 +652,7 @@ def distribute_liquid(
652652
"""This will never be called because it was added in API 2.23"""
653653
assert False, "distribute_liquid is not supported in legacy context"
654654

655-
def consolidate_liquid(
655+
def consolidate_with_liquid_class(
656656
self,
657657
liquid_class: LiquidClass,
658658
volume: float,

Diff for: api/src/opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ def configure_nozzle_layout(
513513
"""This will never be called because it was added in API 2.15."""
514514
pass
515515

516-
def transfer_liquid(
516+
def transfer_with_liquid_class(
517517
self,
518518
liquid_class: LiquidClass,
519519
volume: float,
@@ -527,7 +527,7 @@ def transfer_liquid(
527527
"""This will never be called because it was added in API 2.23."""
528528
assert False, "transfer_liquid is not supported in legacy context"
529529

530-
def distribute_liquid(
530+
def distribute_with_liquid_class(
531531
self,
532532
liquid_class: LiquidClass,
533533
volume: float,
@@ -541,7 +541,7 @@ def distribute_liquid(
541541
"""This will never be called because it was added in API 2.23."""
542542
assert False, "distribute_liquid is not supported in legacy context"
543543

544-
def consolidate_liquid(
544+
def consolidate_with_liquid_class(
545545
self,
546546
liquid_class: LiquidClass,
547547
volume: float,

Diff for: api/src/opentrons/protocol_api/instrument_context.py

+75-17
Original file line numberDiff line numberDiff line change
@@ -1509,7 +1509,7 @@ def _execute_transfer(self, plan: v1_transfer.TransferPlan) -> None:
15091509
getattr(self, cmd["method"])(*cmd["args"], **cmd["kwargs"])
15101510

15111511
@requires_version(2, 23)
1512-
def transfer_liquid(
1512+
def transfer_with_liquid_class(
15131513
self,
15141514
liquid_class: LiquidClass,
15151515
volume: float,
@@ -1526,11 +1526,32 @@ def transfer_liquid(
15261526
return_tip: bool = False,
15271527
visit_every_well: bool = False,
15281528
) -> InstrumentContext:
1529-
"""Transfer liquid from source to dest using the specified liquid class properties.
1529+
"""Move a particular type of liquid from one well or group of wells to another.
15301530
1531-
TODO: Add args description.
1531+
:param liquid_class: The type of liquid to move. You must specify the liquid class,
1532+
even if you have used :py:meth:`.load_liquid` to indicate what liquid the
1533+
source contains.
1534+
:type liquid_class: :py:class:`.LiquidClass`
15321535
1533-
:meta private:
1536+
:param volume: The amount, in µL, to aspirate from each source and dispense to
1537+
each destination.
1538+
:param source: A single well or a list of wells to aspirate liquid from.
1539+
:param dest: A single well or a list of wells to dispense liquid into.
1540+
:param new_tip: When to pick up and drop tips during the command.
1541+
Defaults to ``"once"``.
1542+
1543+
- ``"once"``: Use one tip for the entire command.
1544+
- ``"always"``: Use a new tip for each set of aspirate and dispense steps.
1545+
- ``"per source"``: Use one tip for each source well, even if
1546+
:ref:`tip refilling <complex-tip-refilling>` is required.
1547+
- ``"never"``: Do not pick up or drop tips at all.
1548+
1549+
See :ref:`param-tip-handling` for details.
1550+
1551+
:param trash_location: A trash container, well, or other location to dispose of
1552+
tips. Depending on the liquid class, the pipette may also blow out liquid here.
1553+
:param return_tip: Whether to drop used tips in their original locations
1554+
in the tip rack, instead of the trash.
15341555
"""
15351556
transfer_args = verify_and_normalize_transfer_args(
15361557
source=source,
@@ -1552,7 +1573,7 @@ def transfer_liquid(
15521573
" to transfer liquid onto one destinations from many sources, use 'consolidate_liquid'."
15531574
)
15541575

1555-
self._core.transfer_liquid(
1576+
self._core.transfer_with_liquid_class(
15561577
liquid_class=liquid_class,
15571578
volume=volume,
15581579
source=[
@@ -1574,7 +1595,7 @@ def transfer_liquid(
15741595
return self
15751596

15761597
@requires_version(2, 23)
1577-
def distribute_liquid(
1598+
def distribute_with_liquid_class(
15781599
self,
15791600
liquid_class: LiquidClass,
15801601
volume: float,
@@ -1590,12 +1611,30 @@ def distribute_liquid(
15901611
visit_every_well: bool = False,
15911612
) -> InstrumentContext:
15921613
"""
1593-
Distribute liquid from a single source to multiple destinations
1594-
using the specified liquid class properties.
1614+
Distribute a particular type of liquid from one well to a group of wells.
15951615
1596-
TODO: Add args description.
1616+
:param liquid_class: The type of liquid to move. You must specify the liquid class,
1617+
even if you have used :py:meth:`.load_liquid` to indicate what liquid the
1618+
source contains.
1619+
:type liquid_class: :py:class:`.LiquidClass`
15971620
1598-
:meta private:
1621+
:param volume: The amount, in µL, to aspirate from the source and dispense to
1622+
each destination.
1623+
:param source: A single well to aspirate liquid from.
1624+
:param dest: A list of wells to dispense liquid into.
1625+
:param new_tip: When to pick up and drop tips during the command.
1626+
Defaults to ``"once"``.
1627+
1628+
- ``"once"`` or ``"per source"``: Use one tip for the entire command.
1629+
- ``"always"``: Use a new tip for each set of aspirate and dispense steps.
1630+
- ``"never"``: Do not pick up or drop tips at all.
1631+
1632+
See :ref:`param-tip-handling` for details.
1633+
1634+
:param trash_location: A trash container, well, or other location to dispose of
1635+
tips. Depending on the liquid class, the pipette may also blow out liquid here.
1636+
:param return_tip: Whether to drop used tips in their original locations
1637+
in the tip rack, instead of the trash.
15991638
"""
16001639
transfer_args = verify_and_normalize_transfer_args(
16011640
source=source,
@@ -1621,7 +1660,7 @@ def distribute_liquid(
16211660
)
16221661

16231662
verified_source = transfer_args.sources_list[0]
1624-
self._core.distribute_liquid(
1663+
self._core.distribute_with_liquid_class(
16251664
liquid_class=liquid_class,
16261665
volume=volume,
16271666
source=(
@@ -1643,7 +1682,7 @@ def distribute_liquid(
16431682
return self
16441683

16451684
@requires_version(2, 23)
1646-
def consolidate_liquid(
1685+
def consolidate_with_liquid_class(
16471686
self,
16481687
liquid_class: LiquidClass,
16491688
volume: float,
@@ -1659,12 +1698,31 @@ def consolidate_liquid(
16591698
visit_every_well: bool = False,
16601699
) -> InstrumentContext:
16611700
"""
1662-
Consolidate liquid from multiple sources to a single destination
1663-
using the specified liquid class properties.
1701+
Consolidate a particular type of liquid from a group of wells to one well.
16641702
1665-
TODO: Add args description.
1703+
:param liquid_class: The type of liquid to move. You must specify the liquid class,
1704+
even if you have used :py:meth:`.load_liquid` to indicate what liquid the
1705+
source contains.
1706+
:type liquid_class: :py:class:`.LiquidClass`
16661707
1667-
:meta private:
1708+
:param volume: The amount, in µL, to aspirate from the source and dispense to
1709+
each destination.
1710+
:param source: A list of wells to aspirate liquid from.
1711+
:param dest: A single well to dispense liquid into.
1712+
:param new_tip: When to pick up and drop tips during the command.
1713+
Defaults to ``"once"``.
1714+
1715+
- ``"once"``: Use one tip for the entire command.
1716+
- ``"always"``: Use a new tip for each set of aspirate and dispense steps.
1717+
- ``"per source"``: Not available when consolidating.
1718+
- ``"never"``: Do not pick up or drop tips at all.
1719+
1720+
See :ref:`param-tip-handling` for details.
1721+
1722+
:param trash_location: A trash container, well, or other location to dispose of
1723+
tips. Depending on the liquid class, the pipette may also blow out liquid here.
1724+
:param return_tip: Whether to drop used tips in their original locations
1725+
in the tip rack, instead of the trash.
16681726
"""
16691727
transfer_args = verify_and_normalize_transfer_args(
16701728
source=source,
@@ -1690,7 +1748,7 @@ def consolidate_liquid(
16901748
)
16911749

16921750
verified_dest = transfer_args.destinations_list[0]
1693-
self._core.consolidate_liquid(
1751+
self._core.consolidate_with_liquid_class(
16941752
liquid_class=liquid_class,
16951753
volume=volume,
16961754
source=[

0 commit comments

Comments
 (0)