Skip to content

Commit

Permalink
Merge branch 'chore_release-7.1.0' into correct_addressable_area_posi…
Browse files Browse the repository at this point in the history
…tions

Resolve a conflict in api/tests/opentrons/protocol_engine/state/test_addressable_area_store.py.
  • Loading branch information
SyntaxColoring committed Dec 6, 2023
2 parents 1a4b244 + 463af32 commit aab4acf
Show file tree
Hide file tree
Showing 40 changed files with 1,054 additions and 563 deletions.
15 changes: 15 additions & 0 deletions api/src/opentrons/motion_planning/adjacent_slots_getters.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

from typing import Optional, List

from opentrons.types import StagingSlotName


def get_north_slot(slot: int) -> Optional[int]:
"""Get slot north of the given slot."""
Expand Down Expand Up @@ -35,6 +37,19 @@ def get_west_slot(slot: int) -> Optional[int]:
return slot - 1


_WEST_OF_STAGING_SLOT_MAP = {
StagingSlotName.SLOT_A4: "A3",
StagingSlotName.SLOT_B4: "B3",
StagingSlotName.SLOT_C4: "C3",
StagingSlotName.SLOT_D4: "D3",
}


def get_west_of_staging_slot(staging_slot: StagingSlotName) -> str:
"""Get slot west of a staging slot."""
return _WEST_OF_STAGING_SLOT_MAP[staging_slot]


def get_east_west_slots(slot: int) -> List[int]:
"""Get slots east & west of the given slot."""
east = get_east_slot(slot)
Expand Down
32 changes: 0 additions & 32 deletions api/src/opentrons/protocol_api/_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,35 +17,3 @@ class OffDeckType(enum.Enum):
See :ref:`off-deck-location` for details on using ``OFF_DECK`` with :py:obj:`ProtocolContext.move_labware()`.
"""


# TODO(jbl 11-17-2023) move this away from being an Enum and make this a NewType or something similar
class StagingSlotName(enum.Enum):
"""Staging slot identifiers."""

SLOT_A4 = "A4"
SLOT_B4 = "B4"
SLOT_C4 = "C4"
SLOT_D4 = "D4"

@classmethod
def from_primitive(cls, value: str) -> StagingSlotName:
str_val = value.upper()
return cls(str_val)

@property
def id(self) -> str:
"""This slot's unique ID, as it appears in the deck definition.
This can be used to look up slot details in the deck definition.
This is preferred over `.value` or `.__str__()` for explicitness.
"""
return self.value

def __str__(self) -> str:
"""Stringify to the unique ID.
For explicitness, prefer using `.id` instead.
"""
return self.id
5 changes: 5 additions & 0 deletions api/src/opentrons/protocol_api/core/engine/instrument.py
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,11 @@ def get_hardware_state(self) -> PipetteDict:
def get_channels(self) -> int:
return self._engine_client.state.tips.get_pipette_channels(self._pipette_id)

def get_active_channels(self) -> int:
return self._engine_client.state.tips.get_pipette_active_channels(
self._pipette_id
)

def has_tip(self) -> bool:
return (
self._engine_client.state.pipettes.get_attached_tip(self._pipette_id)
Expand Down
34 changes: 28 additions & 6 deletions api/src/opentrons/protocol_api/core/engine/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,14 @@
from opentrons_shared_data.pipette.dev_types import PipetteNameType
from opentrons_shared_data.robot.dev_types import RobotType

from opentrons.types import DeckSlotName, Location, Mount, MountType, Point
from opentrons.types import (
DeckSlotName,
Location,
Mount,
MountType,
Point,
StagingSlotName,
)
from opentrons.hardware_control import SyncHardwareAPI, SynchronousAdapter
from opentrons.hardware_control.modules import AbstractModule
from opentrons.hardware_control.modules.types import ModuleModel, ModuleType
Expand Down Expand Up @@ -44,7 +51,7 @@
)

from ... import validation
from ..._types import OffDeckType, OFF_DECK, StagingSlotName
from ..._types import OffDeckType, OFF_DECK
from ..._liquid import Liquid
from ..._trash_bin import TrashBin
from ..._waste_chute import WasteChute
Expand Down Expand Up @@ -570,9 +577,21 @@ def get_deck_definition(self) -> DeckDefinitionV4:
"""Get the geometry definition of the robot's deck."""
return self._engine_client.state.labware.get_deck_definition()

