opentrons 8.7.0a2__py3-none-any.whl → 8.7.0a3__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.

Files changed (119) hide show
  1. opentrons/_version.py +2 -2
  2. opentrons/drivers/thermocycler/abstract.py +0 -1
  3. opentrons/drivers/thermocycler/driver.py +4 -33
  4. opentrons/drivers/thermocycler/simulator.py +0 -2
  5. opentrons/hardware_control/api.py +5 -24
  6. opentrons/hardware_control/backends/controller.py +2 -8
  7. opentrons/hardware_control/backends/ot3controller.py +0 -3
  8. opentrons/hardware_control/backends/ot3simulator.py +1 -2
  9. opentrons/hardware_control/backends/simulator.py +1 -2
  10. opentrons/hardware_control/backends/subsystem_manager.py +2 -5
  11. opentrons/hardware_control/module_control.py +8 -82
  12. opentrons/hardware_control/modules/__init__.py +0 -3
  13. opentrons/hardware_control/modules/absorbance_reader.py +4 -11
  14. opentrons/hardware_control/modules/flex_stacker.py +9 -38
  15. opentrons/hardware_control/modules/heater_shaker.py +5 -30
  16. opentrons/hardware_control/modules/magdeck.py +4 -8
  17. opentrons/hardware_control/modules/mod_abc.py +5 -13
  18. opentrons/hardware_control/modules/tempdeck.py +5 -25
  19. opentrons/hardware_control/modules/thermocycler.py +10 -56
  20. opentrons/hardware_control/modules/types.py +1 -20
  21. opentrons/hardware_control/modules/utils.py +4 -11
  22. opentrons/hardware_control/nozzle_manager.py +0 -3
  23. opentrons/hardware_control/ot3api.py +5 -26
  24. opentrons/hardware_control/scripts/update_module_fw.py +0 -5
  25. opentrons/hardware_control/types.py +2 -31
  26. opentrons/legacy_commands/protocol_commands.py +0 -20
  27. opentrons/legacy_commands/types.py +0 -42
  28. opentrons/motion_planning/waypoints.py +29 -15
  29. opentrons/protocol_api/__init__.py +0 -5
  30. opentrons/protocol_api/_types.py +1 -6
  31. opentrons/protocol_api/core/common.py +1 -3
  32. opentrons/protocol_api/core/engine/_default_labware_versions.py +11 -32
  33. opentrons/protocol_api/core/engine/labware.py +1 -8
  34. opentrons/protocol_api/core/engine/module_core.py +0 -4
  35. opentrons/protocol_api/core/engine/protocol.py +43 -23
  36. opentrons/protocol_api/core/legacy/legacy_module_core.py +0 -2
  37. opentrons/protocol_api/core/legacy/legacy_protocol_core.py +1 -11
  38. opentrons/protocol_api/core/legacy_simulator/legacy_protocol_core.py +2 -14
  39. opentrons/protocol_api/core/module.py +0 -1
  40. opentrons/protocol_api/core/protocol.py +2 -11
  41. opentrons/protocol_api/module_contexts.py +0 -1
  42. opentrons/protocol_api/protocol_context.py +4 -26
  43. opentrons/protocol_api/robot_context.py +21 -38
  44. opentrons/protocol_api/validation.py +1 -6
  45. opentrons/protocol_engine/actions/__init__.py +2 -4
  46. opentrons/protocol_engine/actions/actions.py +9 -22
  47. opentrons/protocol_engine/clients/sync_client.py +7 -6
  48. opentrons/protocol_engine/commands/__init__.py +0 -42
  49. opentrons/protocol_engine/commands/absorbance_reader/close_lid.py +15 -2
  50. opentrons/protocol_engine/commands/absorbance_reader/open_lid.py +15 -2
  51. opentrons/protocol_engine/commands/aspirate.py +0 -1
  52. opentrons/protocol_engine/commands/command.py +0 -1
  53. opentrons/protocol_engine/commands/command_unions.py +0 -39
  54. opentrons/protocol_engine/commands/dispense.py +0 -1
  55. opentrons/protocol_engine/commands/drop_tip.py +8 -32
  56. opentrons/protocol_engine/commands/movement_common.py +0 -2
  57. opentrons/protocol_engine/commands/pick_up_tip.py +11 -21
  58. opentrons/protocol_engine/commands/thermocycler/run_extended_profile.py +0 -6
  59. opentrons/protocol_engine/commands/thermocycler/run_profile.py +0 -8
  60. opentrons/protocol_engine/commands/thermocycler/set_target_block_temperature.py +1 -17
  61. opentrons/protocol_engine/commands/touch_tip.py +1 -1
  62. opentrons/protocol_engine/commands/unsafe/unsafe_place_labware.py +22 -6
  63. opentrons/protocol_engine/errors/__init__.py +0 -4
  64. opentrons/protocol_engine/errors/exceptions.py +0 -55
  65. opentrons/protocol_engine/execution/__init__.py +0 -2
  66. opentrons/protocol_engine/execution/command_executor.py +0 -8
  67. opentrons/protocol_engine/execution/create_queue_worker.py +1 -5
  68. opentrons/protocol_engine/execution/labware_movement.py +12 -9
  69. opentrons/protocol_engine/execution/movement.py +0 -2
  70. opentrons/protocol_engine/execution/queue_worker.py +0 -4
  71. opentrons/protocol_engine/execution/run_control.py +0 -8
  72. opentrons/protocol_engine/protocol_engine.py +33 -67
  73. opentrons/protocol_engine/resources/__init__.py +0 -2
  74. opentrons/protocol_engine/resources/deck_configuration_provider.py +0 -7
  75. opentrons/protocol_engine/resources/labware_validation.py +6 -10
  76. opentrons/protocol_engine/state/_labware_origin_math.py +636 -0
  77. opentrons/protocol_engine/state/_well_math.py +18 -60
  78. opentrons/protocol_engine/state/addressable_areas.py +0 -2
  79. opentrons/protocol_engine/state/commands.py +7 -7
  80. opentrons/protocol_engine/state/geometry.py +374 -204
  81. opentrons/protocol_engine/state/labware.py +102 -52
  82. opentrons/protocol_engine/state/module_substates/thermocycler_module_substate.py +0 -37
  83. opentrons/protocol_engine/state/modules.py +8 -21
  84. opentrons/protocol_engine/state/motion.py +0 -44
  85. opentrons/protocol_engine/state/state.py +0 -14
  86. opentrons/protocol_engine/state/state_summary.py +0 -2
  87. opentrons/protocol_engine/state/tips.py +258 -177
  88. opentrons/protocol_engine/state/update_types.py +9 -16
  89. opentrons/protocol_engine/types/__init__.py +3 -9
  90. opentrons/protocol_engine/types/deck_configuration.py +1 -5
  91. opentrons/protocol_engine/types/instrument.py +1 -8
  92. opentrons/protocol_engine/types/labware.py +13 -1
  93. opentrons/protocol_engine/types/module.py +0 -10
  94. opentrons/protocol_engine/types/tip.py +0 -9
  95. opentrons/protocol_runner/create_simulating_orchestrator.py +2 -29
  96. opentrons/protocol_runner/run_orchestrator.py +2 -18
  97. opentrons/protocols/api_support/definitions.py +1 -1
  98. opentrons/protocols/api_support/types.py +1 -2
  99. opentrons/simulate.py +15 -48
  100. opentrons/system/camera.py +1 -1
  101. {opentrons-8.7.0a2.dist-info → opentrons-8.7.0a3.dist-info}/METADATA +4 -4
  102. {opentrons-8.7.0a2.dist-info → opentrons-8.7.0a3.dist-info}/RECORD +105 -118
  103. opentrons/protocol_api/core/engine/tasks.py +0 -35
  104. opentrons/protocol_api/core/legacy/tasks.py +0 -19
  105. opentrons/protocol_api/core/legacy_simulator/tasks.py +0 -19
  106. opentrons/protocol_api/core/tasks.py +0 -31
  107. opentrons/protocol_api/tasks.py +0 -48
  108. opentrons/protocol_engine/commands/create_timer.py +0 -83
  109. opentrons/protocol_engine/commands/set_tip_state.py +0 -97
  110. opentrons/protocol_engine/commands/wait_for_tasks.py +0 -98
  111. opentrons/protocol_engine/execution/task_handler.py +0 -157
  112. opentrons/protocol_engine/resources/concurrency_provider.py +0 -27
  113. opentrons/protocol_engine/state/labware_origin_math/errors.py +0 -94
  114. opentrons/protocol_engine/state/labware_origin_math/stackup_origin_to_labware_origin.py +0 -1331
  115. opentrons/protocol_engine/state/tasks.py +0 -139
  116. opentrons/protocol_engine/types/tasks.py +0 -38
  117. {opentrons-8.7.0a2.dist-info → opentrons-8.7.0a3.dist-info}/WHEEL +0 -0
  118. {opentrons-8.7.0a2.dist-info → opentrons-8.7.0a3.dist-info}/entry_points.txt +0 -0
  119. {opentrons-8.7.0a2.dist-info → opentrons-8.7.0a3.dist-info}/licenses/LICENSE +0 -0
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import asyncio
4
4
  import logging
