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.
- README.md +27 -0
- bump.py +85 -0
- cgse-2025.0.2.dist-info/METADATA +38 -0
- cgse-2025.0.2.dist-info/RECORD +5 -0
- {cgse-2024.7.0.dist-info → cgse-2025.0.2.dist-info}/WHEEL +1 -2
- cgse-2024.7.0.dist-info/COPYING +0 -674
- cgse-2024.7.0.dist-info/COPYING.LESSER +0 -165
- cgse-2024.7.0.dist-info/METADATA +0 -144
- cgse-2024.7.0.dist-info/RECORD +0 -660
- cgse-2024.7.0.dist-info/entry_points.txt +0 -75
- cgse-2024.7.0.dist-info/top_level.txt +0 -2
- egse/__init__.py +0 -12
- egse/__main__.py +0 -32
- egse/aeu/aeu.py +0 -5238
- egse/aeu/aeu_awg.yaml +0 -265
- egse/aeu/aeu_crio.yaml +0 -273
- egse/aeu/aeu_cs.py +0 -627
- egse/aeu/aeu_devif.py +0 -321
- egse/aeu/aeu_main_ui.py +0 -903
- egse/aeu/aeu_metrics.py +0 -131
- egse/aeu/aeu_protocol.py +0 -463
- egse/aeu/aeu_psu.yaml +0 -204
- egse/aeu/aeu_ui.py +0 -873
- egse/aeu/arbdata/FccdRead.arb +0 -2
- egse/aeu/arbdata/FccdRead_min_points.arb +0 -2
- egse/aeu/arbdata/HeaterSync_FccdRead.arb +0 -2
- egse/aeu/arbdata/HeaterSync_ccdRead25.arb +0 -2
- egse/aeu/arbdata/HeaterSync_ccdRead31_25.arb +0 -2
- egse/aeu/arbdata/HeaterSync_ccdRead37_50.arb +0 -2
- egse/aeu/arbdata/HeaterSync_ccdRead43_75.arb +0 -2
- egse/aeu/arbdata/HeaterSync_ccdRead50.arb +0 -2
- egse/aeu/arbdata/Heater_FccdRead_min_points.arb +0 -2
- egse/aeu/arbdata/ccdRead25.arb +0 -2
- egse/aeu/arbdata/ccdRead25_150ms.arb +0 -2
- egse/aeu/arbdata/ccdRead31_25.arb +0 -2
- egse/aeu/arbdata/ccdRead31_25_150ms.arb +0 -2
- egse/aeu/arbdata/ccdRead37_50.arb +0 -2
- egse/aeu/arbdata/ccdRead37_50_150ms.arb +0 -2
- egse/aeu/arbdata/ccdRead43_75.arb +0 -2
- egse/aeu/arbdata/ccdRead43_75_150ms.arb +0 -2
- egse/aeu/arbdata/ccdRead50.arb +0 -2
- egse/aeu/arbdata/ccdRead50_150ms.arb +0 -2
- egse/alert/__init__.py +0 -1049
- egse/alert/alertman.yaml +0 -37
- egse/alert/alertman_cs.py +0 -233
- egse/alert/alertman_ui.py +0 -600
- egse/alert/gsm/beaglebone.py +0 -138
- egse/alert/gsm/beaglebone.yaml +0 -51
- egse/alert/gsm/beaglebone_cs.py +0 -108
- egse/alert/gsm/beaglebone_devif.py +0 -122
- egse/alert/gsm/beaglebone_protocol.py +0 -46
- egse/bits.py +0 -318
- egse/camera.py +0 -44
- egse/collimator/__init__.py +0 -0
- egse/collimator/fcul/__init__.py +0 -0
- egse/collimator/fcul/ogse.py +0 -1077
- egse/collimator/fcul/ogse.yaml +0 -14
- egse/collimator/fcul/ogse_cs.py +0 -154
- egse/collimator/fcul/ogse_devif.py +0 -358
- egse/collimator/fcul/ogse_protocol.py +0 -132
- egse/collimator/fcul/ogse_sim.py +0 -431
- egse/collimator/fcul/ogse_ui.py +0 -1108
- egse/command.py +0 -699
- egse/config.py +0 -410
- egse/confman/__init__.py +0 -1058
- egse/confman/confman.yaml +0 -70
- egse/confman/confman_cs.py +0 -240
- egse/confman/confman_ui.py +0 -381
- egse/confman/setup_ui.py +0 -565
- egse/control.py +0 -632
- egse/coordinates/__init__.py +0 -534
- egse/coordinates/avoidance.py +0 -100
- egse/coordinates/cslmodel.py +0 -127
- egse/coordinates/laser_tracker_to_dict.py +0 -122
- egse/coordinates/point.py +0 -707
- egse/coordinates/pyplot.py +0 -194
- egse/coordinates/referenceFrame.py +0 -1279
- egse/coordinates/refmodel.py +0 -737
- egse/coordinates/rotationMatrix.py +0 -85
- egse/coordinates/transform3d_addon.py +0 -419
- egse/csl/__init__.py +0 -50
- egse/csl/commanding.py +0 -78
- egse/csl/icons/hexapod-connected-selected.svg +0 -30
- egse/csl/icons/hexapod-connected.svg +0 -30
- egse/csl/icons/hexapod-homing-selected.svg +0 -68
- egse/csl/icons/hexapod-homing.svg +0 -68
- egse/csl/icons/hexapod-retract-selected.svg +0 -56
- egse/csl/icons/hexapod-retract.svg +0 -51
- egse/csl/icons/hexapod-zero-selected.svg +0 -56
- egse/csl/icons/hexapod-zero.svg +0 -56
- egse/csl/icons/logo-puna.svg +0 -92
- egse/csl/icons/stop.svg +0 -1
- egse/csl/initialisation.py +0 -102
- egse/csl/mech_pos_settings.yaml +0 -18
- egse/das.py +0 -1240
- egse/das.yaml +0 -7
- egse/data/conf/SETUP_CSL_00000_170620_150000.yaml +0 -5
- egse/data/conf/SETUP_CSL_00001_170620_151010.yaml +0 -69
- egse/data/conf/SETUP_CSL_00002_170620_151020.yaml +0 -69
- egse/data/conf/SETUP_CSL_00003_170620_151030.yaml +0 -69
- egse/data/conf/SETUP_CSL_00004_170620_151040.yaml +0 -69
- egse/data/conf/SETUP_CSL_00005_170620_151050.yaml +0 -69
- egse/data/conf/SETUP_CSL_00006_170620_151060.yaml +0 -69
- egse/data/conf/SETUP_CSL_00007_170620_151070.yaml +0 -69
- egse/data/conf/SETUP_CSL_00008_170620_151080.yaml +0 -75
- egse/data/conf/SETUP_CSL_00010_210308_083016.yaml +0 -138
- egse/data/conf/SETUP_INTA_00000_170620_150000.yaml +0 -4
- egse/data/conf/SETUP_SRON_00000_170620_150000.yaml +0 -4
- egse/decorators.py +0 -514
- egse/device.py +0 -269
- egse/dpu/__init__.py +0 -2698
- egse/dpu/ccd_ui.py +0 -514
- egse/dpu/dpu.py +0 -783
- egse/dpu/dpu.yaml +0 -153
- egse/dpu/dpu_cs.py +0 -272
- egse/dpu/dpu_ui.py +0 -671
- egse/dpu/fitsgen.py +0 -2096
- egse/dpu/fitsgen_ui.py +0 -399
- egse/dpu/hdf5_model.py +0 -332
- egse/dpu/hdf5_ui.py +0 -277
- egse/dpu/hdf5_viewer.py +0 -506
- egse/dpu/hk_ui.py +0 -468
- egse/dpu_commands.py +0 -81
- egse/dsi/__init__.py +0 -33
- egse/dsi/_libesl.py +0 -232
- egse/dsi/constants.py +0 -296
- egse/dsi/esl.py +0 -630
- egse/dsi/rmap.py +0 -444
- egse/dsi/rmapci.py +0 -39
- egse/dsi/spw.py +0 -335
- egse/dsi/spw_state.py +0 -29
- egse/dummy.py +0 -318
- egse/dyndummy.py +0 -179
- egse/env.py +0 -278
- egse/exceptions.py +0 -88
- egse/fdir/__init__.py +0 -26
- egse/fdir/fdir_manager.py +0 -85
- egse/fdir/fdir_manager.yaml +0 -37
- egse/fdir/fdir_manager_controller.py +0 -136
- egse/fdir/fdir_manager_cs.py +0 -164
- egse/fdir/fdir_manager_interface.py +0 -15
- egse/fdir/fdir_remote.py +0 -73
- egse/fdir/fdir_remote.yaml +0 -30
- egse/fdir/fdir_remote_controller.py +0 -30
- egse/fdir/fdir_remote_cs.py +0 -94
- egse/fdir/fdir_remote_interface.py +0 -9
- egse/fdir/fdir_remote_popup.py +0 -26
- egse/fee/__init__.py +0 -106
- egse/fee/f_fee_register.yaml +0 -43
- egse/fee/feesim.py +0 -914
- egse/fee/n_fee_hk.py +0 -768
- egse/fee/nfee.py +0 -188
- egse/filterwheel/__init__.py +0 -4
- egse/filterwheel/eksma/__init__.py +0 -49
- egse/filterwheel/eksma/fw8smc4.py +0 -657
- egse/filterwheel/eksma/fw8smc4.yaml +0 -121
- egse/filterwheel/eksma/fw8smc4_cs.py +0 -144
- egse/filterwheel/eksma/fw8smc4_devif.py +0 -473
- egse/filterwheel/eksma/fw8smc4_protocol.py +0 -82
- egse/filterwheel/eksma/fw8smc4_ui.py +0 -940
- egse/filterwheel/eksma/fw8smc5.py +0 -115
- egse/filterwheel/eksma/fw8smc5.yaml +0 -105
- egse/filterwheel/eksma/fw8smc5_controller.py +0 -307
- egse/filterwheel/eksma/fw8smc5_cs.py +0 -141
- egse/filterwheel/eksma/fw8smc5_interface.py +0 -65
- egse/filterwheel/eksma/fw8smc5_simulator.py +0 -29
- egse/filterwheel/eksma/fw8smc5_ui.py +0 -1065
- egse/filterwheel/eksma/testpythonfw.py +0 -215
- egse/fov/__init__.py +0 -65
- egse/fov/fov_hk.py +0 -710
- egse/fov/fov_ui.py +0 -859
- egse/fov/fov_ui_controller.py +0 -140
- egse/fov/fov_ui_model.py +0 -200
- egse/fov/fov_ui_view.py +0 -345
- egse/gimbal/__init__.py +0 -32
- egse/gimbal/symetrie/__init__.py +0 -26
- egse/gimbal/symetrie/alpha.py +0 -586
- egse/gimbal/symetrie/generic_gimbal_ui.py +0 -1521
- egse/gimbal/symetrie/gimbal.py +0 -877
- egse/gimbal/symetrie/gimbal.yaml +0 -168
- egse/gimbal/symetrie/gimbal_cs.py +0 -183
- egse/gimbal/symetrie/gimbal_protocol.py +0 -138
- egse/gimbal/symetrie/gimbal_ui.py +0 -361
- egse/gimbal/symetrie/pmac.py +0 -1006
- egse/gimbal/symetrie/pmac_regex.py +0 -83
- egse/graph.py +0 -132
- egse/gui/__init__.py +0 -47
- egse/gui/buttons.py +0 -378
- egse/gui/focalplane.py +0 -1285
- egse/gui/formatter.py +0 -10
- egse/gui/led.py +0 -162
- egse/gui/limitswitch.py +0 -143
- egse/gui/mechanisms.py +0 -587
- egse/gui/states.py +0 -148
- egse/gui/stripchart.py +0 -729
- egse/gui/styles.qss +0 -48
- egse/gui/switch.py +0 -112
- egse/h5.py +0 -274
- egse/help/__init__.py +0 -0
- egse/help/help_ui.py +0 -126
- egse/hexapod/__init__.py +0 -32
- egse/hexapod/symetrie/__init__.py +0 -137
- egse/hexapod/symetrie/alpha.py +0 -874
- egse/hexapod/symetrie/dynalpha.py +0 -1387
- egse/hexapod/symetrie/hexapod_ui.py +0 -1516
- egse/hexapod/symetrie/pmac.py +0 -1010
- egse/hexapod/symetrie/pmac_regex.py +0 -83
- egse/hexapod/symetrie/puna.py +0 -1167
- egse/hexapod/symetrie/puna.yaml +0 -193
- egse/hexapod/symetrie/puna_cs.py +0 -195
- egse/hexapod/symetrie/puna_protocol.py +0 -134
- egse/hexapod/symetrie/puna_ui.py +0 -433
- egse/hexapod/symetrie/punaplus.py +0 -107
- egse/hexapod/symetrie/zonda.py +0 -872
- egse/hexapod/symetrie/zonda.yaml +0 -337
- egse/hexapod/symetrie/zonda_cs.py +0 -172
- egse/hexapod/symetrie/zonda_devif.py +0 -414
- egse/hexapod/symetrie/zonda_protocol.py +0 -123
- egse/hexapod/symetrie/zonda_ui.py +0 -449
- egse/hk.py +0 -791
- egse/icons/aeu-cs-start.svg +0 -117
- egse/icons/aeu-cs-stop.svg +0 -118
- egse/icons/aeu-cs.svg +0 -107
- egse/icons/aeu_cs-started.svg +0 -112
- egse/icons/aeu_cs-stopped.svg +0 -112
- egse/icons/aeu_cs.svg +0 -55
- egse/icons/alert.svg +0 -1
- egse/icons/arrow-double-left.png +0 -0
- egse/icons/arrow-double-right.png +0 -0
- egse/icons/arrow-up.svg +0 -11
- egse/icons/backward.svg +0 -1
- egse/icons/busy.svg +0 -1
- egse/icons/cleaning.svg +0 -115
- egse/icons/color-scheme.svg +0 -1
- egse/icons/cs-connected-alert.svg +0 -91
- egse/icons/cs-connected-disabled.svg +0 -43
- egse/icons/cs-connected.svg +0 -89
- egse/icons/cs-not-connected.svg +0 -44
- egse/icons/double-left-arrow.svg +0 -1
- egse/icons/double-right-arrow.svg +0 -1
- egse/icons/erase-disabled.svg +0 -19
- egse/icons/erase.svg +0 -59
- egse/icons/fitsgen-start.svg +0 -47
- egse/icons/fitsgen-stop.svg +0 -48
- egse/icons/fitsgen.svg +0 -1
- egse/icons/forward.svg +0 -1
- egse/icons/fov-hk-start.svg +0 -33
- egse/icons/fov-hk-stop.svg +0 -37
- egse/icons/fov-hk.svg +0 -1
- egse/icons/front-desk.svg +0 -1
- egse/icons/home-actioned.svg +0 -15
- egse/icons/home-disabled.svg +0 -15
- egse/icons/home.svg +0 -13
- egse/icons/info.svg +0 -1
- egse/icons/invalid.png +0 -0
- egse/icons/led-green.svg +0 -20
- egse/icons/led-grey.svg +0 -20
- egse/icons/led-orange.svg +0 -20
- egse/icons/led-red.svg +0 -20
- egse/icons/led-square-green.svg +0 -134
- egse/icons/led-square-grey.svg +0 -134
- egse/icons/led-square-orange.svg +0 -134
- egse/icons/led-square-red.svg +0 -134
- egse/icons/limit-switch-all-green.svg +0 -115
- egse/icons/limit-switch-all-red.svg +0 -117
- egse/icons/limit-switch-el+.svg +0 -116
- egse/icons/limit-switch-el-.svg +0 -117
- egse/icons/location-marker.svg +0 -1
- egse/icons/logo-dpu.svg +0 -48
- egse/icons/logo-gimbal.svg +0 -112
- egse/icons/logo-huber.svg +0 -23
- egse/icons/logo-ogse.svg +0 -31
- egse/icons/logo-puna.svg +0 -92
- egse/icons/logo-tcs.svg +0 -29
- egse/icons/logo-zonda.svg +0 -66
- egse/icons/maximize.svg +0 -1
- egse/icons/meter.svg +0 -1
- egse/icons/more.svg +0 -45
- egse/icons/n-fee-hk-start.svg +0 -24
- egse/icons/n-fee-hk-stop.svg +0 -25
- egse/icons/n-fee-hk.svg +0 -83
- egse/icons/observing-off.svg +0 -46
- egse/icons/observing-on.svg +0 -46
- egse/icons/open-document-hdf5.png +0 -0
- egse/icons/open-document-hdf5.svg +0 -21
- egse/icons/ops-mode.svg +0 -1
- egse/icons/play-green.svg +0 -17
- egse/icons/plugged-disabled.svg +0 -27
- egse/icons/plugged.svg +0 -21
- egse/icons/pm_ui.svg +0 -1
- egse/icons/power-button-green.svg +0 -27
- egse/icons/power-button-red.svg +0 -27
- egse/icons/power-button.svg +0 -27
- egse/icons/radar.svg +0 -1
- egse/icons/radioactive.svg +0 -2
- egse/icons/reload.svg +0 -1
- egse/icons/remote-control-off.svg +0 -28
- egse/icons/remote-control-on.svg +0 -28
- egse/icons/repeat-blue.svg +0 -15
- egse/icons/repeat.svg +0 -1
- egse/icons/settings.svg +0 -1
- egse/icons/shrink.svg +0 -1
- egse/icons/shutter.svg +0 -1
- egse/icons/sign-off.svg +0 -1
- egse/icons/sign-on.svg +0 -1
- egse/icons/sim-mode.svg +0 -1
- egse/icons/small-buttons-go.svg +0 -20
- egse/icons/small-buttons-minus.svg +0 -51
- egse/icons/small-buttons-plus.svg +0 -51
- egse/icons/sponge.svg +0 -220
- egse/icons/start-button-disabled.svg +0 -84
- egse/icons/start-button.svg +0 -50
- egse/icons/stop-button-disabled.svg +0 -84
- egse/icons/stop-button.svg +0 -50
- egse/icons/stop-red.svg +0 -17
- egse/icons/stop.svg +0 -1
- egse/icons/switch-disabled-square.svg +0 -87
- egse/icons/switch-disabled.svg +0 -15
- egse/icons/switch-off-square.svg +0 -87
- egse/icons/switch-off.svg +0 -72
- egse/icons/switch-on-square.svg +0 -87
- egse/icons/switch-on.svg +0 -61
- egse/icons/temperature-control.svg +0 -44
- egse/icons/th_ui_logo.svg +0 -1
- egse/icons/unplugged.svg +0 -23
- egse/icons/unvalid.png +0 -0
- egse/icons/user-interface.svg +0 -1
- egse/icons/vacuum.svg +0 -1
- egse/icons/valid.png +0 -0
- egse/icons/zoom-to-pixel-dark.svg +0 -64
- egse/icons/zoom-to-pixel-white.svg +0 -36
- egse/images/big-rotation-stage.png +0 -0
- egse/images/connected-100.png +0 -0
- egse/images/cross.svg +0 -6
- egse/images/disconnected-100.png +0 -0
- egse/images/gui-icon.png +0 -0
- egse/images/home.svg +0 -6
- egse/images/info-icon.png +0 -0
- egse/images/led-black.svg +0 -89
- egse/images/led-green.svg +0 -85
- egse/images/led-orange.svg +0 -85
- egse/images/led-red.svg +0 -85
- egse/images/load-icon.png +0 -0
- egse/images/load-setup.png +0 -0
- egse/images/load.png +0 -0
- egse/images/pause.png +0 -0
- egse/images/play-button.svg +0 -8
- egse/images/play.png +0 -0
- egse/images/process-status.png +0 -0
- egse/images/restart.png +0 -0
- egse/images/search.png +0 -0
- egse/images/sma.png +0 -0
- egse/images/start.png +0 -0
- egse/images/stop-button.svg +0 -8
- egse/images/stop.png +0 -0
- egse/images/switch-off.svg +0 -48
- egse/images/switch-on.svg +0 -48
- egse/images/undo.png +0 -0
- egse/images/update-button.svg +0 -11
- egse/imageviewer/exposureselection.py +0 -475
- egse/imageviewer/imageviewer.py +0 -198
- egse/imageviewer/matchfocalplane.py +0 -179
- egse/imageviewer/subfieldposition.py +0 -133
- egse/lampcontrol/__init__.py +0 -4
- egse/lampcontrol/beaglebone/beaglebone.py +0 -178
- egse/lampcontrol/beaglebone/beaglebone.yaml +0 -62
- egse/lampcontrol/beaglebone/beaglebone_cs.py +0 -106
- egse/lampcontrol/beaglebone/beaglebone_devif.py +0 -150
- egse/lampcontrol/beaglebone/beaglebone_protocol.py +0 -73
- egse/lampcontrol/energetiq/__init__.py +0 -22
- egse/lampcontrol/energetiq/eq99.yaml +0 -98
- egse/lampcontrol/energetiq/lampEQ99.py +0 -283
- egse/lampcontrol/energetiq/lampEQ99_cs.py +0 -128
- egse/lampcontrol/energetiq/lampEQ99_devif.py +0 -158
- egse/lampcontrol/energetiq/lampEQ99_encode_decode_errors.py +0 -73
- egse/lampcontrol/energetiq/lampEQ99_protocol.py +0 -71
- egse/lampcontrol/energetiq/lampEQ99_ui.py +0 -465
- egse/lib/CentOS-7/EtherSpaceLink_v34_86.dylib +0 -0
- egse/lib/CentOS-8/ESL-RMAP_v34_86.dylib +0 -0
- egse/lib/CentOS-8/EtherSpaceLink_v34_86.dylib +0 -0
- egse/lib/Debian/ESL-RMAP_v34_86.dylib +0 -0
- egse/lib/Debian/EtherSpaceLink_v34_86.dylib +0 -0
- egse/lib/Debian/libetherspacelink_v35_21.dylib +0 -0
- egse/lib/Linux/ESL-RMAP_v34_86.dylib +0 -0
- egse/lib/Linux/EtherSpaceLink_v34_86.dylib +0 -0
- egse/lib/Ubuntu-20/ESL-RMAP_v34_86.dylib +0 -0
- egse/lib/Ubuntu-20/EtherSpaceLink_v34_86.dylib +0 -0
- egse/lib/gssw/python3-gssw_2.2.3+31f63c9f-1_all.deb +0 -0
- egse/lib/ximc/__pycache__/pyximc.cpython-38 2.pyc +0 -0
- egse/lib/ximc/__pycache__/pyximc.cpython-38.pyc +0 -0
- egse/lib/ximc/libximc.framework/Frameworks/libbindy.dylib +0 -0
- egse/lib/ximc/libximc.framework/Frameworks/libxiwrapper.dylib +0 -0
- egse/lib/ximc/libximc.framework/Headers/ximc.h +0 -5510
- egse/lib/ximc/libximc.framework/Resources/Info.plist +0 -42
- egse/lib/ximc/libximc.framework/Resources/keyfile.sqlite +0 -0
- egse/lib/ximc/libximc.framework/libbindy.so +0 -0
- egse/lib/ximc/libximc.framework/libximc +0 -0
- egse/lib/ximc/libximc.framework/libximc.so +0 -0
- egse/lib/ximc/libximc.framework/libximc.so.7.0.0 +0 -0
- egse/lib/ximc/libximc.framework/libxiwrapper.so +0 -0
- egse/lib/ximc/pyximc.py +0 -922
- egse/listener.py +0 -179
- egse/logger/__init__.py +0 -243
- egse/logger/log_cs.py +0 -321
- egse/metrics.py +0 -102
- egse/mixin.py +0 -464
- egse/monitoring.py +0 -95
- egse/ni/alarms/__init__.py +0 -26
- egse/ni/alarms/cdaq9375.py +0 -300
- egse/ni/alarms/cdaq9375.yaml +0 -89
- egse/ni/alarms/cdaq9375_cs.py +0 -130
- egse/ni/alarms/cdaq9375_devif.py +0 -183
- egse/ni/alarms/cdaq9375_protocol.py +0 -48
- egse/obs_inspection.py +0 -165
- egse/observer.py +0 -41
- egse/obsid.py +0 -163
- egse/powermeter/__init__.py +0 -0
- egse/powermeter/ni/__init__.py +0 -38
- egse/powermeter/ni/cdaq9184.py +0 -224
- egse/powermeter/ni/cdaq9184.yaml +0 -73
- egse/powermeter/ni/cdaq9184_cs.py +0 -130
- egse/powermeter/ni/cdaq9184_devif.py +0 -201
- egse/powermeter/ni/cdaq9184_protocol.py +0 -48
- egse/powermeter/ni/cdaq9184_ui.py +0 -544
- egse/powermeter/thorlabs/__init__.py +0 -25
- egse/powermeter/thorlabs/pm100a.py +0 -380
- egse/powermeter/thorlabs/pm100a.yaml +0 -132
- egse/powermeter/thorlabs/pm100a_cs.py +0 -136
- egse/powermeter/thorlabs/pm100a_devif.py +0 -127
- egse/powermeter/thorlabs/pm100a_protocol.py +0 -80
- egse/powermeter/thorlabs/pm100a_ui.py +0 -725
- egse/process.py +0 -451
- egse/procman/__init__.py +0 -834
- egse/procman/cannot_start_process_popup.py +0 -43
- egse/procman/procman.yaml +0 -49
- egse/procman/procman_cs.py +0 -201
- egse/procman/procman_ui.py +0 -2081
- egse/protocol.py +0 -605
- egse/proxy.py +0 -531
- egse/randomwalk.py +0 -140
- egse/reg.py +0 -585
- egse/reload.py +0 -122
- egse/reprocess.py +0 -693
- egse/resource.py +0 -333
- egse/rmap.py +0 -406
- egse/rst.py +0 -135
- egse/search.py +0 -182
- egse/serialdevice.py +0 -190
- egse/services.py +0 -247
- egse/services.yaml +0 -68
- egse/settings.py +0 -379
- egse/settings.yaml +0 -980
- egse/setup.py +0 -1181
- egse/shutter/__init__.py +0 -0
- egse/shutter/thorlabs/__init__.py +0 -19
- egse/shutter/thorlabs/ksc101.py +0 -205
- egse/shutter/thorlabs/ksc101.yaml +0 -105
- egse/shutter/thorlabs/ksc101_cs.py +0 -136
- egse/shutter/thorlabs/ksc101_devif.py +0 -201
- egse/shutter/thorlabs/ksc101_protocol.py +0 -71
- egse/shutter/thorlabs/ksc101_ui.py +0 -548
- egse/shutter/thorlabs/sc10.py +0 -82
- egse/shutter/thorlabs/sc10.yaml +0 -52
- egse/shutter/thorlabs/sc10_controller.py +0 -81
- egse/shutter/thorlabs/sc10_cs.py +0 -108
- egse/shutter/thorlabs/sc10_interface.py +0 -25
- egse/shutter/thorlabs/sc10_simulator.py +0 -30
- egse/simulator.py +0 -41
- egse/slack.py +0 -61
- egse/socketdevice.py +0 -218
- egse/sockets.py +0 -218
- egse/spw.py +0 -1401
- egse/stages/__init__.py +0 -12
- egse/stages/aerotech/ensemble.py +0 -245
- egse/stages/aerotech/ensemble.yaml +0 -205
- egse/stages/aerotech/ensemble_controller.py +0 -275
- egse/stages/aerotech/ensemble_cs.py +0 -110
- egse/stages/aerotech/ensemble_interface.py +0 -132
- egse/stages/aerotech/ensemble_parameters.py +0 -433
- egse/stages/aerotech/ensemble_simulator.py +0 -27
- egse/stages/aerotech/mgse_sim.py +0 -188
- egse/stages/arun/smd3.py +0 -110
- egse/stages/arun/smd3.yaml +0 -68
- egse/stages/arun/smd3_controller.py +0 -470
- egse/stages/arun/smd3_cs.py +0 -112
- egse/stages/arun/smd3_interface.py +0 -53
- egse/stages/arun/smd3_simulator.py +0 -27
- egse/stages/arun/smd3_stop.py +0 -16
- egse/stages/huber/__init__.py +0 -49
- egse/stages/huber/smc9300.py +0 -920
- egse/stages/huber/smc9300.yaml +0 -63
- egse/stages/huber/smc9300_cs.py +0 -178
- egse/stages/huber/smc9300_devif.py +0 -345
- egse/stages/huber/smc9300_protocol.py +0 -113
- egse/stages/huber/smc9300_sim.py +0 -547
- egse/stages/huber/smc9300_ui.py +0 -973
- egse/state.py +0 -173
- egse/statemachine.py +0 -274
- egse/storage/__init__.py +0 -1067
- egse/storage/persistence.py +0 -2295
- egse/storage/storage.yaml +0 -79
- egse/storage/storage_cs.py +0 -231
- egse/styles/dark.qss +0 -343
- egse/styles/default.qss +0 -48
- egse/synoptics/__init__.py +0 -417
- egse/synoptics/syn.yaml +0 -9
- egse/synoptics/syn_cs.py +0 -195
- egse/system.py +0 -1611
- egse/tcs/__init__.py +0 -14
- egse/tcs/tcs.py +0 -879
- egse/tcs/tcs.yaml +0 -14
- egse/tcs/tcs_cs.py +0 -202
- egse/tcs/tcs_devif.py +0 -292
- egse/tcs/tcs_protocol.py +0 -180
- egse/tcs/tcs_sim.py +0 -177
- egse/tcs/tcs_ui.py +0 -543
- egse/tdms.py +0 -171
- egse/tempcontrol/__init__.py +0 -23
- egse/tempcontrol/agilent/agilent34970.py +0 -109
- egse/tempcontrol/agilent/agilent34970.yaml +0 -44
- egse/tempcontrol/agilent/agilent34970_cs.py +0 -114
- egse/tempcontrol/agilent/agilent34970_devif.py +0 -182
- egse/tempcontrol/agilent/agilent34970_protocol.py +0 -96
- egse/tempcontrol/agilent/agilent34972.py +0 -111
- egse/tempcontrol/agilent/agilent34972.yaml +0 -44
- egse/tempcontrol/agilent/agilent34972_cs.py +0 -115
- egse/tempcontrol/agilent/agilent34972_devif.py +0 -189
- egse/tempcontrol/agilent/agilent34972_protocol.py +0 -98
- egse/tempcontrol/beaglebone/beaglebone.py +0 -341
- egse/tempcontrol/beaglebone/beaglebone.yaml +0 -110
- egse/tempcontrol/beaglebone/beaglebone_cs.py +0 -117
- egse/tempcontrol/beaglebone/beaglebone_protocol.py +0 -134
- egse/tempcontrol/beaglebone/beaglebone_ui.py +0 -674
- egse/tempcontrol/digalox/digalox.py +0 -115
- egse/tempcontrol/digalox/digalox.yaml +0 -36
- egse/tempcontrol/digalox/digalox_cs.py +0 -108
- egse/tempcontrol/digalox/digalox_protocol.py +0 -56
- egse/tempcontrol/keithley/__init__.py +0 -33
- egse/tempcontrol/keithley/daq6510.py +0 -662
- egse/tempcontrol/keithley/daq6510.yaml +0 -105
- egse/tempcontrol/keithley/daq6510_cs.py +0 -163
- egse/tempcontrol/keithley/daq6510_devif.py +0 -343
- egse/tempcontrol/keithley/daq6510_protocol.py +0 -79
- egse/tempcontrol/keithley/daq6510_sim.py +0 -186
- egse/tempcontrol/lakeshore/__init__.py +0 -33
- egse/tempcontrol/lakeshore/lsci.py +0 -361
- egse/tempcontrol/lakeshore/lsci.yaml +0 -162
- egse/tempcontrol/lakeshore/lsci_cs.py +0 -174
- egse/tempcontrol/lakeshore/lsci_devif.py +0 -292
- egse/tempcontrol/lakeshore/lsci_protocol.py +0 -76
- egse/tempcontrol/lakeshore/lsci_ui.py +0 -387
- egse/tempcontrol/ni/__init__.py +0 -0
- egse/tempcontrol/spid/spid.py +0 -109
- egse/tempcontrol/spid/spid.yaml +0 -81
- egse/tempcontrol/spid/spid_controller.py +0 -279
- egse/tempcontrol/spid/spid_cs.py +0 -136
- egse/tempcontrol/spid/spid_protocol.py +0 -107
- egse/tempcontrol/spid/spid_ui.py +0 -723
- egse/tempcontrol/srs/__init__.py +0 -22
- egse/tempcontrol/srs/ptc10.py +0 -867
- egse/tempcontrol/srs/ptc10.yaml +0 -227
- egse/tempcontrol/srs/ptc10_cs.py +0 -128
- egse/tempcontrol/srs/ptc10_devif.py +0 -116
- egse/tempcontrol/srs/ptc10_protocol.py +0 -39
- egse/tempcontrol/srs/ptc10_ui.py +0 -906
- egse/ups/apc/apc.py +0 -236
- egse/ups/apc/apc.yaml +0 -45
- egse/ups/apc/apc_cs.py +0 -101
- egse/ups/apc/apc_protocol.py +0 -125
- egse/user.yaml +0 -7
- egse/vacuum/beaglebone/beaglebone.py +0 -149
- egse/vacuum/beaglebone/beaglebone.yaml +0 -44
- egse/vacuum/beaglebone/beaglebone_cs.py +0 -108
- egse/vacuum/beaglebone/beaglebone_devif.py +0 -159
- egse/vacuum/beaglebone/beaglebone_protocol.py +0 -192
- egse/vacuum/beaglebone/beaglebone_ui.py +0 -638
- egse/vacuum/instrutech/igm402.py +0 -91
- egse/vacuum/instrutech/igm402.yaml +0 -90
- egse/vacuum/instrutech/igm402_controller.py +0 -124
- egse/vacuum/instrutech/igm402_cs.py +0 -108
- egse/vacuum/instrutech/igm402_interface.py +0 -49
- egse/vacuum/instrutech/igm402_simulator.py +0 -36
- egse/vacuum/keller/kellerBus.py +0 -256
- egse/vacuum/keller/leo3.py +0 -100
- egse/vacuum/keller/leo3.yaml +0 -38
- egse/vacuum/keller/leo3_controller.py +0 -81
- egse/vacuum/keller/leo3_cs.py +0 -101
- egse/vacuum/keller/leo3_interface.py +0 -33
- egse/vacuum/mks/evision.py +0 -86
- egse/vacuum/mks/evision.yaml +0 -75
- egse/vacuum/mks/evision_cs.py +0 -101
- egse/vacuum/mks/evision_devif.py +0 -313
- egse/vacuum/mks/evision_interface.py +0 -60
- egse/vacuum/mks/evision_simulator.py +0 -24
- egse/vacuum/mks/evision_ui.py +0 -701
- egse/vacuum/pfeiffer/acp40.py +0 -87
- egse/vacuum/pfeiffer/acp40.yaml +0 -60
- egse/vacuum/pfeiffer/acp40_controller.py +0 -117
- egse/vacuum/pfeiffer/acp40_cs.py +0 -109
- egse/vacuum/pfeiffer/acp40_interface.py +0 -40
- egse/vacuum/pfeiffer/acp40_simulator.py +0 -37
- egse/vacuum/pfeiffer/tc400.py +0 -87
- egse/vacuum/pfeiffer/tc400.yaml +0 -83
- egse/vacuum/pfeiffer/tc400_controller.py +0 -136
- egse/vacuum/pfeiffer/tc400_cs.py +0 -109
- egse/vacuum/pfeiffer/tc400_interface.py +0 -70
- egse/vacuum/pfeiffer/tc400_simulator.py +0 -35
- egse/vacuum/pfeiffer/tpg261.py +0 -80
- egse/vacuum/pfeiffer/tpg261.yaml +0 -66
- egse/vacuum/pfeiffer/tpg261_controller.py +0 -150
- egse/vacuum/pfeiffer/tpg261_cs.py +0 -109
- egse/vacuum/pfeiffer/tpg261_interface.py +0 -59
- egse/vacuum/pfeiffer/tpg261_simulator.py +0 -23
- egse/version.py +0 -174
- egse/visitedpositions.py +0 -398
- egse/windowing.py +0 -213
- egse/zmq/__init__.py +0 -28
- egse/zmq/spw.py +0 -160
- egse/zmq_ser.py +0 -41
- scripts/alerts/cold.yaml +0 -278
- scripts/alerts/example_alerts.yaml +0 -54
- scripts/alerts/transition.yaml +0 -14
- scripts/alerts/warm.yaml +0 -49
- scripts/analyse_n_fee_hk_data.py +0 -52
- scripts/check_hdf5_files.py +0 -192
- scripts/check_register_sync.py +0 -47
- scripts/check_tcs_calib_coef.py +0 -90
- scripts/correct_ccd_cold_temperature_cal.py +0 -157
- scripts/create_hdf5_report.py +0 -293
- scripts/csl_model.py +0 -420
- scripts/csl_restore_setup.py +0 -229
- scripts/export-grafana-dashboards.py +0 -49
- scripts/fdir/cs_recovery/fdir_cs_recovery.py +0 -54
- scripts/fdir/fdir_table.yaml +0 -70
- scripts/fdir/fdir_test_recovery.py +0 -10
- scripts/fdir/hw_recovery/fdir_agilent_hw_recovery.py +0 -73
- scripts/fdir/limit_recovery/fdir_agilent_limit.py +0 -61
- scripts/fdir/limit_recovery/fdir_bb_heater_limit.py +0 -59
- scripts/fdir/limit_recovery/fdir_ensemble_limit.py +0 -33
- scripts/fdir/limit_recovery/fdir_pressure_limit_recovery.py +0 -71
- scripts/fix_csv.py +0 -80
- scripts/ias/correct_ccd_temp_cal_elfique.py +0 -43
- scripts/ias/correct_ccd_temp_cal_floreffe.py +0 -43
- scripts/ias/correct_trp_swap_achel.py +0 -199
- scripts/inta/correct_ccd_temp_cal_duvel.py +0 -43
- scripts/inta/correct_ccd_temp_cal_gueuze.py +0 -43
- scripts/n_fee_supply_voltage_calculation.py +0 -92
- scripts/playground.py +0 -30
- scripts/print_hdf5_hk_data.py +0 -68
- scripts/print_register_map.py +0 -43
- scripts/remove_lines_between_matches.py +0 -188
- scripts/sron/commanding/control_heaters.py +0 -44
- scripts/sron/commanding/pumpdown.py +0 -46
- scripts/sron/commanding/set_pid_setpoint.py +0 -19
- scripts/sron/commanding/shutdown_bbb_heaters.py +0 -10
- scripts/sron/commanding/shutdown_pumps.py +0 -33
- scripts/sron/correct_mgse_coordinates_brigand_chimay.py +0 -272
- scripts/sron/correct_trp_swap_brigand.py +0 -204
- scripts/sron/gimbal_conversions.py +0 -75
- scripts/sron/tm_gen/tm_gen_agilent.py +0 -37
- scripts/sron/tm_gen/tm_gen_heaters.py +0 -4
- scripts/sron/tm_gen/tm_gen_spid.py +0 -13
- scripts/update_operational_cgse.py +0 -268
- scripts/update_operational_cgse_old.py +0 -273
egse/fee/n_fee_hk.py
DELETED
|
@@ -1,768 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
import multiprocessing
|
|
3
|
-
import os
|
|
4
|
-
import pickle
|
|
5
|
-
import signal
|
|
6
|
-
from typing import List
|
|
7
|
-
|
|
8
|
-
import click
|
|
9
|
-
import invoke
|
|
10
|
-
import numpy as np
|
|
11
|
-
import rich
|
|
12
|
-
import sys
|
|
13
|
-
import time
|
|
14
|
-
import zmq
|
|
15
|
-
from PyQt5 import QtCore
|
|
16
|
-
from PyQt5.QtCore import QObject
|
|
17
|
-
from PyQt5.QtCore import QRunnable
|
|
18
|
-
from PyQt5.QtCore import QThreadPool
|
|
19
|
-
from PyQt5.QtCore import QTimer
|
|
20
|
-
from PyQt5.QtCore import pyqtSignal
|
|
21
|
-
from PyQt5.QtCore import pyqtSlot
|
|
22
|
-
from PyQt5.QtGui import QCloseEvent
|
|
23
|
-
from PyQt5.QtWidgets import QApplication
|
|
24
|
-
from PyQt5.QtWidgets import QMainWindow
|
|
25
|
-
from PyQt5.QtWidgets import QMessageBox
|
|
26
|
-
from prometheus_client import start_http_server
|
|
27
|
-
|
|
28
|
-
import egse.logger
|
|
29
|
-
from egse.fee.nfee import HousekeepingData
|
|
30
|
-
from egse.hk import convert_hk_names
|
|
31
|
-
from egse.hk import read_conversion_dict
|
|
32
|
-
from egse.metrics import define_metrics
|
|
33
|
-
from egse.settings import Settings
|
|
34
|
-
from egse.setup import NavigableDict, SetupError, load_setup, Setup
|
|
35
|
-
from egse.storage import StorageProxy
|
|
36
|
-
from egse.storage import register_to_storage_manager
|
|
37
|
-
from egse.storage import unregister_from_storage_manager
|
|
38
|
-
from egse.storage.persistence import CSV
|
|
39
|
-
from egse.synoptics import SynopticsManagerProxy
|
|
40
|
-
from egse.system import get_host_ip
|
|
41
|
-
from egse.zmq import MessageIdentifier
|
|
42
|
-
from egse.zmq_ser import bind_address
|
|
43
|
-
from egse.zmq_ser import connect_address
|
|
44
|
-
|
|
45
|
-
LOGGER = logging.getLogger(__name__)
|
|
46
|
-
|
|
47
|
-
DPU_SETTINGS = Settings.load("DPU Processor")
|
|
48
|
-
CTRL_SETTINGS = Settings.load("N-FEE HK Control Server")
|
|
49
|
-
|
|
50
|
-
APP_NAME = "n_fee_hk"
|
|
51
|
-
ORIGIN = "N-FEE-HK"
|
|
52
|
-
TIMEOUT = 1 # timeout for polling the data distribution from the DPU CS
|
|
53
|
-
|
|
54
|
-
HK_TIMESTAMP_NAME = "timestamp"
|
|
55
|
-
|
|
56
|
-
KNOWN_KEYS_NOT_IN_METRICS = ['timestamp', 'timecode_ts']
|
|
57
|
-
|
|
58
|
-
class GeneratorSignals(QObject):
|
|
59
|
-
finished = pyqtSignal()
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
class WorkerSignals(QObject):
|
|
63
|
-
"""
|
|
64
|
-
Defines the signals available from a running worker thread.
|
|
65
|
-
|
|
66
|
-
Supported signals are:
|
|
67
|
-
|
|
68
|
-
finished
|
|
69
|
-
No data
|
|
70
|
-
|
|
71
|
-
error
|
|
72
|
-
'str' Exception string
|
|
73
|
-
|
|
74
|
-
data
|
|
75
|
-
'object' data returned from processing
|
|
76
|
-
|
|
77
|
-
"""
|
|
78
|
-
|
|
79
|
-
finished = pyqtSignal()
|
|
80
|
-
error = pyqtSignal(str)
|
|
81
|
-
data = pyqtSignal(int, object)
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
class DataPuller(QRunnable):
|
|
85
|
-
def __init__(self, hostname: str, port: int, timeout: int = TIMEOUT):
|
|
86
|
-
super().__init__()
|
|
87
|
-
self.signals = WorkerSignals()
|
|
88
|
-
self.hostname = hostname
|
|
89
|
-
self.port = port
|
|
90
|
-
self.quit_request = False
|
|
91
|
-
self.timeout = timeout
|
|
92
|
-
|
|
93
|
-
context = zmq.Context.instance()
|
|
94
|
-
|
|
95
|
-
self.receiver = context.socket(zmq.SUB)
|
|
96
|
-
self.receiver.setsockopt_string(zmq.SUBSCRIBE, "")
|
|
97
|
-
|
|
98
|
-
self.commander = context.socket(zmq.REP)
|
|
99
|
-
|
|
100
|
-
@pyqtSlot()
|
|
101
|
-
def run(self):
|
|
102
|
-
ip_address = get_host_ip()
|
|
103
|
-
receiver_endpoint = f"tcp://{self.hostname}:{self.port}"
|
|
104
|
-
commander_endpoint = bind_address(CTRL_SETTINGS.PROTOCOL, CTRL_SETTINGS.COMMANDING_PORT)
|
|
105
|
-
self.receiver.connect(receiver_endpoint)
|
|
106
|
-
self.commander.bind(commander_endpoint)
|
|
107
|
-
|
|
108
|
-
poller = zmq.Poller()
|
|
109
|
-
poller.register(self.receiver, zmq.POLLIN)
|
|
110
|
-
poller.register(self.commander, zmq.POLLIN)
|
|
111
|
-
|
|
112
|
-
while True:
|
|
113
|
-
|
|
114
|
-
socket_list = dict(poller.poll(timeout=self.timeout))
|
|
115
|
-
|
|
116
|
-
if self.quit_request:
|
|
117
|
-
LOGGER.info('DataPuller quit requested.')
|
|
118
|
-
break
|
|
119
|
-
|
|
120
|
-
if self.receiver in socket_list:
|
|
121
|
-
try:
|
|
122
|
-
sync_id, pickle_string = self.receiver.recv_multipart()
|
|
123
|
-
sync_id = int.from_bytes(sync_id, byteorder='big')
|
|
124
|
-
data = pickle.loads(pickle_string)
|
|
125
|
-
self.signals.data.emit(sync_id, data)
|
|
126
|
-
except Exception as exc:
|
|
127
|
-
LOGGER.error("Exception caught!", exc_info=True)
|
|
128
|
-
self.signals.error.emit(str(exc))
|
|
129
|
-
|
|
130
|
-
if self.commander in socket_list:
|
|
131
|
-
pickle_string = self.commander.recv()
|
|
132
|
-
command = pickle.loads(pickle_string)
|
|
133
|
-
if command.lower() == "quit":
|
|
134
|
-
self.commander.send(pickle.dumps("ACK"))
|
|
135
|
-
LOGGER.info('DataPuller quit requested...')
|
|
136
|
-
break
|
|
137
|
-
if command.lower() == "status":
|
|
138
|
-
LOGGER.info('DataPuller status requested...')
|
|
139
|
-
response = dict(
|
|
140
|
-
status="ACK",
|
|
141
|
-
host=ip_address,
|
|
142
|
-
listening_port=self.port,
|
|
143
|
-
command_port=CTRL_SETTINGS.COMMANDING_PORT,
|
|
144
|
-
)
|
|
145
|
-
self.commander.send(pickle.dumps(response))
|
|
146
|
-
|
|
147
|
-
LOGGER.info("Cleaning up ZeroMQ sockets...")
|
|
148
|
-
|
|
149
|
-
poller.unregister(self.commander)
|
|
150
|
-
poller.unregister(self.receiver)
|
|
151
|
-
|
|
152
|
-
self.receiver.disconnect(f"tcp://{self.hostname}:{self.port}")
|
|
153
|
-
self.receiver.close(linger=0)
|
|
154
|
-
self.commander.close(linger=0)
|
|
155
|
-
|
|
156
|
-
self.signals.finished.emit()
|
|
157
|
-
|
|
158
|
-
def quit(self):
|
|
159
|
-
self.quit_request = True
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
class DataCollector:
|
|
163
|
-
def __init__(self, keys: List):
|
|
164
|
-
self._keys = keys
|
|
165
|
-
|
|
166
|
-
# initialise the data dictionary
|
|
167
|
-
|
|
168
|
-
self._data = {k: None for k in self._keys}
|
|
169
|
-
|
|
170
|
-
def __getitem__(self, item):
|
|
171
|
-
return self._data[item]
|
|
172
|
-
|
|
173
|
-
def __contains__(self, item):
|
|
174
|
-
return item in self._data
|
|
175
|
-
|
|
176
|
-
def get(self, item):
|
|
177
|
-
try:
|
|
178
|
-
return self._data[item]
|
|
179
|
-
except KeyError:
|
|
180
|
-
return None
|
|
181
|
-
|
|
182
|
-
def keys(self):
|
|
183
|
-
return self._keys
|
|
184
|
-
|
|
185
|
-
def values(self):
|
|
186
|
-
return self._data.values()
|
|
187
|
-
|
|
188
|
-
def update(self, data: dict):
|
|
189
|
-
if x := set(data) - set(self._data):
|
|
190
|
-
LOGGER.warning(
|
|
191
|
-
f"New housekeeping found which was not previously in the N-FEE HK packet: {x}"
|
|
192
|
-
)
|
|
193
|
-
self._data.update(data)
|
|
194
|
-
|
|
195
|
-
def clear(self):
|
|
196
|
-
self._data = {k: None for k in self._keys}
|
|
197
|
-
|
|
198
|
-
def as_dict(self):
|
|
199
|
-
return self._data
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
class MainWindow(QMainWindow):
|
|
203
|
-
|
|
204
|
-
def __init__(self):
|
|
205
|
-
super().__init__()
|
|
206
|
-
|
|
207
|
-
self.hk_generator = HousekeepingGenerator()
|
|
208
|
-
|
|
209
|
-
column_names = self.hk_generator.hk_names_mapping.values()
|
|
210
|
-
register_to_storage_manager(ORIGIN, CSV, prep=dict(mode='a', column_names=list(column_names)))
|
|
211
|
-
|
|
212
|
-
self.hk_generator.signals.finished.connect(self.close)
|
|
213
|
-
self.hk_generator.run()
|
|
214
|
-
|
|
215
|
-
LOGGER.info("Initialised MainWindow")
|
|
216
|
-
|
|
217
|
-
def closeEvent(self, event: QCloseEvent) -> None:
|
|
218
|
-
LOGGER.info(f"closeEvent called...{event=}")
|
|
219
|
-
|
|
220
|
-
if self.hk_generator.data_puller:
|
|
221
|
-
self.hk_generator.data_puller.quit()
|
|
222
|
-
else:
|
|
223
|
-
LOGGER.info("Data Puller was already terminated.")
|
|
224
|
-
|
|
225
|
-
time.sleep(TIMEOUT)
|
|
226
|
-
unregister_from_storage_manager(ORIGIN)
|
|
227
|
-
LOGGER.info("AFTER UNREGISTER STORAGE")
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
class HousekeepingGenerator:
|
|
231
|
-
|
|
232
|
-
def __init__(self):
|
|
233
|
-
|
|
234
|
-
self.signals = GeneratorSignals()
|
|
235
|
-
self.setup = load_setup()
|
|
236
|
-
|
|
237
|
-
# Convert with info from HK info table
|
|
238
|
-
# Append the new names
|
|
239
|
-
|
|
240
|
-
self.data_puller = None
|
|
241
|
-
self.threadpool = QThreadPool()
|
|
242
|
-
|
|
243
|
-
# The hk_names_mapping is a dictionary that maps the original device telemetry parameter
|
|
244
|
-
# names to the correct device names as defined in the CGSE. The keys in the mapping are
|
|
245
|
-
# the original device name, the values are the CGSE corrected names
|
|
246
|
-
|
|
247
|
-
self.hk_names_mapping = read_conversion_dict(ORIGIN, use_site=False, setup=self.setup)
|
|
248
|
-
|
|
249
|
-
# Add the timestamp and timecode_ts to the names mapping
|
|
250
|
-
self.hk_names_mapping.update({'timestamp': 'timestamp', 'timecode_ts': 'timecode_ts'})
|
|
251
|
-
|
|
252
|
-
hk_header = self.hk_names_mapping.keys()
|
|
253
|
-
|
|
254
|
-
# Read from the setup: sensor calibration data (as a NavigableDict)
|
|
255
|
-
|
|
256
|
-
self.supply_voltage_calibration = self.setup.camera.fee.calibration.supply_voltages
|
|
257
|
-
self.temperature_calibration = self.setup.camera.fee.calibration.temperatures
|
|
258
|
-
|
|
259
|
-
self.current_data = DataCollector([HK_TIMESTAMP_NAME, *hk_header])
|
|
260
|
-
|
|
261
|
-
self.hk_metrics = define_metrics(ORIGIN, dashboard='*', setup=self.setup)
|
|
262
|
-
|
|
263
|
-
def run(self):
|
|
264
|
-
self.start_pulling_data()
|
|
265
|
-
|
|
266
|
-
def start_pulling_data(self):
|
|
267
|
-
self.data_puller = worker = DataPuller(
|
|
268
|
-
DPU_SETTINGS.HOSTNAME, DPU_SETTINGS.DATA_DISTRIBUTION_PORT
|
|
269
|
-
)
|
|
270
|
-
worker.signals.data.connect(self.worker_output)
|
|
271
|
-
worker.signals.finished.connect(self.worker_complete)
|
|
272
|
-
worker.signals.error.connect(self.worker_error)
|
|
273
|
-
self.threadpool.start(worker)
|
|
274
|
-
|
|
275
|
-
def update_metrics(self):
|
|
276
|
-
|
|
277
|
-
for orig_name, metric_name in self.hk_names_mapping.items():
|
|
278
|
-
# LOGGER.info(f"{orig_name=}, {metric_name=}")
|
|
279
|
-
try:
|
|
280
|
-
value = self.current_data.get(orig_name)
|
|
281
|
-
if value is not None:
|
|
282
|
-
self.hk_metrics[metric_name].set(value)
|
|
283
|
-
else:
|
|
284
|
-
self.hk_metrics[metric_name].set(float('nan'))
|
|
285
|
-
# LOGGER.debug(f"No current data available for {metric_name}.")
|
|
286
|
-
except KeyError as exc:
|
|
287
|
-
if metric_name not in KNOWN_KEYS_NOT_IN_METRICS:
|
|
288
|
-
LOGGER.warning(f"Unknown metric name: {orig_name=}, {metric_name=}")
|
|
289
|
-
|
|
290
|
-
def send_hk_data_to_storage(self):
|
|
291
|
-
|
|
292
|
-
# All saved data needs at least a timestamp
|
|
293
|
-
|
|
294
|
-
if 'timestamp' not in self.current_data or self.current_data['timestamp'] is None:
|
|
295
|
-
return
|
|
296
|
-
|
|
297
|
-
# Translate the HK names (i.e. start using the correct prefix)
|
|
298
|
-
# and append them to the rest of the HK
|
|
299
|
-
|
|
300
|
-
# CHANGED: Remember self.hk_names_mapping shall contain both timestamp and timecode_ts.
|
|
301
|
-
# Be careful here, because the convert_hk_names() returns a new dict while the
|
|
302
|
-
# self.current_data is a DataCollector. So, don't catch the returned dict in the
|
|
303
|
-
# self.current_data.
|
|
304
|
-
current_data = convert_hk_names(self.current_data.as_dict(), self.hk_names_mapping)
|
|
305
|
-
|
|
306
|
-
# Calibration (supply voltages + temperatures)
|
|
307
|
-
|
|
308
|
-
calibrated_supply_voltages = get_calibrated_supply_voltages(current_data, self.supply_voltage_calibration)
|
|
309
|
-
current_data.update(calibrated_supply_voltages)
|
|
310
|
-
|
|
311
|
-
calibrated_temperatures = get_calibrated_temperatures(current_data, self.temperature_calibration, self.setup)
|
|
312
|
-
current_data.update(calibrated_temperatures)
|
|
313
|
-
|
|
314
|
-
with StorageProxy() as storage:
|
|
315
|
-
|
|
316
|
-
rc = storage.save(
|
|
317
|
-
{
|
|
318
|
-
"origin": ORIGIN,
|
|
319
|
-
"data": current_data
|
|
320
|
-
}
|
|
321
|
-
)
|
|
322
|
-
if rc and not rc.successful:
|
|
323
|
-
LOGGER.warning(f"Couldn't save HK data to the Storage manager: {rc}")
|
|
324
|
-
|
|
325
|
-
# Store the calibrated temperatures as synoptics
|
|
326
|
-
# (only when there's actually something there in the N-FEE HK)
|
|
327
|
-
|
|
328
|
-
if len(calibrated_temperatures) > 0:
|
|
329
|
-
|
|
330
|
-
calibrated_temperatures["timestamp"] = current_data[HK_TIMESTAMP_NAME]
|
|
331
|
-
|
|
332
|
-
with SynopticsManagerProxy() as synoptics:
|
|
333
|
-
synoptics.store_common_synoptics(calibrated_temperatures)
|
|
334
|
-
|
|
335
|
-
def worker_output(self, sync_id, data):
|
|
336
|
-
|
|
337
|
-
if sync_id == MessageIdentifier.SYNC_TIMECODE:
|
|
338
|
-
self.current_data.clear()
|
|
339
|
-
|
|
340
|
-
timecode, timestamp = data
|
|
341
|
-
LOGGER.debug(f"Timecode: {timestamp=}, {timecode=}")
|
|
342
|
-
|
|
343
|
-
self.current_data.update({"timecode": timecode, "timecode_ts": timestamp})
|
|
344
|
-
|
|
345
|
-
if sync_id == MessageIdentifier.SYNC_HK_PACKET:
|
|
346
|
-
hk_packet, timestamp = data
|
|
347
|
-
LOGGER.debug(f"HK Packet: {timestamp=}, {hk_packet.type=!s}")
|
|
348
|
-
|
|
349
|
-
hk_data = HousekeepingData(hk_packet.data)
|
|
350
|
-
self._store_hk_data(hk_data, timestamp)
|
|
351
|
-
|
|
352
|
-
if sync_id == MessageIdentifier.SYNC_HK_DATA:
|
|
353
|
-
hk_data, timestamp = data
|
|
354
|
-
LOGGER.debug(f"HK Data: {timestamp=}")
|
|
355
|
-
|
|
356
|
-
self._store_hk_data(hk_data, timestamp)
|
|
357
|
-
|
|
358
|
-
if sync_id == MessageIdentifier.NUM_CYCLES:
|
|
359
|
-
LOGGER.debug(f"num_cycles: {max(0, data)}")
|
|
360
|
-
self.current_data.update({'num_cycles': max(0, data)})
|
|
361
|
-
|
|
362
|
-
def _store_hk_data(self, hk_data: HousekeepingData, timestamp: str):
|
|
363
|
-
self.current_data.update({HK_TIMESTAMP_NAME: timestamp})
|
|
364
|
-
|
|
365
|
-
for par_name in hk_data:
|
|
366
|
-
self.current_data.update({par_name: hk_data[par_name]})
|
|
367
|
-
|
|
368
|
-
self.send_hk_data_to_storage()
|
|
369
|
-
self.update_metrics()
|
|
370
|
-
|
|
371
|
-
def worker_complete(self):
|
|
372
|
-
LOGGER.info("THREAD COMPLETE!")
|
|
373
|
-
LOGGER.info(f"Number of threads running: {self.threadpool.activeThreadCount()}")
|
|
374
|
-
self.data_puller = None
|
|
375
|
-
self.signals.finished.emit()
|
|
376
|
-
|
|
377
|
-
def worker_error(self, msg):
|
|
378
|
-
LOGGER.warning(f"ERROR: {msg}")
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
def get_calibrated_supply_voltages(counts, supply_voltage_calibration):
|
|
382
|
-
""" Calibrate the N-FEE supply voltages.
|
|
383
|
-
|
|
384
|
-
The difference in naming between calibrated and uncalibrated housekeeping is the suffix "_RAW".
|
|
385
|
-
|
|
386
|
-
The calibration consist of applying a linear function to the raw values.
|
|
387
|
-
|
|
388
|
-
Args:
|
|
389
|
-
- counts: Uncalibrated, raw data for all HK.
|
|
390
|
-
- supply_voltage_calibration: Supply voltage calibration s read from the YAML file that was specified in the
|
|
391
|
-
setup
|
|
392
|
-
|
|
393
|
-
Returns: Dictionary with calibrated supply voltages [V].
|
|
394
|
-
"""
|
|
395
|
-
|
|
396
|
-
supply_voltages = {}
|
|
397
|
-
|
|
398
|
-
for cal_name in supply_voltage_calibration:
|
|
399
|
-
|
|
400
|
-
raw_name = f"{cal_name}_RAW"
|
|
401
|
-
cal = supply_voltage_calibration[cal_name]
|
|
402
|
-
|
|
403
|
-
if counts[raw_name] is not None:
|
|
404
|
-
|
|
405
|
-
supply_voltage = cal.gain * counts[raw_name] + cal.offset
|
|
406
|
-
|
|
407
|
-
supply_voltages[cal_name] = supply_voltage
|
|
408
|
-
|
|
409
|
-
return supply_voltages
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
def get_calibrated_temperatures(counts, sensor_calibration, setup):
|
|
413
|
-
""" Calibrate the N-FEE temperatures.
|
|
414
|
-
|
|
415
|
-
The calibrated temperatures come from:
|
|
416
|
-
|
|
417
|
-
- TOU TRP PT1000 sensors
|
|
418
|
-
- CCD PT100/PT1000 sensors
|
|
419
|
-
- PT1000 board sensors
|
|
420
|
-
- ISL71590 board sensors
|
|
421
|
-
|
|
422
|
-
The difference in naming between calibrated and uncalibrated temperatures is the suffix "_RAW".
|
|
423
|
-
|
|
424
|
-
Args:
|
|
425
|
-
- counts: Uncalibrated, raw data for all HK.
|
|
426
|
-
- sensor_calibration: N-FEE temperature calibration as read from the YAML file that was specified in the setup
|
|
427
|
-
- setup: Setup
|
|
428
|
-
|
|
429
|
-
Returns: Dictionary with calibrated temperatures [°C].
|
|
430
|
-
"""
|
|
431
|
-
|
|
432
|
-
temperatures = {}
|
|
433
|
-
|
|
434
|
-
for sensor_type in sensor_calibration:
|
|
435
|
-
temperatures.update(get_calibrated_temperatures_for_type(counts, sensor_calibration, sensor_type, setup))
|
|
436
|
-
|
|
437
|
-
return temperatures
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
def get_calibrated_temperatures_for_type(counts, sensor_calibration, sensor_type, setup) -> dict:
|
|
441
|
-
""" Calibrate the N-FEE temperatures for the given sensor type.
|
|
442
|
-
|
|
443
|
-
Args:
|
|
444
|
-
- counts: Uncalibrated, raw data [ADU]
|
|
445
|
-
- sensor_calibration: Calibration information for the given sensor type
|
|
446
|
-
- sensor_calibration: N-FEE sensor calibration as read from the YAML file that was specified in the setup
|
|
447
|
-
- setup: Setup
|
|
448
|
-
|
|
449
|
-
Returns: Dictionary with calibrated temperatures [°C] for the given sensor type.
|
|
450
|
-
"""
|
|
451
|
-
|
|
452
|
-
cal = sensor_calibration[sensor_type]
|
|
453
|
-
|
|
454
|
-
temperatures = {}
|
|
455
|
-
|
|
456
|
-
for cal_name in cal.sensor_names:
|
|
457
|
-
|
|
458
|
-
if cal_name.endswith("_AMB"):
|
|
459
|
-
raw_name = f"{cal_name[:-4]}_RAW"
|
|
460
|
-
else:
|
|
461
|
-
raw_name = f"{cal_name}_RAW"
|
|
462
|
-
|
|
463
|
-
if counts[raw_name] is not None:
|
|
464
|
-
|
|
465
|
-
sensor_info = cal[cal_name] if cal_name in cal else cal
|
|
466
|
-
|
|
467
|
-
try:
|
|
468
|
-
temperature = counts_to_temperature(cal_name, counts[raw_name], sensor_info, setup)
|
|
469
|
-
|
|
470
|
-
except AttributeError as exc:
|
|
471
|
-
raise SetupError(
|
|
472
|
-
"Not all TOU TRP PT1000 calibration information is available in the setup under "
|
|
473
|
-
"setup.camera.fee.calibration."
|
|
474
|
-
) from exc
|
|
475
|
-
|
|
476
|
-
temperatures[cal_name] = temperature
|
|
477
|
-
|
|
478
|
-
return temperatures
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
def counts_to_temperature(sensor_name: str, counts: float, sensor_info: NavigableDict, setup):
|
|
482
|
-
""" Convert the given counts for the given sensor to temperature.
|
|
483
|
-
|
|
484
|
-
Args:
|
|
485
|
-
- sensor_name: Sensor name
|
|
486
|
-
- counts: Uncalibrated, raw data [ADU]
|
|
487
|
-
- sensor_info: Calibration information for the given sensor (type)
|
|
488
|
-
- setup: Setup
|
|
489
|
-
|
|
490
|
-
Returns: Calibrated temperature [°C] for the given sensor
|
|
491
|
-
"""
|
|
492
|
-
|
|
493
|
-
# Conversion: temperature = counts * gain + offset
|
|
494
|
-
|
|
495
|
-
if "counts_to_temperature_gain" in sensor_info and "counts_to_temperature_offset" in sensor_info:
|
|
496
|
-
return counts * sensor_info.counts_to_temperature_gain + sensor_info.counts_to_temperature_offset
|
|
497
|
-
|
|
498
|
-
# Conversion: counts -> resistance -> temperature
|
|
499
|
-
|
|
500
|
-
resistance = counts_to_resistance(sensor_name, counts, sensor_info)
|
|
501
|
-
return resistance_to_temperature(sensor_name, resistance, sensor_info, setup)
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
def counts_to_resistance(sensor_name: str, counts: float, sensor_info: NavigableDict):
|
|
505
|
-
""" Convert the given counts for the given sensor to resistance.
|
|
506
|
-
|
|
507
|
-
Args:
|
|
508
|
-
- sensor_name: Sensor name
|
|
509
|
-
- counts: Uncalibrated, raw data [ADU]
|
|
510
|
-
- sensor_info: Calibration information for the given sensor (type)
|
|
511
|
-
|
|
512
|
-
Returns: Resistance [Ohm] for the given sensor.
|
|
513
|
-
"""
|
|
514
|
-
|
|
515
|
-
# Offset (if any)
|
|
516
|
-
|
|
517
|
-
counts_to_resistance_offset = sensor_info.counts_to_resistance_offset \
|
|
518
|
-
if "counts_to_resistance_offset" in sensor_info \
|
|
519
|
-
else 0
|
|
520
|
-
|
|
521
|
-
# Conversion: counts -> voltage -> resistance
|
|
522
|
-
|
|
523
|
-
if "counts_to_voltage_gain" in sensor_info and "voltage_to_resistance_gain" in sensor_info:
|
|
524
|
-
return counts * sensor_info.counts_to_voltage_gain * sensor_info.voltage_to_resistance_gain \
|
|
525
|
-
+ counts_to_resistance_offset
|
|
526
|
-
|
|
527
|
-
# Conversion: counts -> resistance
|
|
528
|
-
|
|
529
|
-
elif "counts_to_resistance_gain" in sensor_info:
|
|
530
|
-
return counts * sensor_info.counts_to_resistance_gain \
|
|
531
|
-
+ counts_to_resistance_offset
|
|
532
|
-
|
|
533
|
-
raise SetupError(f"Setup does not contain info for conversion from counts to resistance for {sensor_name}")
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
def resistance_to_temperature(sensor_name: str, resistance: float, sensor_info: NavigableDict, setup):
|
|
537
|
-
""" Convert the given resistance for the given sensor to counts.
|
|
538
|
-
|
|
539
|
-
Args:
|
|
540
|
-
- sensor_name: Sensor name
|
|
541
|
-
- resistance: Resistance [Ohm]
|
|
542
|
-
- sensor_info: Calibration information for the given sensor (type)
|
|
543
|
-
- setup: Setup
|
|
544
|
-
|
|
545
|
-
Returns: Temperature [°C] for the given sensor.
|
|
546
|
-
"""
|
|
547
|
-
|
|
548
|
-
resistance_to_temperature_info = sensor_info.resistance_to_temperature
|
|
549
|
-
|
|
550
|
-
# Series resistance (if any)
|
|
551
|
-
|
|
552
|
-
if "series_resistance" in resistance_to_temperature_info:
|
|
553
|
-
|
|
554
|
-
series_resistance = resistance_to_temperature_info.series_resistance
|
|
555
|
-
if sensor_name in resistance_to_temperature_info:
|
|
556
|
-
series_resistance = series_resistance[sensor_name]
|
|
557
|
-
resistance -= series_resistance
|
|
558
|
-
|
|
559
|
-
method: str = resistance_to_temperature_info.method
|
|
560
|
-
|
|
561
|
-
if "divide_resistance_by" in resistance_to_temperature_info:
|
|
562
|
-
resistance /= resistance_to_temperature_info.divide_resistance_by
|
|
563
|
-
|
|
564
|
-
# Polynomial
|
|
565
|
-
|
|
566
|
-
if method == "polynomial":
|
|
567
|
-
|
|
568
|
-
# Coefficients given for conversion temperature -> resistance
|
|
569
|
-
|
|
570
|
-
if "temperature_to_resistance_coefficients" in resistance_to_temperature_info:
|
|
571
|
-
return solve_temperature(resistance_to_temperature_info.temperature_to_resistance_coefficients, resistance)
|
|
572
|
-
|
|
573
|
-
# Coefficients given for conversion resistance -> temperature
|
|
574
|
-
|
|
575
|
-
if "resistance_to_temperature_coefficients" in resistance_to_temperature_info:
|
|
576
|
-
return np.polyval(resistance_to_temperature_info.resistance_to_temperature_coefficients, resistance)
|
|
577
|
-
|
|
578
|
-
if method != "callendar_van_dusen":
|
|
579
|
-
raise SetupError(f"Setup does not contain info for conversion from resistance to temperature for {sensor_name}")
|
|
580
|
-
|
|
581
|
-
standard = resistance_to_temperature_info.standard
|
|
582
|
-
ref_resistance = resistance_to_temperature_info.ref_resistance
|
|
583
|
-
|
|
584
|
-
return callendar_van_dusen(resistance, ref_resistance, standard, setup)
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
def solve_temperature(temperature_to_resistance_coefficients, resistance):
|
|
588
|
-
""" Solve the temperature from the temperature -> resistance polynomial.
|
|
589
|
-
|
|
590
|
-
For the given temperature -> resistance polynomial and the given resistance, we determine what the corresponding
|
|
591
|
-
temperature is by:
|
|
592
|
-
- Finding the roots of
|
|
593
|
-
polynomial(temperature) = resistance
|
|
594
|
-
- Discarding the roots with an imaginary component
|
|
595
|
-
- Selecting the remaining root in the relevant temperature regime (here: [-200°C, 200°C])
|
|
596
|
-
"""
|
|
597
|
-
|
|
598
|
-
temperature_to_resistance_poly = np.poly1d(temperature_to_resistance_coefficients)
|
|
599
|
-
temperatures = (temperature_to_resistance_poly - resistance).roots
|
|
600
|
-
|
|
601
|
-
for temperature in temperatures:
|
|
602
|
-
if temperature.imag == 0 and -200 <= temperature <= 200:
|
|
603
|
-
return temperature.real
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
def callendar_van_dusen(resistance, ref_resistance, standard, setup):
|
|
607
|
-
""" Solve the Callendar - van Dusen equation for temperature.
|
|
608
|
-
|
|
609
|
-
Args:
|
|
610
|
-
- resistance: Resistance [Ohm] for which to calculate the temperature
|
|
611
|
-
- ref_resistance: Resistance [Ohm] for a temperature of 0°C
|
|
612
|
-
- standard: Sensor standard
|
|
613
|
-
- setup: Setup.
|
|
614
|
-
|
|
615
|
-
Return: Temperature [°C] corresponding to the given resistance.
|
|
616
|
-
"""
|
|
617
|
-
|
|
618
|
-
# Resistances higher than the reference resistance correspond to
|
|
619
|
-
|
|
620
|
-
coefficients = setup.sensor_calibration.callendar_van_dusen[standard]
|
|
621
|
-
|
|
622
|
-
# Positive temperatures
|
|
623
|
-
|
|
624
|
-
if resistance >= ref_resistance:
|
|
625
|
-
resistance_to_temperature_coefficients = [ref_resistance * coefficients.C,
|
|
626
|
-
-ref_resistance * 100 * coefficients.C,
|
|
627
|
-
ref_resistance * coefficients.B,
|
|
628
|
-
ref_resistance * coefficients.A, ref_resistance * 1]
|
|
629
|
-
|
|
630
|
-
# Negative temperatures
|
|
631
|
-
|
|
632
|
-
else:
|
|
633
|
-
resistance_to_temperature_coefficients = [ref_resistance * coefficients.B,
|
|
634
|
-
ref_resistance * coefficients.A,
|
|
635
|
-
ref_resistance * 1]
|
|
636
|
-
|
|
637
|
-
return solve_temperature(resistance_to_temperature_coefficients, resistance)
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
@click.group()
|
|
642
|
-
def cli():
|
|
643
|
-
pass
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
@cli.command()
|
|
647
|
-
@click.option("--gui/--no-gui", default=False,
|
|
648
|
-
help="start the N-FEE HK Process with graphics support [default=--no-gui].")
|
|
649
|
-
def start_bg(gui):
|
|
650
|
-
"""Start the N-FEE HK Processor in the background."""
|
|
651
|
-
|
|
652
|
-
options = "--gui" if gui else "--no-gui"
|
|
653
|
-
invoke.run(f"n_fee_hk start {options}", disown=True)
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
@cli.command()
|
|
657
|
-
@click.option("--gui/--no-gui", default=False,
|
|
658
|
-
help="start the N-FEE HK Process with graphics support [default=--no-gui].")
|
|
659
|
-
def start(gui):
|
|
660
|
-
"""Start the N-FEE HK Processor."""
|
|
661
|
-
|
|
662
|
-
multiprocessing.current_process().name = "n_fee_hk"
|
|
663
|
-
|
|
664
|
-
start_http_server(CTRL_SETTINGS.METRICS_PORT)
|
|
665
|
-
|
|
666
|
-
args = sys.argv
|
|
667
|
-
if not gui:
|
|
668
|
-
args.extend(["-platform", "offscreen"])
|
|
669
|
-
|
|
670
|
-
LOGGER.info(f"{args=}")
|
|
671
|
-
|
|
672
|
-
app = QApplication(args)
|
|
673
|
-
|
|
674
|
-
os.environ["QT_ENABLE_HIGHDPI_SCALING"] = "1"
|
|
675
|
-
QApplication.setHighDpiScaleFactorRoundingPolicy(
|
|
676
|
-
QtCore.Qt.HighDpiScaleFactorRoundingPolicy.PassThrough
|
|
677
|
-
)
|
|
678
|
-
window = MainWindow()
|
|
679
|
-
window.show()
|
|
680
|
-
|
|
681
|
-
def sigint_handler(*args):
|
|
682
|
-
"""Handler for the SIGINT signal."""
|
|
683
|
-
LOGGER.info('Handling signal SIGINT...')
|
|
684
|
-
if QApplication.platformName() == "offscreen":
|
|
685
|
-
window.close()
|
|
686
|
-
QApplication.quit()
|
|
687
|
-
elif QMessageBox.question(
|
|
688
|
-
None, '', "Are you sure you want to quit?",
|
|
689
|
-
QMessageBox.Yes | QMessageBox.No,
|
|
690
|
-
QMessageBox.No
|
|
691
|
-
) == QMessageBox.Yes:
|
|
692
|
-
window.close()
|
|
693
|
-
QApplication.quit()
|
|
694
|
-
|
|
695
|
-
signal.signal(signal.SIGINT, sigint_handler)
|
|
696
|
-
|
|
697
|
-
# The following code is solely here to have the app react faster to CTRL-C in the terminal
|
|
698
|
-
|
|
699
|
-
timer = QTimer()
|
|
700
|
-
timer.start(500) # interval in msec
|
|
701
|
-
timer.timeout.connect(lambda: None) # Let the interpreter run each 500 ms.
|
|
702
|
-
|
|
703
|
-
try:
|
|
704
|
-
rc = app.exec_()
|
|
705
|
-
except KeyboardInterrupt:
|
|
706
|
-
LOGGER.info(f"Keyboard interrupt accepted, terminating application {APP_NAME}")
|
|
707
|
-
|
|
708
|
-
LOGGER.info("Destroying ZeroMQ context...")
|
|
709
|
-
|
|
710
|
-
egse.logger.close_all_zmq_handlers()
|
|
711
|
-
|
|
712
|
-
context = zmq.Context.instance()
|
|
713
|
-
context.destroy(linger=0)
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
@cli.command()
|
|
717
|
-
def stop():
|
|
718
|
-
"""Stop the N-FEE HK Control Server."""
|
|
719
|
-
|
|
720
|
-
response = send_request("quit")
|
|
721
|
-
if response == "ACK":
|
|
722
|
-
rich.print("Logger successfully terminated.")
|
|
723
|
-
else:
|
|
724
|
-
rich.print(f"[red] ERROR: {response}")
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
@cli.command()
|
|
728
|
-
def status():
|
|
729
|
-
"""Roll over the log file of the Logger Control Server."""
|
|
730
|
-
|
|
731
|
-
rich.print("N-FEE HK Generator:")
|
|
732
|
-
|
|
733
|
-
response = send_request("status")
|
|
734
|
-
if response.get("status") == "ACK":
|
|
735
|
-
rich.print(" Status: [green]active")
|
|
736
|
-
rich.print(f" Hostname: {response.get('host')}")
|
|
737
|
-
rich.print(f" Listening port: {response.get('listening_port')}")
|
|
738
|
-
rich.print(f" Commanding port: {response.get('command_port')}")
|
|
739
|
-
else:
|
|
740
|
-
rich.print(" Status: [red]not active")
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
TIMEOUT_RECV = 1.0 # seconds
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
def send_request(command_request: str):
|
|
747
|
-
"""Sends a request to the Logger Control Server and waits for a response."""
|
|
748
|
-
ctx = zmq.Context.instance()
|
|
749
|
-
endpoint = connect_address(
|
|
750
|
-
CTRL_SETTINGS.PROTOCOL, CTRL_SETTINGS.HOSTNAME, CTRL_SETTINGS.COMMANDING_PORT
|
|
751
|
-
)
|
|
752
|
-
socket = ctx.socket(zmq.REQ)
|
|
753
|
-
socket.connect(endpoint)
|
|
754
|
-
|
|
755
|
-
socket.send(pickle.dumps(command_request))
|
|
756
|
-
rlist, _, _ = zmq.select([socket], [], [], timeout=TIMEOUT_RECV)
|
|
757
|
-
if socket in rlist:
|
|
758
|
-
response = socket.recv()
|
|
759
|
-
response = pickle.loads(response)
|
|
760
|
-
else:
|
|
761
|
-
response = {"error": "Received from ZeroMQ socket timed out for N-FEE HK Control Server."}
|
|
762
|
-
socket.close(linger=0)
|
|
763
|
-
|
|
764
|
-
return response
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
if __name__ == '__main__':
|
|
768
|
-
sys.exit(cli())
|