Skip to content

Commit 9d17f2d

Browse files
committed
unseal test cleanup removal of unused pushout command and command schema update
1 parent 2288583 commit 9d17f2d

File tree

7 files changed

+271
-138
lines changed

7 files changed

+271
-138
lines changed

api/src/opentrons/protocol_api/core/engine/instrument.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
from opentrons.protocol_api._liquid import LiquidClass
4949

5050
_DISPENSE_VOLUME_VALIDATION_ADDED_IN = APIVersion(2, 17)
51+
_RESIN_TIP_DEFAULT_VOLUME = 400
5152
_RESIN_TIP_DEFAULT_FLOW_RATE = 10.0
5253

5354

@@ -745,24 +746,20 @@ def resin_tip_dispense(
745746
well_core: WellCore,
746747
volume: Optional[float] = None,
747748
flow_rate: Optional[float] = None,
748-
push_out: Optional[float] = None,
749749
) -> None:
750750
"""
751751
Args:
752-
volume: The volume of liquid to dispense, in microliters.
752+
volume: The volume of liquid to dispense, in microliters. Defaults to 400uL.
753753
location: The exact location to dispense to.
754754
well_core: The well to dispense to, if applicable.
755-
flow_rate: The flow rate in µL/s to dispense at. Defaults to 10.0.
756-
push_out: The amount to push the plunger below bottom position.
755+
flow_rate: The flow rate in µL/s to dispense at. Defaults to 10.0uL/S.
757756
"""
758757
if isinstance(location, (TrashBin, WasteChute)):
759758
raise ValueError("Trash Bin and Waste Chute have no Wells.")
760759
well_name = well_core.get_name()
761760
labware_id = well_core.labware_id
762761
if volume is None:
763-
volume = self._engine_client.state.pipettes.get_maximum_volume(
764-
self._pipette_id
765-
)
762+
volume = _RESIN_TIP_DEFAULT_VOLUME
766763
if flow_rate is None:
767764
flow_rate = _RESIN_TIP_DEFAULT_FLOW_RATE
768765

api/src/opentrons/protocol_api/core/instrument.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,6 @@ def resin_tip_dispense(
204204
well_core: WellCoreType,
205205
volume: Optional[float] = None,
206206
flow_rate: Optional[float] = None,
207-
push_out: Optional[float] = None,
208207
) -> None:
209208
...
210209

api/src/opentrons/protocol_api/core/legacy/legacy_instrument_core.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,6 @@ def resin_tip_dispense(
329329
well_core: WellCore,
330330
volume: Optional[float] = None,
331331
flow_rate: Optional[float] = None,
332-
push_out: Optional[float] = None,
333332
) -> None:
334333
raise APIVersionError(api_element="Dispensing liquid from resin tips.")
335334

api/src/opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,6 @@ def resin_tip_dispense(
297297
well_core: WellCore,
298298
volume: Optional[float] = None,
299299
flow_rate: Optional[float] = None,
300-
push_out: Optional[float] = None,
301300
) -> None:
302301
raise APIVersionError(api_element="Dispensing liquid from resin tips.")
303302

api/src/opentrons/protocol_api/instrument_context.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1792,7 +1792,6 @@ def resin_tip_dispense(
17921792
location: types.Location,
17931793
volume: Optional[float] = None,
17941794
rate: Optional[float] = None,
1795-
push_out: Optional[float] = None,
17961795
) -> InstrumentContext:
17971796
"""Dispense a volume from resin tips into a labware.
17981797
@@ -1814,12 +1813,6 @@ def resin_tip_dispense(
18141813
``rate`` multiplied by :py:attr:`flow_rate.dispense<flow_rate>`.
18151814
:type rate: float
18161815
1817-
:param push_out: Continue past the plunger bottom to help ensure all liquid
1818-
leaves the tip. Measured in µL. The default value is ``None``.
1819-
1820-
See :ref:`push-out-dispense` for details.
1821-
:type push_out: float
1822-
18231816
"""
18241817
well: Optional[labware.Well] = None
18251818
last_location = self._get_last_location_by_api_version()
@@ -1863,7 +1856,6 @@ def resin_tip_dispense(
18631856
well_core=well._core,
18641857
volume=volume,
18651858
flow_rate=rate,
1866-
push_out=push_out,
18671859
)
18681860
return self
18691861

api/tests/opentrons/protocol_engine/commands/test_evotip_unseal_pipette.py

Lines changed: 41 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
from opentrons.protocol_engine.state import update_types
2727
from opentrons.protocol_engine.state.state import StateView
2828
from opentrons.protocol_engine.execution import MovementHandler, GantryMover, TipHandler
29-
29+
from opentrons.protocols.models import LabwareDefinition
30+
import json
31+
from opentrons_shared_data import load_shared_data
3032

