Skip to content

Commit 11002b6

Browse files
committed
Merge branch 'edge' into testing-liquid-classes-api-in-grav-script
2 parents 42dc691 + ac70ce0 commit 11002b6

File tree

199 files changed

+11660
-1452
lines changed

Some content is hidden

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

199 files changed

+11660
-1452
lines changed

api-client/src/maintenance_runs/types.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import type {
66
} from '@opentrons/shared-data'
77
import type {
88
RunCommandSummary,
9-
LabwareOffsetCreateData,
9+
LegacyLabwareOffsetCreateData,
1010
RunStatus,
1111
RunAction,
1212
} from '../runs'
@@ -42,7 +42,7 @@ export interface MaintenanceRunError {
4242
}
4343

4444
export interface CreateMaintenanceRunData {
45-
labwareOffsets?: LabwareOffsetCreateData[]
45+
labwareOffsets?: LegacyLabwareOffsetCreateData[]
4646
}
4747

4848
export interface LabwareDefinitionSummary {

api-client/src/modules/api-types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ interface PhysicalPort {
1010
port: number
1111
hub: boolean
1212
portGroup: PortGroup
13+
hubPort?: number
1314
}
1415

1516
type ModuleOffsetSource =

api-client/src/runs/createLabwareOffset.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ import { POST, request } from '../request'
22

33
import type { ResponsePromise } from '../request'
44
import type { HostConfig } from '../types'
5-
import type { LabwareOffsetCreateData, Run } from './types'
5+
import type { LegacyLabwareOffsetCreateData, Run } from './types'
66

77
export function createLabwareOffset(
88
config: HostConfig,
99
runId: string,
10-
data: LabwareOffsetCreateData
10+
data: LegacyLabwareOffsetCreateData
1111
): ResponsePromise<Run> {
12-
return request<Run, { data: LabwareOffsetCreateData }>(
12+
return request<Run, { data: LegacyLabwareOffsetCreateData }>(
1313
POST,
1414
`/runs/${runId}/labware_offsets`,
1515
{ data },

api-client/src/runs/createRun.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ import type { ResponsePromise } from '../request'
44
import type { HostConfig } from '../types'
55
import type {
66
Run,
7-
LabwareOffsetCreateData,
7+
LegacyLabwareOffsetCreateData,
88
RunTimeParameterValuesCreateData,
99
RunTimeParameterFilesCreateData,
1010
} from './types'
1111

1212
export interface CreateRunData {
1313
protocolId?: string
14-
labwareOffsets?: LabwareOffsetCreateData[]
14+
labwareOffsets?: LegacyLabwareOffsetCreateData[]
1515
runTimeParameterValues?: RunTimeParameterValuesCreateData
1616
runTimeParameterFiles?: RunTimeParameterFilesCreateData
1717
}

api-client/src/runs/types.ts

+26-4
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ export interface LabwareOffset {
8585
id: string
8686
createdAt: string
8787
definitionUri: string
88-
location: LabwareOffsetLocation
88+
location: LegacyLabwareOffsetLocation
89+
locationSequence?: LabwareOffsetLocationSequence
8990
vector: VectorOffset
9091
}
9192

@@ -156,14 +157,35 @@ export interface CreateRunActionData {
156157
actionType: RunActionType
157158
}
158159

159-
export interface LabwareOffsetLocation {
160+
export interface OnAddressableAreaLabwareOffsetLocationSequenceComponent {
161+
kind: 'onAddressableArea'
162+
labware: string
163+
}
164+
165+
export interface OnModuleOffsetLocationSequenceComponent {
166+
kind: 'onModule'
167+
moduleModel: ModuleModel
168+
}
169+
170+
export interface OnLabwareOffsetLocationSequenceComponent {
171+
kind: 'onLabware'
172+
labwareUri: string
173+
}
174+
175+
export type LabwareOffsetLocationSequenceComponent =
176+
| OnAddressableAreaLabwareOffsetLocationSequenceComponent
177+
| OnModuleOffsetLocationSequenceComponent
178+
| OnLabwareOffsetLocationSequenceComponent
179+
export type LabwareOffsetLocationSequence = LabwareOffsetLocationSequenceComponent[]
180+
181+
export interface LegacyLabwareOffsetLocation {
160182
slotName: string
161183
moduleModel?: ModuleModel
162184
definitionUri?: string
163185
}
164-
export interface LabwareOffsetCreateData {
186+
export interface LegacyLabwareOffsetCreateData {
165187
definitionUri: string
166-
location: LabwareOffsetLocation
188+
location: LegacyLabwareOffsetLocation
167189
vector: VectorOffset
168190
}
169191

api/docs/v2/pipettes/characteristics.rst

+26-23
Original file line numberDiff line numberDiff line change
@@ -184,29 +184,32 @@ These flow rates will remain in effect until you change the ``flow_rate`` attrib
184184
Flex Pipette Flow Rates
185185
-----------------------
186186

187-
Flex pipette flow rates depend on pipette volume and tip capacity. Each pipette–tip combination has a default flow rate for aspirating, dispensing, and blowing out liquid. When using a 50 µL pipette, you should only use 50 µL tips.
188-
189-
.. list-table::
190-
:header-rows: 1
191-
192-
* - Pipette Model
193-
- Tip Capacity (µL)
194-
- Flow Rate (µL/s)
195-
* - 50 µL (1- and 8-channel)
196-
- 50
197-
- 57
198-
* - 1000 µL (1-, 8-, and 96-channel)
199-
- 50
200-
- 478
201-
* - 1000 µL (1-, 8-, and 96-channel)
202-
- 200
203-
- 716
204-
* - 1000 µL (1-, 8-, and 96-channel)
205-
- 1000
206-
- 716
207-
208-
209-
Additionally, all Flex pipettes have a well bottom clearance of 1 mm for aspirate and dispense actions.
187+
The following table provides data on the default aspirate, dispense, and blowout flow rates (in µL/s) for Flex pipettes. Default flow rates for each pipette-tip combination are the same across all three actions.
188+
189+
.. Excludes low-vol 96 channel. Not yet released.
190+
191+
+-----------------------------+-------------------+------------------------+
192+
| Pipette Model | Tip Capacity (µL) | Default Flow Rate (µL) |
193+
+=============================+===================+========================+
194+
| 1- and 8-channel (50 µL) | 50 | 35 |
195+
+-----------------------------+-------------------+------------------------+
196+
| 1- and 8-channel (1000 µL) | 50 | 478 |
197+
+ +-------------------+------------------------+
198+
| | 200 | 716 |
199+
+ +-------------------+------------------------+
200+
| | 1000 | 716 |
201+
+-----------------------------+-------------------+------------------------+
202+
| 96-channel (5-1000 µL) | 50 | 6 |
203+
+ +-------------------+------------------------+
204+
| | 200 | 80 |
205+
+ +-------------------+------------------------+
206+
| | 1000 | 160 |
207+
+-----------------------------+-------------------+------------------------+
208+
209+
Additionally:
210+
211+
- When using a 50 µL pipette, you should only use 50 µL tips.
212+
- All Flex pipettes have a well bottom clearance of 1 mm for aspirate and dispense actions.
210213

211214
.. _ot2-flow-rates:
212215

api/release-notes-internal.md

+9
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@ For more details about this release, please see the full [technical change log][
22

33
[technical change log]: https://github.com/Opentrons/opentrons/releases
44

5+
## Internal Release 2.4.0-alpha.1
6+
7+
This internal release, pulled from the `edge` branch, contains features being developed for 8.4.0. It's for internal testing only.
8+
9+
### New Stuff In This Release (list in progress):
10+
11+
- Python API version bumped to 2.23
12+
- Added liquid classes and new transfer functions
13+
514
## Internal Release 2.3.0-alpha.2
615

716
This internal release, pulled from the `edge` branch, contains features being developed for 8.3.0. It's for internal testing only.

api/src/opentrons/config/advanced_settings.py

+9-11
Original file line numberDiff line numberDiff line change
@@ -222,17 +222,6 @@ class Setting(NamedTuple):
222222
robot_type=[RobotTypeEnum.OT2, RobotTypeEnum.FLEX],
223223
internal_only=True,
224224
),
225-
SettingDefinition(
226-
_id="allowLiquidClasses",
227-
title="Allow the use of liquid classes",
228-
description=(
229-
"Do not enable."
230-
" This is an Opentrons internal setting to allow using in-development"
231-
" liquid classes."
232-
),
233-
robot_type=[RobotTypeEnum.OT2, RobotTypeEnum.FLEX],
234-
internal_only=True,
235-
),
236225
]
237226

238227

@@ -736,6 +725,14 @@ def _migrate35to36(previous: SettingsMap) -> SettingsMap:
736725
return newmap
737726

738727

728+
def _migrate36to37(previous: SettingsMap) -> SettingsMap:
729+
"""Migrate to version 37 of the feature flags file.
730+
731+
- Removes the allowLiquidClasses flag.
732+
"""
733+
return {k: v for k, v in previous.items() if "allowLiquidClasses" != k}
734+
735+
739736
_MIGRATIONS = [
740737
_migrate0to1,
741738
_migrate1to2,
@@ -773,6 +770,7 @@ def _migrate35to36(previous: SettingsMap) -> SettingsMap:
773770
_migrate33to34,
774771
_migrate34to35,
775772
_migrate35to36,
773+
_migrate36to37,
776774
]
777775
"""
778776
List of all migrations to apply, indexed by (version - 1). See _migrate below

api/src/opentrons/config/feature_flags.py

-4
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,3 @@ def enable_performance_metrics(robot_type: RobotTypeEnum) -> bool:
7878

7979
def oem_mode_enabled() -> bool:
8080
return advs.get_setting_with_env_overload("enableOEMMode", RobotTypeEnum.FLEX)
81-
82-
83-
def allow_liquid_classes(robot_type: RobotTypeEnum) -> bool:
84-
return advs.get_setting_with_env_overload("allowLiquidClasses", robot_type)

api/src/opentrons/drivers/asyncio/communication/async_serial.py

+4
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,10 @@ def reset_input_buffer(self) -> None:
155155
"""Reset the input buffer"""
156156
self._serial.reset_input_buffer()
157157

158+
def reset_output_buffer(self) -> None:
159+
"""Reset the output buffer"""
160+
self._serial.reset_output_buffer()
161+
158162
@contextlib.asynccontextmanager
159163
async def timeout_override(
160164
self, timeout_property: TimeoutProperties, timeout: Optional[float]

api/src/opentrons/drivers/asyncio/communication/errors.py

+7
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
class ErrorCodes(Enum):
88
UNHANDLED_GCODE = "ERR003"
9+
MOTOR_STALL = "ERR403"
910

1011

1112
class SerialException(Exception):
@@ -43,3 +44,9 @@ class UnhandledGcode(ErrorResponse):
4344
def __init__(self, port: str, response: str, command: str) -> None:
4445
self.command = command
4546
super().__init__(port, response)
47+
48+
49+
class MotorStall(ErrorResponse):
50+
def __init__(self, port: str, response: str, command: str) -> None:
51+
self.command = command
52+
super().__init__(port, response)

api/src/opentrons/drivers/asyncio/communication/serial_connection.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,14 @@
66

77
from opentrons.drivers.command_builder import CommandBuilder
88

9-
from .errors import NoResponse, AlarmResponse, ErrorResponse, UnhandledGcode, ErrorCodes
9+
from .errors import (
10+
MotorStall,
11+
NoResponse,
12+
AlarmResponse,
13+
ErrorResponse,
14+
UnhandledGcode,
15+
ErrorCodes,
16+
)
1017
from .async_serial import AsyncSerial
1118

1219
log = logging.getLogger(__name__)
@@ -254,6 +261,9 @@ def raise_on_error(self, response: str, request: str) -> None:
254261
raise UnhandledGcode(
255262
port=self._port, response=response, command=request
256263
)
264+
265+
elif ErrorCodes.MOTOR_STALL.value.lower() in lower:
266+
raise MotorStall(port=self._port, response=response, command=request)
257267
else:
258268
raise ErrorResponse(port=self._port, response=response)
259269

api/src/opentrons/drivers/flex_stacker/__init__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from .abstract import AbstractFlexStackerDriver
2-
from .driver import FlexStackerDriver, STACKER_MOTION_CONFIG
2+
from .driver import FlexStackerDriver, STACKER_MOTION_CONFIG, STALLGUARD_CONFIG
33
from .simulator import SimulatingDriver
44
from . import types as FlexStackerTypes
55

@@ -9,4 +9,5 @@
99
"SimulatingDriver",
1010
"FlexStackerTypes",
1111
"STACKER_MOTION_CONFIG",
12+
"STALLGUARD_CONFIG",
1213
]

api/src/opentrons/drivers/flex_stacker/abstract.py

+36-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
from typing import List, Protocol
1+
from typing import List, Optional, Protocol
22

33
from .types import (
4+
LEDPattern,
45
LimitSwitchStatus,
56
MoveResult,
67
StackerAxis,
@@ -9,6 +10,7 @@
910
MoveParams,
1011
StackerInfo,
1112
LEDColor,
13+
StallGuardParams,
1214
)
1315

1416

@@ -51,10 +53,30 @@ async def set_ihold_current(self, axis: StackerAxis, current: float) -> bool:
5153
"""Set axis hold current in amps."""
5254
...
5355

56+
async def set_stallguard_threshold(
57+
self, axis: StackerAxis, enable: bool, threshold: int
58+
) -> bool:
59+
"""Enables and sets the stallguard threshold for the given axis motor."""
60+
...
61+
62+
async def set_motor_driver_register(
63+
self, axis: StackerAxis, reg: int, value: int
64+
) -> bool:
65+
"""Set the register of the given motor axis driver to the given value."""
66+
...
67+
68+
async def get_motor_driver_register(self, axis: StackerAxis, reg: int) -> int:
69+
"""Gets the register value of the given motor axis driver."""
70+
...
71+
5472
async def get_motion_params(self, axis: StackerAxis) -> MoveParams:
5573
"""Get the motion parameters used by the given axis motor."""
5674
...
5775

76+
async def get_stallguard_threshold(self, axis: StackerAxis) -> StallGuardParams:
77+
"""Get the stallguard parameters by the given axis motor."""
78+
...
79+
5880
async def get_limit_switch(self, axis: StackerAxis, direction: Direction) -> bool:
5981
"""Get limit switch status.
6082
@@ -96,16 +118,26 @@ async def move_to_limit_switch(
96118
"""Move until limit switch is triggered."""
97119
...
98120

99-
async def home_axis(self, axis: StackerAxis, direction: Direction) -> bool:
121+
async def home_axis(self, axis: StackerAxis, direction: Direction) -> MoveResult:
100122
"""Home axis."""
101123
...
102124

103125
async def set_led(
104-
self, power: float, color: LEDColor | None = None, external: bool | None = None
126+
self,
127+
power: float,
128+
color: Optional[LEDColor] = None,
129+
external: Optional[bool] = None,
130+
pattern: Optional[LEDPattern] = None,
131+
duration: Optional[int] = None,
132+
reps: Optional[int] = None,
105133
) -> bool:
106-
"""Set LED color of status bar."""
134+
"""Set LED Status bar color and pattern."""
107135
...
108136

109137
async def enter_programming_mode(self) -> None:
110138
"""Reboot into programming mode"""
111139
...
140+
141+
def reset_serial_buffers(self) -> None:
142+
"""Reset the input and output serial buffers."""
143+
...

0 commit comments

Comments
 (0)