5
- from typing import Optional, Mapping, Callable
5
+ from typing import Optional, Mapping
6
6
  from typing_extensions import Final
7
7
 
8
8
  from opentrons.drivers.rpi_drivers.types import USBPort
@@ -15,7 +15,6 @@ from opentrons.hardware_control.poller import Reader, Poller
15
15
  from opentrons.hardware_control.modules import mod_abc, update
16
16
  from opentrons.hardware_control.modules.types import (
17
17
  ModuleDisconnectedCallback,
18
- ModuleErrorCallback,
19
18
  ModuleType,
20
19
  TemperatureStatus,
21
20
  SpeedStatus,
@@ -48,13 +47,12 @@ class HeaterShaker(mod_abc.AbstractModule):
48
47
  port: str,
49
48
  usb_port: USBPort,
50
49
  hw_control_loop: asyncio.AbstractEventLoop,
51
- execution_manager: ExecutionManager,
52
- disconnected_callback: ModuleDisconnectedCallback,
53
- error_callback: ModuleErrorCallback,
50
+ execution_manager: Optional[ExecutionManager] = None,
54
51
  poll_interval_seconds: Optional[float] = None,
55
52
  simulating: bool = False,
56
53
  sim_model: Optional[str] = None,
57
54
  sim_serial_number: Optional[str] = None,
55
+ disconnected_callback: ModuleDisconnectedCallback = None,
58
56
  ) -> "HeaterShaker":
