Skip to content

Commit

Permalink
feat(app): Expose Labware Calibration Status on the FileInfo Page (#6100
Browse files Browse the repository at this point in the history
)

Display the current stored calibration offset for all labware used in the protocol, better-enabling users to decide whether labware calibration is necessary without providing an explicit recommendation.

Co-authored-by: Seth Foster <[email protected]>
Co-authored-by: Mike Cousins <[email protected]>
  • Loading branch information
3 people authored Jul 28, 2020
1 parent 6350511 commit 2a22f59
Show file tree
Hide file tree
Showing 35 changed files with 1,411 additions and 120 deletions.
4 changes: 2 additions & 2 deletions api/tests/opentrons/data/mad_mag_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def run(ctx):
ctx.home()
tr = ctx.load_labware('opentrons_96_tiprack_300ul', 1)
mm = ctx.load_module('magnetic module', 4)
lw = mm.load_labware('nest_96_wellplate_100ul_pcr_fullskirt')
lw = mm.load_labware('nest_96_wellplate_100ul_pcr_full_skirt')
right = ctx.load_instrument('p300_single_gen2', types.Mount.RIGHT, [tr])

mm.disengage()
Expand All @@ -24,7 +24,7 @@ def run(ctx):
mm.disengage()

mm.engage(height=30)
mm.disenage()
mm.disengage()

mm.engage(offset=-10)
mm.disengage()
Expand Down
22 changes: 21 additions & 1 deletion app/src/calibration/__tests__/reducer.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// @flow

import * as Fixtures from '../__fixtures__'
import * as LabwareFixtures from '../labware/__fixtures__'
import * as Labware from '../labware'
import * as Actions from '../actions'
import { calibrationReducer } from '../reducer'

Expand All @@ -13,7 +15,25 @@ describe('calibration reducer', () => {
)

expect(calibrationReducer({}, action)).toEqual({
'robot-name': { calibrationStatus: Fixtures.mockCalibrationStatus },
'robot-name': {
calibrationStatus: Fixtures.mockCalibrationStatus,
labwareCalibrations: null,
},
})
})

it('should handle a FETCH_LABWARE_CALIBRATIONS_SUCCESS', () => {
const action = Labware.fetchLabwareCalibrationsSuccess(
'robot-name',
LabwareFixtures.mockAllLabwareCalibraton,
{}
)

expect(calibrationReducer({}, action)).toEqual({
'robot-name': {
calibrationStatus: null,
labwareCalibrations: LabwareFixtures.mockAllLabwareCalibraton,
},
})
})
})
19 changes: 17 additions & 2 deletions app/src/calibration/__tests__/selectors.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,22 @@ describe('calibration selectors', () => {
expect(Selectors.getCalibrationStatus(state, 'robotName')).toBe(null)
})

it('should return null if robot in state but no status', () => {
const state: $Shape<State> = {
calibration: {
robotName: { calibrationStatus: null, labwareCalibrations: null },
},
}
expect(Selectors.getCalibrationStatus(state, 'robotName')).toBe(null)
})

