Skip to content

Commit 21473db

Browse files
committed
Merge branch 'edge' into sg_trash-addressable-area-util
2 parents 36179a3 + e792062 commit 21473db

File tree

106 files changed

+6011
-1998
lines changed

Some content is hidden

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

106 files changed

+6011
-1998
lines changed

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class BaseErrorCode(Enum):
5252
def code_string(self) -> str:
5353
"""Return the error code string."""
5454
code: str = self.value[0]
55-
return code
55+
return code.lower()
5656

5757
@property
5858
def exception(self) -> Type[ErrorResponse]:

api/tests/opentrons/drivers/asyncio/communication/test_serial_connection.py

+8
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,14 @@ def test_raise_on_error(
180180
subject.raise_on_error(response, "fake request")
181181

182182

183+
def test_get_error_codes_lowercase(
184+
subject: SerialKind,
185+
) -> None:
186+
"""It should return an error code dictionary keyed by lowercase value."""
187+
lowercase_result = subject._error_codes.get_error_codes()
188+
assert lowercase_result == {"err003": DefaultErrorCodes.UNHANDLED_GCODE}
189+
190+
183191
async def test_on_retry(mock_serial_port: AsyncMock, subject: SerialKind) -> None:
184192
"""It should try to re-open connection."""
185193
await subject.on_retry()

app/src/assets/localization/en/labware_position_check.json

+27-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
"adapter_in_slot": "{{adapter}} in {{slot}}",
44
"adapter_in_tc": "{{adapter}} in {{module}}",
55
"add": "Add",
6+
"add_a_default_offset": "Add a default offset to automatically apply it to all placements of this labware on the deck",
7+
"add_default_labware_offset": "Add default labware offset",
8+
"adjust": "Adjust",
9+
"adjust_applied_location_offset": "Adjust applied location offset",
10+
"adjust_default_labware_offset": "Adjust default labware offset",
611
"all_modules_and_labware_from_protocol": "All modules and all labware used in the protocol {{protocol_name}}",
712
"applied_location_offsets": "Applied Location Offsets",
813
"applied_offset_data": "Applied Labware Offset data",
@@ -12,16 +17,19 @@
1217
"backmost": "backmost",
1318
"calibration_probe": "Calibration Probe",
1419
"calibration_probe_not_detected": "Calibration probe not detected",
20+
"cancel": "Cancel",
1521
"check_item_in_location": "Check {{item}} in {{location}}",
1622
"check_labware_in_slot_title": "Check Labware {{labware_display_name}} in slot {{slot}}",
1723
"check_remaining_labware_with_primary_pipette_section": "Check remaining labware with {{primary_mount}} Pipette and tip",
1824
"check_tip_location": "the top of the tip in the A1 position",
1925
"check_well_location": "well A1 on the labware",
20-
"clear_all_slots": "Clear all deck slots of labware, leaving modules in place",
21-
"clear_all_slots_odd": "Clear all deck slots of labware",
26+
"clear_deck_all_lw_all_modules_from": "Clear all deck slots of labware and remove any modules from <strong>{{slot}}</strong>",
27+
"clear_deck_all_lw_leave_modules": "Clear all deck slots of labware, leaving modules in place",
2228
"cli_ssh": "Command Line Interface (SSH)",
2329
"close_and_apply_offset_data": "Close and apply labware offset data",
30+
"confirm": "Confirm",
2431
"confirm_detached": "Confirm removal",
32+
"confirm_go_back_without_saving": "Are you sure you want to go back to the the labware list without saving?",
2533
"confirm_pick_up_tip_modal_title": "Did the pipette pick up a tip successfully?",
2634
"confirm_pick_up_tip_modal_try_again_text": "No, try again",
2735
"confirm_placement": "Confirm placement",
@@ -30,6 +38,7 @@
3038
"confirm_position_and_return_tip": "Confirm position, return tip to Slot {{next_slot}} and home",
3139
"confirm_removal": "Confirm removal",
3240
"continue": "Continue",
41+
"default": "Default",
3342
"default_labware_offset": "Default Labware Offset",
3443
"detach_probe": "Remove calibration probe",
3544
"ensure_nozzle_position_desktop": "<block>Ensure that the {{tip_type}} is centered above and level with {{item_location}}. If it isn't, use the controls below or your keyboard to jog the pipette until it is properly aligned.</block>",
@@ -40,14 +49,15 @@
4049
"exit_screen_go_back": "Go back to labware position check",
4150
"exit_screen_subtitle": "If you exit now, all labware offsets will be discarded. This cannot be undone.",
4251
"exit_screen_title": "Exit before completing Labware Position Check?",
52+
"failed_to_save_final_position": "Failed to save final position",
4353
"get_labware_offset_data": "Get Labware Offset Data",
4454
"install_probe": "<block>Take the calibration probe from its storage location. Ensure the collar is fully unlocked. Push the pipette ejector up and press the probe firmly onto the pipette nozzle as far as it can go. Twist the collar to lock the probe.</block><block>Test that the probe is secure by gently pulling it back and forth. It should be firmly in place.</block>",
4555
"jog_controls_adjustment": "Need to make an adjustment?",
4656
"jupyter_notebook": "Jupyter Notebook",
4757
"labware": "labware",
4858
"labware_display_location_text": "Deck Slot {{slot}}",
4959
"labware_offset": "Labware Offset",
50-
"labware_offset_data": "labware offset data",
60+
"labware_offset_data": "Labware Offset Data",
5161
"labware_offsets_deleted_warning": "Once you begin Labware Position Check, previously created Labware Offsets will be discarded.",
5262
"labware_offsets_summary_labware": "Labware",
5363
"labware_offsets_summary_location": "Location",
@@ -73,11 +83,16 @@
7383
"labware_step_detail_tiprack_plural": "The pipette nozzles should be centered above column 1 in <italic>{{tiprack_name}}</italic> and <bold>level</bold> with the top of the tips.",
7484
"learn_more": "Learn more",
7585
"legacy_calibration_probe": "calibration probe",
86+
"legacy_clear_all_slots": "Clear all deck slots of labware, leaving modules in place",
87+
"legacy_clear_all_slots_odd": "Clear all deck slots of labware",
7688
"legacy_install_probe": "Take the calibration probe from its storage location. Ensure its collar is fully unlocked. Push the pipette ejector up and press the probe firmly onto the <bold>{{location}}</bold> pipette nozzle as far as it can go. Twist the collar to lock the probe. Test that the probe is secure by gently pulling it back and forth.",
89+
"legacy_labware_offset_data": "labware offset data",
7790
"legacy_labware_position_check_description": "<block>Labware Position Check is a guided workflow that checks every labware on the deck for an added degree of precision in your protocol.</block><block>Labware Position Check first checks tip racks, and then checks all other labware used in your protocol.</block>",
7891
"legacy_no_offset_data": "No offset data available",
7992
"location": "location",
93+
"location_header": "Location",
8094
"lpc_complete": "Labware Position Check complete",
95+
"lpc_complete_summary_screen_heading": "Labware Position Check Complete",
8196
"module_display_location_text": "{{moduleName}} in Deck Slot {{slot}}",
8297
"module_in_slot": "{{module}} in {{slot}}",
8398
"move_gantry_to_front": "Move gantry to front",
@@ -90,7 +105,12 @@
90105
"no_offset_data": "No offset data",
91106
"no_offset_data_available": "No labware offset data available",
92107
"no_offset_data_on_robot": "This robot has no useable labware offset data for this run.",
108+
"num_missing_offsets": "{{num}} missing offsets",
109+
"num_offsets": "{{num}} offsets",
110+
"offset_values": "X {{x}}, Y {{y}}, Z {{z}}",
93111
"offsets": "Offsets",
112+
"one_missing_offset": "1 missing offset",
113+
"one_offset": "1 offset",
94114
"pick_up_tip_from_rack_in_location": "Pick up tip from tip rack in {{location}}",
95115
"picking_up_tip_title": "Picking up tip in slot {{slot}}",
96116
"pipette_nozzle": "pipette nozzle furthest from you",
@@ -105,6 +125,7 @@
105125
"remove_calibration_probe": "Remove calibration probe",
106126
"remove_probe": "Unlock the calibraiton probe, remove it from the nozzle, and return it to its storage location.",
107127
"remove_probe_before_exit": "Remove the calibration probe before exiting",
128+
"reset_to_default": "Reset to default",
108129
"return_tip_rack_to_location": "Return tip rack to {{location}}",
109130
"return_tip_section": "Return tip",
110131
"returning_tip_title": "Returning tip in slot {{slot}}",
@@ -117,17 +138,19 @@
117138
"save": "Save",
118139
"secondary_pipette_tipracks_section": "Check tip racks with {{secondary_mount}} Pipette",
119140
"see_how_offsets_work": "See how labware offsets work",
120-
"select_labware_from_list": "Select a labware from the list to check its stored offset data",
141+
"select_labware_to_view_data": "Select a labware to view its stored offset data.",
121142
"slot": "Slot {{slotName}}",
122143
"slot_location": "Slot Location",
123144
"slot_name": "slot {{slotName}}",
145+
"specific_slots_can_be_adjusted": "Specific slot locations can be adjusted as needed",
124146
"start_position_check": "begin labware position check, move to Slot {{initial_labware_slot}}",
125147
"store_probe": "Before exiting, unlock the calibration probe, remove it from the nozzle, and return it to its storage location.",
126148
"stored_offset_data": "Apply Stored Labware Offset Data?",
127149
"stored_offsets_for_this_protocol": "Stored Labware Offset data that applies to this protocol",
128150
"table_view": "Table View",
129151
"tip_rack": "tip rack",
130152
"try_again": "Try again",
153+
"unsaved_changes_will_be_lost": "Unsaved changes will be lost",
131154
"view_current_offsets": "view current offsets",
132155
"view_data": "View data",
133156
"what_is_labware_offset_data": "What is labware offset data?"

app/src/molecules/MultiDeckLabelTagBtns/index.tsx

+7
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,15 @@ import {
1818

1919
import { QuaternaryButton, SmallButton } from '/app/atoms/buttons'
2020

21+
import type { SmallButtonTypes } from '/app/atoms/buttons/SmallButton'
22+
2123
const MAX_SUPPORTED_LABELS = 3
2224

2325
export interface MultiDeckLabelTagBtn {
2426
buttonText: string
2527
onClick: () => void
2628
disabled?: boolean
29+
buttonType?: SmallButtonTypes
2730
}
2831

2932
export interface MultiDeckLabelTagBtnsProps {
@@ -92,6 +95,10 @@ const CONTAINER_STYLE = css`
9295
gap: ${SPACING.spacing24};
9396
align-items: ${ALIGN_CENTER};
9497
98+
@media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} {
99+
border-radius: ${BORDERS.borderRadius8};
100+
}
101+
95102
/* Collapse the Tag vertically beneath the DeckInfo labels */
96103
@media (max-width: 423px) {
97104
grid-template-columns: 1fr auto;

app/src/organisms/Desktop/Devices/ProtocolRun/SetupLabwarePositionCheck/CurrentOffsetsTable.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,9 @@ export function CurrentOffsetsTable(
7878
<tr>
7979
<OffsetTableHeader>{t('location')}</OffsetTableHeader>
8080
<OffsetTableHeader>{t('labware')}</OffsetTableHeader>
81-
<OffsetTableHeader>{t('labware_offset_data')}</OffsetTableHeader>
81+
<OffsetTableHeader>
82+
{t('legacy_labware_offset_data')}
83+
</OffsetTableHeader>
8284
</tr>
8385
</thead>
8486
<tbody>

app/src/organisms/LabwarePositionCheck/LPCContentContainer.tsx

+19-6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
Flex,
66
RESPONSIVENESS,
77
SPACING,
8+
POSITION_FIXED,
89
} from '@opentrons/components'
910

1011
import { StepMeter } from '/app/atoms/StepMeter'
@@ -39,11 +40,13 @@ export function LPCContentContainer({
3940

4041
return (
4142
<Flex css={CONTAINER_STYLE}>
42-
<StepMeter
43-
totalSteps={totalStepCount}
44-
currentStep={currentStepIndex + 1}
45-
/>
46-
<ChildNavigation {...rest} css={CHILD_NAV_STYLE} />
43+
<Flex css={FIXED_HEADER_STYLE}>
44+
<StepMeter
45+
totalSteps={totalStepCount}
46+
currentStep={currentStepIndex + 1}
47+
/>
48+
<ChildNavigation {...rest} css={CHILD_NAV_STYLE} />
49+
</Flex>
4750
<Flex css={contentStyle ?? CHILDREN_CONTAINER_STYLE}>{children}</Flex>
4851
</Flex>
4952
)
@@ -54,14 +57,24 @@ const CONTAINER_STYLE = css`
5457
height: 100vh;
5558
`
5659

60+
// TODO(jh, 03-12-25): This should be a fixed value in components.
61+
const FIXED_HEADER_STYLE = css`
62+
position: ${POSITION_FIXED};
63+
top: 0;
64+
left: 0;
65+
right: 0;
66+
flex-direction: ${DIRECTION_COLUMN};
67+
`
68+
5769
// TODO(jh, 02-05-25): Investigate whether we can remove the position: fixed styling from ChildNav.
5870
const CHILD_NAV_STYLE = css`
59-
top: ${SPACING.spacing8};
71+
margin-top: ${SPACING.spacing8};
6072
`
6173
const CHILDREN_CONTAINER_STYLE = css`
6274
margin-top: 7.75rem;
6375
flex-direction: ${DIRECTION_COLUMN};
6476
height: 100%;
77+
overflow-y: auto;
6578
6679
@media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} {
6780
padding: ${SPACING.spacing32} ${SPACING.spacing60} ${SPACING.spacing40}

app/src/organisms/LabwarePositionCheck/LPCErrorModal.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export function LPCErrorModal(props: LPCWizardContentProps): JSX.Element {
3434
<LPCContentContainer
3535
{...props}
3636
header={t('labware_position_check_title')}
37-
onClickButton={headerCommands.handleClose}
37+
onClickButton={headerCommands.handleCloseWithoutHome}
3838
buttonText={t('exit')}
3939
>
4040
<ModalContainer
@@ -71,7 +71,7 @@ export function LPCErrorModal(props: LPCWizardContentProps): JSX.Element {
7171
<PrimaryButton
7272
textTransform={TEXT_TRANSFORM_CAPITALIZE}
7373
alignSelf={ALIGN_FLEX_END}
74-
onClick={headerCommands.handleClose}
74+
onClick={headerCommands.handleCloseWithoutHome}
7575
>
7676
{t('shared:exit')}
7777
</PrimaryButton>

app/src/organisms/LabwarePositionCheck/LPCFlows/hooks/useLPCLabwareInfo/getLPCLabwareInfoFrom.ts

+64-25
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,14 @@ import isEqual from 'lodash/isEqual'
22

33
import { getLabwareDisplayName, getLabwareDefURI } from '@opentrons/shared-data'
44

5+
import { OFFSET_KIND_LOCATION_SPECIFIC } from '/app/redux/protocol-runs'
6+
57
import type { LabwareDefinition2 } from '@opentrons/shared-data'
6-
import type { LPCLabwareInfo, OffsetDetails } from '/app/redux/protocol-runs'
8+
import type {
9+
DefaultOffsetDetails,
10+
LocationSpecificOffsetDetails,
11+
LPCLabwareInfo,
12+
} from '/app/redux/protocol-runs'
713
import type { LabwareLocationCombo } from '/app/organisms/LegacyApplyHistoricOffsets/hooks/getLabwareLocationCombos'
814
import type { UseLPCLabwareInfoProps } from '.'
915

@@ -36,7 +42,16 @@ function getLabwareInfoRecords(
3642
labwareDetails[uri] = {
3743
id: getALabwareIdFromUri({ ...params, uri }),
3844
displayName: getDisplayNameFromUri({ ...params, uri }),
39-
offsetDetails: getOffsetDetailsForLabware({ ...params, uri }),
45+
defaultOffsetDetails: getDefaultOffsetDetailsForLabware({
46+
...params,
47+
uri,
48+
}),
49+
locationSpecificOffsetDetails: getLocationSpecificOffsetDetailsForLabware(
50+
{
51+
...params,
52+
uri,
53+
}
54+
),
4055
}
4156
}
4257
})
@@ -84,30 +99,54 @@ function getDisplayNameFromUri({
8499

85100
// NOTE: A lot of the logic here acts as temporary adapter that resolves the app's current way of getting offset data (scraping the run record)
86101
// and the end goal of treating labware as first class citizens.
87-
function getOffsetDetailsForLabware({
102+
function getLocationSpecificOffsetDetailsForLabware({
88103
currentOffsets,
89104
lwLocationCombos,
90105
uri,
91-
}: GetLPCLabwareInfoForURI): OffsetDetails[] {
92-
return lwLocationCombos.flatMap(comboInfo => {
93-
const { definitionUri, location, ...restInfo } = comboInfo
94-
95-
const existingOffset =
96-
currentOffsets.find(
97-
offset =>
98-
uri === offset.definitionUri &&
99-
isEqual(offset.location, comboInfo.location)
100-
) ?? null
101-
102-
return {
103-
existingOffset: existingOffset ?? null,
104-
workingOffset: null,
105-
locationDetails: {
106-
...location,
107-
...restInfo,
108-
definitionUri,
109-
kind: 'location-specific',
110-
},
111-
}
112-
})
106+
}: GetLPCLabwareInfoForURI): LocationSpecificOffsetDetails[] {
107+
// @ts-expect-error - Temporary util. No need to solve this completely here.
108+
return lwLocationCombos
109+
.flatMap(comboInfo => {
110+
const { definitionUri, location, ...restInfo } = comboInfo
111+
112+
const existingOffset =
113+
currentOffsets.find(
114+
offset =>
115+
uri === offset.definitionUri &&
116+
isEqual(offset.location, comboInfo.location)
117+
) ?? null
118+
119+
return {
120+
existingOffset: existingOffset ?? null,
121+
workingOffset: null,
122+
locationDetails: {
123+
...location,
124+
...restInfo,
125+
definitionUri,
126+
kind: OFFSET_KIND_LOCATION_SPECIFIC,
127+
},
128+
}
129+
})
130+
.filter(detail => detail.locationDetails.definitionUri === uri)
131+
}
132+
133+
// A temporary utility for getting a dummy default offset.
134+
function getDefaultOffsetDetailsForLabware({
135+
lwLocationCombos,
136+
uri,
137+
}: GetLPCLabwareInfoForURI): DefaultOffsetDetails {
138+
const aLabwareId =
139+
lwLocationCombos?.find(combo => combo.definitionUri === uri)?.labwareId ??
140+
''
141+
142+
return {
143+
workingOffset: null,
144+
existingOffset: null,
145+
locationDetails: {
146+
labwareId: aLabwareId,
147+
definitionUri: uri,
148+
kind: 'default',
149+
slotName: 'C2',
150+
},
151+
}
113152
}

app/src/organisms/LabwarePositionCheck/__fixtures__/index.ts

+5
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,8 @@ export * from './mockWorkingOffsets'
22
export * from './mockExistingOffsets'
33
export * from './mockTipRackDef'
44
export * from './mockCompletedAnalysis'
5+
export * from './mockOffsets'
6+
export * from './mockLPCContentProps'
7+
export * from './mockLabwareInfo'
8+
export * from './mockActivePipette'
9+
export * from './mockSelectedLwOverview'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export const mockActivePipette = {
2+
id: 'test-pipette-id',
3+
mount: 'left',
4+
modelSpecs: {
5+
channels: 8,
6+
displayName: 'Test Pipette',
7+
},
8+
} as any

0 commit comments

Comments
 (0)