59
57
  """
60
58
  Build a HeaterShaker
@@ -69,7 +67,6 @@ class HeaterShaker(mod_abc.AbstractModule):
69
67
  loop: Loop
70
68
  sim_model: The model name used by simulator
71
69
  disconnected_callback: Callback to inform the module controller that the device was disconnected
72
- error_callback: Callback to inform the module controller of an asynchronous error
73
70
 
74
71
  Returns:
75
72
  HeaterShaker instance
@@ -94,7 +91,6 @@ class HeaterShaker(mod_abc.AbstractModule):
94
91
  hw_control_loop=hw_control_loop,
95
92
  execution_manager=execution_manager,
96
93
  disconnected_callback=disconnected_callback,
97
- error_callback=error_callback,
98
94
  )
99
95
 
100
96
  try:
@@ -113,9 +109,8 @@ class HeaterShaker(mod_abc.AbstractModule):
113
109
  poller: Poller,
114
110
  device_info: Mapping[str, str],
115
111
  hw_control_loop: asyncio.AbstractEventLoop,
116
- execution_manager: ExecutionManager,
117
- disconnected_callback: ModuleDisconnectedCallback,
118
- error_callback: ModuleErrorCallback,
112
+ execution_manager: Optional[ExecutionManager] = None,
113
+ disconnected_callback: ModuleDisconnectedCallback = None,
119
114
  ):
120
115
  super().__init__(
121
116
  port=port,
@@ -123,22 +118,14 @@ class HeaterShaker(mod_abc.AbstractModule):
123
118
  hw_control_loop=hw_control_loop,
124
119
  execution_manager=execution_manager,
125
120
  disconnected_callback=disconnected_callback,
126
- error_callback=error_callback,
127
121
  )
128
122
  self._device_info = device_info
129
123
  self._driver = driver
130
124
  self._reader = reader
131
125
  self._poller = poller
132
- self._unsubscribe_reader = self._reader.register_error_handler(
133
- self._handle_error
134
- )
135
-
136
- def _handle_error(self, error: Exception) -> None:
137
- self.error_callback(error)
138
126
 
139
127
  async def cleanup(self) -> None:
140
128
  """Stop the poller task"""
141
- self._unsubscribe_reader()
142
129
  await self._poller.stop()
143
130
  await self._driver.disconnect()
144
131
 
@@ -410,16 +397,6 @@ class HeaterShakerReader(Reader):
410
397
  self.labware_latch = HeaterShakerLabwareLatchStatus.IDLE_UNKNOWN
411
398
  self.error: Optional[str] = None
412
399
  self._driver = driver
413
- self._handle_error: Callable[[Exception], None] | None = None
414
-
415
- def register_error_handler(
416
- self, handle_error: Callable[[Exception], None]
417
- ) -> Callable[[], None]:
418
- self._handle_error = handle_error
419
- return self._unsubscribe_error_handler
420
-
421
- def _unsubscribe_error_handler(self) -> None:
422
- self._handle_error = None
423
400
 
424
401
  async def read(self) -> None:
425
402
  await self.read_temperature()
@@ -443,8 +420,6 @@ class HeaterShakerReader(Reader):
443
420
  if exception is None:
444
421
  self.error = None
445
422
  else:
446
- if self._handle_error:
447
- self._handle_error(exception)
448
423
  try:
449
424
  self.error = str(exception.args[0])
450
425
  except Exception:
@@ -49,13 +49,12 @@ class MagDeck(mod_abc.AbstractModule):
49
49
  port: str,
50
50
  usb_port: USBPort,
51
51
  hw_control_loop: asyncio.AbstractEventLoop,
52
- execution_manager: ExecutionManager,
53
- disconnected_callback: types.ModuleDisconnectedCallback,
54
- error_callback: types.ModuleErrorCallback,
52
+ execution_manager: Optional[ExecutionManager] = None,
55
53
  poll_interval_seconds: Optional[float] = None,
56
54
  simulating: bool = False,
57
55
  sim_model: Optional[str] = None,
58
56
  sim_serial_number: Optional[str] = None,
57
+ disconnected_callback: types.ModuleDisconnectedCallback = None,
59
58
  ) -> "MagDeck":
60
59
  """Factory function."""
61
60
  driver: AbstractMagDeckDriver
@@ -74,7 +73,6 @@ class MagDeck(mod_abc.AbstractModule):
74
73
  device_info=await driver.get_device_info(),
75
74
  driver=driver,
76
75
  disconnected_callback=disconnected_callback,
77
- error_callback=error_callback,
78
76
  )
79
77
  return mod
80
78
 
@@ -85,9 +83,8 @@ class MagDeck(mod_abc.AbstractModule):
85
83
  hw_control_loop: asyncio.AbstractEventLoop,
86
84
  driver: AbstractMagDeckDriver,
87
85
  device_info: Dict[str, str],
88
- execution_manager: ExecutionManager,
89
- disconnected_callback: types.ModuleDisconnectedCallback,
90
- error_callback: types.ModuleErrorCallback,
86
+ execution_manager: Optional[ExecutionManager] = None,
87
+ disconnected_callback: types.ModuleDisconnectedCallback = None,
91
88
  ) -> None:
92
89
  """Constructor"""
93
90
  super().__init__(
@@ -96,7 +93,6 @@ class MagDeck(mod_abc.AbstractModule):
96
93
  hw_control_loop=hw_control_loop,
97
94
  execution_manager=execution_manager,
98
95
  disconnected_callback=disconnected_callback,
99
- error_callback=error_callback,
100
96
  )
101
97
  self._device_info = device_info
102
98
  self._driver = driver
@@ -11,7 +11,6 @@ from ..execution_manager import ExecutionManager
11
11
  from .types import (
12
12
  BundledFirmware,
13
13
  ModuleDisconnectedCallback,
14
- ModuleErrorCallback,
15
14
  UploadFunction,
16
15
  LiveData,
17
16
  ModuleType,
@@ -48,13 +47,12 @@ class AbstractModule(abc.ABC):
48
47
  port: str,
49
48
  usb_port: USBPort,
50
49
  hw_control_loop: asyncio.AbstractEventLoop,
51
- execution_manager: ExecutionManager,
52
- disconnected_callback: ModuleDisconnectedCallback,
53
- error_callback: ModuleErrorCallback,
54
- poll_interval_seconds: float | None = None,
50
+ execution_manager: Optional[ExecutionManager] = None,
51
+ poll_interval_seconds: Optional[float] = None,
55
52
  simulating: bool = False,
56
53
  sim_model: Optional[str] = None,
57
54
  sim_serial_number: Optional[str] = None,
55
+ disconnected_callback: ModuleDisconnectedCallback = None,
58
56
  ) -> "AbstractModule":
59
57
  """Modules should always be created using this factory.
