Skip to content

Commit

Permalink
Merge branch 'edge' into fix_RQA-3434
Browse files Browse the repository at this point in the history
  • Loading branch information
koji committed Nov 1, 2024
2 parents 9bf71a6 + d7a6221 commit 95c96b9
Show file tree
Hide file tree
Showing 226 changed files with 53,444 additions and 1,355 deletions.
86 changes: 43 additions & 43 deletions .github/workflows/pd-test-build-deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,49 +79,49 @@ jobs:
files: ./coverage/lcov.info
flags: protocol-designer

e2e-test:
name: 'pd e2e tests'
needs: ['js-unit-test']
timeout-minutes: 30
strategy:
matrix:
os: ['ubuntu-22.04']
runs-on: '${{ matrix.os }}'
steps:
- uses: 'actions/checkout@v3'
with:
fetch-depth: 0
# https://github.com/actions/checkout/issues/290
- name: 'Fix actions/checkout odd handling of tags'
if: startsWith(github.ref, 'refs/tags')
run: |
git fetch -f origin ${{ github.ref }}:${{ github.ref }}
git checkout ${{ github.ref }}
- uses: 'actions/setup-node@v3'
with:
node-version: '18.19.0'
- name: 'install udev for usb-detection'
if: startsWith(matrix.os, 'ubuntu')
run: |
# WORKAROUND: Remove microsoft debian repo due to https://github.com/microsoft/linux-package-repositories/issues/130. Remove line below after it is resolved
sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list
sudo apt-get update && sudo apt-get install libudev-dev
- name: 'cache yarn cache'
uses: actions/cache@v3
with:
path: |
${{ github.workspace }}/.yarn-cache
${{ github.workspace }}/.npm-cache
key: js-${{ secrets.GH_CACHE_VERSION }}-${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }}
restore-keys: |
js-${{ secrets.GH_CACHE_VERSION }}-${{ runner.os }}-yarn-
- name: 'setup-js'
run: |
npm config set cache ./.npm-cache
yarn config set cache-folder ./.yarn-cache
make setup-js
- name: 'test-e2e'
run: make -C protocol-designer test-e2e
# e2e-test:
# name: 'pd e2e tests'
# needs: ['js-unit-test']
# timeout-minutes: 30
# strategy:
# matrix:
# os: ['ubuntu-22.04']
# runs-on: '${{ matrix.os }}'
# steps:
# - uses: 'actions/checkout@v3'
# with:
# fetch-depth: 0
# # https://github.com/actions/checkout/issues/290
# - name: 'Fix actions/checkout odd handling of tags'
# if: startsWith(github.ref, 'refs/tags')
# run: |
# git fetch -f origin ${{ github.ref }}:${{ github.ref }}
# git checkout ${{ github.ref }}
# - uses: 'actions/setup-node@v3'
# with:
# node-version: '18.19.0'
# - name: 'install udev for usb-detection'
# if: startsWith(matrix.os, 'ubuntu')
# run: |
# # WORKAROUND: Remove microsoft debian repo due to https://github.com/microsoft/linux-package-repositories/issues/130. Remove line below after it is resolved
# sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list
# sudo apt-get update && sudo apt-get install libudev-dev
# - name: 'cache yarn cache'
# uses: actions/cache@v3
# with:
# path: |
# ${{ github.workspace }}/.yarn-cache
# ${{ github.workspace }}/.npm-cache
# key: js-${{ secrets.GH_CACHE_VERSION }}-${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }}
# restore-keys: |
# js-${{ secrets.GH_CACHE_VERSION }}-${{ runner.os }}-yarn-
# - name: 'setup-js'
# run: |
# npm config set cache ./.npm-cache
# yarn config set cache-folder ./.yarn-cache
# make setup-js
# - name: 'test-e2e'
# run: make -C protocol-designer test-e2e
build-pd:
name: 'build protocol designer artifact'
needs: ['js-unit-test']
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def module_helper(
y = one_module["moduleOffset"]["offset"].get("y", "")
z = one_module["moduleOffset"]["offset"].get("z", "")
except KeyError:
pass
continue
if mod_serial in module_sheet_serials and modified in module_modify_dates:
continue
module_row = (
Expand Down
9 changes: 9 additions & 0 deletions api-client/src/runs/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type {
RunTimeCommand,
RunTimeParameter,
NozzleLayoutConfig,
OnDeckLabwareLocation,
} from '@opentrons/shared-data'
import type { ResourceLink, ErrorDetails } from '../types'
export * from './commands/types'
Expand Down Expand Up @@ -117,7 +118,9 @@ export interface Runs {
}

export interface RunCurrentStateData {
estopEngaged: boolean
activeNozzleLayouts: Record<string, NozzleLayoutValues> // keyed by pipetteId
placeLabwareState?: PlaceLabwareState
}

export const RUN_ACTION_TYPE_PLAY: 'play' = 'play'
Expand Down Expand Up @@ -209,3 +212,9 @@ export interface NozzleLayoutValues {
activeNozzles: string[]
config: NozzleLayoutConfig
}

export interface PlaceLabwareState {
labwareId: string
location: OnDeckLabwareLocation
shouldPlaceDown: boolean
}
18 changes: 18 additions & 0 deletions api/release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,24 @@ By installing and using Opentrons software, you agree to the Opentrons End-User

---

## Opentrons Robot Software Changes in 8.2.0

Welcome to the v8.2.0 release of the Opentrons robot software! This release adds support for the Opentrons Absorbance Plate Reader Module.

### New Features

- Create and run Python protocols that use the Opentrons Absorbance Plate Reader.

### Improved Features

- Liquid presence detection no longer checks for liquid before every aspiration in a `mix()` command.

### Bug Fixes

- Error recovery no longer causes an `AssertionError` when a Python protocol changes the pipette speed.

---

## Opentrons Robot Software Changes in 8.1.0

Welcome to the v8.1.0 release of the Opentrons robot software!
Expand Down
11 changes: 4 additions & 7 deletions api/src/opentrons/hardware_control/modules/absorbance_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,12 +272,8 @@ def usb_port(self) -> USBPort:
return self._usb_port

async def deactivate(self, must_be_running: bool = True) -> None:
"""Deactivate the module.
Contains an override to the `wait_for_is_running` step in cases where the
module must be deactivated regardless of context."""
await self._poller.stop()
await self._driver.disconnect()
"""Deactivate the module."""
pass

async def wait_for_is_running(self) -> None:
if not self.is_simulated:
Expand Down Expand Up @@ -336,7 +332,8 @@ async def cleanup(self) -> None:
Clean up, i.e. stop pollers, disconnect serial, etc in preparation for
object destruction.
"""
await self.deactivate()
await self._poller.stop()
await self._driver.disconnect()

async def set_sample_wavelength(
self,
Expand Down
2 changes: 2 additions & 0 deletions api/src/opentrons/motion_planning/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
MINIMUM_Z_MARGIN,
get_waypoints,
get_gripper_labware_movement_waypoints,
get_gripper_labware_placement_waypoints,
)

from .types import Waypoint, MoveType
Expand All @@ -27,4 +28,5 @@
"ArcOutOfBoundsError",
"get_waypoints",
"get_gripper_labware_movement_waypoints",
"get_gripper_labware_placement_waypoints",
]
32 changes: 32 additions & 0 deletions api/src/opentrons/motion_planning/waypoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,3 +181,35 @@ def get_gripper_labware_movement_waypoints(
)
)
return waypoints_with_jaw_status


def get_gripper_labware_placement_waypoints(
to_labware_center: Point,
gripper_home_z: float,
drop_offset: Optional[Point],
) -> List[GripperMovementWaypointsWithJawStatus]:
"""Get waypoints for placing labware using a gripper."""
drop_offset = drop_offset or Point()

drop_location = to_labware_center + Point(
drop_offset.x, drop_offset.y, drop_offset.z
)

post_drop_home_pos = Point(drop_location.x, drop_location.y, gripper_home_z)

return [
GripperMovementWaypointsWithJawStatus(
position=Point(drop_location.x, drop_location.y, gripper_home_z),
jaw_open=False,
dropping=False,
),
GripperMovementWaypointsWithJawStatus(
position=drop_location, jaw_open=False, dropping=False
),
# Gripper ungrips here
GripperMovementWaypointsWithJawStatus(
position=post_drop_home_pos,
jaw_open=True,
dropping=True,
),
]
9 changes: 8 additions & 1 deletion api/src/opentrons/protocol_api/core/engine/module_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,7 @@ class AbsorbanceReaderCore(ModuleCore, AbstractAbsorbanceReaderCore):

_sync_module_hardware: SynchronousAdapter[hw_modules.AbsorbanceReader]
_initialized_value: Optional[List[int]] = None
_ready_to_initialize: bool = False

def initialize(
self,
Expand All @@ -575,6 +576,11 @@ def initialize(
reference_wavelength: Optional[int] = None,
) -> None:
"""Initialize the Absorbance Reader by taking zero reading."""
if not self._ready_to_initialize:
raise CannotPerformModuleAction(
"Cannot perform Initialize action on Absorbance Reader without calling `.close_lid()` first."
)

# TODO: check that the wavelengths are within the supported wavelengths
self._engine_client.execute_command(
cmd.absorbance_reader.InitializeParams(
Expand All @@ -586,7 +592,7 @@ def initialize(
)
self._initialized_value = wavelengths

def read(self, filename: Optional[str]) -> Dict[int, Dict[str, float]]:
def read(self, filename: Optional[str] = None) -> Dict[int, Dict[str, float]]:
"""Initiate a read on the Absorbance Reader, and return the results. During Analysis, this will return a measurement of zero for all wells."""
wavelengths = self._engine_client.state.modules.get_absorbance_reader_substate(
self.module_id
Expand Down Expand Up @@ -633,6 +639,7 @@ def close_lid(
moduleId=self.module_id,
)
)
self._ready_to_initialize = True

def open_lid(self) -> None:
"""Close the Absorbance Reader's lid."""
Expand Down
35 changes: 20 additions & 15 deletions api/src/opentrons/protocol_api/core/engine/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -449,9 +449,10 @@ def load_module(

# When the protocol engine is created, we add Module Lids as part of the deck fixed labware
# If a valid module exists in the deck config. For analysis, we add the labware here since
# deck fixed labware is not created under the same conditions.
if self._engine_client.state.config.use_virtual_modules:
self._load_virtual_module_lid(module_core)
# deck fixed labware is not created under the same conditions. We also need to inject the Module
# lids when the module isnt already on the deck config, like when adding a new
# module during a protocol setup.
self._load_virtual_module_lid(module_core)

self._module_cores_by_id[module_core.module_id] = module_core

Expand All @@ -461,20 +462,24 @@ def _load_virtual_module_lid(
self, module_core: Union[ModuleCore, NonConnectedModuleCore]
) -> None:
if isinstance(module_core, AbsorbanceReaderCore):
lid = self._engine_client.execute_command_without_recovery(
cmd.LoadLabwareParams(
loadName="opentrons_flex_lid_absorbance_plate_reader_module",
location=ModuleLocation(moduleId=module_core.module_id),
namespace="opentrons",
version=1,
displayName="Absorbance Reader Lid",
)
substate = self._engine_client.state.modules.get_absorbance_reader_substate(
module_core.module_id
)
if substate.lid_id is None:
lid = self._engine_client.execute_command_without_recovery(
cmd.LoadLabwareParams(
loadName="opentrons_flex_lid_absorbance_plate_reader_module",
location=ModuleLocation(moduleId=module_core.module_id),
namespace="opentrons",
version=1,
displayName="Absorbance Reader Lid",
)
)

self._engine_client.add_absorbance_reader_lid(
module_id=module_core.module_id,
lid_id=lid.labwareId,
)
self._engine_client.add_absorbance_reader_lid(
module_id=module_core.module_id,
lid_id=lid.labwareId,
)

def _create_non_connected_module_core(
self, load_module_result: LoadModuleResult
Expand Down
2 changes: 1 addition & 1 deletion api/src/opentrons/protocol_api/core/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ def initialize(
"""Initialize the Absorbance Reader by taking zero reading."""

@abstractmethod
def read(self, filename: Optional[str]) -> Dict[int, Dict[str, float]]:
def read(self, filename: Optional[str] = None) -> Dict[int, Dict[str, float]]:
"""Get an absorbance reading from the Absorbance Reader."""

@abstractmethod
Expand Down
4 changes: 3 additions & 1 deletion api/src/opentrons/protocol_api/module_contexts.py
Original file line number Diff line number Diff line change
Expand Up @@ -1035,7 +1035,9 @@ def initialize(
)

@requires_version(2, 21)
def read(self, export_filename: Optional[str]) -> Dict[int, Dict[str, float]]:
def read(
self, export_filename: Optional[str] = None
) -> Dict[int, Dict[str, float]]:
"""Initiate read on the Absorbance Reader.
Returns a dictionary of wavelengths to dictionary of values ordered by well name.
Expand Down
5 changes: 5 additions & 0 deletions api/src/opentrons/protocol_engine/commands/command_unions.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@
unsafe.UpdatePositionEstimators,
unsafe.UnsafeEngageAxes,
unsafe.UnsafeUngripLabware,
unsafe.UnsafePlaceLabware,
],
Field(discriminator="commandType"),
]
Expand Down Expand Up @@ -469,6 +470,7 @@
unsafe.UpdatePositionEstimatorsParams,
unsafe.UnsafeEngageAxesParams,
unsafe.UnsafeUngripLabwareParams,
unsafe.UnsafePlaceLabwareParams,
]

CommandType = Union[
Expand Down Expand Up @@ -544,6 +546,7 @@
unsafe.UpdatePositionEstimatorsCommandType,
unsafe.UnsafeEngageAxesCommandType,
unsafe.UnsafeUngripLabwareCommandType,
unsafe.UnsafePlaceLabwareCommandType,
]

CommandCreate = Annotated[
Expand Down Expand Up @@ -620,6 +623,7 @@
unsafe.UpdatePositionEstimatorsCreate,
unsafe.UnsafeEngageAxesCreate,
unsafe.UnsafeUngripLabwareCreate,
unsafe.UnsafePlaceLabwareCreate,
],
Field(discriminator="commandType"),
]
Expand Down Expand Up @@ -697,6 +701,7 @@
unsafe.UpdatePositionEstimatorsResult,
unsafe.UnsafeEngageAxesResult,
unsafe.UnsafeUngripLabwareResult,
unsafe.UnsafePlaceLabwareResult,
]


Expand Down
Loading

0 comments on commit 95c96b9

Please sign in to comment.