it('should return status if in state', () => {
const state: $Shape<State> = {
calibration: {
robotName: { calibrationStatus: Fixtures.mockCalibrationStatus },
robotName: {
calibrationStatus: Fixtures.mockCalibrationStatus,
labwareCalibrations: null,
},
},
}
expect(Selectors.getCalibrationStatus(state, 'robotName')).toEqual(
Expand All @@ -33,7 +45,10 @@ describe('calibration selectors', () => {
it('should return status if in state', () => {
const state: $Shape<State> = {
calibration: {
robotName: { calibrationStatus: Fixtures.mockCalibrationStatus },
robotName: {
calibrationStatus: Fixtures.mockCalibrationStatus,
labwareCalibrations: null,
},
},
}
expect(Selectors.getDeckCalibrationStatus(state, 'robotName')).toEqual(
Expand Down
34 changes: 34 additions & 0 deletions app/src/calibration/api-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,37 @@ export type CalibrationStatus = {|
|},
|},
|}

export type OffsetData = {|
value: [number, number, number],
lastModified: string,
|}

export type TipLengthData = {|
value: number,
lastModified: string,
|}

export type CalibrationData = {|
offset: OffsetData,
tipLength: TipLengthData | null,
|}

export type LabwareCalibration = {|
calibrationData: CalibrationData,
loadName: string,
namespace: string,
version: number,
parent: string,
|}

export type LabwareCalibrationModel = {|
attributes: LabwareCalibration,
type: string,
id: string,
|}

export type AllLabwareCalibrations = {|
data: Array<LabwareCalibrationModel>,
meta: { ... },
|}
6 changes: 5 additions & 1 deletion app/src/calibration/epic/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

import { combineEpics } from 'redux-observable'
import { fetchCalibrationStatusEpic } from './fetchCalibrationStatusEpic'
import { labwareCalibrationEpic } from '../labware/epic'

import type { Epic } from '../../types'

export const calibrationEpic: Epic = combineEpics(fetchCalibrationStatusEpic)
export const calibrationEpic: Epic = combineEpics(
fetchCalibrationStatusEpic,
labwareCalibrationEpic
)
1 change: 1 addition & 0 deletions app/src/calibration/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
export * from './actions'
export * from './constants'
export * from './selectors'
export * from './labware'
2 changes: 2 additions & 0 deletions app/src/calibration/labware/__fixtures__/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// @flow
export * from './labware-calibration'
77 changes: 77 additions & 0 deletions app/src/calibration/labware/__fixtures__/labware-calibration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// @flow
import { GET } from '../../../robot-api'
import {
makeResponseFixtures,
mockFailureBody,
} from '../../../robot-api/__fixtures__'
import { LABWARE_CALIBRATION_PATH } from '../constants'

import type { ResponseFixtures } from '../../../robot-api/__fixtures__'
import type {
LabwareCalibrationModel,
AllLabwareCalibrations,
} from '../../api-types'

export const mockLabwareCalibration1: LabwareCalibrationModel = {
attributes: {
calibrationData: {
offset: {
value: [0.0, 0.0, 0.0],
lastModified: '2020-04-05T14:30',
},
tipLength: {
value: 30,
lastModified: '2007-05-05T0:30',
},
},
loadName: 'opentrons_96_tiprack_10ul',
namespace: 'opentrons',
version: 1,
parent: 'fake_id',
},
id: 'some id',
type: 'Labware Calibration',
}

export const mockLabwareCalibration2: LabwareCalibrationModel = {
attributes: {
calibrationData: {
offset: {
value: [1.0, 1.0, 1.0],
lastModified: '2020-04-05T14:30',
},
tipLength: {
value: 30,
lastModified: '2007-05-05T0:30',
},
},
loadName: 'opentrons_96_tiprack_1000ul',
namespace: 'opentrons',
version: 1,
parent: '',
},
id: 'some id',
type: 'Labware Calibration',
}

export const mockAllLabwareCalibraton: AllLabwareCalibrations = {
data: [mockLabwareCalibration1, mockLabwareCalibration2],
meta: {},
}

export const {
successMeta: mockFetchLabwareCalibrationSuccessMeta,
failureMeta: mockFetchLabwareCalibrationFailureMeta,
success: mockFetchLabwareCalibrationSuccess,
failure: mockFetchLabwareCalibrationFailure,
}: ResponseFixtures<
AllLabwareCalibrations,
{| message: string |}
> = makeResponseFixtures({
method: GET,
path: LABWARE_CALIBRATION_PATH,
successStatus: 200,
successBody: mockAllLabwareCalibraton,
failureStatus: 500,
failureBody: mockFailureBody,
})
67 changes: 67 additions & 0 deletions app/src/calibration/labware/__tests__/actions.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// @flow

import * as Fixtures from '../__fixtures__'
import * as Actions from '../actions'
import type { LawareCalibrationAction } from '../types'

type ActionSpec = {|
should: string,
creator: (...Array<any>) => LawareCalibrationAction,
args: Array<mixed>,
expected: LawareCalibrationAction,
|}

const SPECS: Array<ActionSpec> = [
{
should: 'create a fetchLabwareCalibrations action',
creator: Actions.fetchLabwareCalibrations,
args: ['robot-name'],
expected: {
type: 'calibration:FETCH_LABWARE_CALIBRATIONS',
payload: { robotName: 'robot-name' },
meta: {},
},
},
{
should: 'create a fetchLabwareCalibrationsSuccess action',
creator: Actions.fetchLabwareCalibrationsSuccess,
args: [
'robot-name',
Fixtures.mockFetchLabwareCalibrationSuccess.body,
{ requestId: '123' },
],
expected: {
type: 'calibration:FETCH_LABWARE_CALIBRATIONS_SUCCESS',
payload: {
robotName: 'robot-name',
labwareCalibrations: Fixtures.mockAllLabwareCalibraton,
},
meta: { requestId: '123' },
},
},
{
should: 'create a fetchLabwareCalibrationsFailure action',
creator: Actions.fetchLabwareCalibrationsFailure,
args: [
'robot-name',
Fixtures.mockFetchLabwareCalibrationFailure.body,
{ requestId: '123' },
],
expected: {
type: 'calibration:FETCH_LABWARE_CALIBRATIONS_FAILURE',
payload: {
robotName: 'robot-name',
error: Fixtures.mockFetchLabwareCalibrationFailure.body,
},
meta: { requestId: '123' },
},
},
]

describe('calibration actions', () => {
SPECS.forEach(({ should, creator, args, expected }) => {
it(should, () => {
expect(creator(...args)).toEqual(expected)
})
})
})
Loading

0 comments on commit 2a22f59

Please sign in to comment.