cgse 2024.7.0__py3-none-any.whl → 2025.0.2__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.
Files changed (664) hide show
  1. README.md +27 -0
  2. bump.py +85 -0
  3. cgse-2025.0.2.dist-info/METADATA +38 -0
  4. cgse-2025.0.2.dist-info/RECORD +5 -0
  5. {cgse-2024.7.0.dist-info → cgse-2025.0.2.dist-info}/WHEEL +1 -2
  6. cgse-2024.7.0.dist-info/COPYING +0 -674
  7. cgse-2024.7.0.dist-info/COPYING.LESSER +0 -165
  8. cgse-2024.7.0.dist-info/METADATA +0 -144
  9. cgse-2024.7.0.dist-info/RECORD +0 -660
  10. cgse-2024.7.0.dist-info/entry_points.txt +0 -75
  11. cgse-2024.7.0.dist-info/top_level.txt +0 -2
  12. egse/__init__.py +0 -12
  13. egse/__main__.py +0 -32
  14. egse/aeu/aeu.py +0 -5238
  15. egse/aeu/aeu_awg.yaml +0 -265
  16. egse/aeu/aeu_crio.yaml +0 -273
  17. egse/aeu/aeu_cs.py +0 -627
  18. egse/aeu/aeu_devif.py +0 -321
  19. egse/aeu/aeu_main_ui.py +0 -903
  20. egse/aeu/aeu_metrics.py +0 -131
  21. egse/aeu/aeu_protocol.py +0 -463
  22. egse/aeu/aeu_psu.yaml +0 -204
  23. egse/aeu/aeu_ui.py +0 -873
  24. egse/aeu/arbdata/FccdRead.arb +0 -2
  25. egse/aeu/arbdata/FccdRead_min_points.arb +0 -2
  26. egse/aeu/arbdata/HeaterSync_FccdRead.arb +0 -2
  27. egse/aeu/arbdata/HeaterSync_ccdRead25.arb +0 -2
  28. egse/aeu/arbdata/HeaterSync_ccdRead31_25.arb +0 -2
  29. egse/aeu/arbdata/HeaterSync_ccdRead37_50.arb +0 -2
  30. egse/aeu/arbdata/HeaterSync_ccdRead43_75.arb +0 -2
  31. egse/aeu/arbdata/HeaterSync_ccdRead50.arb +0 -2
  32. egse/aeu/arbdata/Heater_FccdRead_min_points.arb +0 -2
  33. egse/aeu/arbdata/ccdRead25.arb +0 -2
  34. egse/aeu/arbdata/ccdRead25_150ms.arb +0 -2
  35. egse/aeu/arbdata/ccdRead31_25.arb +0 -2
  36. egse/aeu/arbdata/ccdRead31_25_150ms.arb +0 -2
  37. egse/aeu/arbdata/ccdRead37_50.arb +0 -2
  38. egse/aeu/arbdata/ccdRead37_50_150ms.arb +0 -2
  39. egse/aeu/arbdata/ccdRead43_75.arb +0 -2
  40. egse/aeu/arbdata/ccdRead43_75_150ms.arb +0 -2
  41. egse/aeu/arbdata/ccdRead50.arb +0 -2
  42. egse/aeu/arbdata/ccdRead50_150ms.arb +0 -2
  43. egse/alert/__init__.py +0 -1049
  44. egse/alert/alertman.yaml +0 -37
  45. egse/alert/alertman_cs.py +0 -233
  46. egse/alert/alertman_ui.py +0 -600
  47. egse/alert/gsm/beaglebone.py +0 -138
  48. egse/alert/gsm/beaglebone.yaml +0 -51
  49. egse/alert/gsm/beaglebone_cs.py +0 -108
  50. egse/alert/gsm/beaglebone_devif.py +0 -122
  51. egse/alert/gsm/beaglebone_protocol.py +0 -46
  52. egse/bits.py +0 -318
  53. egse/camera.py +0 -44
  54. egse/collimator/__init__.py +0 -0
  55. egse/collimator/fcul/__init__.py +0 -0
  56. egse/collimator/fcul/ogse.py +0 -1077
  57. egse/collimator/fcul/ogse.yaml +0 -14
  58. egse/collimator/fcul/ogse_cs.py +0 -154
  59. egse/collimator/fcul/ogse_devif.py +0 -358
  60. egse/collimator/fcul/ogse_protocol.py +0 -132
  61. egse/collimator/fcul/ogse_sim.py +0 -431
  62. egse/collimator/fcul/ogse_ui.py +0 -1108
  63. egse/command.py +0 -699
  64. egse/config.py +0 -410
  65. egse/confman/__init__.py +0 -1058
  66. egse/confman/confman.yaml +0 -70
  67. egse/confman/confman_cs.py +0 -240
  68. egse/confman/confman_ui.py +0 -381
  69. egse/confman/setup_ui.py +0 -565
  70. egse/control.py +0 -632
  71. egse/coordinates/__init__.py +0 -534
  72. egse/coordinates/avoidance.py +0 -100
  73. egse/coordinates/cslmodel.py +0 -127
  74. egse/coordinates/laser_tracker_to_dict.py +0 -122
  75. egse/coordinates/point.py +0 -707
  76. egse/coordinates/pyplot.py +0 -194
  77. egse/coordinates/referenceFrame.py +0 -1279
  78. egse/coordinates/refmodel.py +0 -737
  79. egse/coordinates/rotationMatrix.py +0 -85
  80. egse/coordinates/transform3d_addon.py +0 -419
  81. egse/csl/__init__.py +0 -50
  82. egse/csl/commanding.py +0 -78
  83. egse/csl/icons/hexapod-connected-selected.svg +0 -30
  84. egse/csl/icons/hexapod-connected.svg +0 -30
  85. egse/csl/icons/hexapod-homing-selected.svg +0 -68
  86. egse/csl/icons/hexapod-homing.svg +0 -68
  87. egse/csl/icons/hexapod-retract-selected.svg +0 -56
  88. egse/csl/icons/hexapod-retract.svg +0 -51
  89. egse/csl/icons/hexapod-zero-selected.svg +0 -56
  90. egse/csl/icons/hexapod-zero.svg +0 -56
  91. egse/csl/icons/logo-puna.svg +0 -92
  92. egse/csl/icons/stop.svg +0 -1
  93. egse/csl/initialisation.py +0 -102
  94. egse/csl/mech_pos_settings.yaml +0 -18
  95. egse/das.py +0 -1240
  96. egse/das.yaml +0 -7
  97. egse/data/conf/SETUP_CSL_00000_170620_150000.yaml +0 -5
  98. egse/data/conf/SETUP_CSL_00001_170620_151010.yaml +0 -69
  99. egse/data/conf/SETUP_CSL_00002_170620_151020.yaml +0 -69
  100. egse/data/conf/SETUP_CSL_00003_170620_151030.yaml +0 -69
  101. egse/data/conf/SETUP_CSL_00004_170620_151040.yaml +0 -69
  102. egse/data/conf/SETUP_CSL_00005_170620_151050.yaml +0 -69
  103. egse/data/conf/SETUP_CSL_00006_170620_151060.yaml +0 -69
  104. egse/data/conf/SETUP_CSL_00007_170620_151070.yaml +0 -69
  105. egse/data/conf/SETUP_CSL_00008_170620_151080.yaml +0 -75
  106. egse/data/conf/SETUP_CSL_00010_210308_083016.yaml +0 -138
  107. egse/data/conf/SETUP_INTA_00000_170620_150000.yaml +0 -4
  108. egse/data/conf/SETUP_SRON_00000_170620_150000.yaml +0 -4
  109. egse/decorators.py +0 -514
  110. egse/device.py +0 -269
  111. egse/dpu/__init__.py +0 -2698
  112. egse/dpu/ccd_ui.py +0 -514
  113. egse/dpu/dpu.py +0 -783
  114. egse/dpu/dpu.yaml +0 -153
  115. egse/dpu/dpu_cs.py +0 -272
  116. egse/dpu/dpu_ui.py +0 -671
  117. egse/dpu/fitsgen.py +0 -2096
  118. egse/dpu/fitsgen_ui.py +0 -399
  119. egse/dpu/hdf5_model.py +0 -332
  120. egse/dpu/hdf5_ui.py +0 -277
  121. egse/dpu/hdf5_viewer.py +0 -506
  122. egse/dpu/hk_ui.py +0 -468
  123. egse/dpu_commands.py +0 -81
  124. egse/dsi/__init__.py +0 -33
  125. egse/dsi/_libesl.py +0 -232
  126. egse/dsi/constants.py +0 -296
  127. egse/dsi/esl.py +0 -630
  128. egse/dsi/rmap.py +0 -444
  129. egse/dsi/rmapci.py +0 -39
  130. egse/dsi/spw.py +0 -335
  131. egse/dsi/spw_state.py +0 -29
  132. egse/dummy.py +0 -318
  133. egse/dyndummy.py +0 -179
  134. egse/env.py +0 -278
  135. egse/exceptions.py +0 -88
  136. egse/fdir/__init__.py +0 -26
  137. egse/fdir/fdir_manager.py +0 -85
  138. egse/fdir/fdir_manager.yaml +0 -37
  139. egse/fdir/fdir_manager_controller.py +0 -136
  140. egse/fdir/fdir_manager_cs.py +0 -164
  141. egse/fdir/fdir_manager_interface.py +0 -15
  142. egse/fdir/fdir_remote.py +0 -73
  143. egse/fdir/fdir_remote.yaml +0 -30
  144. egse/fdir/fdir_remote_controller.py +0 -30
  145. egse/fdir/fdir_remote_cs.py +0 -94
  146. egse/fdir/fdir_remote_interface.py +0 -9
  147. egse/fdir/fdir_remote_popup.py +0 -26
  148. egse/fee/__init__.py +0 -106
  149. egse/fee/f_fee_register.yaml +0 -43
  150. egse/fee/feesim.py +0 -914
  151. egse/fee/n_fee_hk.py +0 -768
  152. egse/fee/nfee.py +0 -188
  153. egse/filterwheel/__init__.py +0 -4
  154. egse/filterwheel/eksma/__init__.py +0 -49
  155. egse/filterwheel/eksma/fw8smc4.py +0 -657
  156. egse/filterwheel/eksma/fw8smc4.yaml +0 -121
  157. egse/filterwheel/eksma/fw8smc4_cs.py +0 -144
  158. egse/filterwheel/eksma/fw8smc4_devif.py +0 -473
  159. egse/filterwheel/eksma/fw8smc4_protocol.py +0 -82
  160. egse/filterwheel/eksma/fw8smc4_ui.py +0 -940
  161. egse/filterwheel/eksma/fw8smc5.py +0 -115
  162. egse/filterwheel/eksma/fw8smc5.yaml +0 -105
  163. egse/filterwheel/eksma/fw8smc5_controller.py +0 -307
  164. egse/filterwheel/eksma/fw8smc5_cs.py +0 -141
  165. egse/filterwheel/eksma/fw8smc5_interface.py +0 -65
  166. egse/filterwheel/eksma/fw8smc5_simulator.py +0 -29
  167. egse/filterwheel/eksma/fw8smc5_ui.py +0 -1065
  168. egse/filterwheel/eksma/testpythonfw.py +0 -215
  169. egse/fov/__init__.py +0 -65
  170. egse/fov/fov_hk.py +0 -710
  171. egse/fov/fov_ui.py +0 -859
  172. egse/fov/fov_ui_controller.py +0 -140
  173. egse/fov/fov_ui_model.py +0 -200
  174. egse/fov/fov_ui_view.py +0 -345
  175. egse/gimbal/__init__.py +0 -32
  176. egse/gimbal/symetrie/__init__.py +0 -26
  177. egse/gimbal/symetrie/alpha.py +0 -586
  178. egse/gimbal/symetrie/generic_gimbal_ui.py +0 -1521
  179. egse/gimbal/symetrie/gimbal.py +0 -877
  180. egse/gimbal/symetrie/gimbal.yaml +0 -168
  181. egse/gimbal/symetrie/gimbal_cs.py +0 -183
  182. egse/gimbal/symetrie/gimbal_protocol.py +0 -138
  183. egse/gimbal/symetrie/gimbal_ui.py +0 -361
  184. egse/gimbal/symetrie/pmac.py +0 -1006
  185. egse/gimbal/symetrie/pmac_regex.py +0 -83
  186. egse/graph.py +0 -132
  187. egse/gui/__init__.py +0 -47
  188. egse/gui/buttons.py +0 -378
  189. egse/gui/focalplane.py +0 -1285
  190. egse/gui/formatter.py +0 -10
  191. egse/gui/led.py +0 -162
  192. egse/gui/limitswitch.py +0 -143
  193. egse/gui/mechanisms.py +0 -587
  194. egse/gui/states.py +0 -148
  195. egse/gui/stripchart.py +0 -729
  196. egse/gui/styles.qss +0 -48
  197. egse/gui/switch.py +0 -112
  198. egse/h5.py +0 -274
  199. egse/help/__init__.py +0 -0
  200. egse/help/help_ui.py +0 -126
  201. egse/hexapod/__init__.py +0 -32
  202. egse/hexapod/symetrie/__init__.py +0 -137
  203. egse/hexapod/symetrie/alpha.py +0 -874
  204. egse/hexapod/symetrie/dynalpha.py +0 -1387
  205. egse/hexapod/symetrie/hexapod_ui.py +0 -1516
  206. egse/hexapod/symetrie/pmac.py +0 -1010
  207. egse/hexapod/symetrie/pmac_regex.py +0 -83
  208. egse/hexapod/symetrie/puna.py +0 -1167
  209. egse/hexapod/symetrie/puna.yaml +0 -193
  210. egse/hexapod/symetrie/puna_cs.py +0 -195
  211. egse/hexapod/symetrie/puna_protocol.py +0 -134
  212. egse/hexapod/symetrie/puna_ui.py +0 -433
  213. egse/hexapod/symetrie/punaplus.py +0 -107
  214. egse/hexapod/symetrie/zonda.py +0 -872
  215. egse/hexapod/symetrie/zonda.yaml +0 -337
  216. egse/hexapod/symetrie/zonda_cs.py +0 -172
  217. egse/hexapod/symetrie/zonda_devif.py +0 -414
  218. egse/hexapod/symetrie/zonda_protocol.py +0 -123
  219. egse/hexapod/symetrie/zonda_ui.py +0 -449
  220. egse/hk.py +0 -791
  221. egse/icons/aeu-cs-start.svg +0 -117
  222. egse/icons/aeu-cs-stop.svg +0 -118
  223. egse/icons/aeu-cs.svg +0 -107
  224. egse/icons/aeu_cs-started.svg +0 -112
  225. egse/icons/aeu_cs-stopped.svg +0 -112
  226. egse/icons/aeu_cs.svg +0 -55
  227. egse/icons/alert.svg +0 -1
  228. egse/icons/arrow-double-left.png +0 -0
  229. egse/icons/arrow-double-right.png +0 -0
  230. egse/icons/arrow-up.svg +0 -11
  231. egse/icons/backward.svg +0 -1
  232. egse/icons/busy.svg +0 -1
  233. egse/icons/cleaning.svg +0 -115
  234. egse/icons/color-scheme.svg +0 -1
  235. egse/icons/cs-connected-alert.svg +0 -91
  236. egse/icons/cs-connected-disabled.svg +0 -43
  237. egse/icons/cs-connected.svg +0 -89
  238. egse/icons/cs-not-connected.svg +0 -44
  239. egse/icons/double-left-arrow.svg +0 -1
  240. egse/icons/double-right-arrow.svg +0 -1
  241. egse/icons/erase-disabled.svg +0 -19
  242. egse/icons/erase.svg +0 -59
  243. egse/icons/fitsgen-start.svg +0 -47
  244. egse/icons/fitsgen-stop.svg +0 -48
  245. egse/icons/fitsgen.svg +0 -1
  246. egse/icons/forward.svg +0 -1
  247. egse/icons/fov-hk-start.svg +0 -33
  248. egse/icons/fov-hk-stop.svg +0 -37
  249. egse/icons/fov-hk.svg +0 -1
  250. egse/icons/front-desk.svg +0 -1
  251. egse/icons/home-actioned.svg +0 -15
  252. egse/icons/home-disabled.svg +0 -15
  253. egse/icons/home.svg +0 -13
  254. egse/icons/info.svg +0 -1
  255. egse/icons/invalid.png +0 -0
  256. egse/icons/led-green.svg +0 -20
  257. egse/icons/led-grey.svg +0 -20
  258. egse/icons/led-orange.svg +0 -20
  259. egse/icons/led-red.svg +0 -20
  260. egse/icons/led-square-green.svg +0 -134
  261. egse/icons/led-square-grey.svg +0 -134
  262. egse/icons/led-square-orange.svg +0 -134
  263. egse/icons/led-square-red.svg +0 -134
  264. egse/icons/limit-switch-all-green.svg +0 -115
  265. egse/icons/limit-switch-all-red.svg +0 -117
  266. egse/icons/limit-switch-el+.svg +0 -116
  267. egse/icons/limit-switch-el-.svg +0 -117
  268. egse/icons/location-marker.svg +0 -1
  269. egse/icons/logo-dpu.svg +0 -48
  270. egse/icons/logo-gimbal.svg +0 -112
  271. egse/icons/logo-huber.svg +0 -23
  272. egse/icons/logo-ogse.svg +0 -31
  273. egse/icons/logo-puna.svg +0 -92
  274. egse/icons/logo-tcs.svg +0 -29
  275. egse/icons/logo-zonda.svg +0 -66
  276. egse/icons/maximize.svg +0 -1
  277. egse/icons/meter.svg +0 -1
  278. egse/icons/more.svg +0 -45
  279. egse/icons/n-fee-hk-start.svg +0 -24
  280. egse/icons/n-fee-hk-stop.svg +0 -25
  281. egse/icons/n-fee-hk.svg +0 -83
  282. egse/icons/observing-off.svg +0 -46
  283. egse/icons/observing-on.svg +0 -46
  284. egse/icons/open-document-hdf5.png +0 -0
  285. egse/icons/open-document-hdf5.svg +0 -21
  286. egse/icons/ops-mode.svg +0 -1
  287. egse/icons/play-green.svg +0 -17
  288. egse/icons/plugged-disabled.svg +0 -27
  289. egse/icons/plugged.svg +0 -21
  290. egse/icons/pm_ui.svg +0 -1
  291. egse/icons/power-button-green.svg +0 -27
  292. egse/icons/power-button-red.svg +0 -27
  293. egse/icons/power-button.svg +0 -27
  294. egse/icons/radar.svg +0 -1
  295. egse/icons/radioactive.svg +0 -2
  296. egse/icons/reload.svg +0 -1
  297. egse/icons/remote-control-off.svg +0 -28
  298. egse/icons/remote-control-on.svg +0 -28
  299. egse/icons/repeat-blue.svg +0 -15
  300. egse/icons/repeat.svg +0 -1
  301. egse/icons/settings.svg +0 -1
  302. egse/icons/shrink.svg +0 -1
  303. egse/icons/shutter.svg +0 -1
  304. egse/icons/sign-off.svg +0 -1
  305. egse/icons/sign-on.svg +0 -1
  306. egse/icons/sim-mode.svg +0 -1
  307. egse/icons/small-buttons-go.svg +0 -20
  308. egse/icons/small-buttons-minus.svg +0 -51
  309. egse/icons/small-buttons-plus.svg +0 -51
  310. egse/icons/sponge.svg +0 -220
  311. egse/icons/start-button-disabled.svg +0 -84
  312. egse/icons/start-button.svg +0 -50
  313. egse/icons/stop-button-disabled.svg +0 -84
  314. egse/icons/stop-button.svg +0 -50
  315. egse/icons/stop-red.svg +0 -17
  316. egse/icons/stop.svg +0 -1
  317. egse/icons/switch-disabled-square.svg +0 -87
  318. egse/icons/switch-disabled.svg +0 -15
  319. egse/icons/switch-off-square.svg +0 -87
  320. egse/icons/switch-off.svg +0 -72
  321. egse/icons/switch-on-square.svg +0 -87
  322. egse/icons/switch-on.svg +0 -61
  323. egse/icons/temperature-control.svg +0 -44
  324. egse/icons/th_ui_logo.svg +0 -1
  325. egse/icons/unplugged.svg +0 -23
  326. egse/icons/unvalid.png +0 -0
  327. egse/icons/user-interface.svg +0 -1
  328. egse/icons/vacuum.svg +0 -1
  329. egse/icons/valid.png +0 -0
  330. egse/icons/zoom-to-pixel-dark.svg +0 -64
  331. egse/icons/zoom-to-pixel-white.svg +0 -36
  332. egse/images/big-rotation-stage.png +0 -0
  333. egse/images/connected-100.png +0 -0
  334. egse/images/cross.svg +0 -6
  335. egse/images/disconnected-100.png +0 -0
  336. egse/images/gui-icon.png +0 -0
  337. egse/images/home.svg +0 -6
  338. egse/images/info-icon.png +0 -0
  339. egse/images/led-black.svg +0 -89
  340. egse/images/led-green.svg +0 -85
  341. egse/images/led-orange.svg +0 -85
  342. egse/images/led-red.svg +0 -85
  343. egse/images/load-icon.png +0 -0
  344. egse/images/load-setup.png +0 -0
  345. egse/images/load.png +0 -0
  346. egse/images/pause.png +0 -0
  347. egse/images/play-button.svg +0 -8
  348. egse/images/play.png +0 -0
  349. egse/images/process-status.png +0 -0
  350. egse/images/restart.png +0 -0
  351. egse/images/search.png +0 -0
  352. egse/images/sma.png +0 -0
  353. egse/images/start.png +0 -0
  354. egse/images/stop-button.svg +0 -8
  355. egse/images/stop.png +0 -0
  356. egse/images/switch-off.svg +0 -48
  357. egse/images/switch-on.svg +0 -48
  358. egse/images/undo.png +0 -0
  359. egse/images/update-button.svg +0 -11
  360. egse/imageviewer/exposureselection.py +0 -475
  361. egse/imageviewer/imageviewer.py +0 -198
  362. egse/imageviewer/matchfocalplane.py +0 -179
  363. egse/imageviewer/subfieldposition.py +0 -133
  364. egse/lampcontrol/__init__.py +0 -4
  365. egse/lampcontrol/beaglebone/beaglebone.py +0 -178
  366. egse/lampcontrol/beaglebone/beaglebone.yaml +0 -62
  367. egse/lampcontrol/beaglebone/beaglebone_cs.py +0 -106
  368. egse/lampcontrol/beaglebone/beaglebone_devif.py +0 -150
  369. egse/lampcontrol/beaglebone/beaglebone_protocol.py +0 -73
  370. egse/lampcontrol/energetiq/__init__.py +0 -22
  371. egse/lampcontrol/energetiq/eq99.yaml +0 -98
  372. egse/lampcontrol/energetiq/lampEQ99.py +0 -283
  373. egse/lampcontrol/energetiq/lampEQ99_cs.py +0 -128
  374. egse/lampcontrol/energetiq/lampEQ99_devif.py +0 -158
  375. egse/lampcontrol/energetiq/lampEQ99_encode_decode_errors.py +0 -73
  376. egse/lampcontrol/energetiq/lampEQ99_protocol.py +0 -71
  377. egse/lampcontrol/energetiq/lampEQ99_ui.py +0 -465
  378. egse/lib/CentOS-7/EtherSpaceLink_v34_86.dylib +0 -0
  379. egse/lib/CentOS-8/ESL-RMAP_v34_86.dylib +0 -0
  380. egse/lib/CentOS-8/EtherSpaceLink_v34_86.dylib +0 -0
  381. egse/lib/Debian/ESL-RMAP_v34_86.dylib +0 -0
  382. egse/lib/Debian/EtherSpaceLink_v34_86.dylib +0 -0
  383. egse/lib/Debian/libetherspacelink_v35_21.dylib +0 -0
  384. egse/lib/Linux/ESL-RMAP_v34_86.dylib +0 -0
  385. egse/lib/Linux/EtherSpaceLink_v34_86.dylib +0 -0
  386. egse/lib/Ubuntu-20/ESL-RMAP_v34_86.dylib +0 -0
  387. egse/lib/Ubuntu-20/EtherSpaceLink_v34_86.dylib +0 -0
  388. egse/lib/gssw/python3-gssw_2.2.3+31f63c9f-1_all.deb +0 -0
  389. egse/lib/ximc/__pycache__/pyximc.cpython-38 2.pyc +0 -0
  390. egse/lib/ximc/__pycache__/pyximc.cpython-38.pyc +0 -0
  391. egse/lib/ximc/libximc.framework/Frameworks/libbindy.dylib +0 -0
  392. egse/lib/ximc/libximc.framework/Frameworks/libxiwrapper.dylib +0 -0
  393. egse/lib/ximc/libximc.framework/Headers/ximc.h +0 -5510
  394. egse/lib/ximc/libximc.framework/Resources/Info.plist +0 -42
  395. egse/lib/ximc/libximc.framework/Resources/keyfile.sqlite +0 -0
  396. egse/lib/ximc/libximc.framework/libbindy.so +0 -0
  397. egse/lib/ximc/libximc.framework/libximc +0 -0
  398. egse/lib/ximc/libximc.framework/libximc.so +0 -0
  399. egse/lib/ximc/libximc.framework/libximc.so.7.0.0 +0 -0
  400. egse/lib/ximc/libximc.framework/libxiwrapper.so +0 -0
  401. egse/lib/ximc/pyximc.py +0 -922
  402. egse/listener.py +0 -179
  403. egse/logger/__init__.py +0 -243
  404. egse/logger/log_cs.py +0 -321
  405. egse/metrics.py +0 -102
  406. egse/mixin.py +0 -464
  407. egse/monitoring.py +0 -95
  408. egse/ni/alarms/__init__.py +0 -26
  409. egse/ni/alarms/cdaq9375.py +0 -300
  410. egse/ni/alarms/cdaq9375.yaml +0 -89
  411. egse/ni/alarms/cdaq9375_cs.py +0 -130
  412. egse/ni/alarms/cdaq9375_devif.py +0 -183
  413. egse/ni/alarms/cdaq9375_protocol.py +0 -48
  414. egse/obs_inspection.py +0 -165
  415. egse/observer.py +0 -41
  416. egse/obsid.py +0 -163
  417. egse/powermeter/__init__.py +0 -0
  418. egse/powermeter/ni/__init__.py +0 -38
  419. egse/powermeter/ni/cdaq9184.py +0 -224
  420. egse/powermeter/ni/cdaq9184.yaml +0 -73
  421. egse/powermeter/ni/cdaq9184_cs.py +0 -130
  422. egse/powermeter/ni/cdaq9184_devif.py +0 -201
  423. egse/powermeter/ni/cdaq9184_protocol.py +0 -48
  424. egse/powermeter/ni/cdaq9184_ui.py +0 -544
  425. egse/powermeter/thorlabs/__init__.py +0 -25
  426. egse/powermeter/thorlabs/pm100a.py +0 -380
  427. egse/powermeter/thorlabs/pm100a.yaml +0 -132
  428. egse/powermeter/thorlabs/pm100a_cs.py +0 -136
  429. egse/powermeter/thorlabs/pm100a_devif.py +0 -127
  430. egse/powermeter/thorlabs/pm100a_protocol.py +0 -80
  431. egse/powermeter/thorlabs/pm100a_ui.py +0 -725
  432. egse/process.py +0 -451
  433. egse/procman/__init__.py +0 -834
  434. egse/procman/cannot_start_process_popup.py +0 -43
  435. egse/procman/procman.yaml +0 -49
  436. egse/procman/procman_cs.py +0 -201
  437. egse/procman/procman_ui.py +0 -2081
  438. egse/protocol.py +0 -605
  439. egse/proxy.py +0 -531
  440. egse/randomwalk.py +0 -140
  441. egse/reg.py +0 -585
  442. egse/reload.py +0 -122
  443. egse/reprocess.py +0 -693
  444. egse/resource.py +0 -333
  445. egse/rmap.py +0 -406
  446. egse/rst.py +0 -135
  447. egse/search.py +0 -182
  448. egse/serialdevice.py +0 -190
  449. egse/services.py +0 -247
  450. egse/services.yaml +0 -68
  451. egse/settings.py +0 -379
  452. egse/settings.yaml +0 -980
  453. egse/setup.py +0 -1181
  454. egse/shutter/__init__.py +0 -0
  455. egse/shutter/thorlabs/__init__.py +0 -19
  456. egse/shutter/thorlabs/ksc101.py +0 -205
  457. egse/shutter/thorlabs/ksc101.yaml +0 -105
  458. egse/shutter/thorlabs/ksc101_cs.py +0 -136
  459. egse/shutter/thorlabs/ksc101_devif.py +0 -201
  460. egse/shutter/thorlabs/ksc101_protocol.py +0 -71
  461. egse/shutter/thorlabs/ksc101_ui.py +0 -548
  462. egse/shutter/thorlabs/sc10.py +0 -82
  463. egse/shutter/thorlabs/sc10.yaml +0 -52
  464. egse/shutter/thorlabs/sc10_controller.py +0 -81
  465. egse/shutter/thorlabs/sc10_cs.py +0 -108
  466. egse/shutter/thorlabs/sc10_interface.py +0 -25
  467. egse/shutter/thorlabs/sc10_simulator.py +0 -30
  468. egse/simulator.py +0 -41
  469. egse/slack.py +0 -61
  470. egse/socketdevice.py +0 -218
  471. egse/sockets.py +0 -218
  472. egse/spw.py +0 -1401
  473. egse/stages/__init__.py +0 -12
  474. egse/stages/aerotech/ensemble.py +0 -245
  475. egse/stages/aerotech/ensemble.yaml +0 -205
  476. egse/stages/aerotech/ensemble_controller.py +0 -275
  477. egse/stages/aerotech/ensemble_cs.py +0 -110
  478. egse/stages/aerotech/ensemble_interface.py +0 -132
  479. egse/stages/aerotech/ensemble_parameters.py +0 -433
  480. egse/stages/aerotech/ensemble_simulator.py +0 -27
  481. egse/stages/aerotech/mgse_sim.py +0 -188
  482. egse/stages/arun/smd3.py +0 -110
  483. egse/stages/arun/smd3.yaml +0 -68
  484. egse/stages/arun/smd3_controller.py +0 -470
  485. egse/stages/arun/smd3_cs.py +0 -112
  486. egse/stages/arun/smd3_interface.py +0 -53
  487. egse/stages/arun/smd3_simulator.py +0 -27
  488. egse/stages/arun/smd3_stop.py +0 -16
  489. egse/stages/huber/__init__.py +0 -49
  490. egse/stages/huber/smc9300.py +0 -920
  491. egse/stages/huber/smc9300.yaml +0 -63
  492. egse/stages/huber/smc9300_cs.py +0 -178
  493. egse/stages/huber/smc9300_devif.py +0 -345
  494. egse/stages/huber/smc9300_protocol.py +0 -113
  495. egse/stages/huber/smc9300_sim.py +0 -547
  496. egse/stages/huber/smc9300_ui.py +0 -973
  497. egse/state.py +0 -173
  498. egse/statemachine.py +0 -274
  499. egse/storage/__init__.py +0 -1067
  500. egse/storage/persistence.py +0 -2295
  501. egse/storage/storage.yaml +0 -79
  502. egse/storage/storage_cs.py +0 -231
  503. egse/styles/dark.qss +0 -343
  504. egse/styles/default.qss +0 -48
  505. egse/synoptics/__init__.py +0 -417
  506. egse/synoptics/syn.yaml +0 -9
  507. egse/synoptics/syn_cs.py +0 -195
  508. egse/system.py +0 -1611
  509. egse/tcs/__init__.py +0 -14
  510. egse/tcs/tcs.py +0 -879
  511. egse/tcs/tcs.yaml +0 -14
  512. egse/tcs/tcs_cs.py +0 -202
  513. egse/tcs/tcs_devif.py +0 -292
  514. egse/tcs/tcs_protocol.py +0 -180
  515. egse/tcs/tcs_sim.py +0 -177
  516. egse/tcs/tcs_ui.py +0 -543
  517. egse/tdms.py +0 -171
  518. egse/tempcontrol/__init__.py +0 -23
  519. egse/tempcontrol/agilent/agilent34970.py +0 -109
  520. egse/tempcontrol/agilent/agilent34970.yaml +0 -44
  521. egse/tempcontrol/agilent/agilent34970_cs.py +0 -114
  522. egse/tempcontrol/agilent/agilent34970_devif.py +0 -182
  523. egse/tempcontrol/agilent/agilent34970_protocol.py +0 -96
  524. egse/tempcontrol/agilent/agilent34972.py +0 -111
  525. egse/tempcontrol/agilent/agilent34972.yaml +0 -44
  526. egse/tempcontrol/agilent/agilent34972_cs.py +0 -115
  527. egse/tempcontrol/agilent/agilent34972_devif.py +0 -189
  528. egse/tempcontrol/agilent/agilent34972_protocol.py +0 -98
  529. egse/tempcontrol/beaglebone/beaglebone.py +0 -341
  530. egse/tempcontrol/beaglebone/beaglebone.yaml +0 -110
  531. egse/tempcontrol/beaglebone/beaglebone_cs.py +0 -117
  532. egse/tempcontrol/beaglebone/beaglebone_protocol.py +0 -134
  533. egse/tempcontrol/beaglebone/beaglebone_ui.py +0 -674
  534. egse/tempcontrol/digalox/digalox.py +0 -115
  535. egse/tempcontrol/digalox/digalox.yaml +0 -36
  536. egse/tempcontrol/digalox/digalox_cs.py +0 -108
  537. egse/tempcontrol/digalox/digalox_protocol.py +0 -56
  538. egse/tempcontrol/keithley/__init__.py +0 -33
  539. egse/tempcontrol/keithley/daq6510.py +0 -662
  540. egse/tempcontrol/keithley/daq6510.yaml +0 -105
  541. egse/tempcontrol/keithley/daq6510_cs.py +0 -163
  542. egse/tempcontrol/keithley/daq6510_devif.py +0 -343
  543. egse/tempcontrol/keithley/daq6510_protocol.py +0 -79
  544. egse/tempcontrol/keithley/daq6510_sim.py +0 -186
  545. egse/tempcontrol/lakeshore/__init__.py +0 -33
  546. egse/tempcontrol/lakeshore/lsci.py +0 -361
  547. egse/tempcontrol/lakeshore/lsci.yaml +0 -162
  548. egse/tempcontrol/lakeshore/lsci_cs.py +0 -174
  549. egse/tempcontrol/lakeshore/lsci_devif.py +0 -292
  550. egse/tempcontrol/lakeshore/lsci_protocol.py +0 -76
  551. egse/tempcontrol/lakeshore/lsci_ui.py +0 -387
  552. egse/tempcontrol/ni/__init__.py +0 -0
  553. egse/tempcontrol/spid/spid.py +0 -109
  554. egse/tempcontrol/spid/spid.yaml +0 -81
  555. egse/tempcontrol/spid/spid_controller.py +0 -279
  556. egse/tempcontrol/spid/spid_cs.py +0 -136
  557. egse/tempcontrol/spid/spid_protocol.py +0 -107
  558. egse/tempcontrol/spid/spid_ui.py +0 -723
  559. egse/tempcontrol/srs/__init__.py +0 -22
  560. egse/tempcontrol/srs/ptc10.py +0 -867
  561. egse/tempcontrol/srs/ptc10.yaml +0 -227
  562. egse/tempcontrol/srs/ptc10_cs.py +0 -128
  563. egse/tempcontrol/srs/ptc10_devif.py +0 -116
  564. egse/tempcontrol/srs/ptc10_protocol.py +0 -39
  565. egse/tempcontrol/srs/ptc10_ui.py +0 -906
  566. egse/ups/apc/apc.py +0 -236
  567. egse/ups/apc/apc.yaml +0 -45
  568. egse/ups/apc/apc_cs.py +0 -101
  569. egse/ups/apc/apc_protocol.py +0 -125
  570. egse/user.yaml +0 -7
  571. egse/vacuum/beaglebone/beaglebone.py +0 -149
  572. egse/vacuum/beaglebone/beaglebone.yaml +0 -44
  573. egse/vacuum/beaglebone/beaglebone_cs.py +0 -108
  574. egse/vacuum/beaglebone/beaglebone_devif.py +0 -159
  575. egse/vacuum/beaglebone/beaglebone_protocol.py +0 -192
  576. egse/vacuum/beaglebone/beaglebone_ui.py +0 -638
  577. egse/vacuum/instrutech/igm402.py +0 -91
  578. egse/vacuum/instrutech/igm402.yaml +0 -90
  579. egse/vacuum/instrutech/igm402_controller.py +0 -124
  580. egse/vacuum/instrutech/igm402_cs.py +0 -108
  581. egse/vacuum/instrutech/igm402_interface.py +0 -49
  582. egse/vacuum/instrutech/igm402_simulator.py +0 -36
  583. egse/vacuum/keller/kellerBus.py +0 -256
  584. egse/vacuum/keller/leo3.py +0 -100
  585. egse/vacuum/keller/leo3.yaml +0 -38
  586. egse/vacuum/keller/leo3_controller.py +0 -81
  587. egse/vacuum/keller/leo3_cs.py +0 -101
  588. egse/vacuum/keller/leo3_interface.py +0 -33
  589. egse/vacuum/mks/evision.py +0 -86
  590. egse/vacuum/mks/evision.yaml +0 -75
  591. egse/vacuum/mks/evision_cs.py +0 -101
  592. egse/vacuum/mks/evision_devif.py +0 -313
  593. egse/vacuum/mks/evision_interface.py +0 -60
  594. egse/vacuum/mks/evision_simulator.py +0 -24
  595. egse/vacuum/mks/evision_ui.py +0 -701
  596. egse/vacuum/pfeiffer/acp40.py +0 -87
  597. egse/vacuum/pfeiffer/acp40.yaml +0 -60
  598. egse/vacuum/pfeiffer/acp40_controller.py +0 -117
  599. egse/vacuum/pfeiffer/acp40_cs.py +0 -109
  600. egse/vacuum/pfeiffer/acp40_interface.py +0 -40
  601. egse/vacuum/pfeiffer/acp40_simulator.py +0 -37
  602. egse/vacuum/pfeiffer/tc400.py +0 -87
  603. egse/vacuum/pfeiffer/tc400.yaml +0 -83
  604. egse/vacuum/pfeiffer/tc400_controller.py +0 -136
  605. egse/vacuum/pfeiffer/tc400_cs.py +0 -109
  606. egse/vacuum/pfeiffer/tc400_interface.py +0 -70
  607. egse/vacuum/pfeiffer/tc400_simulator.py +0 -35
  608. egse/vacuum/pfeiffer/tpg261.py +0 -80
  609. egse/vacuum/pfeiffer/tpg261.yaml +0 -66
  610. egse/vacuum/pfeiffer/tpg261_controller.py +0 -150
  611. egse/vacuum/pfeiffer/tpg261_cs.py +0 -109
  612. egse/vacuum/pfeiffer/tpg261_interface.py +0 -59
  613. egse/vacuum/pfeiffer/tpg261_simulator.py +0 -23
  614. egse/version.py +0 -174
  615. egse/visitedpositions.py +0 -398
  616. egse/windowing.py +0 -213
  617. egse/zmq/__init__.py +0 -28
  618. egse/zmq/spw.py +0 -160
  619. egse/zmq_ser.py +0 -41
  620. scripts/alerts/cold.yaml +0 -278
  621. scripts/alerts/example_alerts.yaml +0 -54
  622. scripts/alerts/transition.yaml +0 -14
  623. scripts/alerts/warm.yaml +0 -49
  624. scripts/analyse_n_fee_hk_data.py +0 -52
  625. scripts/check_hdf5_files.py +0 -192
  626. scripts/check_register_sync.py +0 -47
  627. scripts/check_tcs_calib_coef.py +0 -90
  628. scripts/correct_ccd_cold_temperature_cal.py +0 -157
  629. scripts/create_hdf5_report.py +0 -293
  630. scripts/csl_model.py +0 -420
  631. scripts/csl_restore_setup.py +0 -229
  632. scripts/export-grafana-dashboards.py +0 -49
  633. scripts/fdir/cs_recovery/fdir_cs_recovery.py +0 -54
  634. scripts/fdir/fdir_table.yaml +0 -70
  635. scripts/fdir/fdir_test_recovery.py +0 -10
  636. scripts/fdir/hw_recovery/fdir_agilent_hw_recovery.py +0 -73
  637. scripts/fdir/limit_recovery/fdir_agilent_limit.py +0 -61
  638. scripts/fdir/limit_recovery/fdir_bb_heater_limit.py +0 -59
  639. scripts/fdir/limit_recovery/fdir_ensemble_limit.py +0 -33
  640. scripts/fdir/limit_recovery/fdir_pressure_limit_recovery.py +0 -71
  641. scripts/fix_csv.py +0 -80
  642. scripts/ias/correct_ccd_temp_cal_elfique.py +0 -43
  643. scripts/ias/correct_ccd_temp_cal_floreffe.py +0 -43
  644. scripts/ias/correct_trp_swap_achel.py +0 -199
  645. scripts/inta/correct_ccd_temp_cal_duvel.py +0 -43
  646. scripts/inta/correct_ccd_temp_cal_gueuze.py +0 -43
  647. scripts/n_fee_supply_voltage_calculation.py +0 -92
  648. scripts/playground.py +0 -30
  649. scripts/print_hdf5_hk_data.py +0 -68
  650. scripts/print_register_map.py +0 -43
  651. scripts/remove_lines_between_matches.py +0 -188
  652. scripts/sron/commanding/control_heaters.py +0 -44
  653. scripts/sron/commanding/pumpdown.py +0 -46
  654. scripts/sron/commanding/set_pid_setpoint.py +0 -19
  655. scripts/sron/commanding/shutdown_bbb_heaters.py +0 -10
  656. scripts/sron/commanding/shutdown_pumps.py +0 -33
  657. scripts/sron/correct_mgse_coordinates_brigand_chimay.py +0 -272
  658. scripts/sron/correct_trp_swap_brigand.py +0 -204
  659. scripts/sron/gimbal_conversions.py +0 -75
  660. scripts/sron/tm_gen/tm_gen_agilent.py +0 -37
  661. scripts/sron/tm_gen/tm_gen_heaters.py +0 -4
  662. scripts/sron/tm_gen/tm_gen_spid.py +0 -13
  663. scripts/update_operational_cgse.py +0 -268
  664. scripts/update_operational_cgse_old.py +0 -273