def get_slot_definition(self, slot: DeckSlotName) -> SlotDefV3:
def get_slot_definition(
self, slot: Union[DeckSlotName, StagingSlotName]
) -> SlotDefV3:
"""Get the slot definition from the robot's deck."""
return self._engine_client.state.addressable_areas.get_slot_definition(slot)
return self._engine_client.state.addressable_areas.get_slot_definition(slot.id)

def get_slot_definitions(self) -> Dict[str, SlotDefV3]:
"""Get all standard slot definitions available in the deck definition."""
return self._engine_client.state.addressable_areas.get_deck_slot_definitions()

def get_staging_slot_definitions(self) -> Dict[str, SlotDefV3]:
"""Get all staging slot definitions available in the deck definition."""
return (
self._engine_client.state.addressable_areas.get_staging_slot_definitions()
)

def _ensure_module_location(
self, slot: DeckSlotName, module_type: ModuleType
Expand All @@ -583,7 +602,7 @@ def _ensure_module_location(
raise ValueError(f"A {module_type.value} cannot be loaded into slot {slot}")

def get_slot_item(
self, slot_name: DeckSlotName
self, slot_name: Union[DeckSlotName, StagingSlotName]
) -> Union[LabwareCore, ModuleCore, NonConnectedModuleCore, None]:
"""Get the contents of a given slot, if any."""
loaded_item = self._engine_client.state.geometry.get_slot_item(
Expand Down Expand Up @@ -622,7 +641,7 @@ def get_labware_on_labware(
except LabwareNotLoadedOnLabwareError:
return None

def get_slot_center(self, slot_name: DeckSlotName) -> Point:
def get_slot_center(self, slot_name: Union[DeckSlotName, StagingSlotName]) -> Point:
"""Get the absolute coordinate of a slot's center."""
return self._engine_client.state.addressable_areas.get_addressable_area_center(
slot_name.id
Expand Down Expand Up @@ -671,6 +690,9 @@ def get_labware_location(
return validation.internal_slot_to_public_string(
labware_location.slotName, self._engine_client.state.config.robot_type
)
elif isinstance(labware_location, AddressableAreaLocation):
# This will only ever be a robot accurate deck slot name or Flex staging slot name
return labware_location.addressableAreaName
elif isinstance(labware_location, ModuleLocation):
return self._module_cores_by_id[labware_location.moduleId]
elif isinstance(labware_location, OnLabwareLocation):
Expand Down
4 changes: 4 additions & 0 deletions api/src/opentrons/protocol_api/core/instrument.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,10 @@ def get_hardware_state(self) -> PipetteDict:
def get_channels(self) -> int:
...

@abstractmethod
def get_active_channels(self) -> int:
...

@abstractmethod
def has_tip(self) -> bool:
...
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -528,5 +528,9 @@ def configure_nozzle_layout(
primary_nozzle: Optional[str],
front_right_nozzle: Optional[str],
) -> None:
"""This will never be called because it was added in API 2.15."""
"""This will never be called because it was added in API 2.16."""
pass

def get_active_channels(self) -> int:
"""This will never be called because it was added in API 2.16."""
assert False, "get_active_channels only supported in API 2.16 & later"
20 changes: 15 additions & 5 deletions api/src/opentrons/protocol_api/core/legacy/legacy_protocol_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from opentrons_shared_data.pipette.dev_types import PipetteNameType
from opentrons_shared_data.robot.dev_types import RobotType

from opentrons.types import DeckSlotName, Location, Mount, Point
from opentrons.types import DeckSlotName, StagingSlotName, Location, Mount, Point
from opentrons.util.broker import Broker
from opentrons.hardware_control import SyncHardwareAPI
from opentrons.hardware_control.modules import AbstractModule, ModuleModel, ModuleType
Expand All @@ -17,7 +17,7 @@

from ...labware import Labware
from ..._liquid import Liquid
from ..._types import OffDeckType, StagingSlotName
from ..._types import OffDeckType
from ..._trash_bin import TrashBin
from ..._waste_chute import WasteChute
from ..protocol import AbstractProtocol
Expand Down Expand Up @@ -480,17 +480,27 @@ def get_deck_definition(self) -> DeckDefinitionV4:
"""Get the geometry definition of the robot's deck."""
assert False, "get_deck_definition only supported on engine core"

def get_slot_definition(self, slot: DeckSlotName) -> SlotDefV3:
def get_slot_definition(
self, slot: Union[DeckSlotName, StagingSlotName]
) -> SlotDefV3:
"""Get the slot definition from the robot's deck."""
assert False, "get_slot_definition only supported on engine core"

def get_slot_definitions(self) -> Dict[str, SlotDefV3]:
"""Get all standard slot definitions available in the deck definition."""
assert False, "get_slot_definitions only supported on engine core"

def get_staging_slot_definitions(self) -> Dict[str, SlotDefV3]:
"""Get all staging slot definitions available in the deck definition."""
assert False, "get_staging_slot_definitions only supported on engine core"

def get_slot_item(
self, slot_name: DeckSlotName
self, slot_name: Union[DeckSlotName, StagingSlotName]
) -> Union[LegacyLabwareCore, legacy_module_core.LegacyModuleCore, None]:
"""Get the contents of a given slot, if any."""
assert False, "get_slot_item only supported on engine core"

def get_slot_center(self, slot_name: DeckSlotName) -> Point:
def get_slot_center(self, slot_name: Union[DeckSlotName, StagingSlotName]) -> Point:
"""Get the absolute coordinate of a slot's center."""
assert False, "get_slot_center only supported on engine core."

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -448,3 +448,7 @@ def configure_nozzle_layout(
) -> None:
"""This will never be called because it was added in API 2.15."""
pass

def get_active_channels(self) -> int:
"""This will never be called because it was added in API 2.16."""
assert False, "get_active_channels only supported in API 2.16 & later"
23 changes: 16 additions & 7 deletions api/src/opentrons/protocol_api/core/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
from __future__ import annotations

from abc import abstractmethod, ABC
from typing import Generic, List, Optional, Union, Tuple, TYPE_CHECKING
from typing import Generic, List, Optional, Union, Tuple, Dict, TYPE_CHECKING

from opentrons_shared_data.deck.dev_types import DeckDefinitionV4, SlotDefV3
from opentrons_shared_data.pipette.dev_types import PipetteNameType
from opentrons_shared_data.labware.dev_types import LabwareDefinition
from opentrons_shared_data.robot.dev_types import RobotType

from opentrons.types import DeckSlotName, Location, Mount, Point
from opentrons.types import DeckSlotName, StagingSlotName, Location, Mount, Point
from opentrons.hardware_control import SyncHardwareAPI
from opentrons.hardware_control.modules.types import ModuleModel
from opentrons.protocols.api_support.util import AxisMaxSpeeds
Expand All @@ -21,7 +21,7 @@
from .._liquid import Liquid
from .._trash_bin import TrashBin
from .._waste_chute import WasteChute
from .._types import OffDeckType, StagingSlotName
from .._types import OffDeckType

if TYPE_CHECKING:
from ..labware import Labware
Expand Down Expand Up @@ -179,14 +179,23 @@ def set_last_location(
def get_deck_definition(self) -> DeckDefinitionV4:
"""Get the geometry definition of the robot's deck."""

# TODO(jbl 10-30-2023) this method may no longer need to exist post deck config work being completed
@abstractmethod
def get_slot_definition(self, slot: DeckSlotName) -> SlotDefV3:
def get_slot_definition(
self, slot: Union[DeckSlotName, StagingSlotName]
) -> SlotDefV3:
"""Get the slot definition from the robot's deck."""

@abstractmethod
def get_slot_definitions(self) -> Dict[str, SlotDefV3]:
"""Get all standard slot definitions available in the deck definition."""

@abstractmethod
def get_staging_slot_definitions(self) -> Dict[str, SlotDefV3]:
"""Get all staging slot definitions available in the deck definition."""

@abstractmethod
def get_slot_item(
self, slot_name: DeckSlotName
self, slot_name: Union[DeckSlotName, StagingSlotName]
) -> Union[LabwareCoreType, ModuleCoreType, None]:
"""Get the contents of a given slot, if any."""

Expand All @@ -203,7 +212,7 @@ def get_labware_on_labware(
"""Get the labware on a given labware, if any."""

@abstractmethod
def get_slot_center(self, slot_name: DeckSlotName) -> Point:
def get_slot_center(self, slot_name: Union[DeckSlotName, StagingSlotName]) -> Point:
"""Get the absolute coordinate of a slot's center."""

@abstractmethod
Expand Down
Loading

0 comments on commit aab4acf

Please sign in to comment.