Skip to content

Commit

Permalink
Merge branch 'edge' into feat_add-info-to-chip
Browse files Browse the repository at this point in the history
  • Loading branch information
koji committed Mar 15, 2024
2 parents 132b579 + 30d9548 commit 8635725
Show file tree
Hide file tree
Showing 433 changed files with 5,792 additions and 2,903 deletions.
17 changes: 1 addition & 16 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ module.exports = {
'plugin:storybook/recommended',
],

plugins: ['react', 'react-hooks', 'json', 'jest', 'testing-library'],
plugins: ['react', 'react-hooks', 'json', 'testing-library'],

rules: {
camelcase: 'off',
Expand Down Expand Up @@ -107,31 +107,16 @@ module.exports = {
'**/fixtures/**.@(js|ts|tsx)',
'scripts/*.@(js|ts|tsx)',
],
env: {
jest: true,
},
extends: ['plugin:jest/recommended'],
rules: {
'jest/expect-expect': 'off',
'jest/no-standalone-expect': 'off',
'jest/no-disabled-tests': 'error',
'jest/consistent-test-it': ['error', { fn: 'it' }],
'@typescript-eslint/consistent-type-assertions': 'off',
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/no-confusing-void-expression': 'warn',
'node/handle-callback-err': 'off',
// TODO(mc, 2021-01-29): fix these and remove warning overrides
'jest/no-deprecated-functions': 'warn',
'jest/valid-title': 'warn',
'jest/no-conditional-expect': 'warn',
'jest/no-alias-methods': 'warn',
'jest/valid-describe-callback': 'warn',
},
},
{
files: ['**/__tests__/**test.tsx'],
env: { jest: true },
extends: ['plugin:testing-library/react'],
rules: {
'testing-library/no-manual-cleanup': 'off',
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ JavaScript dependencies are installed by [yarn][]. When calling yarn, you should
A development dependency is any dependency that is used only to help manage the project. Examples of development dependencies would be:

- Build tools (webpack, babel)
- Testing/linting/checking tools (jest, typescript, eslint)
- Testing/linting/checking tools (vitest, typescript, eslint)
- Libraries used only in support scripts (aws, express)

To add a development dependency:
Expand Down
2 changes: 1 addition & 1 deletion DEV_SETUP.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ Close and re-open your terminal to confirm `nvs` is installed.
nvs --version
```

Now we can use nvs to install Node.js v18 and switch on `auto` mode, which will make sure Node.js v18 is used any time we're in the `opentrons` project directory.
Now we can use `nvs` to install the currently required Node.js version set in `.nvmrc`. The `auto` command selects the correct version of Node.js any time we're in the `opentrons` project directory. Without `auto`, we would have to manually run `use` or `install` each time we work on the project.

```shell
nvs add 18
Expand Down
20 changes: 0 additions & 20 deletions api-client/src/maintenance_runs/createMaintenanceRunAction.ts

This file was deleted.

1 change: 0 additions & 1 deletion api-client/src/maintenance_runs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ export { getMaintenanceRun } from './getMaintenanceRun'
export { deleteMaintenanceRun } from './deleteMaintenanceRun'
export { createMaintenanceRun } from './createMaintenanceRun'
export { createMaintenanceCommand } from './createMaintenanceCommand'
export { createMaintenanceRunAction } from './createMaintenanceRunAction'
export { createMaintenanceRunLabwareDefinition } from './createMaintenanceRunLabwareDefinition'
export { getCurrentMaintenanceRun } from './getCurrentMaintenanceRun'

Expand Down
53 changes: 8 additions & 45 deletions api-client/src/maintenance_runs/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,19 @@ import type {
LoadedModule,
LoadedPipette,
} from '@opentrons/shared-data'
import type { RunCommandSummary, LabwareOffsetCreateData } from '../runs'

export const ENGINE_STATUS_IDLE = 'idle' as const
export const ENGINE_STATUS_RUNNING = 'running' as const
export const ENGINE_STATUS_PAUSE_REQUESTED = 'pause-requested' as const
export const ENGINE_STATUS_PAUSED = 'paused'
export const ENGINE_STATUS_STOP_REQUESTED = 'stop-requested' as const
export const ENGINE_STATUS_STOPPED = 'stopped' as const
export const ENGINE_STATUS_FAILED = 'failed' as const
export const ENGINE_STATUS_FINISHING = 'finishing' as const
export const ENGINE_STATUS_SUCCEEDED = 'succeeded' as const
export const ENGINE_STATUS_BLOCKED_BY_OPEN_DOOR = 'blocked-by-open-door' as const

export type EngineStatus =
| typeof ENGINE_STATUS_IDLE
| typeof ENGINE_STATUS_RUNNING
| typeof ENGINE_STATUS_PAUSE_REQUESTED
| typeof ENGINE_STATUS_PAUSED
| typeof ENGINE_STATUS_STOP_REQUESTED
| typeof ENGINE_STATUS_STOPPED
| typeof ENGINE_STATUS_FAILED
| typeof ENGINE_STATUS_FINISHING
| typeof ENGINE_STATUS_SUCCEEDED
| typeof ENGINE_STATUS_BLOCKED_BY_OPEN_DOOR
import type {
RunCommandSummary,
LabwareOffsetCreateData,
RunStatus,
RunAction,
} from '../runs'

export interface MaintenanceRunData {
id: string
createdAt: string
status: EngineStatus
status: RunStatus
current: boolean
actions: MaintenanceRunAction[]
actions: RunAction[]
errors: MaintenanceRunError[]
pipettes: LoadedPipette[]
modules: LoadedModule[]
Expand All @@ -48,25 +30,6 @@ export interface MaintenanceRun {
data: MaintenanceRunData
}

export const MAINTENANCE_RUN_ACTION_TYPE_PLAY: 'play' = 'play'
export const MAINTENANCE_RUN_ACTION_TYPE_PAUSE: 'pause' = 'pause'
export const MAINTENANCE_RUN_ACTION_TYPE_STOP: 'stop' = 'stop'

export type MaintenanceRunActionType =
| typeof MAINTENANCE_RUN_ACTION_TYPE_PLAY
| typeof MAINTENANCE_RUN_ACTION_TYPE_PAUSE
| typeof MAINTENANCE_RUN_ACTION_TYPE_STOP

export interface MaintenanceRunAction {
id: string
createdAt: string
actionType: MaintenanceRunActionType
}

export interface MaintenanceCreateRunActionData {
actionType: MaintenanceRunActionType
}

export interface MaintenanceCommandData {
data: RunCommandSummary
}
Expand Down
2 changes: 2 additions & 0 deletions api-client/src/runs/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export const RUN_STATUS_FAILED = 'failed' as const
export const RUN_STATUS_FINISHING = 'finishing' as const
export const RUN_STATUS_SUCCEEDED = 'succeeded' as const
export const RUN_STATUS_BLOCKED_BY_OPEN_DOOR = 'blocked-by-open-door' as const
export const RUN_STATUS_AWAITING_RECOVERY = 'awaiting-recovery' as const

export type RunStatus =
| typeof RUN_STATUS_IDLE
Expand All @@ -30,6 +31,7 @@ export type RunStatus =
| typeof RUN_STATUS_FINISHING
| typeof RUN_STATUS_SUCCEEDED
| typeof RUN_STATUS_BLOCKED_BY_OPEN_DOOR
| typeof RUN_STATUS_AWAITING_RECOVERY

export interface RunData {
id: string
Expand Down
3 changes: 3 additions & 0 deletions api/docs/v2/robot_position.rst
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,9 @@ Movement Speeds

In addition to instructing the robot where to move a pipette, you can also control the speed at which it moves. Speed controls can be applied either to all pipette motions or to movement along a particular axis.

.. note::
Like all mechanical systems, Opentrons robots have resonant frequencies that depend on their construction and current configuration. It's possible to set a speed that causes your robot to resonate, producing louder sounds than typical operation. This is safe, but if you find it annoying, increase or decrease the speed slightly.

.. _gantry_speed:

Gantry Speed
Expand Down
5 changes: 5 additions & 0 deletions api/src/opentrons/cli/analyze.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from typing import Any, Dict, List, Optional, Sequence, Union
from typing_extensions import Literal

from opentrons.protocol_engine.types import RunTimeParameter
from opentrons.protocols.api_support.types import APIVersion
from opentrons.protocol_reader import (
ProtocolReader,
Expand Down Expand Up @@ -99,6 +100,9 @@ async def _analyze(
),
metadata=protocol_source.metadata,
robotType=protocol_source.robot_type,
# TODO(spp, 2024-03-12): update this once protocol reader/ runner can parse
# and report the runTimeParameters
runTimeParameters=[],
commands=analysis.commands,
errors=analysis.state_summary.errors,
labware=analysis.state_summary.labware,
Expand Down Expand Up @@ -156,6 +160,7 @@ class AnalyzeResults(BaseModel):

# Fields that should match robot-server:
robotType: RobotType
runTimeParameters: List[RunTimeParameter]
commands: List[Command]
labware: List[LoadedLabware]
pipettes: List[LoadedPipette]
Expand Down
25 changes: 25 additions & 0 deletions api/src/opentrons/config/advanced_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,20 @@ class Setting(NamedTuple):
description="When this setting is on, Flex will continue its activities regardless of pressure changes inside the pipette. Do not turn this setting on unless you are intentionally causing pressures over 8 kPa inside the pipette air channel.",
robot_type=[RobotTypeEnum.FLEX],
),
SettingDefinition(
_id="enableErrorRecoveryExperiments",
title="Enable error recovery experiments",
description=(
"Do not enable."
" This is an Opentrons internal setting to experiment with"
" in-development error recovery features."
" This will interfere with your protocol runs,"
" corrupt your robot's storage,"
" bring misfortune and pestilence upon you and your livestock, etc."
),
robot_type=[RobotTypeEnum.FLEX],
internal_only=True,
),
]

if (
Expand Down Expand Up @@ -668,6 +682,16 @@ def _migrate29to30(previous: SettingsMap) -> SettingsMap:
return {k: v for k, v in previous.items() if "disableTipPresenceDetection" != k}


def _migrate30to31(previous: SettingsMap) -> SettingsMap:
"""Migrate to version 31 of the feature flags file.
- Adds the enableErrorRecoveryExperiments config element.
"""
newmap = {k: v for k, v in previous.items()}
newmap["enableErrorRecoveryExperiments"] = None
return newmap


_MIGRATIONS = [
_migrate0to1,
_migrate1to2,
Expand Down Expand Up @@ -699,6 +723,7 @@ def _migrate29to30(previous: SettingsMap) -> SettingsMap:
_migrate27to28,
_migrate28to29,
_migrate29to30,
_migrate30to31,
]
"""
List of all migrations to apply, indexed by (version - 1). See _migrate below
Expand Down
6 changes: 6 additions & 0 deletions api/src/opentrons/config/feature_flags.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,9 @@ def require_estop() -> bool:
return not advs.get_setting_with_env_overload(
"estopNotRequired", RobotTypeEnum.FLEX
)


def enable_error_recovery_experiments() -> bool:
return advs.get_setting_with_env_overload(
"enableErrorRecoveryExperiments", RobotTypeEnum.FLEX
)
13 changes: 6 additions & 7 deletions api/src/opentrons/protocol_api/core/engine/instrument.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
from opentrons_shared_data.pipette.dev_types import PipetteNameType
from opentrons.protocol_api._nozzle_layout import NozzleLayout
from opentrons.hardware_control.nozzle_manager import NozzleConfigurationType
from opentrons.hardware_control.nozzle_manager import NozzleMap
from . import deck_conflict

from ..instrument import AbstractInstrument
Expand Down Expand Up @@ -675,6 +676,9 @@ def get_active_channels(self) -> int:
self._pipette_id
)

def get_nozzle_map(self) -> NozzleMap:
return self._engine_client.state.tips.get_pipette_nozzle_map(self._pipette_id)

def has_tip(self) -> bool:
return (
self._engine_client.state.pipettes.get_attached_tip(self._pipette_id)
Expand Down Expand Up @@ -709,14 +713,9 @@ def is_tip_tracking_available(self) -> bool:
return True
else:
if self.get_channels() == 96:
# SINGLE configuration with H12 nozzle is technically supported by the
# current tip tracking implementation but we don't do any deck conflict
# checks for it, so we won't provide full support for it yet.
return (
self.get_nozzle_configuration() == NozzleConfigurationType.COLUMN
and primary_nozzle == "A12"
)
return True
if self.get_channels() == 8:
# TODO: (cb, 03/06/24): Enable automatic tip tracking on the 8 channel pipettes once PAPI support exists
return (
self.get_nozzle_configuration() == NozzleConfigurationType.SINGLE
and primary_nozzle == "H1"
Expand Down
7 changes: 6 additions & 1 deletion api/src/opentrons/protocol_api/core/engine/labware.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from opentrons.protocol_engine.errors import LabwareNotOnDeckError, ModuleNotOnDeckError
from opentrons.protocol_engine.clients import SyncClient as ProtocolEngineClient
from opentrons.types import DeckSlotName, Point
from opentrons.hardware_control.nozzle_manager import NozzleMap

from ..labware import AbstractLabware, LabwareLoadParams
from .well import WellCore
Expand Down Expand Up @@ -122,7 +123,10 @@ def reset_tips(self) -> None:
raise TypeError(f"{self.get_display_name()} is not a tip rack.")

def get_next_tip(
self, num_tips: int, starting_tip: Optional[WellCore]
self,
num_tips: int,
starting_tip: Optional[WellCore],
nozzle_map: Optional[NozzleMap],
) -> Optional[str]:
return self._engine_client.state.tips.get_next_tip(
labware_id=self._labware_id,
Expand All @@ -132,6 +136,7 @@ def get_next_tip(
if starting_tip and starting_tip.labware_id == self._labware_id
else None
),
nozzle_map=nozzle_map,
)

def get_well_columns(self) -> List[List[str]]:
Expand Down
5 changes: 5 additions & 0 deletions api/src/opentrons/protocol_api/core/instrument.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from opentrons.hardware_control.dev_types import PipetteDict
from opentrons.protocols.api_support.util import FlowRates
from opentrons.protocol_api._nozzle_layout import NozzleLayout
from opentrons.hardware_control.nozzle_manager import NozzleMap

from ..disposal_locations import TrashBin, WasteChute
from .well import WellCoreType
Expand Down Expand Up @@ -218,6 +219,10 @@ def get_channels(self) -> int:
def get_active_channels(self) -> int:
...

@abstractmethod
def get_nozzle_map(self) -> NozzleMap:
...

@abstractmethod
def has_tip(self) -> bool:
...
Expand Down
6 changes: 5 additions & 1 deletion api/src/opentrons/protocol_api/core/labware.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
)

from opentrons.types import DeckSlotName, Point
from opentrons.hardware_control.nozzle_manager import NozzleMap

from .well import WellCoreType

Expand Down Expand Up @@ -110,7 +111,10 @@ def reset_tips(self) -> None:

@abstractmethod
def get_next_tip(
self, num_tips: int, starting_tip: Optional[WellCoreType]
self,
num_tips: int,
starting_tip: Optional[WellCoreType],
nozzle_map: Optional[NozzleMap],
) -> Optional[str]:
"""Get the name of the next available tip(s) in the rack, if available."""

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
)
from opentrons.protocols.geometry import planning
from opentrons.protocol_api._nozzle_layout import NozzleLayout
from opentrons.hardware_control.nozzle_manager import NozzleMap

from ...disposal_locations import TrashBin, WasteChute
from ..instrument import AbstractInstrument
Expand Down Expand Up @@ -550,6 +551,10 @@ 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"

def get_nozzle_map(self) -> NozzleMap:
"""This will never be called because it was added in API 2.18."""
assert False, "get_nozzle_map only supported in API 2.18 & later"

def is_tip_tracking_available(self) -> bool:
# Tip tracking is always available in legacy context
return True
Loading

0 comments on commit 8635725

Please sign in to comment.