opentrons 8.7.0a0__py3-none-any.whl → 8.7.0a2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of opentrons might be problematic. Click here for more details.
- opentrons/_version.py +2 -2
- opentrons/drivers/thermocycler/abstract.py +1 -0
- opentrons/drivers/thermocycler/driver.py +33 -4
- opentrons/drivers/thermocycler/simulator.py +2 -0
- opentrons/hardware_control/api.py +24 -5
- opentrons/hardware_control/backends/controller.py +8 -2
- opentrons/hardware_control/backends/ot3controller.py +3 -0
- opentrons/hardware_control/backends/ot3simulator.py +2 -1
- opentrons/hardware_control/backends/simulator.py +2 -1
- opentrons/hardware_control/backends/subsystem_manager.py +5 -2
- opentrons/hardware_control/module_control.py +82 -8
- opentrons/hardware_control/modules/__init__.py +3 -0
- opentrons/hardware_control/modules/absorbance_reader.py +11 -4
- opentrons/hardware_control/modules/flex_stacker.py +38 -9
- opentrons/hardware_control/modules/heater_shaker.py +30 -5
- opentrons/hardware_control/modules/magdeck.py +8 -4
- opentrons/hardware_control/modules/mod_abc.py +13 -5
- opentrons/hardware_control/modules/tempdeck.py +25 -5
- opentrons/hardware_control/modules/thermocycler.py +56 -10
- opentrons/hardware_control/modules/types.py +20 -1
- opentrons/hardware_control/modules/utils.py +11 -4
- opentrons/hardware_control/nozzle_manager.py +3 -0
- opentrons/hardware_control/ot3api.py +26 -5
- opentrons/hardware_control/scripts/update_module_fw.py +5 -0
- opentrons/hardware_control/types.py +31 -2
- opentrons/legacy_commands/protocol_commands.py +20 -0
- opentrons/legacy_commands/types.py +42 -0
- opentrons/motion_planning/waypoints.py +15 -29
- opentrons/protocol_api/__init__.py +5 -0
- opentrons/protocol_api/_types.py +6 -1
- opentrons/protocol_api/core/common.py +3 -1
- opentrons/protocol_api/core/engine/_default_labware_versions.py +32 -11
- opentrons/protocol_api/core/engine/_default_liquid_class_versions.py +2 -0
- opentrons/protocol_api/core/engine/labware.py +8 -1
- opentrons/protocol_api/core/engine/module_core.py +4 -0
- opentrons/protocol_api/core/engine/pipette_movement_conflict.py +77 -17
- opentrons/protocol_api/core/engine/protocol.py +18 -1
- opentrons/protocol_api/core/engine/tasks.py +35 -0
- opentrons/protocol_api/core/legacy/legacy_module_core.py +2 -0
- opentrons/protocol_api/core/legacy/legacy_protocol_core.py +11 -1
- opentrons/protocol_api/core/legacy/tasks.py +19 -0
- opentrons/protocol_api/core/legacy_simulator/legacy_protocol_core.py +14 -2
- opentrons/protocol_api/core/legacy_simulator/tasks.py +19 -0
- opentrons/protocol_api/core/module.py +1 -0
- opentrons/protocol_api/core/protocol.py +11 -2
- opentrons/protocol_api/core/tasks.py +31 -0
- opentrons/protocol_api/module_contexts.py +1 -0
- opentrons/protocol_api/protocol_context.py +26 -4
- opentrons/protocol_api/robot_context.py +38 -21
- opentrons/protocol_api/tasks.py +48 -0
- opentrons/protocol_api/validation.py +6 -1
- opentrons/protocol_engine/actions/__init__.py +4 -2
- opentrons/protocol_engine/actions/actions.py +22 -9
- opentrons/protocol_engine/clients/sync_client.py +6 -7
- opentrons/protocol_engine/commands/__init__.py +42 -0
- opentrons/protocol_engine/commands/absorbance_reader/close_lid.py +2 -15
- opentrons/protocol_engine/commands/absorbance_reader/open_lid.py +2 -15
- opentrons/protocol_engine/commands/aspirate.py +1 -0
- opentrons/protocol_engine/commands/command.py +1 -0
- opentrons/protocol_engine/commands/command_unions.py +39 -0
- opentrons/protocol_engine/commands/create_timer.py +83 -0
- opentrons/protocol_engine/commands/dispense.py +1 -0
- opentrons/protocol_engine/commands/drop_tip.py +32 -8
- opentrons/protocol_engine/commands/movement_common.py +2 -0
- opentrons/protocol_engine/commands/pick_up_tip.py +21 -11
- opentrons/protocol_engine/commands/set_tip_state.py +97 -0
- opentrons/protocol_engine/commands/thermocycler/run_extended_profile.py +6 -0
- opentrons/protocol_engine/commands/thermocycler/run_profile.py +8 -0
- opentrons/protocol_engine/commands/thermocycler/set_target_block_temperature.py +17 -1
- opentrons/protocol_engine/commands/touch_tip.py +1 -1
- opentrons/protocol_engine/commands/unsafe/unsafe_place_labware.py +6 -22
- opentrons/protocol_engine/commands/wait_for_tasks.py +98 -0
- opentrons/protocol_engine/errors/__init__.py +4 -0
- opentrons/protocol_engine/errors/exceptions.py +55 -0
- opentrons/protocol_engine/execution/__init__.py +2 -0
- opentrons/protocol_engine/execution/command_executor.py +8 -0
- opentrons/protocol_engine/execution/create_queue_worker.py +5 -1
- opentrons/protocol_engine/execution/labware_movement.py +9 -12
- opentrons/protocol_engine/execution/movement.py +2 -0
- opentrons/protocol_engine/execution/queue_worker.py +4 -0
- opentrons/protocol_engine/execution/run_control.py +8 -0
- opentrons/protocol_engine/execution/task_handler.py +157 -0
- opentrons/protocol_engine/protocol_engine.py +67 -33
- opentrons/protocol_engine/resources/__init__.py +2 -0
- opentrons/protocol_engine/resources/concurrency_provider.py +27 -0
- opentrons/protocol_engine/resources/deck_configuration_provider.py +7 -0
- opentrons/protocol_engine/resources/labware_validation.py +10 -6
- opentrons/protocol_engine/state/_well_math.py +60 -18
- opentrons/protocol_engine/state/addressable_areas.py +2 -0
- opentrons/protocol_engine/state/commands.py +7 -7
- opentrons/protocol_engine/state/geometry.py +237 -379
- opentrons/protocol_engine/state/labware.py +52 -102
- opentrons/protocol_engine/state/labware_origin_math/errors.py +94 -0
- opentrons/protocol_engine/state/labware_origin_math/stackup_origin_to_labware_origin.py +1331 -0
- opentrons/protocol_engine/state/module_substates/thermocycler_module_substate.py +37 -0
- opentrons/protocol_engine/state/modules.py +26 -7
- opentrons/protocol_engine/state/motion.py +44 -0
- opentrons/protocol_engine/state/state.py +14 -0
- opentrons/protocol_engine/state/state_summary.py +2 -0
- opentrons/protocol_engine/state/tasks.py +139 -0
- opentrons/protocol_engine/state/tips.py +177 -258
- opentrons/protocol_engine/state/update_types.py +16 -9
- opentrons/protocol_engine/types/__init__.py +9 -3
- opentrons/protocol_engine/types/deck_configuration.py +5 -1
- opentrons/protocol_engine/types/instrument.py +8 -1
- opentrons/protocol_engine/types/labware.py +1 -13
- opentrons/protocol_engine/types/module.py +10 -0
- opentrons/protocol_engine/types/tasks.py +38 -0
- opentrons/protocol_engine/types/tip.py +9 -0
- opentrons/protocol_runner/create_simulating_orchestrator.py +29 -2
- opentrons/protocol_runner/run_orchestrator.py +18 -2
- opentrons/protocols/api_support/definitions.py +1 -1
- opentrons/protocols/api_support/types.py +2 -1
- opentrons/simulate.py +48 -15
- opentrons/system/camera.py +1 -1
- {opentrons-8.7.0a0.dist-info → opentrons-8.7.0a2.dist-info}/METADATA +4 -4
- {opentrons-8.7.0a0.dist-info → opentrons-8.7.0a2.dist-info}/RECORD +120 -107
- opentrons/protocol_engine/state/_labware_origin_math.py +0 -636
- {opentrons-8.7.0a0.dist-info → opentrons-8.7.0a2.dist-info}/WHEEL +0 -0
- {opentrons-8.7.0a0.dist-info → opentrons-8.7.0a2.dist-info}/entry_points.txt +0 -0
- {opentrons-8.7.0a0.dist-info → opentrons-8.7.0a2.dist-info}/licenses/LICENSE +0 -0
|
@@ -271,6 +271,22 @@ from .wait_for_duration import (
|
|
|
271
271
|
WaitForDurationCommandType,
|
|
272
272
|
)
|
|
273
273
|
|
|
274
|
+
from .create_timer import (
|
|
275
|
+
CreateTimer,
|
|
276
|
+
CreateTimerCreate,
|
|
277
|
+
CreateTimerParams,
|
|
278
|
+
CreateTimerResult,
|
|
279
|
+
CreateTimerCommandType,
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
from .wait_for_tasks import (
|
|
283
|
+
WaitForTasks,
|
|
284
|
+
WaitForTasksCreate,
|
|
285
|
+
WaitForTasksParams,
|
|
286
|
+
WaitForTasksResult,
|
|
287
|
+
WaitForTasksCommandType,
|
|
288
|
+
)
|
|
289
|
+
|
|
274
290
|
from .pick_up_tip import (
|
|
275
291
|
PickUpTip,
|
|
276
292
|
PickUpTipParams,
|
|
@@ -384,6 +400,14 @@ from .get_next_tip import (
|
|
|
384
400
|
GetNextTipCommandType,
|
|
385
401
|
)
|
|
386
402
|
|
|
403
|
+
from .set_tip_state import (
|
|
404
|
+
SetTipState,
|
|
405
|
+
SetTipStateCreate,
|
|
406
|
+
SetTipStateParams,
|
|
407
|
+
SetTipStateResult,
|
|
408
|
+
SetTipStateCommandType,
|
|
409
|
+
)
|
|
410
|
+
|
|
387
411
|
from .liquid_probe import (
|
|
388
412
|
LiquidProbe,
|
|
389
413
|
LiquidProbeParams,
|
|
@@ -619,6 +643,12 @@ __all__ = [
|
|
|
619
643
|
"WaitForDurationCreate",
|
|
620
644
|
"WaitForDurationResult",
|
|
621
645
|
"WaitForDurationCommandType",
|
|
646
|
+
# Timer command models
|
|
647
|
+
"CreateTimer",
|
|
648
|
+
"CreateTimerCreate",
|
|
649
|
+
"CreateTimerParams",
|
|
650
|
+
"CreateTimerResult",
|
|
651
|
+
"CreateTimerCommandType",
|
|
622
652
|
# pick up tip command models
|
|
623
653
|
"PickUpTip",
|
|
624
654
|
"PickUpTipCreate",
|
|
@@ -725,6 +755,12 @@ __all__ = [
|
|
|
725
755
|
"GetNextTipParams",
|
|
726
756
|
"GetNextTipResult",
|
|
727
757
|
"GetNextTipCommandType",
|
|
758
|
+
# set tip state command bundle
|
|
759
|
+
"SetTipState",
|
|
760
|
+
"SetTipStateCreate",
|
|
761
|
+
"SetTipStateParams",
|
|
762
|
+
"SetTipStateResult",
|
|
763
|
+
"SetTipStateCommandType",
|
|
728
764
|
# liquid probe command bundle
|
|
729
765
|
"LiquidProbe",
|
|
730
766
|
"LiquidProbeParams",
|
|
@@ -754,4 +790,10 @@ __all__ = [
|
|
|
754
790
|
"PressureDispenseCreate",
|
|
755
791
|
"PressureDispenseResult",
|
|
756
792
|
"PressureDispenseCommandType",
|
|
793
|
+
# wait for tasks command bundle
|
|
794
|
+
"WaitForTasks",
|
|
795
|
+
"WaitForTasksCreate",
|
|
796
|
+
"WaitForTasksParams",
|
|
797
|
+
"WaitForTasksResult",
|
|
798
|
+
"WaitForTasksCommandType",
|
|
757
799
|
]
|
|
@@ -102,25 +102,12 @@ class CloseLidImpl(AbstractCommandImpl[CloseLidParams, SuccessData[CloseLidResul
|
|
|
102
102
|
)
|
|
103
103
|
)
|
|
104
104
|
|
|
105
|
-
# The lid's labware definition stores gripper offsets for itself in the
|
|
106
|
-
# space normally meant for offsets for labware stacked atop it.
|
|
107
|
-
lid_gripper_offsets = self._state_view.labware.get_child_gripper_offsets(
|
|
108
|
-
labware_definition=lid_definition,
|
|
109
|
-
slot_name=None,
|
|
110
|
-
)
|
|
111
|
-
if lid_gripper_offsets is None:
|
|
112
|
-
raise ValueError(
|
|
113
|
-
"Gripper Offset values for Absorbance Reader Lid labware must not be None."
|
|
114
|
-
)
|
|
115
|
-
|
|
116
105
|
await self._labware_movement.move_labware_with_gripper(
|
|
117
106
|
labware_definition=lid_definition,
|
|
118
107
|
current_location=current_location,
|
|
119
108
|
new_location=new_location,
|
|
120
|
-
user_pick_up_offset=Point
|
|
121
|
-
|
|
122
|
-
),
|
|
123
|
-
user_drop_offset=Point.from_xyz_attrs(lid_gripper_offsets.dropOffset),
|
|
109
|
+
user_pick_up_offset=Point(),
|
|
110
|
+
user_drop_offset=Point(),
|
|
124
111
|
post_drop_slide_offset=None,
|
|
125
112
|
gripper_z_offset=LID_Z_CLEARANCE,
|
|
126
113
|
)
|
|
@@ -103,25 +103,12 @@ class OpenLidImpl(AbstractCommandImpl[OpenLidParams, SuccessData[OpenLidResult]]
|
|
|
103
103
|
mod_substate.module_id
|
|
104
104
|
)
|
|
105
105
|
|
|
106
|
-
# The lid's labware definition stores gripper offsets for itself in the
|
|
107
|
-
# space normally meant for offsets for labware stacked atop it.
|
|
108
|
-
lid_gripper_offsets = self._state_view.labware.get_child_gripper_offsets(
|
|
109
|
-
labware_definition=lid_definition,
|
|
110
|
-
slot_name=None,
|
|
111
|
-
)
|
|
112
|
-
if lid_gripper_offsets is None:
|
|
113
|
-
raise ValueError(
|
|
114
|
-
"Gripper Offset values for Absorbance Reader Lid labware must not be None."
|
|
115
|
-
)
|
|
116
|
-
|
|
117
106
|
await self._labware_movement.move_labware_with_gripper(
|
|
118
107
|
labware_definition=lid_definition,
|
|
119
108
|
current_location=current_location,
|
|
120
109
|
new_location=new_location,
|
|
121
|
-
user_pick_up_offset=Point
|
|
122
|
-
|
|
123
|
-
),
|
|
124
|
-
user_drop_offset=Point.from_xyz_attrs(lid_gripper_offsets.dropOffset),
|
|
110
|
+
user_pick_up_offset=Point(),
|
|
111
|
+
user_drop_offset=Point(),
|
|
125
112
|
post_drop_slide_offset=None,
|
|
126
113
|
gripper_z_offset=LID_Z_CLEARANCE,
|
|
127
114
|
)
|
|
@@ -161,6 +161,7 @@ class AspirateImplementation(AbstractCommandImpl[AspirateParams, _ExecuteReturn]
|
|
|
161
161
|
well_location=well_location,
|
|
162
162
|
current_well=current_well,
|
|
163
163
|
operation_volume=-params.volume,
|
|
164
|
+
offset_pipette_for_reservoir_subwells=False,
|
|
164
165
|
)
|
|
165
166
|
state_update.append(move_result.state_update)
|
|
166
167
|
if isinstance(move_result, DefinedErrorData):
|
|
@@ -185,6 +185,7 @@ class AbstractCommandImpl(
|
|
|
185
185
|
tip_handler: execution.TipHandler,
|
|
186
186
|
run_control: execution.RunControlHandler,
|
|
187
187
|
rail_lights: execution.RailLightsHandler,
|
|
188
|
+
task_handler: execution.TaskHandler,
|
|
188
189
|
model_utils: ModelUtils,
|
|
189
190
|
status_bar: execution.StatusBarHandler,
|
|
190
191
|
command_note_adder: CommandNoteAdder,
|
|
@@ -267,6 +267,22 @@ from .wait_for_duration import (
|
|
|
267
267
|
WaitForDurationCommandType,
|
|
268
268
|
)
|
|
269
269
|
|
|
270
|
+
from .create_timer import (
|
|
271
|
+
CreateTimer,
|
|
272
|
+
CreateTimerCreate,
|
|
273
|
+
CreateTimerParams,
|
|
274
|
+
CreateTimerResult,
|
|
275
|
+
CreateTimerCommandType,
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
from .wait_for_tasks import (
|
|
279
|
+
WaitForTasks,
|
|
280
|
+
WaitForTasksCreate,
|
|
281
|
+
WaitForTasksParams,
|
|
282
|
+
WaitForTasksResult,
|
|
283
|
+
WaitForTasksCommandType,
|
|
284
|
+
)
|
|
285
|
+
|
|
270
286
|
from .pick_up_tip import (
|
|
271
287
|
PickUpTip,
|
|
272
288
|
PickUpTipParams,
|
|
@@ -372,6 +388,14 @@ from .get_next_tip import (
|
|
|
372
388
|
GetNextTipCommandType,
|
|
373
389
|
)
|
|
374
390
|
|
|
391
|
+
from .set_tip_state import (
|
|
392
|
+
SetTipState,
|
|
393
|
+
SetTipStateCreate,
|
|
394
|
+
SetTipStateParams,
|
|
395
|
+
SetTipStateResult,
|
|
396
|
+
SetTipStateCommandType,
|
|
397
|
+
)
|
|
398
|
+
|
|
375
399
|
from .liquid_probe import (
|
|
376
400
|
LiquidProbe,
|
|
377
401
|
LiquidProbeParams,
|
|
@@ -454,6 +478,8 @@ Command = Annotated[
|
|
|
454
478
|
PrepareToAspirate,
|
|
455
479
|
WaitForResume,
|
|
456
480
|
WaitForDuration,
|
|
481
|
+
WaitForTasks,
|
|
482
|
+
CreateTimer,
|
|
457
483
|
PickUpTip,
|
|
458
484
|
SavePosition,
|
|
459
485
|
SetRailLights,
|
|
@@ -462,6 +488,7 @@ Command = Annotated[
|
|
|
462
488
|
VerifyTipPresence,
|
|
463
489
|
GetTipPresence,
|
|
464
490
|
GetNextTip,
|
|
491
|
+
SetTipState,
|
|
465
492
|
LiquidProbe,
|
|
466
493
|
TryLiquidProbe,
|
|
467
494
|
SealPipetteToTip,
|
|
@@ -557,6 +584,8 @@ CommandParams = Union[
|
|
|
557
584
|
PrepareToAspirateParams,
|
|
558
585
|
WaitForResumeParams,
|
|
559
586
|
WaitForDurationParams,
|
|
587
|
+
WaitForTasksParams,
|
|
588
|
+
CreateTimerParams,
|
|
560
589
|
PickUpTipParams,
|
|
561
590
|
SavePositionParams,
|
|
562
591
|
SetRailLightsParams,
|
|
@@ -565,6 +594,7 @@ CommandParams = Union[
|
|
|
565
594
|
VerifyTipPresenceParams,
|
|
566
595
|
GetTipPresenceParams,
|
|
567
596
|
GetNextTipParams,
|
|
597
|
+
SetTipStateParams,
|
|
568
598
|
LiquidProbeParams,
|
|
569
599
|
TryLiquidProbeParams,
|
|
570
600
|
SealPipetteToTipParams,
|
|
@@ -658,6 +688,8 @@ CommandType = Union[
|
|
|
658
688
|
PrepareToAspirateCommandType,
|
|
659
689
|
WaitForResumeCommandType,
|
|
660
690
|
WaitForDurationCommandType,
|
|
691
|
+
WaitForTasksCommandType,
|
|
692
|
+
CreateTimerCommandType,
|
|
661
693
|
PickUpTipCommandType,
|
|
662
694
|
SavePositionCommandType,
|
|
663
695
|
SetRailLightsCommandType,
|
|
@@ -666,6 +698,7 @@ CommandType = Union[
|
|
|
666
698
|
VerifyTipPresenceCommandType,
|
|
667
699
|
GetTipPresenceCommandType,
|
|
668
700
|
GetNextTipCommandType,
|
|
701
|
+
SetTipStateCommandType,
|
|
669
702
|
LiquidProbeCommandType,
|
|
670
703
|
TryLiquidProbeCommandType,
|
|
671
704
|
SealPipetteToTipCommandType,
|
|
@@ -760,6 +793,8 @@ CommandCreate = Annotated[
|
|
|
760
793
|
PrepareToAspirateCreate,
|
|
761
794
|
WaitForResumeCreate,
|
|
762
795
|
WaitForDurationCreate,
|
|
796
|
+
WaitForTasksCreate,
|
|
797
|
+
CreateTimerCreate,
|
|
763
798
|
PickUpTipCreate,
|
|
764
799
|
SavePositionCreate,
|
|
765
800
|
SetRailLightsCreate,
|
|
@@ -768,6 +803,7 @@ CommandCreate = Annotated[
|
|
|
768
803
|
VerifyTipPresenceCreate,
|
|
769
804
|
GetTipPresenceCreate,
|
|
770
805
|
GetNextTipCreate,
|
|
806
|
+
SetTipStateCreate,
|
|
771
807
|
LiquidProbeCreate,
|
|
772
808
|
TryLiquidProbeCreate,
|
|
773
809
|
SealPipetteToTipCreate,
|
|
@@ -870,6 +906,8 @@ CommandResult = Union[
|
|
|
870
906
|
PrepareToAspirateResult,
|
|
871
907
|
WaitForResumeResult,
|
|
872
908
|
WaitForDurationResult,
|
|
909
|
+
WaitForTasksResult,
|
|
910
|
+
CreateTimerResult,
|
|
873
911
|
PickUpTipResult,
|
|
874
912
|
SavePositionResult,
|
|
875
913
|
SetRailLightsResult,
|
|
@@ -878,6 +916,7 @@ CommandResult = Union[
|
|
|
878
916
|
VerifyTipPresenceResult,
|
|
879
917
|
GetTipPresenceResult,
|
|
880
918
|
GetNextTipResult,
|
|
919
|
+
SetTipStateResult,
|
|
881
920
|
LiquidProbeResult,
|
|
882
921
|
TryLiquidProbeResult,
|
|
883
922
|
SealPipetteToTipResult,
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"""CreateTimer command request, result, and implementation models."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from pydantic import BaseModel, Field
|
|
5
|
+
from typing import Optional, Type, TYPE_CHECKING
|
|
6
|
+
from typing_extensions import Literal
|
|
7
|
+
|
|
8
|
+
from .command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, SuccessData
|
|
9
|
+
from ..errors.error_occurrence import ErrorOccurrence
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from ..execution import TaskHandler, RunControlHandler
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
CreateTimerCommandType = Literal["createTimer"]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class CreateTimerParams(BaseModel):
|
|
19
|
+
"""Payload required to annotate execution with a CreateTimer."""
|
|
20
|
+
|
|
21
|
+
time: float = Field(
|
|
22
|
+
...,
|
|
23
|
+
description="The time before the timer should elapse in seconds. This is the minimum time before the timer elapses; it may in practice take longer than this.",
|
|
24
|
+
)
|
|
25
|
+
task_id: str | None = Field(
|
|
26
|
+
None,
|
|
27
|
+
description="The id of the timer task",
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class CreateTimerResult(BaseModel):
|
|
32
|
+
"""Result data from the execution of a CreateTimer command."""
|
|
33
|
+
|
|
34
|
+
task_id: str = Field(..., description="The id of the timer task")
|
|
35
|
+
time: float = Field(..., description="The same time as the parameter.")
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class CreateTimerImplementation(
|
|
39
|
+
AbstractCommandImpl[CreateTimerParams, SuccessData[CreateTimerResult]]
|
|
40
|
+
):
|
|
41
|
+
"""CreateTimer command implementation."""
|
|
42
|
+
|
|
43
|
+
def __init__(
|
|
44
|
+
self,
|
|
45
|
+
task_handler: TaskHandler,
|
|
46
|
+
run_control: RunControlHandler,
|
|
47
|
+
**kwargs: object,
|
|
48
|
+
) -> None:
|
|
49
|
+
self._task_handler = task_handler
|
|
50
|
+
self._run_control = run_control
|
|
51
|
+
|
|
52
|
+
async def execute(
|
|
53
|
+
self, params: CreateTimerParams
|
|
54
|
+
) -> SuccessData[CreateTimerResult]:
|
|
55
|
+
"""No operation taken other than capturing message in command."""
|
|
56
|
+
|
|
57
|
+
async def timer(task_handler: TaskHandler) -> None:
|
|
58
|
+
async with task_handler.synchronize_concurrent("createTimer"):
|
|
59
|
+
await self._run_control.wait_for_duration(params.time)
|
|
60
|
+
|
|
61
|
+
task = await self._task_handler.create_task(timer, params.task_id)
|
|
62
|
+
return SuccessData(
|
|
63
|
+
public=CreateTimerResult(task_id=task.id, time=params.time),
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class CreateTimer(BaseCommand[CreateTimerParams, CreateTimerResult, ErrorOccurrence]):
|
|
68
|
+
"""CreateTimer command model."""
|
|
69
|
+
|
|
70
|
+
commandType: CreateTimerCommandType = "createTimer"
|
|
71
|
+
params: CreateTimerParams
|
|
72
|
+
result: Optional[CreateTimerResult] = None
|
|
73
|
+
|
|
74
|
+
_ImplementationCls: Type[CreateTimerImplementation] = CreateTimerImplementation
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class CreateTimerCreate(BaseCommandCreate[CreateTimerParams]):
|
|
78
|
+
"""CreateTimer command request model."""
|
|
79
|
+
|
|
80
|
+
commandType: CreateTimerCommandType = "createTimer"
|
|
81
|
+
params: CreateTimerParams
|
|
82
|
+
|
|
83
|
+
_CommandCls: Type[CreateTimer] = CreateTimer
|
|
@@ -101,6 +101,7 @@ class DispenseImplementation(AbstractCommandImpl[DispenseParams, _ExecuteReturn]
|
|
|
101
101
|
well_name=well_name,
|
|
102
102
|
well_location=well_location,
|
|
103
103
|
operation_volume=volume,
|
|
104
|
+
offset_pipette_for_reservoir_subwells=False,
|
|
104
105
|
)
|
|
105
106
|
if isinstance(move_result, DefinedErrorData):
|
|
106
107
|
return move_result
|
|
@@ -12,7 +12,7 @@ from opentrons.protocol_engine.errors.exceptions import TipAttachedError
|
|
|
12
12
|
from opentrons.protocol_engine.resources.model_utils import ModelUtils
|
|
13
13
|
|
|
14
14
|
from ..state.update_types import StateUpdate
|
|
15
|
-
from ..types import DropTipWellLocation
|
|
15
|
+
from ..types import DropTipWellLocation, TipRackWellState
|
|
16
16
|
from .pipetting_common import (
|
|
17
17
|
PipetteIdMixin,
|
|
18
18
|
TipPhysicallyAttachedError,
|
|
@@ -140,6 +140,25 @@ class DropTipImplementation(AbstractCommandImpl[DropTipParams, _ExecuteReturn]):
|
|
|
140
140
|
partially_configured=is_partially_configured,
|
|
141
141
|
)
|
|
142
142
|
|
|
143
|
+
is_tip_rack = self._state_view.labware.get_definition(
|
|
144
|
+
labware_id
|
|
145
|
+
).parameters.isTiprack
|
|
146
|
+
|
|
147
|
+
# It's possible that we are dropping tips into a labware trash for pre API v2.14 OT-2 protocols
|
|
148
|
+
# (or something else unexpected), so if it is not a tip rack mark no wells as used
|
|
149
|
+
if is_tip_rack:
|
|
150
|
+
tips_to_mark_as_used = (
|
|
151
|
+
self._state_view.tips.compute_tips_to_mark_as_used_or_empty(
|
|
152
|
+
labware_id=labware_id,
|
|
153
|
+
well_name=well_name,
|
|
154
|
+
nozzle_map=self._state_view.pipettes.get_nozzle_configuration(
|
|
155
|
+
pipette_id
|
|
156
|
+
),
|
|
157
|
+
)
|
|
158
|
+
)
|
|
159
|
+
else:
|
|
160
|
+
tips_to_mark_as_used = []
|
|
161
|
+
|
|
143
162
|
move_result = await move_to_well(
|
|
144
163
|
movement=self._movement_handler,
|
|
145
164
|
model_utils=self._model_utils,
|
|
@@ -152,12 +171,7 @@ class DropTipImplementation(AbstractCommandImpl[DropTipParams, _ExecuteReturn]):
|
|
|
152
171
|
return move_result
|
|
153
172
|
|
|
154
173
|
scrape_type = TipScrapeType.NONE
|
|
155
|
-
if
|
|
156
|
-
params.scrape_tips
|
|
157
|
-
and self._state_view.geometry._labware.get_definition(
|
|
158
|
-
labware_id
|
|
159
|
-
).parameters.isTiprack
|
|
160
|
-
):
|
|
174
|
+
if params.scrape_tips and is_tip_rack:
|
|
161
175
|
if int("".join(filter(str.isdigit, well_name))) <= 6:
|
|
162
176
|
scrape_type = TipScrapeType.RIGHT_ONE_COL
|
|
163
177
|
else:
|
|
@@ -194,6 +208,10 @@ class DropTipImplementation(AbstractCommandImpl[DropTipParams, _ExecuteReturn]):
|
|
|
194
208
|
pipette_id=params.pipetteId,
|
|
195
209
|
tip_geometry=None,
|
|
196
210
|
tip_source=None,
|
|
211
|
+
).update_tip_rack_well_state(
|
|
212
|
+
tip_state=TipRackWellState.USED,
|
|
213
|
+
labware_id=labware_id,
|
|
214
|
+
well_names=tips_to_mark_as_used,
|
|
197
215
|
),
|
|
198
216
|
)
|
|
199
217
|
else:
|
|
@@ -201,10 +219,16 @@ class DropTipImplementation(AbstractCommandImpl[DropTipParams, _ExecuteReturn]):
|
|
|
201
219
|
public=DropTipResult(position=move_result.public.position),
|
|
202
220
|
state_update=move_result.state_update.set_fluid_unknown(
|
|
203
221
|
pipette_id=pipette_id
|
|
204
|
-
)
|
|
222
|
+
)
|
|
223
|
+
.update_pipette_tip_state(
|
|
205
224
|
pipette_id=params.pipetteId,
|
|
206
225
|
tip_geometry=None,
|
|
207
226
|
tip_source=None,
|
|
227
|
+
)
|
|
228
|
+
.update_tip_rack_well_state(
|
|
229
|
+
tip_state=TipRackWellState.USED,
|
|
230
|
+
labware_id=labware_id,
|
|
231
|
+
well_names=tips_to_mark_as_used,
|
|
208
232
|
),
|
|
209
233
|
)
|
|
210
234
|
|
|
@@ -152,6 +152,7 @@ async def move_to_well(
|
|
|
152
152
|
minimum_z_height: Optional[float] = None,
|
|
153
153
|
speed: Optional[float] = None,
|
|
154
154
|
operation_volume: Optional[float] = None,
|
|
155
|
+
offset_pipette_for_reservoir_subwells: bool = False,
|
|
155
156
|
) -> MoveToWellOperationReturn:
|
|
156
157
|
"""Execute a move to well microoperation."""
|
|
157
158
|
try:
|
|
@@ -165,6 +166,7 @@ async def move_to_well(
|
|
|
165
166
|
minimum_z_height=minimum_z_height,
|
|
166
167
|
speed=speed,
|
|
167
168
|
operation_volume=operation_volume,
|
|
169
|
+
offset_pipette_for_reservoir_subwells=offset_pipette_for_reservoir_subwells,
|
|
168
170
|
)
|
|
169
171
|
except StallOrCollisionDetectedError as e:
|
|
170
172
|
return DefinedErrorData(
|
|
@@ -10,7 +10,7 @@ from typing_extensions import Literal
|
|
|
10
10
|
from ..errors import ErrorOccurrence, PickUpTipTipNotAttachedError
|
|
11
11
|
from ..resources import ModelUtils
|
|
12
12
|
from ..state import update_types
|
|
13
|
-
from ..types import PickUpTipWellLocation, LabwareWellId
|
|
13
|
+
from ..types import PickUpTipWellLocation, LabwareWellId, TipRackWellState
|
|
14
14
|
from .pipetting_common import (
|
|
15
15
|
PipetteIdMixin,
|
|
16
16
|
)
|
|
@@ -121,10 +121,14 @@ class PickUpTipImplementation(AbstractCommandImpl[PickUpTipParams, _ExecuteRetur
|
|
|
121
121
|
labware_id = params.labwareId
|
|
122
122
|
well_name = params.wellName
|
|
123
123
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
124
|
+
tips_to_mark_as_empty = (
|
|
125
|
+
self._state_view.tips.compute_tips_to_mark_as_used_or_empty(
|
|
126
|
+
labware_id=labware_id,
|
|
127
|
+
well_name=well_name,
|
|
128
|
+
nozzle_map=self._state_view.pipettes.get_nozzle_configuration(
|
|
129
|
+
pipette_id
|
|
130
|
+
),
|
|
131
|
+
)
|
|
128
132
|
)
|
|
129
133
|
|
|
130
134
|
well_location = self._state_view.geometry.convert_pick_up_tip_well_location(
|
|
@@ -160,16 +164,20 @@ class PickUpTipImplementation(AbstractCommandImpl[PickUpTipParams, _ExecuteRetur
|
|
|
160
164
|
),
|
|
161
165
|
)
|
|
162
166
|
.set_fluid_empty(pipette_id=pipette_id, clean_tip=True)
|
|
163
|
-
.
|
|
164
|
-
|
|
167
|
+
.update_tip_rack_well_state(
|
|
168
|
+
tip_state=TipRackWellState.EMPTY,
|
|
169
|
+
labware_id=labware_id,
|
|
170
|
+
well_names=tips_to_mark_as_empty,
|
|
165
171
|
)
|
|
166
172
|
)
|
|
167
173
|
state_update = (
|
|
168
174
|
update_types.StateUpdate.reduce(
|
|
169
175
|
update_types.StateUpdate(), move_result.state_update
|
|
170
176
|
)
|
|
171
|
-
.
|
|
172
|
-
|
|
177
|
+
.update_tip_rack_well_state(
|
|
178
|
+
tip_state=TipRackWellState.EMPTY,
|
|
179
|
+
labware_id=labware_id,
|
|
180
|
+
well_names=tips_to_mark_as_empty,
|
|
173
181
|
)
|
|
174
182
|
.set_fluid_unknown(pipette_id=pipette_id)
|
|
175
183
|
)
|
|
@@ -197,8 +205,10 @@ class PickUpTipImplementation(AbstractCommandImpl[PickUpTipParams, _ExecuteRetur
|
|
|
197
205
|
labware_id=labware_id, well_name=well_name
|
|
198
206
|
),
|
|
199
207
|
)
|
|
200
|
-
.
|
|
201
|
-
|
|
208
|
+
.update_tip_rack_well_state(
|
|
209
|
+
tip_state=TipRackWellState.EMPTY,
|
|
210
|
+
labware_id=labware_id,
|
|
211
|
+
well_names=tips_to_mark_as_empty,
|
|
202
212
|
)
|
|
203
213
|
.set_fluid_empty(pipette_id=pipette_id, clean_tip=True)
|
|
204
214
|
.set_pipette_ready_to_aspirate(
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""Set tip state command request, result, and implementation models."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from pydantic import BaseModel, Field
|
|
5
|
+
from typing import TYPE_CHECKING, Optional, Type, List
|
|
6
|
+
from typing_extensions import Literal
|
|
7
|
+
|
|
8
|
+
from ..errors.error_occurrence import ErrorOccurrence
|
|
9
|
+
from ..state.update_types import StateUpdate
|
|
10
|
+
from ..types import TipRackWellState
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
from .command import (
|
|
14
|
+
AbstractCommandImpl,
|
|
15
|
+
BaseCommand,
|
|
16
|
+
BaseCommandCreate,
|
|
17
|
+
SuccessData,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
if TYPE_CHECKING:
|
|
21
|
+
from ..state.state import StateView
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
SetTipStateCommandType = Literal["setTipState"]
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class SetTipStateParams(BaseModel):
|
|
28
|
+
"""Payload needed to set tip wells of a tip rack to the requested state."""
|
|
29
|
+
|
|
30
|
+
labwareId: str = Field(
|
|
31
|
+
..., description="Identifier of tip rack labware to set tip wells in."
|
|
32
|
+
)
|
|
33
|
+
wellNames: List[str] = Field(
|
|
34
|
+
..., description="Names of the well to set tip well state for."
|
|
35
|
+
)
|
|
36
|
+
tipWellState: TipRackWellState = Field(
|
|
37
|
+
..., description="State to set tip wells to."
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class SetTipStateResult(BaseModel):
|
|
42
|
+
"""Result data from the execution of a setTipState command."""
|
|
43
|
+
|
|
44
|
+
pass
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class SetTipStateImplementation(
|
|
48
|
+
AbstractCommandImpl[SetTipStateParams, SuccessData[SetTipStateResult]]
|
|
49
|
+
):
|
|
50
|
+
"""Set tip state command implementation."""
|
|
51
|
+
|
|
52
|
+
def __init__(
|
|
53
|
+
self,
|
|
54
|
+
state_view: StateView,
|
|
55
|
+
**kwargs: object,
|
|
56
|
+
) -> None:
|
|
57
|
+
self._state_view = state_view
|
|
58
|
+
|
|
59
|
+
async def execute(
|
|
60
|
+
self, params: SetTipStateParams
|
|
61
|
+
) -> SuccessData[SetTipStateResult]:
|
|
62
|
+
"""Set the tip rack wells to the requested state."""
|
|
63
|
+
labware_id = params.labwareId
|
|
64
|
+
well_names = params.wellNames
|
|
65
|
+
|
|
66
|
+
self._state_view.labware.raise_if_not_tip_rack(labware_id=labware_id)
|
|
67
|
+
self._state_view.labware.raise_if_wells_are_invalid(
|
|
68
|
+
labware_id=labware_id, well_names=well_names
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
return SuccessData(
|
|
72
|
+
public=SetTipStateResult(),
|
|
73
|
+
state_update=StateUpdate().update_tip_rack_well_state(
|
|
74
|
+
tip_state=params.tipWellState,
|
|
75
|
+
labware_id=labware_id,
|
|
76
|
+
well_names=well_names,
|
|
77
|
+
),
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class SetTipState(BaseCommand[SetTipStateParams, SetTipStateResult, ErrorOccurrence]):
|
|
82
|
+
"""Set tip state command model."""
|
|
83
|
+
|
|
84
|
+
commandType: SetTipStateCommandType = "setTipState"
|
|
85
|
+
params: SetTipStateParams
|
|
86
|
+
result: Optional[SetTipStateResult] = None
|
|
87
|
+
|
|
88
|
+
_ImplementationCls: Type[SetTipStateImplementation] = SetTipStateImplementation
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class SetTipStateCreate(BaseCommandCreate[SetTipStateParams]):
|
|
92
|
+
"""Set tip state command creation request model."""
|
|
93
|
+
|
|
94
|
+
commandType: SetTipStateCommandType = "setTipState"
|
|
95
|
+
params: SetTipStateParams
|
|
96
|
+
|
|
97
|
+
_CommandCls: Type[SetTipState] = SetTipState
|
|
@@ -33,6 +33,11 @@ class ProfileStep(BaseModel):
|
|
|
33
33
|
holdSeconds: float = Field(
|
|
34
34
|
..., description="Time to hold target temperature in seconds."
|
|
35
35
|
)
|
|
36
|
+
rampRate: float | SkipJsonSchema[None] = Field(
|
|
37
|
+
None,
|
|
38
|
+
description="How quickly to change temperature in °C/second.",
|
|
39
|
+
json_schema_extra=_remove_default,
|
|
40
|
+
)
|
|
36
41
|
|
|
37
42
|
|
|
38
43
|
class ProfileCycle(BaseModel):
|
|
@@ -68,6 +73,7 @@ def _transform_profile_step(
|
|
|
68
73
|
return ThermocyclerStep(
|
|
69
74
|
temperature=thermocycler_state.validate_target_block_temperature(step.celsius),
|
|
70
75
|
hold_time_seconds=step.holdSeconds,
|
|
76
|
+
ramp_rate=thermocycler_state.validate_ramp_rate(step.rampRate, step.celsius),
|
|
71
77
|
)
|
|
72
78
|
|
|
73
79
|
|
|
@@ -30,6 +30,11 @@ class RunProfileStepParams(BaseModel):
|
|
|
30
30
|
holdSeconds: float = Field(
|
|
31
31
|
..., description="Time to hold target temperature at in seconds."
|
|
32
32
|
)
|
|
33
|
+
rampRate: float | SkipJsonSchema[None] = Field(
|
|
34
|
+
None,
|
|
35
|
+
description="How quickly to change temperature in °C/second.",
|
|
36
|
+
json_schema_extra=_remove_default,
|
|
37
|
+
)
|
|
33
38
|
|
|
34
39
|
|
|
35
40
|
class RunProfileParams(BaseModel):
|
|
@@ -81,6 +86,9 @@ class RunProfileImpl(
|
|
|
81
86
|
profile_step.celsius
|
|
82
87
|
),
|
|
83
88
|
hold_time_seconds=profile_step.holdSeconds,
|
|
89
|
+
ramp_rate=thermocycler_state.validate_ramp_rate(
|
|
90
|
+
profile_step.rampRate, profile_step.celsius
|
|
91
|
+
),
|
|
84
92
|
)
|
|
85
93
|
for profile_step in params.profile
|
|
86
94
|
]
|