opentrons 8.6.0__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 (601) hide show
  1. opentrons/__init__.py +150 -0
  2. opentrons/_version.py +34 -0
  3. opentrons/calibration_storage/__init__.py +54 -0
  4. opentrons/calibration_storage/deck_configuration.py +62 -0
  5. opentrons/calibration_storage/encoder_decoder.py +31 -0
  6. opentrons/calibration_storage/file_operators.py +142 -0
  7. opentrons/calibration_storage/helpers.py +103 -0
  8. opentrons/calibration_storage/ot2/__init__.py +34 -0
  9. opentrons/calibration_storage/ot2/deck_attitude.py +85 -0
  10. opentrons/calibration_storage/ot2/mark_bad_calibration.py +27 -0
  11. opentrons/calibration_storage/ot2/models/__init__.py +0 -0
  12. opentrons/calibration_storage/ot2/models/v1.py +149 -0
  13. opentrons/calibration_storage/ot2/pipette_offset.py +129 -0
  14. opentrons/calibration_storage/ot2/tip_length.py +281 -0
  15. opentrons/calibration_storage/ot3/__init__.py +31 -0
  16. opentrons/calibration_storage/ot3/deck_attitude.py +83 -0
  17. opentrons/calibration_storage/ot3/gripper_offset.py +156 -0
  18. opentrons/calibration_storage/ot3/models/__init__.py +0 -0
  19. opentrons/calibration_storage/ot3/models/v1.py +122 -0
  20. opentrons/calibration_storage/ot3/module_offset.py +138 -0
  21. opentrons/calibration_storage/ot3/pipette_offset.py +95 -0
  22. opentrons/calibration_storage/types.py +45 -0
  23. opentrons/cli/__init__.py +21 -0
  24. opentrons/cli/__main__.py +5 -0
  25. opentrons/cli/analyze.py +557 -0
  26. opentrons/config/__init__.py +631 -0
  27. opentrons/config/advanced_settings.py +871 -0
  28. opentrons/config/defaults_ot2.py +214 -0
  29. opentrons/config/defaults_ot3.py +499 -0
  30. opentrons/config/feature_flags.py +86 -0
  31. opentrons/config/gripper_config.py +55 -0
  32. opentrons/config/reset.py +203 -0
  33. opentrons/config/robot_configs.py +187 -0
  34. opentrons/config/types.py +183 -0
  35. opentrons/drivers/__init__.py +0 -0
  36. opentrons/drivers/absorbance_reader/__init__.py +11 -0
  37. opentrons/drivers/absorbance_reader/abstract.py +72 -0
  38. opentrons/drivers/absorbance_reader/async_byonoy.py +352 -0
  39. opentrons/drivers/absorbance_reader/driver.py +81 -0
  40. opentrons/drivers/absorbance_reader/hid_protocol.py +161 -0
  41. opentrons/drivers/absorbance_reader/simulator.py +84 -0
  42. opentrons/drivers/asyncio/__init__.py +0 -0
  43. opentrons/drivers/asyncio/communication/__init__.py +22 -0
  44. opentrons/drivers/asyncio/communication/async_serial.py +187 -0
  45. opentrons/drivers/asyncio/communication/errors.py +88 -0
  46. opentrons/drivers/asyncio/communication/serial_connection.py +557 -0
  47. opentrons/drivers/command_builder.py +102 -0
  48. opentrons/drivers/flex_stacker/__init__.py +13 -0
  49. opentrons/drivers/flex_stacker/abstract.py +214 -0
  50. opentrons/drivers/flex_stacker/driver.py +768 -0
  51. opentrons/drivers/flex_stacker/errors.py +68 -0
  52. opentrons/drivers/flex_stacker/simulator.py +309 -0
  53. opentrons/drivers/flex_stacker/types.py +367 -0
  54. opentrons/drivers/flex_stacker/utils.py +19 -0
  55. opentrons/drivers/heater_shaker/__init__.py +5 -0
  56. opentrons/drivers/heater_shaker/abstract.py +76 -0
  57. opentrons/drivers/heater_shaker/driver.py +204 -0
  58. opentrons/drivers/heater_shaker/simulator.py +94 -0
  59. opentrons/drivers/mag_deck/__init__.py +6 -0
  60. opentrons/drivers/mag_deck/abstract.py +44 -0
  61. opentrons/drivers/mag_deck/driver.py +208 -0
  62. opentrons/drivers/mag_deck/simulator.py +63 -0
  63. opentrons/drivers/rpi_drivers/__init__.py +33 -0
  64. opentrons/drivers/rpi_drivers/dev_types.py +94 -0
  65. opentrons/drivers/rpi_drivers/gpio.py +282 -0
  66. opentrons/drivers/rpi_drivers/gpio_simulator.py +127 -0
  67. opentrons/drivers/rpi_drivers/interfaces.py +15 -0
  68. opentrons/drivers/rpi_drivers/types.py +364 -0
  69. opentrons/drivers/rpi_drivers/usb.py +102 -0
  70. opentrons/drivers/rpi_drivers/usb_simulator.py +22 -0
  71. opentrons/drivers/serial_communication.py +151 -0
  72. opentrons/drivers/smoothie_drivers/__init__.py +4 -0
  73. opentrons/drivers/smoothie_drivers/connection.py +51 -0
  74. opentrons/drivers/smoothie_drivers/constants.py +121 -0
  75. opentrons/drivers/smoothie_drivers/driver_3_0.py +1933 -0
  76. opentrons/drivers/smoothie_drivers/errors.py +49 -0
  77. opentrons/drivers/smoothie_drivers/parse_utils.py +143 -0
  78. opentrons/drivers/smoothie_drivers/simulator.py +99 -0
  79. opentrons/drivers/smoothie_drivers/types.py +16 -0
  80. opentrons/drivers/temp_deck/__init__.py +10 -0
  81. opentrons/drivers/temp_deck/abstract.py +54 -0
  82. opentrons/drivers/temp_deck/driver.py +197 -0
  83. opentrons/drivers/temp_deck/simulator.py +57 -0
  84. opentrons/drivers/thermocycler/__init__.py +12 -0
  85. opentrons/drivers/thermocycler/abstract.py +99 -0
  86. opentrons/drivers/thermocycler/driver.py +395 -0
  87. opentrons/drivers/thermocycler/simulator.py +126 -0
  88. opentrons/drivers/types.py +107 -0
  89. opentrons/drivers/utils.py +222 -0
  90. opentrons/execute.py +742 -0
  91. opentrons/hardware_control/__init__.py +65 -0
  92. opentrons/hardware_control/__main__.py +77 -0
  93. opentrons/hardware_control/adapters.py +98 -0
  94. opentrons/hardware_control/api.py +1347 -0
  95. opentrons/hardware_control/backends/__init__.py +7 -0
  96. opentrons/hardware_control/backends/controller.py +400 -0
  97. opentrons/hardware_control/backends/errors.py +9 -0
  98. opentrons/hardware_control/backends/estop_state.py +164 -0
  99. opentrons/hardware_control/backends/flex_protocol.py +497 -0
  100. opentrons/hardware_control/backends/ot3controller.py +1930 -0
  101. opentrons/hardware_control/backends/ot3simulator.py +900 -0
  102. opentrons/hardware_control/backends/ot3utils.py +664 -0
  103. opentrons/hardware_control/backends/simulator.py +442 -0
  104. opentrons/hardware_control/backends/status_bar_state.py +240 -0
  105. opentrons/hardware_control/backends/subsystem_manager.py +431 -0
  106. opentrons/hardware_control/backends/tip_presence_manager.py +173 -0
  107. opentrons/hardware_control/backends/types.py +14 -0
  108. opentrons/hardware_control/constants.py +6 -0
  109. opentrons/hardware_control/dev_types.py +125 -0
  110. opentrons/hardware_control/emulation/__init__.py +0 -0
  111. opentrons/hardware_control/emulation/abstract_emulator.py +21 -0
  112. opentrons/hardware_control/emulation/app.py +56 -0
  113. opentrons/hardware_control/emulation/connection_handler.py +38 -0
  114. opentrons/hardware_control/emulation/heater_shaker.py +150 -0
  115. opentrons/hardware_control/emulation/magdeck.py +60 -0
  116. opentrons/hardware_control/emulation/module_server/__init__.py +8 -0
  117. opentrons/hardware_control/emulation/module_server/client.py +78 -0
  118. opentrons/hardware_control/emulation/module_server/helpers.py +130 -0
  119. opentrons/hardware_control/emulation/module_server/models.py +31 -0
  120. opentrons/hardware_control/emulation/module_server/server.py +110 -0
  121. opentrons/hardware_control/emulation/parser.py +74 -0
  122. opentrons/hardware_control/emulation/proxy.py +241 -0
  123. opentrons/hardware_control/emulation/run_emulator.py +68 -0
  124. opentrons/hardware_control/emulation/scripts/__init__.py +0 -0
  125. opentrons/hardware_control/emulation/scripts/run_app.py +54 -0
  126. opentrons/hardware_control/emulation/scripts/run_module_emulator.py +72 -0
  127. opentrons/hardware_control/emulation/scripts/run_smoothie.py +37 -0
  128. opentrons/hardware_control/emulation/settings.py +119 -0
  129. opentrons/hardware_control/emulation/simulations.py +133 -0
  130. opentrons/hardware_control/emulation/smoothie.py +192 -0
  131. opentrons/hardware_control/emulation/tempdeck.py +69 -0
  132. opentrons/hardware_control/emulation/thermocycler.py +128 -0
  133. opentrons/hardware_control/emulation/types.py +10 -0
  134. opentrons/hardware_control/emulation/util.py +38 -0
  135. opentrons/hardware_control/errors.py +43 -0
  136. opentrons/hardware_control/execution_manager.py +164 -0
  137. opentrons/hardware_control/instruments/__init__.py +5 -0
  138. opentrons/hardware_control/instruments/instrument_abc.py +39 -0
  139. opentrons/hardware_control/instruments/ot2/__init__.py +0 -0
  140. opentrons/hardware_control/instruments/ot2/instrument_calibration.py +152 -0
  141. opentrons/hardware_control/instruments/ot2/pipette.py +777 -0
  142. opentrons/hardware_control/instruments/ot2/pipette_handler.py +995 -0
  143. opentrons/hardware_control/instruments/ot3/__init__.py +0 -0
  144. opentrons/hardware_control/instruments/ot3/gripper.py +420 -0
  145. opentrons/hardware_control/instruments/ot3/gripper_handler.py +173 -0
  146. opentrons/hardware_control/instruments/ot3/instrument_calibration.py +214 -0
  147. opentrons/hardware_control/instruments/ot3/pipette.py +858 -0
  148. opentrons/hardware_control/instruments/ot3/pipette_handler.py +1030 -0
  149. opentrons/hardware_control/module_control.py +332 -0
  150. opentrons/hardware_control/modules/__init__.py +69 -0
  151. opentrons/hardware_control/modules/absorbance_reader.py +373 -0
  152. opentrons/hardware_control/modules/errors.py +7 -0
  153. opentrons/hardware_control/modules/flex_stacker.py +948 -0
  154. opentrons/hardware_control/modules/heater_shaker.py +426 -0
  155. opentrons/hardware_control/modules/lid_temp_status.py +35 -0
  156. opentrons/hardware_control/modules/magdeck.py +233 -0
  157. opentrons/hardware_control/modules/mod_abc.py +245 -0
  158. opentrons/hardware_control/modules/module_calibration.py +93 -0
  159. opentrons/hardware_control/modules/plate_temp_status.py +61 -0
  160. opentrons/hardware_control/modules/tempdeck.py +299 -0
  161. opentrons/hardware_control/modules/thermocycler.py +731 -0
  162. opentrons/hardware_control/modules/types.py +417 -0
  163. opentrons/hardware_control/modules/update.py +255 -0
  164. opentrons/hardware_control/modules/utils.py +73 -0
  165. opentrons/hardware_control/motion_utilities.py +318 -0
  166. opentrons/hardware_control/nozzle_manager.py +422 -0
  167. opentrons/hardware_control/ot3_calibration.py +1171 -0
  168. opentrons/hardware_control/ot3api.py +3227 -0
  169. opentrons/hardware_control/pause_manager.py +31 -0
  170. opentrons/hardware_control/poller.py +112 -0
  171. opentrons/hardware_control/protocols/__init__.py +106 -0
  172. opentrons/hardware_control/protocols/asyncio_configurable.py +11 -0
  173. opentrons/hardware_control/protocols/calibratable.py +45 -0
  174. opentrons/hardware_control/protocols/chassis_accessory_manager.py +90 -0
  175. opentrons/hardware_control/protocols/configurable.py +48 -0
  176. opentrons/hardware_control/protocols/event_sourcer.py +18 -0
  177. opentrons/hardware_control/protocols/execution_controllable.py +33 -0
  178. opentrons/hardware_control/protocols/flex_calibratable.py +96 -0
  179. opentrons/hardware_control/protocols/flex_instrument_configurer.py +52 -0
  180. opentrons/hardware_control/protocols/gripper_controller.py +55 -0
  181. opentrons/hardware_control/protocols/hardware_manager.py +51 -0
  182. opentrons/hardware_control/protocols/identifiable.py +16 -0
  183. opentrons/hardware_control/protocols/instrument_configurer.py +206 -0
  184. opentrons/hardware_control/protocols/liquid_handler.py +266 -0
  185. opentrons/hardware_control/protocols/module_provider.py +16 -0
  186. opentrons/hardware_control/protocols/motion_controller.py +243 -0
  187. opentrons/hardware_control/protocols/position_estimator.py +45 -0
  188. opentrons/hardware_control/protocols/simulatable.py +10 -0
  189. opentrons/hardware_control/protocols/stoppable.py +9 -0
  190. opentrons/hardware_control/protocols/types.py +27 -0
  191. opentrons/hardware_control/robot_calibration.py +224 -0
  192. opentrons/hardware_control/scripts/README.md +28 -0
  193. opentrons/hardware_control/scripts/__init__.py +1 -0
  194. opentrons/hardware_control/scripts/gripper_control.py +208 -0
  195. opentrons/hardware_control/scripts/ot3gripper +7 -0
  196. opentrons/hardware_control/scripts/ot3repl +7 -0
  197. opentrons/hardware_control/scripts/repl.py +187 -0
  198. opentrons/hardware_control/scripts/tc_control.py +97 -0
  199. opentrons/hardware_control/scripts/update_module_fw.py +274 -0
  200. opentrons/hardware_control/simulator_setup.py +260 -0
  201. opentrons/hardware_control/thread_manager.py +431 -0
  202. opentrons/hardware_control/threaded_async_lock.py +97 -0
  203. opentrons/hardware_control/types.py +792 -0
  204. opentrons/hardware_control/util.py +234 -0
  205. opentrons/legacy_broker.py +53 -0
  206. opentrons/legacy_commands/__init__.py +1 -0
  207. opentrons/legacy_commands/commands.py +483 -0
  208. opentrons/legacy_commands/helpers.py +153 -0
  209. opentrons/legacy_commands/module_commands.py +276 -0
  210. opentrons/legacy_commands/protocol_commands.py +54 -0
  211. opentrons/legacy_commands/publisher.py +155 -0
  212. opentrons/legacy_commands/robot_commands.py +51 -0
  213. opentrons/legacy_commands/types.py +1186 -0
  214. opentrons/motion_planning/__init__.py +32 -0
  215. opentrons/motion_planning/adjacent_slots_getters.py +168 -0
  216. opentrons/motion_planning/deck_conflict.py +501 -0
  217. opentrons/motion_planning/errors.py +35 -0
  218. opentrons/motion_planning/types.py +42 -0
  219. opentrons/motion_planning/waypoints.py +218 -0
  220. opentrons/ordered_set.py +138 -0
  221. opentrons/protocol_api/__init__.py +105 -0
  222. opentrons/protocol_api/_liquid.py +157 -0
  223. opentrons/protocol_api/_liquid_properties.py +814 -0
  224. opentrons/protocol_api/_nozzle_layout.py +31 -0
  225. opentrons/protocol_api/_parameter_context.py +300 -0
  226. opentrons/protocol_api/_parameters.py +31 -0
  227. opentrons/protocol_api/_transfer_liquid_validation.py +108 -0
  228. opentrons/protocol_api/_types.py +43 -0
  229. opentrons/protocol_api/config.py +23 -0
  230. opentrons/protocol_api/core/__init__.py +23 -0
  231. opentrons/protocol_api/core/common.py +33 -0
  232. opentrons/protocol_api/core/core_map.py +74 -0
  233. opentrons/protocol_api/core/engine/__init__.py +22 -0
  234. opentrons/protocol_api/core/engine/_default_labware_versions.py +179 -0
  235. opentrons/protocol_api/core/engine/deck_conflict.py +400 -0
  236. opentrons/protocol_api/core/engine/exceptions.py +19 -0
  237. opentrons/protocol_api/core/engine/instrument.py +2391 -0
  238. opentrons/protocol_api/core/engine/labware.py +238 -0
  239. opentrons/protocol_api/core/engine/load_labware_params.py +73 -0
  240. opentrons/protocol_api/core/engine/module_core.py +1027 -0
  241. opentrons/protocol_api/core/engine/overlap_versions.py +20 -0
  242. opentrons/protocol_api/core/engine/pipette_movement_conflict.py +358 -0
  243. opentrons/protocol_api/core/engine/point_calculations.py +64 -0
  244. opentrons/protocol_api/core/engine/protocol.py +1153 -0
  245. opentrons/protocol_api/core/engine/robot.py +139 -0
  246. opentrons/protocol_api/core/engine/stringify.py +74 -0
  247. opentrons/protocol_api/core/engine/transfer_components_executor.py +1006 -0
  248. opentrons/protocol_api/core/engine/well.py +241 -0
  249. opentrons/protocol_api/core/instrument.py +459 -0
  250. opentrons/protocol_api/core/labware.py +151 -0
  251. opentrons/protocol_api/core/legacy/__init__.py +11 -0
  252. opentrons/protocol_api/core/legacy/_labware_geometry.py +37 -0
  253. opentrons/protocol_api/core/legacy/deck.py +369 -0
  254. opentrons/protocol_api/core/legacy/labware_offset_provider.py +108 -0
  255. opentrons/protocol_api/core/legacy/legacy_instrument_core.py +709 -0
  256. opentrons/protocol_api/core/legacy/legacy_labware_core.py +235 -0
  257. opentrons/protocol_api/core/legacy/legacy_module_core.py +592 -0
  258. opentrons/protocol_api/core/legacy/legacy_protocol_core.py +612 -0
  259. opentrons/protocol_api/core/legacy/legacy_well_core.py +162 -0
  260. opentrons/protocol_api/core/legacy/load_info.py +67 -0
  261. opentrons/protocol_api/core/legacy/module_geometry.py +547 -0
  262. opentrons/protocol_api/core/legacy/well_geometry.py +148 -0
  263. opentrons/protocol_api/core/legacy_simulator/__init__.py +16 -0
  264. opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py +624 -0
  265. opentrons/protocol_api/core/legacy_simulator/legacy_protocol_core.py +85 -0
  266. opentrons/protocol_api/core/module.py +484 -0
  267. opentrons/protocol_api/core/protocol.py +311 -0
  268. opentrons/protocol_api/core/robot.py +51 -0
  269. opentrons/protocol_api/core/well.py +116 -0
  270. opentrons/protocol_api/core/well_grid.py +45 -0
  271. opentrons/protocol_api/create_protocol_context.py +177 -0
  272. opentrons/protocol_api/deck.py +223 -0
  273. opentrons/protocol_api/disposal_locations.py +244 -0
  274. opentrons/protocol_api/instrument_context.py +3272 -0
  275. opentrons/protocol_api/labware.py +1579 -0
  276. opentrons/protocol_api/module_contexts.py +1447 -0
  277. opentrons/protocol_api/module_validation_and_errors.py +61 -0
  278. opentrons/protocol_api/protocol_context.py +1688 -0
  279. opentrons/protocol_api/robot_context.py +303 -0
  280. opentrons/protocol_api/validation.py +761 -0
  281. opentrons/protocol_engine/__init__.py +155 -0
  282. opentrons/protocol_engine/actions/__init__.py +65 -0
  283. opentrons/protocol_engine/actions/action_dispatcher.py +30 -0
  284. opentrons/protocol_engine/actions/action_handler.py +13 -0
  285. opentrons/protocol_engine/actions/actions.py +302 -0
  286. opentrons/protocol_engine/actions/get_state_update.py +38 -0
  287. opentrons/protocol_engine/clients/__init__.py +5 -0
  288. opentrons/protocol_engine/clients/sync_client.py +174 -0
  289. opentrons/protocol_engine/clients/transports.py +197 -0
  290. opentrons/protocol_engine/commands/__init__.py +757 -0
  291. opentrons/protocol_engine/commands/absorbance_reader/__init__.py +61 -0
  292. opentrons/protocol_engine/commands/absorbance_reader/close_lid.py +154 -0
  293. opentrons/protocol_engine/commands/absorbance_reader/common.py +6 -0
  294. opentrons/protocol_engine/commands/absorbance_reader/initialize.py +151 -0
  295. opentrons/protocol_engine/commands/absorbance_reader/open_lid.py +154 -0
  296. opentrons/protocol_engine/commands/absorbance_reader/read.py +226 -0
  297. opentrons/protocol_engine/commands/air_gap_in_place.py +162 -0
  298. opentrons/protocol_engine/commands/aspirate.py +244 -0
  299. opentrons/protocol_engine/commands/aspirate_in_place.py +184 -0
  300. opentrons/protocol_engine/commands/aspirate_while_tracking.py +211 -0
  301. opentrons/protocol_engine/commands/blow_out.py +146 -0
  302. opentrons/protocol_engine/commands/blow_out_in_place.py +119 -0
  303. opentrons/protocol_engine/commands/calibration/__init__.py +60 -0
  304. opentrons/protocol_engine/commands/calibration/calibrate_gripper.py +166 -0
  305. opentrons/protocol_engine/commands/calibration/calibrate_module.py +117 -0
  306. opentrons/protocol_engine/commands/calibration/calibrate_pipette.py +96 -0
  307. opentrons/protocol_engine/commands/calibration/move_to_maintenance_position.py +156 -0
  308. opentrons/protocol_engine/commands/command.py +308 -0
  309. opentrons/protocol_engine/commands/command_unions.py +974 -0
  310. opentrons/protocol_engine/commands/comment.py +57 -0
  311. opentrons/protocol_engine/commands/configure_for_volume.py +108 -0
  312. opentrons/protocol_engine/commands/configure_nozzle_layout.py +115 -0
  313. opentrons/protocol_engine/commands/custom.py +67 -0
  314. opentrons/protocol_engine/commands/dispense.py +194 -0
  315. opentrons/protocol_engine/commands/dispense_in_place.py +179 -0
  316. opentrons/protocol_engine/commands/dispense_while_tracking.py +204 -0
  317. opentrons/protocol_engine/commands/drop_tip.py +232 -0
  318. opentrons/protocol_engine/commands/drop_tip_in_place.py +205 -0
  319. opentrons/protocol_engine/commands/flex_stacker/__init__.py +64 -0
  320. opentrons/protocol_engine/commands/flex_stacker/common.py +900 -0
  321. opentrons/protocol_engine/commands/flex_stacker/empty.py +293 -0
  322. opentrons/protocol_engine/commands/flex_stacker/fill.py +281 -0
  323. opentrons/protocol_engine/commands/flex_stacker/retrieve.py +339 -0
  324. opentrons/protocol_engine/commands/flex_stacker/set_stored_labware.py +328 -0
  325. opentrons/protocol_engine/commands/flex_stacker/store.py +339 -0
  326. opentrons/protocol_engine/commands/generate_command_schema.py +61 -0
  327. opentrons/protocol_engine/commands/get_next_tip.py +134 -0
  328. opentrons/protocol_engine/commands/get_tip_presence.py +87 -0
  329. opentrons/protocol_engine/commands/hash_command_params.py +38 -0
  330. opentrons/protocol_engine/commands/heater_shaker/__init__.py +102 -0
  331. opentrons/protocol_engine/commands/heater_shaker/close_labware_latch.py +83 -0
  332. opentrons/protocol_engine/commands/heater_shaker/deactivate_heater.py +82 -0
  333. opentrons/protocol_engine/commands/heater_shaker/deactivate_shaker.py +84 -0
  334. opentrons/protocol_engine/commands/heater_shaker/open_labware_latch.py +110 -0
  335. opentrons/protocol_engine/commands/heater_shaker/set_and_wait_for_shake_speed.py +125 -0
  336. opentrons/protocol_engine/commands/heater_shaker/set_target_temperature.py +90 -0
  337. opentrons/protocol_engine/commands/heater_shaker/wait_for_temperature.py +102 -0
  338. opentrons/protocol_engine/commands/home.py +100 -0
  339. opentrons/protocol_engine/commands/identify_module.py +86 -0
  340. opentrons/protocol_engine/commands/labware_handling_common.py +29 -0
  341. opentrons/protocol_engine/commands/liquid_probe.py +464 -0
  342. opentrons/protocol_engine/commands/load_labware.py +210 -0
  343. opentrons/protocol_engine/commands/load_lid.py +154 -0
  344. opentrons/protocol_engine/commands/load_lid_stack.py +272 -0
  345. opentrons/protocol_engine/commands/load_liquid.py +95 -0
  346. opentrons/protocol_engine/commands/load_liquid_class.py +144 -0
  347. opentrons/protocol_engine/commands/load_module.py +223 -0
  348. opentrons/protocol_engine/commands/load_pipette.py +167 -0
  349. opentrons/protocol_engine/commands/magnetic_module/__init__.py +32 -0
  350. opentrons/protocol_engine/commands/magnetic_module/disengage.py +97 -0
  351. opentrons/protocol_engine/commands/magnetic_module/engage.py +119 -0
  352. opentrons/protocol_engine/commands/move_labware.py +546 -0
  353. opentrons/protocol_engine/commands/move_relative.py +102 -0
  354. opentrons/protocol_engine/commands/move_to_addressable_area.py +176 -0
  355. opentrons/protocol_engine/commands/move_to_addressable_area_for_drop_tip.py +198 -0
  356. opentrons/protocol_engine/commands/move_to_coordinates.py +107 -0
  357. opentrons/protocol_engine/commands/move_to_well.py +119 -0
  358. opentrons/protocol_engine/commands/movement_common.py +338 -0
  359. opentrons/protocol_engine/commands/pick_up_tip.py +241 -0
  360. opentrons/protocol_engine/commands/pipetting_common.py +443 -0
  361. opentrons/protocol_engine/commands/prepare_to_aspirate.py +121 -0
  362. opentrons/protocol_engine/commands/pressure_dispense.py +155 -0
  363. opentrons/protocol_engine/commands/reload_labware.py +90 -0
  364. opentrons/protocol_engine/commands/retract_axis.py +75 -0
  365. opentrons/protocol_engine/commands/robot/__init__.py +70 -0
  366. opentrons/protocol_engine/commands/robot/close_gripper_jaw.py +96 -0
  367. opentrons/protocol_engine/commands/robot/common.py +18 -0
  368. opentrons/protocol_engine/commands/robot/move_axes_relative.py +101 -0
  369. opentrons/protocol_engine/commands/robot/move_axes_to.py +100 -0
  370. opentrons/protocol_engine/commands/robot/move_to.py +94 -0
  371. opentrons/protocol_engine/commands/robot/open_gripper_jaw.py +86 -0
  372. opentrons/protocol_engine/commands/save_position.py +109 -0
  373. opentrons/protocol_engine/commands/seal_pipette_to_tip.py +353 -0
  374. opentrons/protocol_engine/commands/set_rail_lights.py +67 -0
  375. opentrons/protocol_engine/commands/set_status_bar.py +89 -0
  376. opentrons/protocol_engine/commands/temperature_module/__init__.py +46 -0
  377. opentrons/protocol_engine/commands/temperature_module/deactivate.py +86 -0
  378. opentrons/protocol_engine/commands/temperature_module/set_target_temperature.py +97 -0
  379. opentrons/protocol_engine/commands/temperature_module/wait_for_temperature.py +104 -0
  380. opentrons/protocol_engine/commands/thermocycler/__init__.py +152 -0
  381. opentrons/protocol_engine/commands/thermocycler/close_lid.py +87 -0
  382. opentrons/protocol_engine/commands/thermocycler/deactivate_block.py +80 -0
  383. opentrons/protocol_engine/commands/thermocycler/deactivate_lid.py +80 -0
  384. opentrons/protocol_engine/commands/thermocycler/open_lid.py +87 -0
  385. opentrons/protocol_engine/commands/thermocycler/run_extended_profile.py +171 -0
  386. opentrons/protocol_engine/commands/thermocycler/run_profile.py +124 -0
  387. opentrons/protocol_engine/commands/thermocycler/set_target_block_temperature.py +140 -0
  388. opentrons/protocol_engine/commands/thermocycler/set_target_lid_temperature.py +100 -0
  389. opentrons/protocol_engine/commands/thermocycler/wait_for_block_temperature.py +93 -0
  390. opentrons/protocol_engine/commands/thermocycler/wait_for_lid_temperature.py +89 -0
  391. opentrons/protocol_engine/commands/touch_tip.py +189 -0
  392. opentrons/protocol_engine/commands/unsafe/__init__.py +161 -0
  393. opentrons/protocol_engine/commands/unsafe/unsafe_blow_out_in_place.py +100 -0
  394. opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py +121 -0
  395. opentrons/protocol_engine/commands/unsafe/unsafe_engage_axes.py +82 -0
  396. opentrons/protocol_engine/commands/unsafe/unsafe_place_labware.py +208 -0
  397. opentrons/protocol_engine/commands/unsafe/unsafe_stacker_close_latch.py +94 -0
  398. opentrons/protocol_engine/commands/unsafe/unsafe_stacker_manual_retrieve.py +295 -0
  399. opentrons/protocol_engine/commands/unsafe/unsafe_stacker_open_latch.py +91 -0
  400. opentrons/protocol_engine/commands/unsafe/unsafe_stacker_prepare_shuttle.py +136 -0
  401. opentrons/protocol_engine/commands/unsafe/unsafe_ungrip_labware.py +77 -0
  402. opentrons/protocol_engine/commands/unsafe/update_position_estimators.py +90 -0
  403. opentrons/protocol_engine/commands/unseal_pipette_from_tip.py +153 -0
  404. opentrons/protocol_engine/commands/verify_tip_presence.py +100 -0
  405. opentrons/protocol_engine/commands/wait_for_duration.py +76 -0
  406. opentrons/protocol_engine/commands/wait_for_resume.py +75 -0
  407. opentrons/protocol_engine/create_protocol_engine.py +193 -0
  408. opentrons/protocol_engine/engine_support.py +28 -0
  409. opentrons/protocol_engine/error_recovery_policy.py +81 -0
  410. opentrons/protocol_engine/errors/__init__.py +191 -0
  411. opentrons/protocol_engine/errors/error_occurrence.py +182 -0
  412. opentrons/protocol_engine/errors/exceptions.py +1308 -0
  413. opentrons/protocol_engine/execution/__init__.py +50 -0
  414. opentrons/protocol_engine/execution/command_executor.py +216 -0
  415. opentrons/protocol_engine/execution/create_queue_worker.py +102 -0
  416. opentrons/protocol_engine/execution/door_watcher.py +119 -0
  417. opentrons/protocol_engine/execution/equipment.py +819 -0
  418. opentrons/protocol_engine/execution/error_recovery_hardware_state_synchronizer.py +101 -0
  419. opentrons/protocol_engine/execution/gantry_mover.py +686 -0
  420. opentrons/protocol_engine/execution/hardware_stopper.py +147 -0
  421. opentrons/protocol_engine/execution/heater_shaker_movement_flagger.py +207 -0
  422. opentrons/protocol_engine/execution/labware_movement.py +297 -0
  423. opentrons/protocol_engine/execution/movement.py +350 -0
  424. opentrons/protocol_engine/execution/pipetting.py +607 -0
  425. opentrons/protocol_engine/execution/queue_worker.py +86 -0
  426. opentrons/protocol_engine/execution/rail_lights.py +25 -0
  427. opentrons/protocol_engine/execution/run_control.py +33 -0
  428. opentrons/protocol_engine/execution/status_bar.py +34 -0
  429. opentrons/protocol_engine/execution/thermocycler_movement_flagger.py +188 -0
  430. opentrons/protocol_engine/execution/thermocycler_plate_lifter.py +81 -0
  431. opentrons/protocol_engine/execution/tip_handler.py +550 -0
  432. opentrons/protocol_engine/labware_offset_standardization.py +194 -0
  433. opentrons/protocol_engine/notes/__init__.py +17 -0
  434. opentrons/protocol_engine/notes/notes.py +59 -0
  435. opentrons/protocol_engine/plugins.py +104 -0
  436. opentrons/protocol_engine/protocol_engine.py +683 -0
  437. opentrons/protocol_engine/resources/__init__.py +26 -0
  438. opentrons/protocol_engine/resources/deck_configuration_provider.py +232 -0
  439. opentrons/protocol_engine/resources/deck_data_provider.py +94 -0
  440. opentrons/protocol_engine/resources/file_provider.py +161 -0
  441. opentrons/protocol_engine/resources/fixture_validation.py +68 -0
  442. opentrons/protocol_engine/resources/labware_data_provider.py +106 -0
  443. opentrons/protocol_engine/resources/labware_validation.py +73 -0
  444. opentrons/protocol_engine/resources/model_utils.py +32 -0
  445. opentrons/protocol_engine/resources/module_data_provider.py +44 -0
  446. opentrons/protocol_engine/resources/ot3_validation.py +21 -0
  447. opentrons/protocol_engine/resources/pipette_data_provider.py +379 -0
  448. opentrons/protocol_engine/slot_standardization.py +128 -0
  449. opentrons/protocol_engine/state/__init__.py +1 -0
  450. opentrons/protocol_engine/state/_abstract_store.py +27 -0
  451. opentrons/protocol_engine/state/_axis_aligned_bounding_box.py +50 -0
  452. opentrons/protocol_engine/state/_labware_origin_math.py +636 -0
  453. opentrons/protocol_engine/state/_move_types.py +83 -0
  454. opentrons/protocol_engine/state/_well_math.py +193 -0
  455. opentrons/protocol_engine/state/addressable_areas.py +699 -0
  456. opentrons/protocol_engine/state/command_history.py +309 -0
  457. opentrons/protocol_engine/state/commands.py +1164 -0
  458. opentrons/protocol_engine/state/config.py +39 -0
  459. opentrons/protocol_engine/state/files.py +57 -0
  460. opentrons/protocol_engine/state/fluid_stack.py +138 -0
  461. opentrons/protocol_engine/state/geometry.py +2408 -0
  462. opentrons/protocol_engine/state/inner_well_math_utils.py +548 -0
  463. opentrons/protocol_engine/state/labware.py +1432 -0
  464. opentrons/protocol_engine/state/liquid_classes.py +82 -0
  465. opentrons/protocol_engine/state/liquids.py +73 -0
  466. opentrons/protocol_engine/state/module_substates/__init__.py +45 -0
  467. opentrons/protocol_engine/state/module_substates/absorbance_reader_substate.py +35 -0
  468. opentrons/protocol_engine/state/module_substates/flex_stacker_substate.py +112 -0
  469. opentrons/protocol_engine/state/module_substates/heater_shaker_module_substate.py +115 -0
  470. opentrons/protocol_engine/state/module_substates/magnetic_block_substate.py +17 -0
  471. opentrons/protocol_engine/state/module_substates/magnetic_module_substate.py +65 -0
  472. opentrons/protocol_engine/state/module_substates/temperature_module_substate.py +67 -0
  473. opentrons/protocol_engine/state/module_substates/thermocycler_module_substate.py +163 -0
  474. opentrons/protocol_engine/state/modules.py +1515 -0
  475. opentrons/protocol_engine/state/motion.py +373 -0
  476. opentrons/protocol_engine/state/pipettes.py +905 -0
  477. opentrons/protocol_engine/state/state.py +421 -0
  478. opentrons/protocol_engine/state/state_summary.py +36 -0
  479. opentrons/protocol_engine/state/tips.py +420 -0
  480. opentrons/protocol_engine/state/update_types.py +904 -0
  481. opentrons/protocol_engine/state/wells.py +290 -0
  482. opentrons/protocol_engine/types/__init__.py +310 -0
  483. opentrons/protocol_engine/types/automatic_tip_selection.py +39 -0
  484. opentrons/protocol_engine/types/command_annotations.py +53 -0
  485. opentrons/protocol_engine/types/deck_configuration.py +81 -0
  486. opentrons/protocol_engine/types/execution.py +96 -0
  487. opentrons/protocol_engine/types/hardware_passthrough.py +25 -0
  488. opentrons/protocol_engine/types/instrument.py +47 -0
  489. opentrons/protocol_engine/types/instrument_sensors.py +47 -0
  490. opentrons/protocol_engine/types/labware.py +131 -0
  491. opentrons/protocol_engine/types/labware_movement.py +22 -0
  492. opentrons/protocol_engine/types/labware_offset_location.py +111 -0
  493. opentrons/protocol_engine/types/labware_offset_vector.py +16 -0
  494. opentrons/protocol_engine/types/liquid.py +40 -0
  495. opentrons/protocol_engine/types/liquid_class.py +59 -0
  496. opentrons/protocol_engine/types/liquid_handling.py +13 -0
  497. opentrons/protocol_engine/types/liquid_level_detection.py +191 -0
  498. opentrons/protocol_engine/types/location.py +194 -0
  499. opentrons/protocol_engine/types/module.py +310 -0
  500. opentrons/protocol_engine/types/partial_tip_configuration.py +76 -0
  501. opentrons/protocol_engine/types/run_time_parameters.py +133 -0
  502. opentrons/protocol_engine/types/tip.py +18 -0
  503. opentrons/protocol_engine/types/util.py +21 -0
  504. opentrons/protocol_engine/types/well_position.py +124 -0
  505. opentrons/protocol_reader/__init__.py +37 -0
  506. opentrons/protocol_reader/extract_labware_definitions.py +66 -0
  507. opentrons/protocol_reader/file_format_validator.py +152 -0
  508. opentrons/protocol_reader/file_hasher.py +27 -0
  509. opentrons/protocol_reader/file_identifier.py +284 -0
  510. opentrons/protocol_reader/file_reader_writer.py +90 -0
  511. opentrons/protocol_reader/input_file.py +16 -0
  512. opentrons/protocol_reader/protocol_files_invalid_error.py +6 -0
  513. opentrons/protocol_reader/protocol_reader.py +188 -0
  514. opentrons/protocol_reader/protocol_source.py +124 -0
  515. opentrons/protocol_reader/role_analyzer.py +86 -0
  516. opentrons/protocol_runner/__init__.py +26 -0
  517. opentrons/protocol_runner/create_simulating_orchestrator.py +118 -0
  518. opentrons/protocol_runner/json_file_reader.py +55 -0
  519. opentrons/protocol_runner/json_translator.py +314 -0
  520. opentrons/protocol_runner/legacy_command_mapper.py +852 -0
  521. opentrons/protocol_runner/legacy_context_plugin.py +116 -0
  522. opentrons/protocol_runner/protocol_runner.py +530 -0
  523. opentrons/protocol_runner/python_protocol_wrappers.py +179 -0
  524. opentrons/protocol_runner/run_orchestrator.py +496 -0
  525. opentrons/protocol_runner/task_queue.py +95 -0
  526. opentrons/protocols/__init__.py +6 -0
  527. opentrons/protocols/advanced_control/__init__.py +0 -0
  528. opentrons/protocols/advanced_control/common.py +38 -0
  529. opentrons/protocols/advanced_control/mix.py +60 -0
  530. opentrons/protocols/advanced_control/transfers/__init__.py +0 -0
  531. opentrons/protocols/advanced_control/transfers/common.py +180 -0
  532. opentrons/protocols/advanced_control/transfers/transfer.py +972 -0
  533. opentrons/protocols/advanced_control/transfers/transfer_liquid_utils.py +231 -0
  534. opentrons/protocols/api_support/__init__.py +0 -0
  535. opentrons/protocols/api_support/constants.py +8 -0
  536. opentrons/protocols/api_support/deck_type.py +110 -0
  537. opentrons/protocols/api_support/definitions.py +18 -0
  538. opentrons/protocols/api_support/instrument.py +151 -0
  539. opentrons/protocols/api_support/labware_like.py +233 -0
  540. opentrons/protocols/api_support/tip_tracker.py +175 -0
  541. opentrons/protocols/api_support/types.py +32 -0
  542. opentrons/protocols/api_support/util.py +403 -0
  543. opentrons/protocols/bundle.py +89 -0
  544. opentrons/protocols/duration/__init__.py +4 -0
  545. opentrons/protocols/duration/errors.py +5 -0
  546. opentrons/protocols/duration/estimator.py +628 -0
  547. opentrons/protocols/execution/__init__.py +0 -0
  548. opentrons/protocols/execution/dev_types.py +181 -0
  549. opentrons/protocols/execution/errors.py +40 -0
  550. opentrons/protocols/execution/execute.py +84 -0
  551. opentrons/protocols/execution/execute_json_v3.py +275 -0
  552. opentrons/protocols/execution/execute_json_v4.py +359 -0
  553. opentrons/protocols/execution/execute_json_v5.py +28 -0
  554. opentrons/protocols/execution/execute_python.py +169 -0
  555. opentrons/protocols/execution/json_dispatchers.py +87 -0
  556. opentrons/protocols/execution/types.py +7 -0
  557. opentrons/protocols/geometry/__init__.py +0 -0
  558. opentrons/protocols/geometry/planning.py +297 -0
  559. opentrons/protocols/labware.py +312 -0
  560. opentrons/protocols/models/__init__.py +0 -0
  561. opentrons/protocols/models/json_protocol.py +679 -0
  562. opentrons/protocols/parameters/__init__.py +0 -0
  563. opentrons/protocols/parameters/csv_parameter_definition.py +77 -0
  564. opentrons/protocols/parameters/csv_parameter_interface.py +96 -0
  565. opentrons/protocols/parameters/exceptions.py +34 -0
  566. opentrons/protocols/parameters/parameter_definition.py +272 -0
  567. opentrons/protocols/parameters/types.py +17 -0
  568. opentrons/protocols/parameters/validation.py +267 -0
  569. opentrons/protocols/parse.py +671 -0
  570. opentrons/protocols/types.py +159 -0
  571. opentrons/py.typed +0 -0
  572. opentrons/resources/scripts/lpc21isp +0 -0
  573. opentrons/resources/smoothie-edge-8414642.hex +23010 -0
  574. opentrons/simulate.py +1065 -0
  575. opentrons/system/__init__.py +6 -0
  576. opentrons/system/camera.py +51 -0
  577. opentrons/system/log_control.py +59 -0
  578. opentrons/system/nmcli.py +856 -0
  579. opentrons/system/resin.py +24 -0
  580. opentrons/system/smoothie_update.py +15 -0
  581. opentrons/system/wifi.py +204 -0
  582. opentrons/tools/__init__.py +0 -0
  583. opentrons/tools/args_handler.py +22 -0
  584. opentrons/tools/write_pipette_memory.py +157 -0
  585. opentrons/types.py +618 -0
  586. opentrons/util/__init__.py +1 -0
  587. opentrons/util/async_helpers.py +166 -0
  588. opentrons/util/broker.py +84 -0
  589. opentrons/util/change_notifier.py +47 -0
  590. opentrons/util/entrypoint_util.py +278 -0
  591. opentrons/util/get_union_elements.py +26 -0
  592. opentrons/util/helpers.py +6 -0
  593. opentrons/util/linal.py +178 -0
  594. opentrons/util/logging_config.py +265 -0
  595. opentrons/util/logging_queue_handler.py +61 -0
  596. opentrons/util/performance_helpers.py +157 -0
  597. opentrons-8.6.0.dist-info/METADATA +37 -0
  598. opentrons-8.6.0.dist-info/RECORD +601 -0
  599. opentrons-8.6.0.dist-info/WHEEL +4 -0
  600. opentrons-8.6.0.dist-info/entry_points.txt +3 -0
  601. opentrons-8.6.0.dist-info/licenses/LICENSE +202 -0