60
58
 
@@ -67,9 +65,8 @@ class AbstractModule(abc.ABC):
67
65
  port: str,
68
66
  usb_port: USBPort,
69
67
  hw_control_loop: asyncio.AbstractEventLoop,
70
- execution_manager: ExecutionManager,
71
- disconnected_callback: ModuleDisconnectedCallback,
72
- error_callback: ModuleErrorCallback,
68
+ execution_manager: Optional[ExecutionManager] = None,
69
+ disconnected_callback: ModuleDisconnectedCallback = None,
73
70
  ) -> None:
74
71
  self._port = port
75
72
  self._usb_port = usb_port
@@ -78,7 +75,6 @@ class AbstractModule(abc.ABC):
78
75
  self._bundled_fw: Optional[BundledFirmware] = self.get_bundled_fw()
79
76
  self._disconnected_callback = disconnected_callback
80
77
  self._updating = False
81
- self._error_callback = error_callback
82
78
 
83
79
  @staticmethod
84
80
  def sort_key(inst: "AbstractModule") -> int:
@@ -107,10 +103,6 @@ class AbstractModule(abc.ABC):
107
103
  if self._disconnected_callback is not None:
108
104
  self._disconnected_callback(self.port, self.serial_number)
109
105
 
110
- def error_callback(self, exc: Exception) -> None:
111
- """Called from within the module object when an asynchronous hardware error occurrs."""
112
- self._error_callback(exc, self.model(), self.port, self.serial_number)
113
-
114
106
  def get_bundled_fw(self) -> Optional[BundledFirmware]:
115
107
  """Get absolute path to bundled version of module fw if available."""
116
108
  if not IS_ROBOT:
@@ -2,11 +2,10 @@ from __future__ import annotations
2
2
 
3
3
  import asyncio
4
4
  import logging
5
- from typing import Dict, Optional, Callable
5
+ from typing import Dict, Optional
6
6
 
7
7
  from opentrons.hardware_control.modules.types import (
8
8
  ModuleDisconnectedCallback,
9
- ModuleErrorCallback,
10
9
  TemperatureStatus,
11
10
  )
12
11
  from opentrons.hardware_control.poller import Reader, Poller
@@ -39,13 +38,12 @@ class TempDeck(mod_abc.AbstractModule):
39
38
  port: str,
40
39
  usb_port: USBPort,
41
40
  hw_control_loop: asyncio.AbstractEventLoop,