egse/command.py DELETED
@@ -1,699 +0,0 @@
1
- """
2
- This module defines a number of classes and helper functions to define and work
3
- with commands that operate hardware devices. The goal is to be able to define /
4
- create commands transparently from a YAML file without having to write (too much)
5
- code.
6
-
7
- A few definitions for the classes defined in this module:
8
-
9
- **command**
10
-
11
- a string that is sent to a device over an interface like TCP/IP or USB. This
12
- string is generated by the get_cmd_string() method of the Command class.
13
-
14
- The string contains format like syntax that looks like an f-string, but is
15
- interpreted differently. See further: How to format device command strings.
16
-
17
- **Command**
18
-
19
- the base class for commands. This class contains the definition of the command
20
- and provides methods to parse and check arguments. The Command can be 'called'
21
- or 'executed' in which case a number of actons are performed based on the
22
- provided arguments.
23
-
24
- **CommandExecution**
25
-
26
- this class contains all the information needed to execute a command, without
27
- actually executing it. A CommandExecution contains the command definition and
28
- the parameters for the execution. It is mainly served as a communication
29
- mechanism to the control servers, i.e. the client side (Proxy) defines a
30
- command execution and the server then executes the command.
31
-
32
- **CommandError**
33
-
34
- a catch-all exception for unrecoverable errors in this module
35
-
36
- **InvalidArgumentsError**
37
-
38
- a CommandError raised when the arguments provided are themselve invalid
39
- or if the number of arguments is not matching expectations
40
-
41
- The basic interface is:
42
-
43
- cmd = Command(name = <command name>,
44
- cmd = <command string>,
45
- response = <callable to retreive a response>,
46
- wait = <callable to wait a specific time/delay>)
47
-
48
- where:
49
-
50
- * name: a name for the command, this is just needed for reporting, not used in commanding
51
- * cmd: the command string to send or execute, see further for details
52
- * response: send a second command to read or get a response on the 'cmd' sent
53
- * wait: a function object that will wait for a specific duration,
54
- e.g. ```partial(time.sleep, 10)```
55
-
56
- How to format device command strings
57
-
58
- The ``cmd`` argument is a string that contains placeholders (replacement fields)
59
- for future arguments that will be passed when calling the Command. The replacement
60
- fields are marked with curly braces and are mandatory. When a name is provided
61
- in the curly braces, the argument shall be provided as a keyword argument, otherwise
62
- a positional argument is expected. In the current implementation the ``cmd``
63
- can only contain either positional arguments or keyword argument, not a mix of both.
64
-
65
- The replacement fields may also have a format specifier to specify a precise format
66
- for that field.
67
-
68
- **Examples**
69
-
70
- moveAbsolute = Command(
71
- name = "moveAbsolute",
72
- cmd = "&2 Q70=0 Q71={tx:.6f} Q72={ty:.6f} Q73={tz:.6f} "
73
- "Q74={rx:.6f} Q75={ry:.6f} Q76={rz:.6f} Q20=11"
74
- )
75
-
76
- response = moveAbsolute(1, 1, 1, 0, 0, 20)
77
- response = moveAbsolute(tx=1, ty=1, tz=1, rx=0, ry=0, rz=20)
78
-
79
-
80
- Questions
81
-
82
- Do we need additional hooks into this commanding?
83
-
84
- * add a meaning to the check, what is it and what is it used for?
85
- * add a output processor possibility. A callback function that will process the
86
- output value before returning it by the __call__.
87
- * provide an execute method for the CommandExecution that executes the command
88
- with the saved parameters
89
- """
90
- import functools
91
- import inspect
92
- import logging
93
- import re
94
- from collections import namedtuple
95
- from typing import Callable
96
-
97
- from egse.control import Success
98
- from egse.exceptions import Error
99
-
100
- logger = logging.getLogger(__name__)
101
-
102
-
103
- def stringify_function_call(function_info: dict) -> str:
104
- def quote(value):
105
- return f'"{value}"' if isinstance(value, str) else value
106
-
107
- description = function_info.get("description")
108
- if description:
109
- return description
110
-
111
- result = ""
112
-
113
- name = function_info.get("func_name")
114
- args = function_info.get("args")
115
- kwargs = function_info.get("kwargs")
116
-
117
- if name:
118
- result += name
119
- else:
120
- result += "unknown_function"
121
-
122
- result += "("
123
-
124
- if args:
125
- result += f"{args}"[1:-1]
126
-
127
- if kwargs:
128
- result += ", " if args else ""
129
- result += ", ".join([f"{k}={quote(v)}" for k, v in kwargs.items()])
130
-
131
- result += ")"
132
-
133
- return result
134
-
135
-
136
- def dry_run(func: Callable) -> Callable:
137
- """This decorator prepares the function to handle a dry run.
138
-
139
- A dry run is used to check the logic of an instrument commanding script without
140
- actually executing the instrument commands. The commands are instead added to the
141
- command sequence in the global state.
142
-
143
- Args:
144
- func: the function that needs to be executed
145
-
146
- Returns:
147
- A wrapper around the given function.
148
- """
149
-
150
- @functools.wraps(func)
151
- def func_wrapper(self, *args, **kwargs):
152
-
153
- from egse.state import GlobalState # prevent circular import
154
-
155
- if GlobalState.dry_run:
156
- if callable(func) and func.__name__ == "client_call":
157
- # This client_call function takes an additional argument which is the Proxy.
158
- # the Proxy is not part of the CommandExecution signature and shall be removed
159
- # FIXME: do we introduce a memory leak here by adding 'self' to this GlobalState?
160
- args = args[1:]
161
- try:
162
- self.validate_arguments(*args, **kwargs)
163
- except CommandError as e_ce:
164
- GlobalState.add_command(InvalidCommandExecution(e_ce, self, *args, **kwargs))
165
- else:
166
- GlobalState.add_command(CommandExecution(self, *args, **kwargs))
167
- else:
168
- FunctionExecution = namedtuple("FunctionExecution", ["name", "args", "kwargs"])
169
- GlobalState.add_command(FunctionExecution(func.__name__, args, kwargs))
170
- return Success(
171
- "Command execution appended to command sequence, function not executed in dry_run."
172
- )
173
- else:
174
- return func(self, *args, **kwargs)
175
-
176
- return func_wrapper
177
-
178
-
179
- def parse_format_string(fstring):
180
- """
181
- Parse and decode the format string.
182
- """
183
- # Remove occurrences of {{ }} from the fstring as they are not replacement fields
184
- # and will occur after formatting as single braces.
185
-
186
- fstring = re.sub(r"{{.*}}", lambda x: "_", fstring)
187
-
188
- # logger.debug(f"fstring = '{fstring}', replaced {{{{.*}}}} with _")
189
-
190
- parts = re.findall(r"\{(.*?)\}", fstring)
191
-
192
- # logger.debug(f"Parts: {parts!r}, n={len(parts)}")
193
-
194
- tot_n_args = len(parts)
195
- n_args = 0
196
- n_kwargs = 0
197
- keys = []
198
-
199
- for part in parts:
200
- result = re.split(r"(:)", part)
201
- if result[0] == "":
202
- n_args += 1
203
- else:
204
- n_kwargs += 1
205
- keys.append(result[0])
206
-
207
- # If this assertion fails, there is a flaw in the algorithm above
208
- assert tot_n_args == n_args + n_kwargs, (
209
- f"Total number of arguments ({tot_n_args}) doesn't match # args ({n_args}) + "
210
- f"# kwargs ({n_kwargs})."
211
- )
212
-
213
- if n_args > 0 and n_kwargs > 0:
214
- raise InvalidArgumentsError("Mixing of positional and keyword arguments is not available.")
215
-
216
- return tot_n_args, n_args, n_kwargs, keys
217
-
218
-
219
- class CommandError(Error):
220
- """A Command Exception as a base class for this module."""
221
-
222
-
223
- class InvalidArgumentsError(CommandError):
224
- """The arguments provided are invalid"""
225
-
226
-
227
- class CommandExecution:
228
- """
229
- This class contains all the information that is needed to execute a command
230
- with a set of parameters/arguments. The command is however not executed
231
- automatically. That is the responsibility of the caller to actually execute
232
- the command with the given parameters.
233
-
234
- Developer info
235
-
236
- you can see this as a partial (functools) which defines the command and
237
- its arguments, but doesn't execute until explicitly called. You can execute
238
- the command by calling the `cmd` with the given arguments:
239
-
240
- ```
241
- ce = CommandExecution(cmd, 20.0)
242
- ...
243
- response = ce.run()
244
- ```
245
- """
246
-
247
- def __init__(self, cmd, *args, **kwargs):
248
- self._cmd = cmd
249
- self._args = args
250
- self._kwargs = kwargs
251
-
252
- def get_name(self):
253
- return self._cmd.get_name()
254
-
255
- def get_cmd(self):
256
- return self._cmd
257
-
258
- def get_args(self):
259
- return self._args
260
-
261
- def get_kwargs(self):
262
- return self._kwargs
263
-
264
- def run(self):
265
- return self._cmd(*self._args, **self._kwargs)
266
-
267
- def __str__(self):
268
- msg = f"[{self.get_cmd().__class__.__name__}] {self.get_name()}("
269
- for arg in self.get_args():
270
- msg += f"{arg}, "
271
- for k, v in self.get_kwargs().items():
272
- msg += f"{k}={v}, "
273
- if msg.endswith(", "):
274
- msg = msg[:-2]
275
- msg += ")"
276
- return msg
277
-
278
-
279
- class InvalidCommandExecution(CommandExecution):
280
- """A invalid command execution."""
281
-
282
- def __init__(self, exc, cmd, *args, **kwargs):
283
- """
284
- Args:
285
- exc: the Exception that was raised and describes the problem
286
- cmd: the Command object
287
- *args: the positional arguments that were given
288
- **kwargs: the keyword arguments that were given
289
- """
290
- super().__init__(cmd, *args, **kwargs)
291
- self._exc = exc
292
-
293
- def run(self):
294
- raise InvalidArgumentsError(
295
- f"The command {self.get_name()} can not be executed. Reason: {self._exc}"
296
- )
297
-
298
- def __str__(self):
299
- msg = super().__str__()
300
- msg += f" [ERROR: {self._exc}]"
301
- return msg
302
-
303
-
304
- class WaitCommand:
305
- def __init__(self, command, condition):
306
- self._command = command
307
- self._condition = condition
308
-
309
- def __call__(self):
310
-
311
- # .. todo:: do we need a timeout possibility here?
312
-
313
- while True:
314
- return_code = self._command()
315
- if self._condition(return_code):
316
- break
317
-
318
- return 0
319
-
320
-
321
- class Command:
322
- """
323
- A Command is basically a string that is send to a device and for which the
324
- device returns a response.
325
-
326
- The command string can contain placeholders that will be filled when the
327
- command is 'called'.
328
-
329
- The arguments that are given will be filled into the formatted string.
330
- Arguments can be positional or keyword arguments, not both.
331
- """
332
-
333
- def __init__(
334
- self, name, cmd, response=None, wait=None, check=None, description=None,
335
- device_method=None
336
- ):
337
- self._name = name
338
- self._cmd = cmd
339
- self._response = response
340
- self._wait = wait
341
- self._check = check
342
- self._description = description
343
- self._device_method = device_method
344
-
345
- tot_n_args, n_args, n_kwargs, keys = parse_format_string(cmd)
346
-
347
- self._tot_n_args = tot_n_args
348
- self._n_args = n_args
349
- self._n_kwargs = n_kwargs
350
- self._keys = keys
351
-
352
- self.__doc__ = self.doc_string()
353
-
354
- def doc_string(self):
355
- msg = f"usage: {self._name}(nargs={self._tot_n_args}, keys={self._keys})\n"
356
- msg += " args & kwargs can be mixed (limited)"
357
-
358
- if self._description is not None:
359
- msg += "\n"
360
- msg += f"{self._description}\n"
361
-
362
- return msg
363
-
364
- def validate_arguments(self, *args, **kwargs):
365
-
366
- # Special case for commands with *args or **kwargs, we don't validate
367
-
368
- if self._cmd in ("*", "**"):
369
- return
370
-
371
- nargs = len(args)
372
- nkwargs = len(kwargs)
373
-
374
- if self._tot_n_args != nargs + nkwargs:
375
- raise InvalidArgumentsError(
376
- f"Expected {self._tot_n_args} arguments for command {self._name}, "
377
- f"got {nargs + nkwargs} arguments."
378
- )
379
-
380
- if self._tot_n_args == 0:
381
- pass
382
- elif nargs and nargs == self._n_args:
383
- pass
384
- elif nkwargs and nkwargs == self._n_kwargs:
385
- pass
386
- elif nargs == self._n_kwargs and nkwargs == 0:
387
- pass
388
- else:
389
- raise InvalidArgumentsError(
390
- f"Expected {self._n_args} positional arguments and {self._n_kwargs} "
391
- f"keyword arguments for command {self._name}, got {nargs} positional "
392
- f"and {nkwargs} keyword arguments instead."
393
- )
394
-
395
- def execute(self, cmd):
396
- return 0
397
-
398
- def get_name(self):
399
- return self._name
400
-
401
- def needs_argument(self, name):
402
- if name in self._keys:
403
- return True
404
- return False
405
-
406
- def __repr__(self):
407
- name = self._name if hasattr(self, "_name") else None
408
- return f"<{self.__class__.__name__}({name})>"
409
-
410
- def get_device_method(self):
411
- return self._device_method
412
-
413
- def get_device_method_name(self):
414
- return self._device_method.__name__
415
-
416
- def get_command_execution(self, *args, **kwargs):
417
-
418
- return CommandExecution(self, *args, **kwargs)
419
-
420
- def __call__(self, *args, **kwargs):
421
- cmd_string = self.get_cmd_string(*args, **kwargs)
422
-
423
- # Now execute the cmd_string
424
-
425
- response = self.execute(cmd_string)
426
-
427
- if self._wait is not None:
428
- self._wait()
429
-
430
- if self._response is not None:
431
- response = self._response()
432
-
433
- if self._check is not None:
434
- response = self._check(response)
435
-
436
- return response
437
-
438
- def get_raw_cmd_string(self):
439
- return self._cmd
440
-
441
- def get_cmd_string(self, *args, **kwargs):
442
- nargs = len(args)
443
- nkwargs = len(kwargs)
444
-
445
- if self._tot_n_args != nargs + nkwargs:
446
- raise CommandError(
447
- f"Expected {self._tot_n_args} arguments for command {self._name}, "
448
- f"got {nargs + nkwargs} arguments."
449
- )
450
-
451
- if self._tot_n_args == 0:
452
- cmd_string = self._cmd or self._name
453
- elif nargs and nargs == self._n_args:
454
- cmd_string = self._create_command_string_from_args(*args)
455
- elif nkwargs and nkwargs == self._n_kwargs:
456
- cmd_string = self._create_command_string_from_kwargs(**kwargs)
457
- elif nargs == self._n_kwargs and nkwargs == 0:
458
- cmd_string = self._create_command_string_from_args_with_kw(*args)
459
- else:
460
- raise CommandError(
461
- f"Expected {self._n_args} positional arguments and {self._n_kwargs} "
462
- f"keyword arguments for command {self._name}, got {nargs} positional "
463
- f"and {nkwargs} keyword arguments instead."
464
- )
465
-
466
- return cmd_string
467
-
468
- def _create_command_string_from_args(self, *args):
469
- full_command = self._cmd.format(*args)
470
- return full_command
471
-
472
- def _create_command_string_from_args_with_kw(self, *args):
473
- full_command = self._cmd.format(**{k: v for k, v in zip(self._keys, args)})
474
- return full_command
475
-
476
- def _create_command_string_from_kwargs(self, **kwargs):
477
- full_command = self._cmd.format(**kwargs)
478
- return full_command
479
-
480
-
481
- class ClientServerCommand(Command):
482
- @dry_run
483
- def client_call(self, other, *args, **kwargs):
484
- """
485
- This method is called at the client side. It is used by the Proxy
486
- as a generic command to send a command execution to the server.
487
-
488
- Args:
489
- other: a sub-class of the Proxy class
490
- args: arguments that will be passed on to this command when executed
491
- kwargs: keyword arguments that will be passed on to this command when executed
492
-
493
- Returns:
494
- the response that is returned by calling the command (at the server side).
495
- """
496
-
497
- try:
498
- self.validate_arguments(*args, **kwargs)
499
- except CommandError as e_ce:
500
- logger.error(str(e_ce))
501
- return None
502
-
503
- ce = CommandExecution(self, *args, **kwargs)
504
- rc = other.send(ce)
505
-
506
- # FIXME:
507
- # not sure if I should do this, the Success/Failure returns from the CS should be
508
- # re-designed. I have put this here for the following reason: when requesting an obsid
509
- # from the CM_CS we don't want a Success message back, but we need the number!
510
-
511
- # if isinstance(rc, Success):
512
- # logger.info(rc)
513
- # rc = rc.return_code
514
-
515
- return rc
516
-
517
- def server_call(self, other, *args, **kwargs):
518
- """
519
- This method is called at the server side. It is used by the CommandProtocol class in the
520
- ``execute`` method.
521
-
522
- Args:
523
- other: a sub-class of the CommandProtocol
524
- args: arguments are passed on to the response method
525
- kwargs: keyword arguments are passed on to the response method
526
-
527
- Returns:
528
- 0 on success and -1 on failure.
529
- """
530
-
531
- if self._response is None:
532
- logger.warning(f"No response defined for {other} command {self.get_name()}")
533
- return -1
534
-
535
- # Note that `_response` is of type 'function' because it was loaded from
536
- # a class object and therefore not bound to a class instance. The reason
537
- # that we could not use a bound method for `_response` is that we pass the
538
- # command objects back and forth from the control server to the proxy and
539
- # the class instances are not known at the other side.
540
-
541
- if self._response.__name__ == "handle_device_method":
542
-
543
- # call the handle_device_method of the Protocol sub-class
544
-
545
- logger.log(0,
546
- f"Executing Command {self._response.__name__}({other!r}, "
547
- f"{self!r}, {args}, {kwargs})")
548
-
549
- rc = self._response(other, self, *args, **kwargs)
550
- else:
551
- logger.log(0,
552
- f"Executing Command {self._response.__name__}({other!r}, {args}, {kwargs})")
553
-
554
- rc = self._response(other, *args, **kwargs)
555
-
556
- logger.log(0, f"Response is {rc}.")
557
-
558
- return 0
559
-
560
-
561
- def get_method(parent_obj, method_name: str):
562
- """
563
- Returns a bound method from a given class instance.
564
-
565
- Args:
566
- parent_obj: the class instance that provides the method
567
- method_name: name of the method that is requested
568
-
569
- Returns:
570
- the method [type: method].
571
-
572
- .. note::
573
- The method returned is an bound class instance method and therefore
574
- this method *does not* expects as its first argument the class
575
- instance, i.e. self, when you call this as a function.
576
-
577
- """
578
- if method_name is None or method_name == "None":
579
- return None
580
-
581
- if hasattr(parent_obj, method_name):
582
- method = getattr(parent_obj, method_name)
583
- if inspect.ismethod(method):
584
- return method
585
- logger.warning(f"{method_name} is not a method, type={type(method)}")
586
- else:
587
- logger.warning(f"{parent_obj!r} has no method called {method_name}")
588
-
589
- return None
590
-
591
-
592
- def get_function(parent_class, method_name: str):
593
- """
594
- Returns a function (unbound method) from a given class.
595
-
596
- Args:
597
- parent_class: the class that provides the method
598
- method_name: name of the method that is requested
599
-
600
- Returns:
601
- the method [type: function].
602
-
603
- .. note::
604
- The function returned is an unbound class instance method and
605
- therefore this function expects as its first argument the class
606
- instance, i.e. self, when you call it as a function.
607
-
608
- """
609
- if method_name is None or method_name == "None":
610
- return None
611
-
612
- if hasattr(parent_class, method_name):
613
- func = getattr(parent_class, method_name)
614
- if inspect.isfunction(func):
615
- return func
616
- logger.warning(f"{method_name} is not a function, type={type(func)}")
617
- else:
618
- logger.warning(
619
- f"{parent_class.__module__}.{parent_class.__name__} has no method called {method_name}"
620
- )
621
-
622
- return None
623
-
624
-
625
- def load_commands(protocol_class, command_settings, command_class, device_class):
626
- """
627
- Loads the command definitions from the given ``command_settings`` and builds an internal
628
- dictionary containing the command names as keys and the corresponding ``Command`` class objects
629
- as values.
630
-
631
- The ``command_settings`` is usually loaded from a YAML configuration file containing the
632
- command definitions for the device.
633
-
634
- Args:
635
- protocol_class: the CommandProtocol or a sub-class
636
- command_settings: a dictionary containing the command definitions for this device
637
- command_class: the type of command to create, a subclass of Command
638
- device_class: the type of the base device class from which the methods are loaded
639
- """
640
- commands = {}
641
-
642
- for name in command_settings:
643
- command_settings_name = command_settings[name]
644
- if "cmd" in command_settings_name:
645
- cmd = command_settings_name["cmd"]
646
- else:
647
- cmd = ""
648
-
649
- if "description" in command_settings_name:
650
- description = command_settings_name["description"]
651
- else:
652
- description = None
653
-
654
- # The response field is the name of a function from the CommandProtocol class
655
- # or a sub-class. This function shall send a response back to the client (Proxy). That's
656
- # why this field is called response.
657
- # By convention we like that this method name would start with `handle_` so that we can
658
- # make a distinction between response commands and normal methods in Protocol. Remember
659
- # that response methods should send a reply back to the client (which will be waiting for
660
- # it..). If no response field is given, then the `handle_device_method` will be called.
661
-
662
- if "response" in command_settings_name:
663
- response_method = get_function(protocol_class, command_settings_name["response"])
664
- else:
665
- response_method = get_function(protocol_class, "handle_device_method")
666
- response_method = None
667
-
668
- # The device_method field is used in the `handle_device_method` to call the method on the
669
- # device class. That is the class that implements the DeviceInterface and is usually called
670
- # a Controller or a Simulator.
671
- #
672
- # If no device_name field is given, the name from the command_settings is used.
673
-
674
- if "device_method" in command_settings_name:
675
- device_method_name = command_settings_name["device_method"]
676
- else:
677
- device_method_name = name
678
-
679
- # check if the device_method exists in the device base class
680
-
681
- if device_method_name == "None":
682
- device_method = None
683
- else:
684
- device_method = get_function(device_class, device_method_name)
685
-
686
- logger.debug(
687
- f"Creating {command_class.__module__}.{command_class.__name__}(name='{name}', "
688
- f"cmd='{cmd}', response={response_method}, device_method={device_method})"
689
- )
690
-
691
- commands[name] = command_class(
692
- name=name,
693
- cmd=cmd,
694
- response=response_method,
695
- description=description,
696
- device_method=device_method,
697
- )
698
-
699
- return commands