@@ -0,0 +1,119 @@
1
+ from typing import List
2
+ from opentrons.hardware_control.emulation.types import ModuleType
3
+ from opentrons.hardware_control.emulation.util import TEMPERATURE_ROOM
4
+ from pydantic import BaseModel
5
+ from pydantic_settings import BaseSettings, SettingsConfigDict
6
+
7
+
8
+ class PipetteSettings(BaseModel):
9
+ model: str = "p20_single_v2.0"
10
+ id: str = "P20SV202020070101"
11
+
12
+
13
+ class SmoothieSettings(BaseModel):
14
+ left: PipetteSettings = PipetteSettings(
15
+ model="p20_multi_v2.0", id="P3HMV202020041605"
16
+ )
17
+ right: PipetteSettings = PipetteSettings(
18
+ model="p20_single_v2.0", id="P20SV202020070101"
19
+ )
20
+ host: str = "0.0.0.0"
21
+ port: int = 9996
22
+
23
+
24
+ class BaseModuleSettings(BaseModel):
25
+ serial_number: str
26
+ model: str
27
+ version: str
28
+
29
+
30
+ class TemperatureModelSettings(BaseModel):
31
+ degrees_per_tick: float = 2.0
32
+ starting: float = float(TEMPERATURE_ROOM)
33
+
34
+
35
+ class RPMModelSettings(BaseModel):
36
+ rpm_per_tick: float = 100.0
37
+ starting: float = 0.0
38
+
39
+
40
+ class MagDeckSettings(BaseModuleSettings):
41
+ pass
42
+
43
+
44
+ class TempDeckSettings(BaseModuleSettings):
45
+ temperature: TemperatureModelSettings
46
+
47
+
48
+ class ThermocyclerSettings(BaseModuleSettings):
49
+ lid_temperature: TemperatureModelSettings
50
+ plate_temperature: TemperatureModelSettings
51
+
52
+
53
+ class HeaterShakerSettings(BaseModuleSettings):
54
+ temperature: TemperatureModelSettings
55
+ rpm: RPMModelSettings
56
+ home_delay_time: int = 0
57
+
58
+
59
+ class ProxySettings(BaseModel):
60
+ """Settings for a proxy."""
61
+
62
+ host: str = "0.0.0.0"
63
+ emulator_port: int
64
+ driver_port: int
65
+ use_local_host: bool = True
66
+
67
+
68
+ class ModuleServerSettings(BaseModel):
69
+ """Settings for the module server"""
70
+
71
+ host: str = "0.0.0.0"
72
+ port: int = 8989
73
+
74
+
75
+ class Settings(BaseSettings):
76
+ modules: List[ModuleType] = [
77
+ ModuleType.Magnetic,
78
+ ModuleType.Temperature,
79
+ ModuleType.Thermocycler,
80
+ ]
81
+ smoothie: SmoothieSettings = SmoothieSettings()
82
+ magdeck: MagDeckSettings = MagDeckSettings(
83
+ serial_number="magnetic_emulator", model="mag_deck_v20", version="2.0.0"
84
+ )
85
+ tempdeck: TempDeckSettings = TempDeckSettings(
86
+ serial_number="temperature_emulator",
87
+ model="temp_deck_v20",
88
+ version="v2.0.1",
89
+ temperature=TemperatureModelSettings(starting=0.0),
90
+ )
91
+ thermocycler: ThermocyclerSettings = ThermocyclerSettings(
92
+ serial_number="thermocycler_emulator",
93
+ model="v02",
94
+ version="v1.1.0",
95
+ lid_temperature=TemperatureModelSettings(),
96
+ plate_temperature=TemperatureModelSettings(),
97
+ )
98
+ heatershaker: HeaterShakerSettings = HeaterShakerSettings(
99
+ serial_number="heater_shaker_emulator",
100
+ model="v01",
101
+ version="v0.0.1",
102
+ temperature=TemperatureModelSettings(),
103
+ rpm=RPMModelSettings(),
104
+ home_delay_time=0,
105
+ )
106
+
107
+ heatershaker_proxy: ProxySettings = ProxySettings(
108
+ emulator_port=9000, driver_port=9995
109
+ )
110
+ thermocycler_proxy: ProxySettings = ProxySettings(
111
+ emulator_port=9002, driver_port=9997
112
+ )
113
+ temperature_proxy: ProxySettings = ProxySettings(
114
+ emulator_port=9003, driver_port=9998
115
+ )
116
+ magdeck_proxy: ProxySettings = ProxySettings(emulator_port=9004, driver_port=9999)
117
+ model_config = SettingsConfigDict(env_prefix="OT_EMULATOR_")
118
+
119
+ module_server: ModuleServerSettings = ModuleServerSettings()
@@ -0,0 +1,133 @@
1
+ from typing import Optional
2
+
3
+
4
+ class Simulation:
5
+ def tick(self) -> None:
6
+ pass
7
+
8
+
9
+ class Temperature(Simulation):
10
+ """A model with a current and target temperature. The current temperature is
11
+ always moving towards the target.
12
+ """
13
+
14
+ def __init__(self, per_tick: float, current: float) -> None:
15
+ """Construct a temperature simulation.
16
+
17
+ Args:
18
+ per_tick: amount to move per tick,
19
+ current: the starting temperature
20
+ """
21
+ self._per_tick = per_tick
22
+ self._current = current
23
+ self._target: Optional[float] = None
24
+
25
+ def tick(self) -> None:
26
+ if self._target is None:
27
+ return
28
+
29
+ diff = self._target - self._current
30
+
31
+ if abs(diff) < self._per_tick:
32
+ self._current = self._target
33
+ elif diff > 0:
34
+ self._current += self._per_tick
35
+ else:
36
+ self._current -= self._per_tick
37
+
38
+ def deactivate(self, temperature: float) -> None:
39
+ """Deactivate and reset to temperature"""
40
+ self._target = None
41
+ self._current = temperature
42
+
43
+ def set_target(self, target: Optional[float]) -> None:
44
+ self._target = target
45
+
46
+ @property
47
+ def current(self) -> float:
48
+ return self._current
49
+
50
+ @property
51
+ def target(self) -> Optional[float]:
52
+ return self._target
53
+
54
+
55
+ class RPM(Simulation):
56
+ """A model with a current and target rpm. The current rpm is
57
+ always moving towards the target.
58
+ """
59
+
60
+ def __init__(self, per_tick: float, current: float) -> None:
61
+ """Construct a rpm simulation.
62
+
63
+ Args:
64
+ per_tick: amount to move per tick,
65
+ current: the starting rpm
66
+ """
67
+ self._per_tick = per_tick
68
+ self._current = current
69
+ self._target: Optional[float] = None
70
+
71
+ def tick(self) -> None:
72
+
73
+ if self._target is None:
74
+ target = 0.0
75
+ else:
76
+ target = self._target
77
+
78
+ diff = target - self._current
79
+
80
+ if abs(diff) < self._per_tick:
81
+ self._current = target
82
+ elif diff > 0:
83
+ self._current += self._per_tick
84
+ else:
85
+ self._current -= self._per_tick
86
+
87
+ def deactivate(self, rpm: float) -> None:
88
+ """Deactivate and reset to rpm"""
89
+ self._target = None
90
+ self._current = rpm
91
+
92
+ def set_target(self, target: Optional[float]) -> None:
93
+ self._target = target
94
+
95
+ @property
96
+ def current(self) -> float:
97
+ return self._current
98
+
99
+ @property
100
+ def target(self) -> Optional[float]:
101
+ return self._target
102
+
103
+
104
+ class TemperatureWithHold(Temperature):
105
+ """A model with a current temperature, target temperature, and hold time.
106
+ The current temperature is always moving towards the target.
107
+
108
+ When the current temperature is within close enough from target the hold time
109
+ decrements once per tick.
110
+ """
111
+
112
+ def __init__(self, per_tick: float, current: float) -> None:
113
+ """Construct a temperature with hold simulation."""
114
+ super().__init__(per_tick=per_tick, current=current)
115
+ self._total_hold: Optional[float] = None
116
+ self._hold: Optional[float] = None
117
+
118
+ def tick(self) -> None:
119
+ super().tick()
120
+ if self.target == self._current and self._hold is not None:
121
+ self._hold = max(0, self._hold - 1)
122
+
123
+ def set_hold(self, hold: float) -> None:
124
+ self._total_hold = hold
125
+ self._hold = hold
126
+
127
+ @property
128
+ def time_remaining(self) -> Optional[float]:
129
+ return self._hold
130
+
131
+ @property
132
+ def total_hold(self) -> Optional[float]:
133
+ return self._total_hold
@@ -0,0 +1,192 @@
1
+ """An emulation of the Smoothie.
2
+
3
+ The purpose is to provide a fake backend that responds to the GCODE sent by the
4
+ Opentrons smoothie driver.
5
+ """
6
+ import logging
7
+ import re
8
+ from typing import Optional, Dict
9
+
10
+ from opentrons import _find_smoothie_file
11
+ from opentrons.drivers import utils
12
+ from opentrons.drivers.smoothie_drivers.constants import GCODE, HOMED_POSITION
13
+ from opentrons.hardware_control.emulation.parser import Command, Parser
14
+
15
+ from .abstract_emulator import AbstractEmulator
16
+ from .settings import SmoothieSettings
17
+
18
+ logger = logging.getLogger(__name__)
19
+
20
+
21
+ class SmoothieEmulator(AbstractEmulator):
22
+ """Smoothie emulator"""
23
+
24
+ WRITE_INSTRUMENT_RE = re.compile(r"(?P<mount>[LR])\s*(?P<value>[a-f0-9]+)")
25
+ INSTRUMENT_AND_MODEL_STRING_LENGTH = 64
26
+
27
+ _version_string: str
28
+ _pos: Dict[str, float]
29
+ _home_status: Dict[str, bool]
30
+ _speed: float
31
+ _pipette_model: Dict[str, str]
32
+ _pipette_id: Dict[str, str]
33
+
34
+ def __init__(self, parser: Parser, settings: SmoothieSettings) -> None:
35
+ """Constructor.
36
+
37
+ Args:
38
+ parser: GCODE Parser.
39
+ settings: emulator settings.
40
+ """
41
+ self._parser = parser
42
+ self._settings = settings
43
+ self._gcode_to_function_mapping = {
44
+ GCODE.HOMING_STATUS.value: self._get_homing_status,
45
+ GCODE.CURRENT_POSITION.value: self._get_current_position,
46
+ GCODE.VERSION.value: self._get_version,
47
+ GCODE.READ_INSTRUMENT_ID.value: self._get_pipette_id,
48
+ GCODE.READ_INSTRUMENT_MODEL.value: self._get_pipette_model,
49
+ GCODE.WRITE_INSTRUMENT_ID.value: self._set_pipette_id,
50
+ GCODE.WRITE_INSTRUMENT_MODEL.value: self._set_pipette_model,
51
+ GCODE.MOVE.value: self._move_gantry,
52
+ GCODE.HOME.value: self._home_gantry,
53
+ }
54
+ self.reset()
55
+
56
+ def handle(self, line: str) -> Optional[str]:
57
+ """Handle a line"""
58
+ results = (self._handle(c) for c in self._parser.parse(line))
59
+ joined = " ".join(r for r in results if r)
60
+ return None if not joined else joined
61
+
62
+ def reset(self) -> None:
63
+ _, fw_version = _find_smoothie_file()
64
+ self._version_string = (
65
+ f"Build version: {fw_version}, Build date: CURRENT, "
66
+ f"MCU: NONE, System Clock: NONE"
67
+ )
68
+
69
+ self._pos = {"A": 0.0, "B": 0.0, "C": 0.0, "X": 0.0, "Y": 0.0, "Z": 0.0}
70
+ self._home_status: Dict[str, bool] = {
71
+ "X": False,
72
+ "Y": False,
73
+ "Z": False,
74
+ "A": False,
75
+ "B": False,
76
+ "C": False,
77
+ }
78
+ self._speed = 0.0
79
+
80
+ self._pipette_model = {
81
+ "L": utils.string_to_hex(
82
+ self._settings.left.model, self.INSTRUMENT_AND_MODEL_STRING_LENGTH
83
+ ),
84
+ "R": utils.string_to_hex(
85
+ self._settings.right.model, self.INSTRUMENT_AND_MODEL_STRING_LENGTH
86
+ ),
87
+ }
88
+
89
+ self._pipette_id = {
90
+ "L": utils.string_to_hex(
91
+ self._settings.left.id, self.INSTRUMENT_AND_MODEL_STRING_LENGTH
92
+ ),
93
+ "R": utils.string_to_hex(
94
+ self._settings.right.id, self.INSTRUMENT_AND_MODEL_STRING_LENGTH
95
+ ),
96
+ }
97
+
98
+ def get_current_position(self) -> Dict[str, float]:
99
+ return self._pos
100
+
101
+ def _get_homing_status(self, command: Command) -> str:
102
+ """Get the current homing status of the emulated gantry"""
103
+ return " ".join(f"{k}:{int(v)}" for k, v in self._home_status.items())
104
+
105
+ def _get_current_position(self, command: Command) -> str:
106
+ """Get the current position of the emulated gantry"""
107
+ pos_string = " ".join(f"{k}:{v}" for k, v in self._pos.items())
108
+ return f"{command.gcode}\r\n\r\nok MCS: {pos_string}"
109
+
110
+ def _get_version(self, command: Command) -> str:
111
+ """Get the current firmware version"""
112
+ return self._version_string
113
+
114
+ def _get_pipette_id(self, command: Command) -> Optional[str]:
115
+ """Get the current id of the specified pipette"""
116
+ pipette_postion = None
117
+
118
+ if "L" in command.params:
119
+ pipette_postion = f"L:{self._pipette_id['L']}"
120
+ elif "R" in command.params:
121
+ pipette_postion = f"R:{self._pipette_id['R']}"
122
+
123
+ return pipette_postion
124
+
125
+ def _get_pipette_model(self, command: Command) -> Optional[str]:
126
+ """Get the current model of the specified pipette"""
127
+ pipette_model = None
128
+
129
+ if "L" in command.params:
130
+ pipette_model = f"L:{self._pipette_model['L']}"
131
+ elif "R" in command.params:
132
+ pipette_model = f"R:{self._pipette_model['R']}"
133
+
134
+ return pipette_model
135
+
136
+ def _set_pipette_id(self, command: Command) -> None:
137
+ """Sets the id for the pipette"""
138
+ self._pipette_id.update(self._mount_strings(command))
139
+
140
+ def _set_pipette_model(self, command: Command) -> None:
141
+ """Sets the model for the pipette"""
142
+ self._pipette_model.update(self._mount_strings(command))
143
+
144
+ def _move_gantry(self, command: Command) -> None:
145
+ """Moves the gantry to the position provided in the command"""
146
+ for key, value in command.params.items():
147
+ assert isinstance(value, float), f"invalid value '{value}'"
148
+ if "F" == key:
149
+ self._speed = value
150
+ else:
151
+ self._pos[key] = value
152
+
153
+ def _home_gantry(self, command: Command) -> None:
154
+ """Returns gantry to home position"""
155
+ for axis in command.params.keys():
156
+ self._pos[axis] = HOMED_POSITION[axis]
157
+ self._home_status[axis] = True
158
+
159
+ def _handle(self, command: Command) -> Optional[str]:
160
+ """Handle a command."""
161
+ logger.info(f"Got command {command}")
162
+ func_to_run = self._gcode_to_function_mapping.get(command.gcode)
163
+ return None if func_to_run is None else func_to_run(command)
164
+
165
+ @staticmethod
166
+ def _mount_strings(command: Command) -> Dict[str, str]:
167
+ """
168
+ Parse the body of the command for the mount strings.
169
+
170
+ Write instrument id and model use the format:
171
+ MOUNT VALUE
172
+ where MOUNT is either L or R and VALUE is a string of ascii codes.
173
+
174
+ Args:
175
+ command: Command
176
+
177
+ Returns:
178
+ A dict of L and/or R to the string value following it.
179
+ """
180
+ pars = (
181
+ i.groupdict()
182
+ for i in SmoothieEmulator.WRITE_INSTRUMENT_RE.finditer(command.body)
183
+ )
184
+ result = {
185
+ p["mount"]: p["value"]
186
+ + "0"
187
+ * (SmoothieEmulator.INSTRUMENT_AND_MODEL_STRING_LENGTH - len(p["value"]))
188
+ for p in pars
189
+ }
190
+
191
+ assert result, f"missing mount values '{command.body}'"
192
+ return result
@@ -0,0 +1,69 @@
1
+ """An emulation of the opentrons temperature module.
2
+
3
+ The purpose is to provide a fake backend that responds to GCODE commands.
4
+ """
5
+
6
+ import logging
7
+ from typing import Optional
8
+
9
+ from opentrons.drivers.temp_deck.driver import GCODE
10
+ from opentrons.hardware_control.emulation import util
11
+ from opentrons.hardware_control.emulation.parser import Parser, Command
12
+ from opentrons.hardware_control.emulation.settings import TempDeckSettings
13
+
14
+ from .abstract_emulator import AbstractEmulator
15
+ from .simulations import Temperature
16
+
17
+
18
+ logger = logging.getLogger(__name__)
19
+
20
+
21
+ class TempDeckEmulator(AbstractEmulator):
22
+ """TempDeck emulator"""
23
+
24
+ _temperature: Temperature
25
+
26
+ def __init__(self, parser: Parser, settings: TempDeckSettings) -> None:
27
+ self._settings = settings
28
+ self._parser = parser
29
+ self.reset()
30
+
31
+ def handle(self, line: str) -> Optional[str]:
32
+ """Handle a line"""
33
+ results = (self._handle(c) for c in self._parser.parse(line))
34
+ joined = " ".join(r for r in results if r)
35
+ return None if not joined else joined
36
+
37
+ def reset(self) -> None:
38
+ self._temperature = Temperature(
39
+ per_tick=self._settings.temperature.degrees_per_tick,
40
+ current=self._settings.temperature.starting,
41
+ )
42
+
43
+ def _handle(self, command: Command) -> Optional[str]:
44
+ """Handle a command."""
45
+ logger.info(f"Got command {command}")
46
+ if command.gcode == GCODE.GET_TEMP:
47
+ res = (
48
+ f"T:{util.OptionalValue(self._temperature.target)} "
49
+ f"C:{self._temperature.current}"
50
+ )
51
+ self._temperature.tick()
52
+ return res
53
+ elif command.gcode == GCODE.SET_TEMP:
54
+ temperature = command.params["S"]
55
+ assert isinstance(
56
+ temperature, float
57
+ ), f"invalid temperature '{temperature}'"
58
+ self._temperature.set_target(temperature)
59
+ elif command.gcode == GCODE.DISENGAGE:
60
+ self._temperature.deactivate(util.TEMPERATURE_ROOM)
61
+ elif command.gcode == GCODE.DEVICE_INFO:
62
+ return (
63
+ f"serial:{self._settings.serial_number} "
64
+ f"model:{self._settings.model} "
65
+ f"version:{self._settings.version}"
66
+ )
67
+ elif command.gcode == GCODE.PROGRAMMING_MODE:
68
+ pass
69
+ return None
@@ -0,0 +1,128 @@
1
+ """An emulation of the opentrons thermocycler module.
2
+
3
+ The purpose is to provide a fake backend that responds to GCODE commands.
4
+ """
5
+
6
+ import logging
7
+ from typing import Optional
8
+ from opentrons.drivers.thermocycler.driver import GCODE
9
+ from opentrons.drivers.types import ThermocyclerLidStatus
10
+ from opentrons.hardware_control.emulation.parser import Parser, Command
11
+ from opentrons.hardware_control.emulation.settings import ThermocyclerSettings
12
+
13
+ from .abstract_emulator import AbstractEmulator
14
+ from .simulations import Temperature, TemperatureWithHold
15
+ from . import util
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+
20
+ class ThermocyclerEmulator(AbstractEmulator):
21
+ """Thermocycler emulator"""
22
+
23
+ _lid_temperature: Temperature
24
+ _plate_temperature: TemperatureWithHold
25
+ lid_status: ThermocyclerLidStatus
26
+ plate_volume: util.OptionalValue[float]
27
+ plate_ramp_rate: util.OptionalValue[float]
28
+
29
+ def __init__(self, parser: Parser, settings: ThermocyclerSettings) -> None:
30
+ self._parser = parser
31
+ self._settings = settings
32
+ self.reset()
33
+
34
+ def handle(self, line: str) -> Optional[str]:
35
+ """Handle a line"""
36
+ results = (self._handle(c) for c in self._parser.parse(line))
37
+ joined = " ".join(r for r in results if r)
38
+ return None if not joined else joined
39
+
40
+ def reset(self) -> None:
41
+ self._lid_temperature = Temperature(
42
+ per_tick=self._settings.lid_temperature.degrees_per_tick,
43
+ current=self._settings.lid_temperature.starting,
44
+ )
45
+ self._plate_temperature = TemperatureWithHold(
46
+ per_tick=self._settings.plate_temperature.degrees_per_tick,
47
+ current=self._settings.plate_temperature.starting,
48
+ )
49
+ self.lid_status = ThermocyclerLidStatus.OPEN
50
+ self.plate_volume = util.OptionalValue[float]()
51
+ self.plate_ramp_rate = util.OptionalValue[float]()
52
+
53
+ def _handle(self, command: Command) -> Optional[str]: # noqa: C901
54
+ """
55
+ Handle a command.
56
+
57
+ TODO: AL 20210218 create dispatch map and remove 'noqa(C901)'
58
+ """
59
+ logger.info(f"Got command {command}")
60
+ if command.gcode == GCODE.OPEN_LID:
61
+ self.lid_status = ThermocyclerLidStatus.OPEN
62
+ elif command.gcode == GCODE.CLOSE_LID:
63
+ self.lid_status = ThermocyclerLidStatus.CLOSED
64
+ elif command.gcode == GCODE.GET_LID_STATUS:
65
+ return f"Lid:{self.lid_status}"
66
+ elif command.gcode == GCODE.SET_LID_TEMP:
67
+ temperature = command.params["S"]
68
+ assert isinstance(
69
+ temperature, float
70
+ ), f"invalid temperature '{temperature}'"
71
+ self._lid_temperature.set_target(temperature)
72
+ elif command.gcode == GCODE.GET_LID_TEMP:
73
+ res = (
74
+ f"T:{util.OptionalValue(self._lid_temperature.target)} "
75
+ f"C:{self._lid_temperature.current} "
76
+ f"H:none Total_H:none"
77
+ )
78
+ self._lid_temperature.tick()
79
+ return res
80
+ elif command.gcode == GCODE.EDIT_PID_PARAMS:
81
+ pass
82
+ elif command.gcode == GCODE.SET_PLATE_TEMP:
83
+ for prefix, value in command.params.items():
84
+ assert isinstance(value, float), f"invalid value '{value}'"
85
+ if prefix == "S":
86
+ self._plate_temperature.set_target(value)
87
+ elif prefix == "V":
88
+ self.plate_volume.val = value
89
+ elif prefix == "H":
90
+ self._plate_temperature.set_hold(value)
91
+ elif command.gcode == GCODE.GET_PLATE_TEMP:
92
+ plate_target = util.OptionalValue(self._plate_temperature.target)
93
+ plate_current = self._plate_temperature.current
94
+ plate_time_remaining = util.OptionalValue(
95
+ self._plate_temperature.time_remaining
96
+ )
97
+ plate_total_hold_time = util.OptionalValue(
98
+ self._plate_temperature.total_hold
99
+ )
100
+
101
+ res = (
102
+ f"T:{plate_target} "
103
+ f"C:{plate_current} "
104
+ f"H:{plate_time_remaining} "
105
+ f"Total_H:{plate_total_hold_time} "
106
+ )
107
+ self._plate_temperature.tick()
108
+ return res
109
+ elif command.gcode == GCODE.SET_RAMP_RATE:
110
+ self.plate_ramp_rate.val = command.params["S"]
111
+ elif command.gcode == GCODE.DEACTIVATE_ALL:
112
+ self._plate_temperature.deactivate(temperature=util.TEMPERATURE_ROOM)
113
+ self._lid_temperature.deactivate(temperature=util.TEMPERATURE_ROOM)
114
+ elif command.gcode == GCODE.DEACTIVATE_LID:
115
+ self._lid_temperature.deactivate(temperature=util.TEMPERATURE_ROOM)
116
+ elif command.gcode == GCODE.DEACTIVATE_BLOCK:
117
+ self._plate_temperature.deactivate(temperature=util.TEMPERATURE_ROOM)
118
+ elif command.gcode == GCODE.DEVICE_INFO:
119
+ return (
120
+ f"serial:{self._settings.serial_number} "
121
+ f"model:{self._settings.model} "
122
+ f"version:{self._settings.version}"
123
+ )
124
+ return None
125
+
126
+ @staticmethod
127
+ def get_terminator() -> bytes:
128
+ return b"\r\n"
@@ -0,0 +1,10 @@
1
+ from enum import Enum
2
+
3
+
4
+ class ModuleType(str, Enum):
5
+ """Module type enumeration."""
6
+
7
+ Magnetic = "magdeck"
8
+ Temperature = "tempdeck"
9
+ Thermocycler = "thermocycler"
10
+ Heatershaker = "heatershaker"
@@ -0,0 +1,38 @@
1
+ from typing import Optional, Generic, TypeVar
2
+
3
+ TEMPERATURE_ROOM = 23
4
+
5
+
6
+ ValueType = TypeVar("ValueType")
7
+
8
+
9
+ class OptionalValue(Generic[ValueType]):
10
+ """
11
+ A class that serializes optional values.
12
+
13
+ Modules represent a null value as 'none'. For example this response from
14
+ the thermocycler means the hold time is not set:
15
+ H:none T:1.23
16
+ """
17
+
18
+ _value: Optional[ValueType]
19
+
20
+ def __init__(self, value: Optional[ValueType] = None):
21
+ self._value = value
22
+
23
+ @property
24
+ def val(self) -> Optional[ValueType]:
25
+ return self._value
26
+
27
+ @val.setter
28
+ def val(self, value: Optional[ValueType]) -> None:
29
+ self._value = value
30
+
31
+ def __repr__(self) -> str:
32
+ return "none" if self._value is None else str(self._value)
33
+
34
+ def __eq__(self, other: object) -> bool:
35
+ if not isinstance(other, OptionalValue):
36
+ return False
37
+
38
+ return other.val == self.val