42
- execution_manager: ExecutionManager,
43
- disconnected_callback: ModuleDisconnectedCallback,
44
- error_callback: ModuleErrorCallback,
41
+ execution_manager: Optional[ExecutionManager] = None,
45
42
  poll_interval_seconds: Optional[float] = None,
46
43
  simulating: bool = False,
47
44
  sim_model: Optional[str] = None,
48
45
  sim_serial_number: Optional[str] = None,
46
+ disconnected_callback: ModuleDisconnectedCallback = None,
49
47
  ) -> "TempDeck":
50
48
  """
51
49
  Build a TempDeck
@@ -85,7 +83,6 @@ class TempDeck(mod_abc.AbstractModule):
85
83
  device_info=await driver.get_device_info(),
86
84
  hw_control_loop=hw_control_loop,
87
85
  disconnected_callback=disconnected_callback,
88
- error_callback=error_callback,
89
86
  )
90
87
 
91
88
  try:
@@ -104,9 +101,8 @@ class TempDeck(mod_abc.AbstractModule):
104
101
  poller: Poller,
105
102
  device_info: Dict[str, str],
106
103
  hw_control_loop: asyncio.AbstractEventLoop,
107
- execution_manager: ExecutionManager,
108
- disconnected_callback: ModuleDisconnectedCallback,
109
- error_callback: ModuleErrorCallback,
104
+ execution_manager: Optional[ExecutionManager] = None,
105
+ disconnected_callback: ModuleDisconnectedCallback = None,
110
106
  ) -> None:
111
107
  """Constructor"""
112
108
  super().__init__(
@@ -115,13 +111,11 @@ class TempDeck(mod_abc.AbstractModule):
115
111
  hw_control_loop=hw_control_loop,
116
112
  execution_manager=execution_manager,
117
113
  disconnected_callback=disconnected_callback,
118
- error_callback=error_callback,
119
114
  )
120
115
  self._device_info = device_info
121
116
  self._driver = driver
122
117
  self._reader = reader
123
118
  self._poller = poller
124
- self._reader.set_error_callback(self.error_callback)
125
119
 
126
120
  async def cleanup(self) -> None:
127
121
  """Stop the poller task."""
@@ -299,21 +293,7 @@ class TempDeckReader(Reader):
299
293
  def __init__(self, driver: AbstractTempDeckDriver) -> None:
300
294
  self.temperature = Temperature(current=25, target=None)
301
295
  self._driver = driver
302
- self._error_callback: Optional[Callable[[Exception], None]] = None
303
296
 
304
297
  async def read(self) -> None:
305
298
  """Read the module's current and target temperatures."""
306
299
  self.temperature = await self._driver.get_temperature()
307
-
308
- def set_error_callback(
309
- self, error_callback: Callable[[Exception], None]
310
- ) -> Callable[[], None]:
311
- self._error_callback = error_callback
312
- return self._remove_error_callback
313
-
314
- def _remove_error_callback(self) -> None:
315
- self._error_callback = None
316
-
317
- def on_error(self, exception: Exception) -> None:
318
- if self._error_callback:
319
- self._error_callback(exception)
@@ -9,7 +9,6 @@ from opentrons.hardware_control.modules.lid_temp_status import LidTemperatureSta
9
9
  from opentrons.hardware_control.modules.plate_temp_status import PlateTemperatureStatus
10
10
  from opentrons.hardware_control.modules.types import (
11
11
  ModuleDisconnectedCallback,
12
- ModuleErrorCallback,
13
12
  TemperatureStatus,
14
13
  )
15
14
  from opentrons.hardware_control.poller import Reader, Poller
@@ -37,8 +36,6 @@ DFU_PID = "df11"
37
36
  _TC_PLATE_LIFT_OPEN_DEGREES = 20
38
37
  _TC_PLATE_LIFT_RETURN_DEGREES = 23
39
38
 
40
- _TC_RAMP_RATE_ADDED_VERSION = (1, 0, 8) # v1.0.8
41
-
42
39
 
43
40
  class ThermocyclerError(Exception):
44
41
  pass
@@ -65,13 +62,12 @@ class Thermocycler(mod_abc.AbstractModule):
65
62
  port: str,
66
63
  usb_port: USBPort,
67
64
  hw_control_loop: asyncio.AbstractEventLoop,
68
- execution_manager: ExecutionManager,
69
- disconnected_callback: ModuleDisconnectedCallback,
70
- error_callback: ModuleErrorCallback,
65
+ execution_manager: Optional[ExecutionManager] = None,
71
66
  poll_interval_seconds: Optional[float] = None,
72
67
  simulating: bool = False,
73
68
  sim_model: Optional[str] = None,
74
69
  sim_serial_number: Optional[str] = None,
70
+ disconnected_callback: ModuleDisconnectedCallback = None,
75
71
  ) -> "Thermocycler":
76
72
  """
77
73
  Build and connect to a Thermocycler
@@ -112,7 +108,6 @@ class Thermocycler(mod_abc.AbstractModule):
112
108
  hw_control_loop=hw_control_loop,
113
109
  execution_manager=execution_manager,
114
110
  disconnected_callback=disconnected_callback,
115
- error_callback=error_callback,
116
111
  )
117
112
 
118
113
  try:
@@ -131,9 +126,8 @@ class Thermocycler(mod_abc.AbstractModule):
131
126
  poller: Poller,
132
127
  device_info: Dict[str, str],
133
128
  hw_control_loop: asyncio.AbstractEventLoop,
134
- execution_manager: ExecutionManager,
135
- disconnected_callback: ModuleDisconnectedCallback,
136
- error_callback: ModuleErrorCallback,
129
+ execution_manager: Optional[ExecutionManager] = None,
130
+ disconnected_callback: ModuleDisconnectedCallback = None,
137
131
  ) -> None:
138
132
  """
139
133
  Constructor
@@ -156,7 +150,6 @@ class Thermocycler(mod_abc.AbstractModule):
156
150
  hw_control_loop=hw_control_loop,
157
151
  execution_manager=execution_manager,
158
152
  disconnected_callback=disconnected_callback,
159
- error_callback=error_callback,
160
153
  )
161
154
  self._device_info = device_info
162
155
  self._reader = reader
@@ -166,13 +159,10 @@ class Thermocycler(mod_abc.AbstractModule):
166
159
  self._total_step_count: Optional[int] = None
167
160
  self._current_step_index: Optional[int] = None
168
161
  self._error: Optional[str] = None
169
- self._unsubscribe_reader = self._reader.register_error_handler(
170
- self._enter_error_state
171
- )
162
+ self._reader.register_error_handler(self._enter_error_state)
172
163
 
173
164
  async def cleanup(self) -> None:
174
165
  """Stop the poller task."""
175
- self._unsubscribe_reader()
176
166
  await self._poller.stop()
177
167
  await self._driver.disconnect()
178
168
 
@@ -275,19 +265,6 @@ class Thermocycler(mod_abc.AbstractModule):
275
265
  await self.open()
276
266
  await self._wait_for_lid_status(ThermocyclerLidStatus.OPEN)
277
267
 
