-
Notifications
You must be signed in to change notification settings - Fork 179
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(api): allow volume 0 commands in engine (#14211)
A previous PR (12a630b / #13989 ) changed the python protocol api in version 2.16 to allow commanding 0ul liquid handling commands like aspirate, mix, and dispense. This is useful in programmatic protocols that read out volumes to handle; they can now handle 0 volume properly. In 2.15 and previous, specifying 0 would lead to those commands doing the most volume they could (i.e. aspirate the full tip volume, dispense whatever's currently in the pipette, mix at full volume) and this likely was an unintentional side effect because of python truthiness. However, that change only touched the python protocol API; that API would emit commands to the engine that specified 0 volume, and those were not allowed: the pydantic models for the commands and responses required strictly greater than 0 volume. This PR - changes the pydantic models and updates the schema to allow 0ul commands - adds a python protocol to be an integration test - adds unit tests for the python protocol api aspirate and dispense commands --------- Co-authored-by: Seth Foster <[email protected]> Co-authored-by: Max Marrone <[email protected]>
- Loading branch information
1 parent
5fc0e29
commit 5a939ea
Showing
4 changed files
with
221 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
71 changes: 71 additions & 0 deletions
71
app-testing/files/protocols/py/OT2_P300M_P20S_TC_HS_TM_2_16_aspirateDispenseMix0Volume.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
"""Smoke Test v3.0 """ | ||
from opentrons import protocol_api | ||
|
||
metadata = { | ||
"protocolName": "API 2.16 Aspirate Dispense Mix 0 Volume", | ||
"author": "Opentrons Engineering <[email protected]>", | ||
"source": "Software Testing Team", | ||
} | ||
|
||
requirements = {"robotType": "OT-2", "apiLevel": "2.16"} | ||
|
||
|
||
def run(ctx: protocol_api.ProtocolContext) -> None: | ||
"""This method is run by the protocol engine.""" | ||
|
||
ctx.set_rail_lights(True) | ||
|
||
# deck positions | ||
tips_300ul_position = "5" | ||
tips_20ul_position = "4" | ||
dye_source_position = "3" | ||
logo_position = "2" | ||
|
||
# 300ul tips | ||
tips_300ul = [ | ||
ctx.load_labware( | ||
load_name="opentrons_96_tiprack_300ul", | ||
location=tips_300ul_position, | ||
label="300ul tips", | ||
) | ||
] | ||
|
||
# 20ul tips | ||
tips_20ul = [ | ||
ctx.load_labware( | ||
load_name="opentrons_96_tiprack_20ul", | ||
location=tips_20ul_position, | ||
label="20ul tips", | ||
) | ||
] | ||
|
||
# pipettes | ||
ctx.load_instrument(instrument_name="p300_multi_gen2", mount="left", tip_racks=tips_300ul) | ||
|
||
pipette_right = ctx.load_instrument(instrument_name="p20_single_gen2", mount="right", tip_racks=tips_20ul) | ||
|
||
dye_container = ctx.load_labware( | ||
load_name="nest_12_reservoir_15ml", | ||
location=dye_source_position, | ||
label="dye container", | ||
) | ||
|
||
# >= 2.14 define_liquid and load_liquid | ||
water = ctx.define_liquid( | ||
name="water", description="H₂O", display_color="#42AB2D" | ||
) # subscript 2 https://www.compart.com/en/unicode/U+2082 | ||
|
||
dye_container.wells_by_name()["A1"].load_liquid(liquid=water, volume=20) | ||
|
||
pipette_right.pick_up_tip() | ||
|
||
# >= 2.15: Aspirate everything, then dispense everything | ||
# < 2.15: Aspirate nothing, then dispense everything(Which in this case means nothing) | ||
# pipette_right.aspirate(volume=0, location=dye_container.wells_by_name()["A1"]) | ||
# pipette_right.dispense(location=dye_container.wells_by_name()["A1"]) | ||
|
||
# >= 2.15: Aspirate everything, dispense everything, mix everything | ||
# < 2.15: Aspirate everything, dispense nothing, mix nothing | ||
pipette_right.aspirate(volume=20, location=dye_container.wells_by_name()["A1"]) | ||
pipette_right.dispense(volume=0, location=dye_container.wells_by_name()["A1"]) | ||
pipette_right.mix(volume=0, location=dye_container.wells_by_name()["A1"]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters