Skip to content

Commit 04ef356

Browse files
committed
feat(app): update LPC store with previous run offsets
1 parent 7288573 commit 04ef356

File tree

7 files changed

+135
-3
lines changed

7 files changed

+135
-3
lines changed

app/src/redux/protocol-runs/actions/lpc.ts

+11-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
RESET_OFFSET_TO_DEFAULT,
1414
CLEAR_WORKING_OFFSETS,
1515
APPLIED_OFFSETS_TO_RUN,
16+
UPDATE_LPC_WITH_OFFSETS,
1617
} from '../constants'
1718

1819
import type {
@@ -35,8 +36,9 @@ import type {
3536
ResetLocationSpecificOffsetToDefaultAction,
3637
ClearSelectedLabwareWorkingOffsetsAction,
3738
AppliedOffsetsToRunAction,
39+
UpdateLPCWithOffsetsAction,
3840
} from '../types'
39-
import type { StoredLabwareOffset } from '@opentrons/api-client'
41+
import type { LabwareOffset, StoredLabwareOffset } from '@opentrons/api-client'
4042

4143
export const proceedStep = (
4244
runId: string,
@@ -150,3 +152,11 @@ export const appliedOffsetsToRun = (
150152
type: APPLIED_OFFSETS_TO_RUN,
151153
payload: { runId },
152154
})
155+
156+
export const updateLPCWithOffsets = (
157+
runId: string,
158+
offsets: LabwareOffset[]
159+
): UpdateLPCWithOffsetsAction => ({
160+
type: UPDATE_LPC_WITH_OFFSETS,
161+
payload: { runId, offsets },
162+
})

app/src/redux/protocol-runs/constants/lpc/actions.ts

+1
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ export const APPLY_WORKING_OFFSETS = 'APPLY_WORKING_OFFSETS'
1212
export const PROCEED_HANDLE_LW_SUBSTEP = 'PROCEED_HANDLE_LW_SUBSTEP'
1313
export const GO_BACK_HANDLE_LW_SUBSTEP = 'GO_BACK_HANDLE_LW_SUBSTEP'
1414
export const APPLIED_OFFSETS_TO_RUN = 'APPLIED_OFFSETS_TO_RUN'
15+
export const UPDATE_LPC_WITH_OFFSETS = 'UPDATE_LPC_WITH_OFFSETS'

app/src/redux/protocol-runs/reducer/index.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ export const protocolRunReducer: Reducer<ProtocolRunState, Action> = (
4242
case Constants.SET_FINAL_POSITION:
4343
case Constants.CLEAR_WORKING_OFFSETS:
4444
case Constants.RESET_OFFSET_TO_DEFAULT:
45-
case Constants.APPLY_WORKING_OFFSETS: {
45+
case Constants.APPLY_WORKING_OFFSETS:
46+
case Constants.UPDATE_LPC_WITH_OFFSETS: {
4647
const runId = action.payload.runId
4748
const currentRunState = state[runId] || { lpc: undefined }
4849
const nextLpcState = LPCReducer(currentRunState.lpc, action)

app/src/redux/protocol-runs/reducer/lpc.ts

+17
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@ import {
1414
RESET_OFFSET_TO_DEFAULT,
1515
CLEAR_WORKING_OFFSETS,
1616
APPLIED_OFFSETS_TO_RUN,
17+
UPDATE_LPC_WITH_OFFSETS,
1718
} from '../constants'
1819
import {
1920
updateOffsetsForURI,
2021
proceedToNextHandleLwSubstep,
2122
goBackToPreviousHandleLwSubstep,
2223
handleApplyWorkingOffsets,
2324
clearAllWorkingOffsets,
25+
updateLPCLabwareInfoFrom,
2426
} from './transforms'
2527

2628
import type {
@@ -203,6 +205,21 @@ export function LPCReducer(
203205
}
204206
}
205207

208+
case UPDATE_LPC_WITH_OFFSETS: {
209+
const { offsets } = action.payload
210+
211+
return {
212+
...state,
213+
labwareInfo: {
214+
...state.labwareInfo,
215+
labware: updateLPCLabwareInfoFrom(
216+
offsets,
217+
state.labwareInfo.labware
218+
),
219+
},
220+
}
221+
}
222+
206223
default:
207224
return state
208225
}

app/src/redux/protocol-runs/reducer/transforms/lpc/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ export { updateOffsetsForURI } from './updateOffsetsForURI'
22
export * from './handleLwSubstep'
33
export * from './handleApplyWorkingOffsets'
44
export * from './clearAllWorkingOffsets'
5+
export * from './updateLPCLabwareInfoFrom'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import type { LabwareOffset } from '@opentrons/api-client'
2+
import type { LPCLabwareInfo } from '/app/redux/protocol-runs'
3+
import isEqual from 'lodash/isEqual'
4+
5+
// Given run record offsets, update the LPC store with those supplied vectors details.
6+
// All run record supplied offsets will either match location-specific offsets or default offsets
7+
// supplied by the database.
8+
//
9+
// The database provided offsets are injected at LPC store initialization.
10+
//
11+
// Note that hardcoded offsets are injected into the store on initialization too,
12+
// and these will never need updating, as they are never supplied by the run record.
13+
export function updateLPCLabwareInfoFrom(
14+
clonedRunOffsets: LabwareOffset[],
15+
currentLwInfoLw: LPCLabwareInfo['labware']
16+
): LPCLabwareInfo['labware'] {
17+
return clonedRunOffsets.reduce(
18+
(acc, clonedRunOffset) => {
19+
const definitionUri = clonedRunOffset.definitionUri
20+
const lwInfo = acc[definitionUri]
21+
22+
if (clonedRunOffset.locationSequence == null || lwInfo == null) {
23+
console.error(
24+
'Expected cloned run offset to have location sequence, but did not.'
25+
)
26+
return acc
27+
}
28+
29+
const { locationSpecificOffsetDetails, defaultOffsetDetails } = lwInfo
30+
const { vector: defaultVector } = defaultOffsetDetails.existingOffset ?? {
31+
vector: null,
32+
}
33+
34+
// Whether the cloned run offset location matches a location-specific offset location
35+
// in the LPC store keyed at the same labware URI.
36+
const relevantLSIdx = locationSpecificOffsetDetails.findIndex(
37+
lsStoreOffset =>
38+
isEqual(
39+
lsStoreOffset.locationDetails.lwOffsetLocSeq,
40+
clonedRunOffset.locationSequence
41+
)
42+
)
43+
44+
// Matching location-specific offset case.
45+
if (relevantLSIdx > -1) {
46+
const newLocationSpecificOffsetDetails = locationSpecificOffsetDetails.map(
47+
(detail, idx) => {
48+
if (idx === relevantLSIdx) {
49+
return {
50+
...detail,
51+
existingOffset: {
52+
...clonedRunOffset,
53+
},
54+
}
55+
}
56+
return detail
57+
}
58+
)
59+
60+
return {
61+
...acc,
62+
[definitionUri]: {
63+
...lwInfo,
64+
locationSpecificOffsetDetails: newLocationSpecificOffsetDetails,
65+
},
66+
}
67+
}
68+
// Matching default offset case.
69+
// Whether the cloned run offset matches the default offset keyed
70+
// at the same labware URI.
71+
else if (
72+
defaultVector != null &&
73+
isEqual(defaultVector, clonedRunOffset.vector)
74+
) {
75+
// Return updated state with new default offset
76+
return {
77+
...acc,
78+
[definitionUri]: {
79+
...lwInfo,
80+
defaultOffsetDetails: {
81+
...defaultOffsetDetails,
82+
existingOffset: { ...clonedRunOffset },
83+
},
84+
},
85+
}
86+
}
87+
88+
return acc
89+
},
90+
{ ...currentLwInfoLw }
91+
)
92+
}

app/src/redux/protocol-runs/types/lpc/actions.ts

+11-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ import type {
44
LPCWizardState,
55
OffsetLocationDetails,
66
} from '/app/redux/protocol-runs/types/lpc'
7-
import type { StoredLabwareOffset, VectorOffset } from '@opentrons/api-client'
7+
import type {
8+
LabwareOffset,
9+
StoredLabwareOffset,
10+
VectorOffset,
11+
} from '@opentrons/api-client'
812

913
export interface PositionParams {
1014
labwareUri: string
@@ -93,6 +97,11 @@ export interface AppliedOffsetsToRunAction {
9397
payload: { runId: string }
9498
}
9599

100+
export interface UpdateLPCWithOffsetsAction {
101+
type: 'UPDATE_LPC_WITH_OFFSETS'
102+
payload: { runId: string; offsets: LabwareOffset[] }
103+
}
104+
96105
export type LPCWizardAction =
97106
| StartLPCAction
98107
| FinishLPCAction
@@ -108,3 +117,4 @@ export type LPCWizardAction =
108117
| ProceedHandleLwSubstepAction
109118
| GoBackHandleLwSubstepAction
110119
| AppliedOffsetsToRunAction
120+
| UpdateLPCWithOffsetsAction

0 commit comments

Comments
 (0)