opentrons 8.7.0a6__py3-none-any.whl → 8.7.0a7__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/asyncio/communication/serial_connection.py +129 -52
- opentrons/drivers/heater_shaker/abstract.py +5 -0
- opentrons/drivers/heater_shaker/driver.py +10 -0
- opentrons/drivers/heater_shaker/simulator.py +4 -0
- opentrons/drivers/thermocycler/abstract.py +6 -0
- opentrons/drivers/thermocycler/driver.py +61 -10
- opentrons/drivers/thermocycler/simulator.py +6 -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/emulation/abstract_emulator.py +6 -4
- opentrons/hardware_control/emulation/connection_handler.py +8 -5
- opentrons/hardware_control/emulation/heater_shaker.py +12 -3
- opentrons/hardware_control/emulation/settings.py +1 -1
- opentrons/hardware_control/emulation/thermocycler.py +67 -15
- 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 +42 -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 +68 -11
- 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/poller.py +22 -8
- opentrons/hardware_control/scripts/update_module_fw.py +5 -0
- opentrons/hardware_control/types.py +31 -2
- opentrons/legacy_commands/module_commands.py +23 -0
- opentrons/legacy_commands/protocol_commands.py +20 -0
- opentrons/legacy_commands/types.py +80 -0
- opentrons/motion_planning/deck_conflict.py +17 -12
- opentrons/motion_planning/waypoints.py +15 -29
- opentrons/protocol_api/__init__.py +5 -1
- 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/labware.py +8 -1
- opentrons/protocol_api/core/engine/module_core.py +75 -8
- opentrons/protocol_api/core/engine/protocol.py +18 -1
- opentrons/protocol_api/core/engine/tasks.py +48 -0
- opentrons/protocol_api/core/engine/well.py +8 -0
- opentrons/protocol_api/core/legacy/legacy_module_core.py +24 -4
- opentrons/protocol_api/core/legacy/legacy_protocol_core.py +11 -1
- opentrons/protocol_api/core/legacy/legacy_well_core.py +4 -0
- 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 +37 -4
- opentrons/protocol_api/core/protocol.py +11 -2
- opentrons/protocol_api/core/tasks.py +31 -0
- opentrons/protocol_api/core/well.py +4 -0
- opentrons/protocol_api/labware.py +5 -0
- opentrons/protocol_api/module_contexts.py +117 -11
- 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 +42 -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 +49 -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/heater_shaker/__init__.py +14 -0
- opentrons/protocol_engine/commands/heater_shaker/common.py +20 -0
- opentrons/protocol_engine/commands/heater_shaker/set_and_wait_for_shake_speed.py +5 -4
- opentrons/protocol_engine/commands/heater_shaker/set_shake_speed.py +136 -0
- opentrons/protocol_engine/commands/heater_shaker/set_target_temperature.py +31 -5
- 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/temperature_module/set_target_temperature.py +38 -7
- opentrons/protocol_engine/commands/thermocycler/__init__.py +16 -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 +40 -6
- opentrons/protocol_engine/commands/thermocycler/set_target_lid_temperature.py +29 -5
- opentrons/protocol_engine/commands/thermocycler/start_run_extended_profile.py +191 -0
- 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 +75 -34
- 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 +14 -11
- opentrons/protocol_engine/state/geometry.py +213 -374
- 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 +21 -8
- 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.0a6.dist-info → opentrons-8.7.0a7.dist-info}/METADATA +4 -4
- {opentrons-8.7.0a6.dist-info → opentrons-8.7.0a7.dist-info}/RECORD +143 -127
- opentrons/protocol_engine/state/_labware_origin_math.py +0 -636
- {opentrons-8.7.0a6.dist-info → opentrons-8.7.0a7.dist-info}/WHEEL +0 -0
- {opentrons-8.7.0a6.dist-info → opentrons-8.7.0a7.dist-info}/entry_points.txt +0 -0
- {opentrons-8.7.0a6.dist-info → opentrons-8.7.0a7.dist-info}/licenses/LICENSE +0 -0
|
@@ -6,7 +6,10 @@ from enum import Enum
|
|
|
6
6
|
|
|
7
7
|
from opentrons.types import DeckSlotName
|
|
8
8
|
|
|
9
|
-
from opentrons_shared_data.module.types import
|
|
9
|
+
from opentrons_shared_data.module.types import (
|
|
10
|
+
ModuleType as SharedDataModuleType,
|
|
11
|
+
ModuleOrientation,
|
|
12
|
+
)
|
|
10
13
|
from opentrons_shared_data.deck.types import SlotDefV3
|
|
11
14
|
from opentrons_shared_data.labware.types import LocatingFeatures
|
|
12
15
|
|
|
@@ -57,6 +60,7 @@ class AddressableArea:
|
|
|
57
60
|
position: AddressableOffsetVector
|
|
58
61
|
compatible_module_types: List[SharedDataModuleType]
|
|
59
62
|
features: LocatingFeatures
|
|
63
|
+
orientation: ModuleOrientation
|
|
60
64
|
|
|
61
65
|
|
|
62
66
|
# TODO make the below some sort of better type
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""Protocol Engine types to do with instruments."""
|
|
2
|
-
|
|
2
|
+
import enum
|
|
3
3
|
from typing import Union
|
|
4
4
|
|
|
5
5
|
from dataclasses import dataclass
|
|
@@ -45,3 +45,10 @@ class InstrumentOffsetVector(BaseModel):
|
|
|
45
45
|
x: float
|
|
46
46
|
y: float
|
|
47
47
|
z: float
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class GripperMoveType(enum.Enum):
|
|
51
|
+
"""Types of gripper movement."""
|
|
52
|
+
|
|
53
|
+
PICK_UP_LABWARE = enum.auto()
|
|
54
|
+
DROP_LABWARE = enum.auto()
|
|
@@ -2,16 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
from typing import Optional
|
|
5
|
+
from typing import Optional
|
|
6
6
|
from dataclasses import dataclass
|
|
7
7
|
from datetime import datetime
|
|
8
8
|
|
|
9
9
|
from pydantic import BaseModel, Field
|
|
10
10
|
|
|
11
|
-
from opentrons_shared_data.labware.labware_definition import (
|
|
12
|
-
LabwareDefinition,
|
|
13
|
-
)
|
|
14
|
-
|
|
15
11
|
from .location import LabwareLocation
|
|
16
12
|
from .labware_offset_location import (
|
|
17
13
|
LegacyLabwareOffsetLocation,
|
|
@@ -19,8 +15,6 @@ from .labware_offset_location import (
|
|
|
19
15
|
)
|
|
20
16
|
from .labware_offset_vector import LabwareOffsetVector
|
|
21
17
|
from .util import Vec3f
|
|
22
|
-
from .module import ModuleDefinition
|
|
23
|
-
from .deck_configuration import DeckLocationDefinition
|
|
24
18
|
|
|
25
19
|
|
|
26
20
|
@dataclass(frozen=True)
|
|
@@ -126,12 +120,6 @@ class LoadedLabware(BaseModel):
|
|
|
126
120
|
)
|
|
127
121
|
|
|
128
122
|
|
|
129
|
-
LabwareParentDefinition = Union[
|
|
130
|
-
DeckLocationDefinition, ModuleDefinition, LabwareDefinition
|
|
131
|
-
]
|
|
132
|
-
"""Information pertaining to a labware's parent (deck slot, module, or another labware) location."""
|
|
133
|
-
|
|
134
|
-
|
|
135
123
|
@dataclass(frozen=True)
|
|
136
124
|
class LabwareWellId:
|
|
137
125
|
"""Designates a well in a labware."""
|
|
@@ -21,6 +21,7 @@ from opentrons_shared_data.labware.types import LocatingFeatures
|
|
|
21
21
|
|
|
22
22
|
from opentrons.hardware_control.modules import (
|
|
23
23
|
ModuleType as ModuleType,
|
|
24
|
+
ModuleModel as HardwareModuleModel,
|
|
24
25
|
)
|
|
25
26
|
|
|
26
27
|
from .location import DeckSlotLocation
|
|
@@ -43,6 +44,11 @@ class ModuleModel(str, Enum):
|
|
|
43
44
|
ABSORBANCE_READER_V1 = "absorbanceReaderV1"
|
|
44
45
|
FLEX_STACKER_MODULE_V1 = "flexStackerModuleV1"
|
|
45
46
|
|
|
47
|
+
@classmethod
|
|
48
|
+
def from_hardware(cls, hardware_model: HardwareModuleModel) -> "ModuleModel":
|
|
49
|
+
"""Convert from the hardware model representation."""
|
|
50
|
+
return cls(hardware_model.value)
|
|
51
|
+
|
|
46
52
|
def as_type(self) -> ModuleType:
|
|
47
53
|
"""Get the ModuleType of this model."""
|
|
48
54
|
if ModuleModel.is_temperature_module_model(self):
|
|
@@ -193,6 +199,10 @@ class ModuleDefinition(BaseModel):
|
|
|
193
199
|
...,
|
|
194
200
|
)
|
|
195
201
|
|
|
202
|
+
orientation: Dict[str, str] = Field(
|
|
203
|
+
...,
|
|
204
|
+
)
|
|
205
|
+
|
|
196
206
|
compatibleWith: List[ModuleModel] = Field(
|
|
197
207
|
...,
|
|
198
208
|
)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""Types for Tasks."""
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
from opentrons.protocol_engine.errors import ErrorOccurrence
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
import asyncio
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@dataclass
|
|
9
|
+
class _BaseTask:
|
|
10
|
+
"""A base task representation."""
|
|
11
|
+
|
|
12
|
+
id: str
|
|
13
|
+
createdAt: datetime
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass
|
|
17
|
+
class Task(_BaseTask):
|
|
18
|
+
"""A task representation."""
|
|
19
|
+
|
|
20
|
+
asyncioTask: asyncio.Task[None]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@dataclass
|
|
24
|
+
class FinishedTask(_BaseTask):
|
|
25
|
+
"""A finished task representation."""
|
|
26
|
+
|
|
27
|
+
finishedAt: datetime
|
|
28
|
+
error: ErrorOccurrence | None
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@dataclass
|
|
32
|
+
class TaskSummary:
|
|
33
|
+
"""Task info for use in summary lists."""
|
|
34
|
+
|
|
35
|
+
id: str
|
|
36
|
+
createdAt: datetime
|
|
37
|
+
finishedAt: datetime | None = None
|
|
38
|
+
error: ErrorOccurrence | None = None
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""Protocol Engine types to deal with tips."""
|
|
2
2
|
|
|
3
3
|
from dataclasses import dataclass
|
|
4
|
+
from enum import Enum
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
@dataclass(frozen=True)
|
|
@@ -16,3 +17,11 @@ class TipGeometry:
|
|
|
16
17
|
length: float
|
|
17
18
|
diameter: float
|
|
18
19
|
volume: float
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class TipRackWellState(Enum):
|
|
23
|
+
"""The state of a single tip in a tip rack's well."""
|
|
24
|
+
|
|
25
|
+
CLEAN = "clean"
|
|
26
|
+
USED = "used"
|
|
27
|
+
EMPTY = "empty"
|
|
@@ -16,11 +16,38 @@ from opentrons_shared_data.robot.types import RobotType
|
|
|
16
16
|
from .python_protocol_wrappers import SimulatingContextCreator
|
|
17
17
|
from .run_orchestrator import RunOrchestrator
|
|
18
18
|
from .protocol_runner import create_protocol_runner, LiveRunner
|
|
19
|
+
from ..protocol_engine.types import (
|
|
20
|
+
PostRunHardwareState,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class SimulatingRunOrchestrator(RunOrchestrator):
|
|
25
|
+
"""A RunOrchestrator that cleans up its simulating hardware controller.
|
|
26
|
+
|
|
27
|
+
This should only be created and returned by create_simulating_orchestrator, unless
|
|
28
|
+
you are sure it's appropriate to clean up the hardware controller.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
async def finish(
|
|
32
|
+
self,
|
|
33
|
+
error: Exception | None = None,
|
|
34
|
+
drop_tips_after_run: bool = True,
|
|
35
|
+
set_run_status: bool = True,
|
|
36
|
+
post_run_hardware_state: PostRunHardwareState = PostRunHardwareState.HOME_AND_STAY_ENGAGED,
|
|
37
|
+
) -> None:
|
|
38
|
+
"""Finish the run and clean up the simulating hardware controller."""
|
|
39
|
+
await super().finish(
|
|
40
|
+
error=error,
|
|
41
|
+
drop_tips_after_run=drop_tips_after_run,
|
|
42
|
+
set_run_status=set_run_status,
|
|
43
|
+
post_run_hardware_state=post_run_hardware_state,
|
|
44
|
+
)
|
|
45
|
+
await self._hardware_api.clean_up()
|
|
19
46
|
|
|
20
47
|
|
|
21
48
|
async def create_simulating_orchestrator(
|
|
22
49
|
robot_type: RobotType, protocol_config: ProtocolConfig
|
|
23
|
-
) ->
|
|
50
|
+
) -> SimulatingRunOrchestrator:
|
|
24
51
|
"""Create a RunOrchestrator wired to a simulating HardwareControlAPI.
|
|
25
52
|
|
|
26
53
|
Example:
|
|
@@ -96,7 +123,7 @@ async def create_simulating_orchestrator(
|
|
|
96
123
|
hardware_api=simulating_hardware_api,
|
|
97
124
|
)
|
|
98
125
|
|
|
99
|
-
return
|
|
126
|
+
return SimulatingRunOrchestrator(
|
|
100
127
|
hardware_api=simulating_hardware_api,
|
|
101
128
|
json_or_python_protocol_runner=runner,
|
|
102
129
|
protocol_engine=protocol_engine,
|
|
@@ -15,7 +15,10 @@ from opentrons_shared_data.robot.types import RobotType
|
|
|
15
15
|
|
|
16
16
|
from . import protocol_runner, RunResult, JsonRunner, PythonAndLegacyRunner
|
|
17
17
|
from ..hardware_control import HardwareControlAPI
|
|
18
|
-
from ..hardware_control.modules import
|
|
18
|
+
from ..hardware_control.modules import (
|
|
19
|
+
AbstractModule as HardwareModuleAPI,
|
|
20
|
+
ModuleModel as HardwareModuleModel,
|
|
21
|
+
)
|
|
19
22
|
from ..protocol_engine import (
|
|
20
23
|
ProtocolEngine,
|
|
21
24
|
CommandCreate,
|
|
@@ -85,7 +88,6 @@ class RunOrchestrator:
|
|
|
85
88
|
def __init__(
|
|
86
89
|
self,
|
|
87
90
|
protocol_engine: ProtocolEngine,
|
|
88
|
-
# todo(mm, 2024-07-05): This hardware_api param looks unused?
|
|
89
91
|
hardware_api: HardwareControlAPI,
|
|
90
92
|
fixit_runner: protocol_runner.LiveRunner,
|
|
91
93
|
setup_runner: protocol_runner.LiveRunner,
|
|
@@ -115,6 +117,8 @@ class RunOrchestrator:
|
|
|
115
117
|
self._fixit_runner.prepare()
|
|
116
118
|
self._setup_runner.prepare()
|
|
117
119
|
self._protocol_engine.set_and_start_queue_worker(self.command_generator)
|
|
120
|
+
# used by SimulatingRunOrchestrator to clean up the simulating hardware controller
|
|
121
|
+
self._hardware_api = hardware_api
|
|
118
122
|
|
|
119
123
|
@property
|
|
120
124
|
def run_id(self) -> str:
|
|
@@ -380,6 +384,18 @@ class RunOrchestrator:
|
|
|
380
384
|
"""Handle an E-stop event from the hardware API."""
|
|
381
385
|
return self._protocol_engine.estop()
|
|
382
386
|
|
|
387
|
+
async def asynchronous_module_error(
|
|
388
|
+
self, module_model: HardwareModuleModel, module_serial: str | None
|
|
389
|
+
) -> bool:
|
|
390
|
+
"""Handle an asynchronous module error reported by hardware.
|
|
391
|
+
|
|
392
|
+
If this function returns true, the caller should call finish() immediately; if it returns
|
|
393
|
+
False, the caller should not call finish() until it otherwise would.
|
|
394
|
+
"""
|
|
395
|
+
return await self._protocol_engine.async_module_error(
|
|
396
|
+
module_model=ModuleModel.from_hardware(module_model), serial=module_serial
|
|
397
|
+
)
|
|
398
|
+
|
|
383
399
|
async def use_attached_modules(
|
|
384
400
|
self, modules_by_id: Dict[str, HardwareModuleAPI]
|
|
385
401
|
) -> None:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
|
-
from typing import NamedTuple, TypedDict
|
|
2
|
+
from typing import NamedTuple, TypedDict, Optional
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
class APIVersion(NamedTuple):
|
|
@@ -30,3 +30,4 @@ class ThermocyclerStep(ThermocyclerStepBase, total=False):
|
|
|
30
30
|
|
|
31
31
|
hold_time_seconds: float
|
|
32
32
|
hold_time_minutes: float
|
|
33
|
+
ramp_rate: Optional[float]
|
opentrons/simulate.py
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
This module has functions that provide a console entrypoint for simulating
|
|
4
4
|
a protocol from the command line.
|
|
5
5
|
"""
|
|
6
|
+
|
|
6
7
|
import argparse
|
|
7
8
|
import asyncio
|
|
8
9
|
import atexit
|
|
@@ -24,6 +25,7 @@ from typing import (
|
|
|
24
25
|
BinaryIO,
|
|
25
26
|
Optional,
|
|
26
27
|
Union,
|
|
28
|
+
Iterator,
|
|
27
29
|
)
|
|
28
30
|
from typing_extensions import Literal
|
|
29
31
|
|
|
@@ -81,6 +83,7 @@ if TYPE_CHECKING:
|
|
|
81
83
|
from opentrons_shared_data.labware.types import (
|
|
82
84
|
LabwareDefinition as LabwareDefinitionDict,
|
|
83
85
|
)
|
|
86
|
+
from opentrons.protocol_engine import ProtocolEngine
|
|
84
87
|
|
|
85
88
|
|
|
86
89
|
# See Jira RCORE-535.
|
|
@@ -309,6 +312,7 @@ def get_protocol_api(
|
|
|
309
312
|
bundled_labware=bundled_labware,
|
|
310
313
|
bundled_data=bundled_data,
|
|
311
314
|
extra_labware=extra_labware,
|
|
315
|
+
clean_up_hardware=(hardware_simulator is None),
|
|
312
316
|
)
|
|
313
317
|
else:
|
|
314
318
|
if bundled_labware is not None:
|
|
@@ -326,6 +330,7 @@ def get_protocol_api(
|
|
|
326
330
|
bundled_data=bundled_data,
|
|
327
331
|
extra_labware=extra_labware,
|
|
328
332
|
use_pe_virtual_hardware=use_virtual_hardware,
|
|
333
|
+
clean_up_hardware=(hardware_simulator is None),
|
|
329
334
|
)
|
|
330
335
|
|
|
331
336
|
# Intentional difference from execute.get_protocol_api():
|
|
@@ -781,13 +786,15 @@ def _create_live_context_non_pe(
|
|
|
781
786
|
extra_labware: Optional[Dict[str, "LabwareDefinitionDict"]],
|
|
782
787
|
bundled_labware: Optional[Dict[str, "LabwareDefinitionDict"]],
|
|
783
788
|
bundled_data: Optional[Dict[str, bytes]],
|
|
789
|
+
clean_up_hardware: bool,
|
|
784
790
|
) -> ProtocolContext:
|
|
785
791
|
"""Return a live ProtocolContext.
|
|
786
792
|
|
|
787
793
|
This controls the robot through the older infrastructure, instead of through Protocol Engine.
|
|
788
794
|
"""
|
|
789
795
|
assert api_version < ENGINE_CORE_API_VERSION
|
|
790
|
-
|
|
796
|
+
|
|
797
|
+
ctx = protocol_api.create_protocol_context(
|
|
791
798
|
api_version=api_version,
|
|
792
799
|
deck_type=deck_type,
|
|
793
800
|
hardware_api=hardware_api,
|
|
@@ -795,6 +802,17 @@ def _create_live_context_non_pe(
|
|
|
795
802
|
bundled_data=bundled_data,
|
|
796
803
|
extra_labware=extra_labware,
|
|
797
804
|
)
|
|
805
|
+
# Hack: we need to hook the protocol context cleanup in a way that isn't safe to put
|
|
806
|
+
# in the context generally, so we can do it like this and feel sad
|
|
807
|
+
original_cleanup = ctx.cleanup
|
|
808
|
+
|
|
809
|
+
def _cleanup_hook() -> None:
|
|
810
|
+
if clean_up_hardware:
|
|
811
|
+
ctx._hw_manager.hardware.clean_up()
|
|
812
|
+
original_cleanup()
|
|
813
|
+
|
|
814
|
+
ctx.cleanup = _cleanup_hook # type: ignore[method-assign]
|
|
815
|
+
return ctx
|
|
798
816
|
|
|
799
817
|
|
|
800
818
|
def _create_live_context_pe(
|
|
@@ -805,26 +823,40 @@ def _create_live_context_pe(
|
|
|
805
823
|
extra_labware: Dict[str, "LabwareDefinitionDict"],
|
|
806
824
|
bundled_data: Optional[Dict[str, bytes]],
|
|
807
825
|
use_pe_virtual_hardware: bool = True,
|
|
826
|
+
clean_up_hardware: bool = True,
|
|
808
827
|
) -> ProtocolContext:
|
|
809
828
|
"""Return a live ProtocolContext that controls the robot through ProtocolEngine."""
|
|
810
829
|
assert api_version >= ENGINE_CORE_API_VERSION
|
|
811
830
|
hardware_api_wrapped = hardware_api.wrapped()
|
|
812
831
|
global _LIVE_PROTOCOL_ENGINE_CONTEXTS
|
|
832
|
+
|
|
833
|
+
@contextmanager
|
|
834
|
+
def _cleanup_hardware_with_engine() -> (
|
|
835
|
+
Iterator[tuple["ProtocolEngine", asyncio.AbstractEventLoop]]
|
|
836
|
+
):
|
|
837
|
+
|
|
838
|
+
try:
|
|
839
|
+
with create_protocol_engine_in_thread(
|
|
840
|
+
hardware_api=hardware_api_wrapped,
|
|
841
|
+
config=_get_protocol_engine_config(
|
|
842
|
+
robot_type, use_pe_virtual_hardware=use_pe_virtual_hardware
|
|
843
|
+
),
|
|
844
|
+
deck_configuration=None,
|
|
845
|
+
file_provider=None,
|
|
846
|
+
error_recovery_policy=error_recovery_policy.never_recover,
|
|
847
|
+
drop_tips_after_run=False,
|
|
848
|
+
post_run_hardware_state=PostRunHardwareState.STAY_ENGAGED_IN_PLACE,
|
|
849
|
+
load_fixed_trash=should_load_fixed_trash_labware_for_python_protocol(
|
|
850
|
+
api_version
|
|
851
|
+
),
|
|
852
|
+
) as (engine, loop):
|
|
853
|
+
yield engine, loop
|
|
854
|
+
finally:
|
|
855
|
+
if clean_up_hardware:
|
|
856
|
+
hardware_api.clean_up()
|
|
857
|
+
|
|
813
858
|
pe, loop = _LIVE_PROTOCOL_ENGINE_CONTEXTS.enter_context(
|
|
814
|
-
|
|
815
|
-
hardware_api=hardware_api_wrapped,
|
|
816
|
-
config=_get_protocol_engine_config(
|
|
817
|
-
robot_type, use_pe_virtual_hardware=use_pe_virtual_hardware
|
|
818
|
-
),
|
|
819
|
-
deck_configuration=None,
|
|
820
|
-
file_provider=None,
|
|
821
|
-
error_recovery_policy=error_recovery_policy.never_recover,
|
|
822
|
-
drop_tips_after_run=False,
|
|
823
|
-
post_run_hardware_state=PostRunHardwareState.STAY_ENGAGED_IN_PLACE,
|
|
824
|
-
load_fixed_trash=should_load_fixed_trash_labware_for_python_protocol(
|
|
825
|
-
api_version
|
|
826
|
-
),
|
|
827
|
-
)
|
|
859
|
+
_cleanup_hardware_with_engine()
|
|
828
860
|
)
|
|
829
861
|
|
|
830
862
|
# `async def` so we can use loop.run_coroutine_threadsafe() to wait for its completion.
|
|
@@ -879,6 +911,7 @@ def _run_file_non_pe(
|
|
|
879
911
|
extra_labware=extra_labware,
|
|
880
912
|
bundled_labware=bundled_labware,
|
|
881
913
|
bundled_data=bundled_data,
|
|
914
|
+
clean_up_hardware=False,
|
|
882
915
|
)
|
|
883
916
|
|
|
884
917
|
scraper = _CommandScraper(logger=logger, level=level, broker=context.broker)
|
opentrons/system/camera.py
CHANGED
|
@@ -30,7 +30,7 @@ async def take_picture(filename: Path) -> None:
|
|
|
30
30
|
pass
|
|
31
31
|
|
|
32
32
|
if ARCHITECTURE == SystemArchitecture.YOCTO:
|
|
33
|
-
cmd = f"v4l2-ctl --device /dev/
|
|
33
|
+
cmd = f"v4l2-ctl --device /dev/ot_system_camera --set-fmt-video=width=1280,height=720,pixelformat=MJPG --stream-mmap --stream-to={str(filename)} --stream-count=1"
|
|
34
34
|
elif ARCHITECTURE == SystemArchitecture.BUILDROOT:
|
|
35
35
|
cmd = f"ffmpeg -f video4linux2 -s 640x480 -i /dev/video0 -ss 0:0:1 -frames 1 {str(filename)}"
|
|
36
36
|
else: # HOST
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: opentrons
|
|
3
|
-
Version: 8.7.
|
|
3
|
+
Version: 8.7.0a7
|
|
4
4
|
Summary: The Opentrons API is a simple framework designed to make writing automated biology lab protocols easy.
|
|
5
5
|
Project-URL: opentrons.com, https://www.opentrons.com
|
|
6
6
|
Project-URL: Source Code On Github, https://github.com/Opentrons/opentrons/tree/edge/api
|
|
@@ -24,7 +24,7 @@ Requires-Dist: click<9,>=8.0.0
|
|
|
24
24
|
Requires-Dist: importlib-metadata>=1.0; python_version < '3.8'
|
|
25
25
|
Requires-Dist: jsonschema<4.18.0,>=3.0.1
|
|
26
26
|
Requires-Dist: numpy<2,>=1.20.0
|
|
27
|
-
Requires-Dist: opentrons-shared-data==8.7.
|
|
27
|
+
Requires-Dist: opentrons-shared-data==8.7.0a7
|
|
28
28
|
Requires-Dist: packaging>=21.0
|
|
29
29
|
Requires-Dist: pydantic-settings<3,>=2
|
|
30
30
|
Requires-Dist: pydantic<3,>=2.0.0
|
|
@@ -32,6 +32,6 @@ Requires-Dist: pyserial>=3.5
|
|
|
32
32
|
Requires-Dist: pyusb==1.2.1
|
|
33
33
|
Requires-Dist: typing-extensions<5,>=4.0.0
|
|
34
34
|
Provides-Extra: flex-hardware
|
|
35
|
-
Requires-Dist: opentrons-hardware[flex]==8.7.
|
|
35
|
+
Requires-Dist: opentrons-hardware[flex]==8.7.0a7; extra == 'flex-hardware'
|
|
36
36
|
Provides-Extra: ot2-hardware
|
|
37
|
-
Requires-Dist: opentrons-hardware==8.7.
|
|
37
|
+
Requires-Dist: opentrons-hardware==8.7.0a7; extra == 'ot2-hardware'
|