3133
from opentrons.types import Point
3234

@@ -82,13 +84,27 @@ def test_drop_tip_params_default_origin() -> None:
8284
)
8385

8486

87+
@pytest.fixture
88+
def evotips_definition() -> LabwareDefinition:
89+
"""A fixturee of the evotips definition."""
90+
# TODO (chb 2025-01-29): When we migrate all labware to v3 we can clean this up
91+
return LabwareDefinition.model_validate(
92+
json.loads(
93+
load_shared_data(
94+
"labware/definitions/3/evotips_opentrons_96_labware/1.json"
95+
)
96+
)
97+
)
98+
99+
85100
async def test_drop_tip_implementation(
86101
decoy: Decoy,
87102
mock_state_view: StateView,
88103
mock_movement_handler: MovementHandler,
89104
mock_tip_handler: TipHandler,
90105
mock_model_utils: ModelUtils,
91106
gantry_mover: GantryMover,
107+
evotips_definition: LabwareDefinition,
92108
) -> None:
93109
"""A DropTip command should have an execution implementation."""
94110
subject = EvotipUnsealPipetteImplementation(
@@ -105,6 +121,9 @@ async def test_drop_tip_implementation(
105121
wellName="A3",
106122
wellLocation=DropTipWellLocation(offset=WellOffset(x=1, y=2, z=3)),
107123
)
124+
decoy.when(mock_state_view.labware.get_definition("123")).then_return(
125+
evotips_definition
126+
)
108127

109128
decoy.when(
110129
mock_state_view.pipettes.get_is_partially_configured(pipette_id="abc")
@@ -154,90 +173,14 @@ async def test_drop_tip_implementation(
154173
),
155174
),
156175
)
157-
158176
decoy.verify(
159-
await mock_tip_handler.drop_tip(pipette_id="abc", home_after=True),
160-
times=1,
161-
)
162-
163-
164-
async def test_drop_tip_with_alternating_locations(
165-
decoy: Decoy,
166-
mock_state_view: StateView,
167-
mock_movement_handler: MovementHandler,
168-
mock_tip_handler: TipHandler,
169-
mock_model_utils: ModelUtils,
170-
gantry_mover: GantryMover,
171-
) -> None:
172-
"""It should drop tip at random location within the labware every time."""
173-
subject = EvotipUnsealPipetteImplementation(
174-
state_view=mock_state_view,
175-
movement=mock_movement_handler,
176-
tip_handler=mock_tip_handler,
177-
model_utils=mock_model_utils,
178-
gantry_mover=gantry_mover,
179-
)
180-
params = EvotipUnsealPipetteParams(
181-
pipetteId="abc",
182-
labwareId="123",
183-
wellName="A3",
184-
wellLocation=DropTipWellLocation(offset=WellOffset(x=1, y=2, z=3)),
185-
)
186-
drop_location = DropTipWellLocation(
187-
origin=DropTipWellOrigin.DEFAULT, offset=WellOffset(x=10, y=20, z=30)
188-
)
189-
decoy.when(
190-
mock_state_view.geometry.get_next_tip_drop_location(
191-
labware_id="123", well_name="A3", pipette_id="abc"
192-
)
193-
).then_return(drop_location)
194-
195-
decoy.when(
196-
mock_state_view.pipettes.get_is_partially_configured(pipette_id="abc")
197-
).then_return(False)
198-
199-
decoy.when(
200-
mock_state_view.geometry.get_checked_tip_drop_location(
177+
await mock_tip_handler.drop_tip(
201178
pipette_id="abc",
202-
labware_id="123",
203-
well_location=drop_location,
204-
partially_configured=False,
205-
)
206-
).then_return(WellLocation(offset=WellOffset(x=4, y=5, z=6)))
207-
208-
decoy.when(
209-
await mock_movement_handler.move_to_well(
210-
pipette_id="abc",
211-
labware_id="123",
212-
well_name="A3",
213-
well_location=WellLocation(offset=WellOffset(x=4, y=5, z=6)),
214-
current_well=None,
215-
force_direct=False,
216-
minimum_z_height=None,
217-
speed=None,
218-
operation_volume=None,
219-
)
220-
).then_return(Point(x=111, y=222, z=333))
221-
222-
result = await subject.execute(params)
223-
assert result == SuccessData(
224-
public=EvotipUnsealPipetteResult(position=DeckPoint(x=111, y=222, z=333)),
225-
state_update=update_types.StateUpdate(
226-
pipette_location=update_types.PipetteLocationUpdate(
227-
pipette_id="abc",
228-
new_location=update_types.Well(
229-
labware_id="123",
230-
well_name="A3",
231-
),
232-
new_deck_point=DeckPoint(x=111, y=222, z=333),
233-
),
234-
pipette_tip_state=update_types.PipetteTipStateUpdate(
235-
pipette_id="abc", tip_geometry=None
236-
),
237-
pipette_aspirated_fluid=update_types.PipetteUnknownFluidUpdate(
238-
pipette_id="abc"
239-
),
179+
home_after=None,
180+
do_not_ignore_tip_presence=False,
181+
ignore_plunger=True,
240182
),
183+
times=1,
241184
)
242185

243186

@@ -248,6 +191,7 @@ async def test_tip_attached_error(
248191
mock_tip_handler: TipHandler,
249192
mock_model_utils: ModelUtils,
250193
gantry_mover: GantryMover,
194+
evotips_definition: LabwareDefinition,
251195
) -> None:
252196
"""A Evotip Unseal command should have an execution implementation."""
253197
subject = EvotipUnsealPipetteImplementation(
@@ -264,6 +208,9 @@ async def test_tip_attached_error(
264208
wellName="A3",
265209
wellLocation=DropTipWellLocation(offset=WellOffset(x=1, y=2, z=3)),
266210
)
211+
decoy.when(mock_state_view.labware.get_definition("123")).then_return(
212+
evotips_definition
213+
)
267214

268215
decoy.when(
269216
mock_state_view.pipettes.get_is_partially_configured(pipette_id="abc")
@@ -292,51 +239,21 @@ async def test_tip_attached_error(
292239
)
293240
).then_return(Point(x=111, y=222, z=333))
294241
decoy.when(
295-
await mock_tip_handler.drop_tip(pipette_id="abc", home_after=None)
242+
await mock_tip_handler.drop_tip(
243+
pipette_id="abc",
244+
home_after=None,
245+
do_not_ignore_tip_presence=False,
246+
ignore_plunger=True,
247+
)
296248
).then_raise(TipAttachedError("Egads!"))
297249

298250
decoy.when(mock_model_utils.generate_id()).then_return("error-id")
299251
decoy.when(mock_model_utils.get_timestamp()).then_return(
300252
datetime(year=1, month=2, day=3)
301253
)
302254

303-
result = await subject.execute(params)
304-
305-
assert result == DefinedErrorData(
306-
public=StallOrCollisionError.model_construct(
307-
id="error-id",
308-
createdAt=datetime(year=1, month=2, day=3),
309-
wrappedErrors=[matchers.Anything()],
310-
errorInfo={"retryLocation": (111, 222, 333)},
311-
),
312-
state_update=update_types.StateUpdate(
313-
pipette_location=update_types.PipetteLocationUpdate(
314-
pipette_id="abc",
315-
new_location=update_types.Well(
316-
labware_id="123",
317-
well_name="A3",
318-
),
319-
new_deck_point=DeckPoint(x=111, y=222, z=333),
320-
),
321-
pipette_aspirated_fluid=update_types.PipetteUnknownFluidUpdate(
322-
pipette_id="abc"
323-
),
324-
),
325-
state_update_if_false_positive=update_types.StateUpdate(
326-
pipette_tip_state=update_types.PipetteTipStateUpdate(
327-
pipette_id="abc",
328-
tip_geometry=None,
329-
),
330-
pipette_location=update_types.PipetteLocationUpdate(
331-
pipette_id="abc",
332-
new_location=update_types.Well(
333-
labware_id="123",
334-
well_name="A3",
335-
),
336-
new_deck_point=DeckPoint(x=111, y=222, z=333),
337-
),
338-
),
339-
)
255+
with pytest.raises(TipAttachedError):
256+
await subject.execute(params)
340257

341258

342259
async def test_stall_error(
@@ -346,6 +263,7 @@ async def test_stall_error(
346263
mock_tip_handler: TipHandler,
347264
mock_model_utils: ModelUtils,
348265
gantry_mover: GantryMover,
266+
evotips_definition: LabwareDefinition,
349267
) -> None:
350268
"""A DropTip command should have an execution implementation."""
351269
subject = EvotipUnsealPipetteImplementation(
@@ -362,6 +280,9 @@ async def test_stall_error(
362280
wellName="A3",
363281
wellLocation=DropTipWellLocation(offset=WellOffset(x=1, y=2, z=3)),
364282
)
283+
decoy.when(mock_state_view.labware.get_definition("123")).then_return(
284+
evotips_definition
285+
)
365286

366287
decoy.when(
367288
mock_state_view.pipettes.get_is_partially_configured(pipette_id="abc")

0 commit comments

Comments
 (0)