278
- def can_use_ramp_rate(self) -> bool:
279
- version_string = self._device_info.get("version", "v")
280
- if version_string.startswith("v"):
281
- version_string = version_string[1:]
282
- try:
283
- version_tuple = tuple(int(c) for c in version_string.split("."))
284
- return version_tuple >= _TC_RAMP_RATE_ADDED_VERSION
285
- except (ValueError, IndexError):
286
- log.error(
287
- f"Invalid version from device: {self._device_info.get('version', '')}"
288
- )
289
- return False
290
-
291
268
  async def set_temperature(
292
269
  self,
293
270
  temperature: float,
@@ -313,11 +290,6 @@ class Thermocycler(mod_abc.AbstractModule):
313
290
 
314
291
  Returns: None
315
292
  """
316
- if ramp_rate and not self.can_use_ramp_rate():
317
- raise ThermocyclerError(
318
- "Ramp rate is not supported by this thermocycler's firmware version, please update."
319
- )
320
-
321
293
  await self.wait_for_is_running()
322
294
  await self._set_temperature_no_pause(
323
295
  temperature=temperature,
@@ -340,13 +312,11 @@ class Thermocycler(mod_abc.AbstractModule):
340
312
  total_seconds = seconds + (minutes * 60)
341
313
  hold_time = total_seconds if total_seconds > 0 else 0
342
314
 
343
- if ramp_rate and not self.can_use_ramp_rate():
344
- raise ThermocyclerError(
345
- "Ramp rate is not supported by this thermocycler's firmware version, please update."
346
- )
315
+ if ramp_rate is not None:
316
+ await self._driver.set_ramp_rate(ramp_rate=ramp_rate)
347
317
 
348
318
  await self._driver.set_plate_temperature(
349
- temp=temperature, hold_time=hold_time, volume=volume, ramp_rate=ramp_rate
319
+ temp=temperature, hold_time=hold_time, volume=volume
350
320
  )
351
321
 
352
322
  task = self._loop.create_task(self._wait_for_block_target())
@@ -449,7 +419,6 @@ class Thermocycler(mod_abc.AbstractModule):
449
419
  celsius: float,
450
420
  hold_time_seconds: Optional[float] = None,
451
421
  volume: Optional[float] = None,
452
- ramp_rate: Optional[float] = None,
453
422
  ) -> None:
454
423
  """Set the Thermocycler's target block temperature.
455
424
 
@@ -459,17 +428,10 @@ class Thermocycler(mod_abc.AbstractModule):
459
428
  celsius: The target block temperature, in degrees celsius.
460
429
  """
461
430
  await self.wait_for_is_running()
462
-
463
- if ramp_rate and not self.can_use_ramp_rate():
464
- raise ThermocyclerError(
465
- "Ramp rate is not supported by this thermocycler's firmware version, please update."
466
- )
467
-
468
431
  await self._driver.set_plate_temperature(
469
432
  temp=celsius,
470
433
  hold_time=hold_time_seconds,
471
434
  volume=volume,
472
- ramp_rate=ramp_rate,
473
435
  )
474
436
  await self._reader.read_block_temperature()
475
437
 
@@ -634,12 +596,11 @@ class Thermocycler(mod_abc.AbstractModule):
634
596
  temperature = step.get("temperature")
635
597
  hold_time_minutes = step.get("hold_time_minutes", None)
636
598
  hold_time_seconds = step.get("hold_time_seconds", None)
637
- ramp_rate = step.get("ramp_rate", None)
638
599
  await self._set_temperature_no_pause(
639
600
  temperature=temperature, # type: ignore
640
601
  hold_time_minutes=hold_time_minutes,
641
602
  hold_time_seconds=hold_time_seconds,
642
- ramp_rate=ramp_rate,
603
+ ramp_rate=None,
643
604
  volume=volume,
644
605
  )
645
606
 
@@ -712,7 +673,6 @@ class Thermocycler(mod_abc.AbstractModule):
712
673
  f" for troubleshooting."
713
674
  )
714
675
  asyncio.run_coroutine_threadsafe(self.cleanup(), self._loop)
715
- self.error_callback(error)
716
676
 
717
677
 
718
678
  class ThermocyclerReader(Reader):
@@ -750,14 +710,8 @@ class ThermocyclerReader(Reader):
750
710
  if self._handle_error is not None:
751
711
  self._handle_error(exception)
752
712
 
753
- def register_error_handler(
754
- self, handle_error: Callable[[Exception], None]
755
- ) -> Callable[[], None]:
713
+ def register_error_handler(self, handle_error: Callable[[Exception], None]) -> None:
756
714
  self._handle_error = handle_error
757
- return self._unsubscribe_error_handler
758
-
759
- def _unsubscribe_error_handler(self) -> None:
760
- self._handle_error = None
761
715
 
762
716
  async def read(self) -> None:
763
717
  """Poll the thermocycler."""
@@ -11,7 +11,6 @@ from typing import (
11
11
  Awaitable,
12
12
  Union,
13
13
  Optional,
14
- Protocol,
15
14
  cast,
16
15
  TYPE_CHECKING,
17
16
  TypeGuard,
@@ -45,7 +44,6 @@ class ThermocyclerStepBase(TypedDict):
45
44
  class ThermocyclerStep(ThermocyclerStepBase, total=False):
46
45
  hold_time_seconds: float
47
46
  hold_time_minutes: float
48
- ramp_rate: Optional[float]
49
47
 
50
48
 
51
49
  class ThermocyclerCycle(TypedDict):
@@ -56,24 +54,7 @@ class ThermocyclerCycle(TypedDict):
56
54
  UploadFunction = Callable[[str, str, Dict[str, Any]], Awaitable[Tuple[bool, str]]]
57
55
 
58
56
 
59
- class ModuleDisconnectedCallback(Protocol):
60
- """Protocol for the callback when the module should be disconnected."""
61
-
62
- def __call__(self, port: str, serial: str | None) -> None:
63
- ...
64
-
65
-
66
- class ModuleErrorCallback(Protocol):
67
- """Protocol for the callback when the module sees a hardware error."""
68
-
69
- def __call__(
70
- self,
71
- exc: Exception,
72
- model: str,
73
- port: str,
74
- serial: str | None,
75
- ) -> None:
76
- ...
57
+ ModuleDisconnectedCallback = Optional[Callable[[str, str | None], None]]
77
58
 
78
59
 
79
60
  class MagneticModuleData(TypedDict):
@@ -6,12 +6,7 @@ from opentrons.drivers.rpi_drivers.types import USBPort
6
6
 
7
7
  from ..execution_manager import ExecutionManager
8
8
 
9
- from .types import (
10
- ModuleDisconnectedCallback,
11
- ModuleType,
12
- SpeedStatus,
13
- ModuleErrorCallback,
14
- )
9
+ from .types import ModuleDisconnectedCallback, ModuleType, SpeedStatus
15
10
  from .mod_abc import AbstractModule
16
11
  from .tempdeck import TempDeck
17
12
  from .magdeck import MagDeck
@@ -51,11 +46,10 @@ async def build(
51
46
  simulating: bool,
52
47
  usb_port: USBPort,
53
48
  hw_control_loop: asyncio.AbstractEventLoop,
54
- execution_manager: ExecutionManager,
55
- disconnected_callback: ModuleDisconnectedCallback,
56
- error_callback: ModuleErrorCallback,
49
+ execution_manager: Optional[ExecutionManager] = None,
57
50
  sim_model: Optional[str] = None,
58
51
  sim_serial_number: Optional[str] = None,
52
+ disconnected_callback: ModuleDisconnectedCallback = None,
59
53
  ) -> AbstractModule:
60
54
  return await _MODULE_CLS_BY_TYPE[type].build(
61
55
  port=port,
@@ -63,10 +57,9 @@ async def build(
63
57
  simulating=simulating,
64
58
  hw_control_loop=hw_control_loop,
65
59
  execution_manager=execution_manager,
66
- disconnected_callback=disconnected_callback,
67
- error_callback=error_callback,
68
60
  sim_model=sim_model,
69
61
  sim_serial_number=sim_serial_number,
62
+ disconnected_callback=disconnected_callback,
70
63
  )
71
64
 
72
65
 
@@ -77,8 +77,6 @@ class NozzleMap:
77
77
  #: A map of all of the nozzles of an instrument
78
78
  full_instrument_rows: Dict[str, List[str]]
79
79
  #: A map of all the rows of an instrument
80
- full_instrument_columns: Dict[str, List[str]]
81
- #: A map of all the columns of an instrument
82
80
 
83
81
  @classmethod
84
82
  def determine_nozzle_configuration(
@@ -301,7 +299,6 @@ class NozzleMap:
301
299
  rows=rows,
302
300
  full_instrument_map_store=physical_nozzles,
303
301
  full_instrument_rows=physical_rows,
304
- full_instrument_columns=physical_columns,
305
302
  columns=columns,
306
303
  configuration=cls.determine_nozzle_configuration(
307
304
  physical_rows, rows, physical_columns, columns
@@ -74,7 +74,6 @@ from .types import (
74
74
  DoorStateNotification,
75
75
  ErrorMessageNotification,
76
76
  HardwareEvent,
77
- AsynchronousModuleErrorNotification,
78
77
  HardwareEventHandler,
79
78
  HardwareAction,
80
79
  HepaFanState,
@@ -368,21 +367,6 @@ class OT3API(
368
367
 
369
368
  return futures
370
369
 
371
- def _send_module_notification(self, event: HardwareEvent) -> None:
372
- if not isinstance(
373
- event,
374
- AsynchronousModuleErrorNotification,
375
- ):
376
- return
377
- mod_log.info(
378
- f"Forwarding module event {event.event} for {event.module_model} {event.module_serial} at {event.port}"
379
- )
380
- for cb in self._callbacks:
381
- try:
382
- cb(event)
383
- except Exception:
384
- mod_log.exception("Errored during module asynchronous callback")
385
-
386
370
  def _reset_last_mount(self) -> None:
387
371
  self._last_moved_mount = None
388
372
 
@@ -438,9 +422,7 @@ class OT3API(
438
422
 
439
423
  await api_instance.set_status_bar_enabled(status_bar_enabled)
440
424
  module_controls = await AttachedModulesControl.build(
441
- api_instance,
442
- board_revision=backend.board_revision,
443
- event_callback=api_instance._send_module_notification,
425
+ api_instance, board_revision=backend.board_revision
444
426
  )
445
427
  backend.module_controls = module_controls
446
428
  await backend.build_estop_detector()
@@ -502,9 +484,7 @@ class OT3API(
502
484
  )
503
485
  await api_instance.cache_instruments()
504
486
  module_controls = await AttachedModulesControl.build(
505
- api_instance,
506
- board_revision=backend.board_revision,
507
- event_callback=api_instance._send_module_notification,
487
+ api_instance, board_revision=backend.board_revision
508
488
  )
509
489
  backend.module_controls = module_controls
510
490
  await backend.watch(api_instance.loop)
@@ -647,10 +627,9 @@ class OT3API(
647
627
  self.is_simulator
648
628
  ), "Cannot build simulating module from non-simulating hardware control API"
649
629
 
650
- return await self._backend.module_controls.register_simulated_module(
651
- simulated_usb_port=USBPort(
652
- name="", port_number=1, port_group=PortGroup.LEFT
653
- ),
630
+ return await self._backend.module_controls.build_module(
631
+ port="",
632
+ usb_port=USBPort(name="", port_number=1, port_group=PortGroup.LEFT),
654
633
  type=modules.ModuleType.from_model(model),
655
634
  sim_model=model.value,
656
635
  )
@@ -1,5 +1,4 @@
1
1
  """Module Firmware update script."""
2
-
3
2
  import argparse
4
3
  import asyncio
5
4
  from glob import glob
@@ -15,7 +14,6 @@ from opentrons.hardware_control import modules
15
14
  from opentrons.hardware_control.modules.mod_abc import AbstractModule
16
15
  from opentrons.hardware_control.modules.update import update_firmware
17
16
  from opentrons.hardware_control.types import BoardRevision
18
- from opentrons.hardware_control.execution_manager import ExecutionManager
19
17
 
20
18
 
21
19
  # Constants for checking if module is back online
@@ -86,9 +84,6 @@ async def build_module(
86
84
  port=port,
87
85
  usb_port=mod.usb_port,
88
86
  type=modules.MODULE_TYPE_BY_NAME[mod.name],
89
- execution_manager=ExecutionManager(),
90
- disconnected_callback=lambda *args: None,
91
- error_callback=lambda *args: None,
92
87
  simulating=False,
93
88
  hw_control_loop=loop,
94
89
  )