cgse 2024.7.0__py3-none-any.whl → 2025.0.1__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.1.dist-info/METADATA +38 -0
- cgse-2025.0.1.dist-info/RECORD +5 -0
- {cgse-2024.7.0.dist-info → cgse-2025.0.1.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/state.py
DELETED
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
import abc
|
|
2
|
-
import logging
|
|
3
|
-
import textwrap
|
|
4
|
-
from pathlib import Path
|
|
5
|
-
from typing import Optional
|
|
6
|
-
|
|
7
|
-
from egse.decorators import borg
|
|
8
|
-
from egse.decorators import deprecate
|
|
9
|
-
from egse.setup import Setup
|
|
10
|
-
|
|
11
|
-
LOGGER = logging.getLogger(__name__)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class StateError(Exception):
|
|
15
|
-
pass
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class UnknownStateError(StateError):
|
|
19
|
-
pass
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
class IllegalStateTransition(StateError):
|
|
23
|
-
pass
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
class NotImplementedTransition(StateError):
|
|
27
|
-
pass
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
class ConnectionStateInterface(abc.ABC):
|
|
31
|
-
"""
|
|
32
|
-
A class used to enforce the implementation of the _connection_ interface
|
|
33
|
-
to model the state of a (network) connection.
|
|
34
|
-
|
|
35
|
-
Subclasses only need to implement those methods that are applicable to
|
|
36
|
-
their state.
|
|
37
|
-
|
|
38
|
-
"""
|
|
39
|
-
|
|
40
|
-
# This class is to enforce the implementation of the interface on both the
|
|
41
|
-
# model, i.e. the Proxy, and the State class. At the same time, it will allow
|
|
42
|
-
# the State subclasses to implement only those methods that are applicable
|
|
43
|
-
# in their state.
|
|
44
|
-
|
|
45
|
-
@abc.abstractmethod
|
|
46
|
-
def connect(self, proxy):
|
|
47
|
-
pass
|
|
48
|
-
|
|
49
|
-
@abc.abstractmethod
|
|
50
|
-
def disconnect(self, proxy):
|
|
51
|
-
pass
|
|
52
|
-
|
|
53
|
-
@abc.abstractmethod
|
|
54
|
-
def reconnect(self, proxy):
|
|
55
|
-
pass
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
@borg
|
|
59
|
-
class _GlobalState:
|
|
60
|
-
"""
|
|
61
|
-
This class implements global state that is shared between instances of this class.
|
|
62
|
-
"""
|
|
63
|
-
|
|
64
|
-
# TODO (rik): turn command sequence into a class and move add_, clear_ and get_ to that class
|
|
65
|
-
|
|
66
|
-
def __init__(self):
|
|
67
|
-
self._dry_run = False
|
|
68
|
-
self._command_sequence = []
|
|
69
|
-
self._setup: Optional[Setup] = None
|
|
70
|
-
|
|
71
|
-
def __call__(self, *args, **kwargs):
|
|
72
|
-
return self
|
|
73
|
-
|
|
74
|
-
@property
|
|
75
|
-
def dry_run(self):
|
|
76
|
-
return self._dry_run
|
|
77
|
-
|
|
78
|
-
@dry_run.setter
|
|
79
|
-
def dry_run(self, flag: bool):
|
|
80
|
-
self._dry_run = flag
|
|
81
|
-
|
|
82
|
-
def add_command(self, cmd):
|
|
83
|
-
self._command_sequence.append(cmd)
|
|
84
|
-
|
|
85
|
-
def get_command_sequence(self):
|
|
86
|
-
return self._command_sequence
|
|
87
|
-
|
|
88
|
-
def clear_command_sequence(self):
|
|
89
|
-
self._command_sequence.clear()
|
|
90
|
-
|
|
91
|
-
@property
|
|
92
|
-
def setup(self) -> Optional[Setup]:
|
|
93
|
-
"""
|
|
94
|
-
Returns the currently active Setup from the configuration manager. Please note that each call
|
|
95
|
-
to this property sends a request to the configuration manager to return its current Setup. If
|
|
96
|
-
you are accessing information from the Setup in a loop or function that is called often, save
|
|
97
|
-
the Setup into a local variable before proceeding.
|
|
98
|
-
|
|
99
|
-
Returns:
|
|
100
|
-
The currently active Setup or None (when the configuration manager is not reachable).
|
|
101
|
-
"""
|
|
102
|
-
return self.load_setup()
|
|
103
|
-
|
|
104
|
-
# This function should be the standard function to reload a setup from the configuration manager
|
|
105
|
-
# Since we have no proper CM yet, the function loads from the default setup.yaml file.
|
|
106
|
-
# But what happens then in other parts of the system, where e.g. the PM has also the 'rights'
|
|
107
|
-
# to call load_setup() on the CM_CS?
|
|
108
|
-
|
|
109
|
-
def load_setup(self) -> Optional[Setup]:
|
|
110
|
-
"""
|
|
111
|
-
Loads the currently active Setup from the Configuration manager. The current Setup is the Setup
|
|
112
|
-
that is defined and loaded in the Configuration manager. When the configuration manager is not
|
|
113
|
-
reachable, None will be returned and a warning will be logged.
|
|
114
|
-
|
|
115
|
-
Since the GlobalState should reflect the configuration of the test, it can only load the current
|
|
116
|
-
Setup from the configuration manager. If you need to work with different Setups, work with the `Setup`
|
|
117
|
-
class and the Configuration Manager directly.
|
|
118
|
-
|
|
119
|
-
Returns:
|
|
120
|
-
The currently active Setup or None.
|
|
121
|
-
"""
|
|
122
|
-
from egse.confman import ConfigurationManagerProxy
|
|
123
|
-
from egse.confman import is_configuration_manager_active
|
|
124
|
-
|
|
125
|
-
if is_configuration_manager_active():
|
|
126
|
-
with ConfigurationManagerProxy() as cm_proxy:
|
|
127
|
-
self._setup = cm_proxy.get_setup()
|
|
128
|
-
else:
|
|
129
|
-
LOGGER.warning(textwrap.dedent(
|
|
130
|
-
f"""\
|
|
131
|
-
Could not reach the Configuration Manager to request the Setup, returning the current local Setup.
|
|
132
|
-
|
|
133
|
-
Check if the Configuration Manager is running and why it can not be consulted. When it's
|
|
134
|
-
back on-line, do a 'load_setup()'.
|
|
135
|
-
"""
|
|
136
|
-
))
|
|
137
|
-
|
|
138
|
-
return self._setup
|
|
139
|
-
|
|
140
|
-
# FIXME:
|
|
141
|
-
# These two 'private' methods are still called in plato-test-scripts, so until that is fixed,
|
|
142
|
-
# leave the methods here
|
|
143
|
-
|
|
144
|
-
@deprecate(reason="this is a private function", alternative="reload_setup()")
|
|
145
|
-
def _reload_setup(self):
|
|
146
|
-
self._setup = Setup.from_yaml_file()
|
|
147
|
-
return self._setup
|
|
148
|
-
|
|
149
|
-
@deprecate(reason="this is a private function", alternative="reload_setup_from()")
|
|
150
|
-
def _reload_setup_from(self, filename: Path):
|
|
151
|
-
"""Used by the unit tests to load a predefined setup."""
|
|
152
|
-
self._setup = Setup.from_yaml_file(filename=filename)
|
|
153
|
-
return self.setup
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
GlobalState = _GlobalState()
|
|
157
|
-
|
|
158
|
-
__all__ = [
|
|
159
|
-
"GlobalState",
|
|
160
|
-
]
|
|
161
|
-
|
|
162
|
-
if __name__ == "__main__":
|
|
163
|
-
|
|
164
|
-
from rich import print
|
|
165
|
-
|
|
166
|
-
print(textwrap.dedent(
|
|
167
|
-
f"""\
|
|
168
|
-
GlobalState info:
|
|
169
|
-
Setup loaded: {GlobalState.setup.get_id()}
|
|
170
|
-
Dry run: {'ON' if GlobalState.dry_run else 'OFF'}
|
|
171
|
-
Command Sequence: {GlobalState.get_command_sequence()} \
|
|
172
|
-
""")
|
|
173
|
-
)
|
egse/statemachine.py
DELETED
|
@@ -1,274 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
A quick and dirty state machine inspired by a `Django Snippet`__\ , which was in
|
|
3
|
-
turn inspired by the rails plugin ``acts_as_state_machine``.
|
|
4
|
-
|
|
5
|
-
__ https://djangosnippets.org/snippets/737/
|
|
6
|
-
|
|
7
|
-
Changes that are made for this project were again inspired by the `transitions`__
|
|
8
|
-
module and the project's specific needs.
|
|
9
|
-
|
|
10
|
-
__ https://github.com/pytransitions/transitions
|
|
11
|
-
|
|
12
|
-
This FSM (Finite State Machine) can be applied to any *model* that has a finite
|
|
13
|
-
number of clearly defined states and transitions between those states.
|
|
14
|
-
|
|
15
|
-
First define the states that the model can be in and initialize a Machine object
|
|
16
|
-
with those states and an initial states.
|
|
17
|
-
|
|
18
|
-
Then you need to define the way that the model moves from one state to the next,
|
|
19
|
-
i.e. a *transition*. Add those transitions to the Machine object with the
|
|
20
|
-
``add_transition`` method.
|
|
21
|
-
|
|
22
|
-
The model will be adapted with methods that represent the transitions and methods
|
|
23
|
-
to query the state. The example below shows a simple model with two states\ [*]_\ , i.e.
|
|
24
|
-
'on' and 'off'::
|
|
25
|
-
|
|
26
|
-
Class MyButton(QPushButton):
|
|
27
|
-
|
|
28
|
-
def __init__(self, *args, **kwargs):
|
|
29
|
-
super().__init__(*args, **kwargs)
|
|
30
|
-
|
|
31
|
-
states = ('on', 'off')
|
|
32
|
-
|
|
33
|
-
self.machine = Machine(self, states, initial='on')
|
|
34
|
-
|
|
35
|
-
self.machine.add_transition(trigger='set_on', source='off', dest='on')
|
|
36
|
-
self.machine.add_transition(trigger='set_off', source='on', dest='off')
|
|
37
|
-
|
|
38
|
-
This will dynamically create two new methods in the class ``MyButton``, i.e. the
|
|
39
|
-
method ``set_on()`` and the method ``set_off()``. Additionally, there will be
|
|
40
|
-
two state checking method: ``is_on()`` and ``is_off()``. You can also check the
|
|
41
|
-
state of the model MyButton by inspecting the state attribute.
|
|
42
|
-
|
|
43
|
-
.. [*] When working in **Qt 5**, a similar state machine can better be implemented
|
|
44
|
-
with the ``QStateMachine`` provided by the Qt framework. Check out this
|
|
45
|
-
`example for a Two-way Button`__.
|
|
46
|
-
|
|
47
|
-
__ https://doc.qt.io/qt-5/qtwidgets-statemachine-twowaybutton-example.html
|
|
48
|
-
|
|
49
|
-
"""
|
|
50
|
-
import inspect
|
|
51
|
-
import logging
|
|
52
|
-
|
|
53
|
-
module_logger = logging.getLogger(__name__)
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
# You can't trivially replace this with `functools.partial` because this binds
|
|
57
|
-
# to classes and returns bound instances, whereas functools.partial (on
|
|
58
|
-
# CPython) is a type and its instances don't bind.
|
|
59
|
-
# source: from django.utils.functional import curry
|
|
60
|
-
def curry(_curried_func, *args, **kwargs):
|
|
61
|
-
def _curried(*moreargs, **morekwargs):
|
|
62
|
-
return _curried_func(*args, *moreargs, **{**kwargs, **morekwargs})
|
|
63
|
-
|
|
64
|
-
return _curried
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
class MachineError(Exception):
|
|
68
|
-
def __init__(self, value):
|
|
69
|
-
self.value = value
|
|
70
|
-
|
|
71
|
-
def __str__(self):
|
|
72
|
-
return repr(self.value)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
class Machine():
|
|
76
|
-
"""
|
|
77
|
-
Create a Finite State Machine (FSM).
|
|
78
|
-
"""
|
|
79
|
-
|
|
80
|
-
def __init__(self, model, states, **kwargs):
|
|
81
|
-
"""
|
|
82
|
-
Initialise the finite state machine.
|
|
83
|
-
|
|
84
|
-
:param str model: the model object that needs to be converted into a FSM
|
|
85
|
-
:param list states: a list with the names of the states
|
|
86
|
-
:param str initial: the initial state
|
|
87
|
-
"""
|
|
88
|
-
self.model = model
|
|
89
|
-
self.state = None
|
|
90
|
-
self.last_state = None
|
|
91
|
-
|
|
92
|
-
try:
|
|
93
|
-
initial_state = kwargs.pop('initial')
|
|
94
|
-
except KeyError:
|
|
95
|
-
raise MachineError("A Finite State Machine needs an initial state, "
|
|
96
|
-
"please provide the 'initial' keyword argument")
|
|
97
|
-
|
|
98
|
-
module_logger.debug(f"Initial State = {initial_state}")
|
|
99
|
-
|
|
100
|
-
self._set_initial(initial_state)
|
|
101
|
-
|
|
102
|
-
self.states = []
|
|
103
|
-
self.state_triggers = {}
|
|
104
|
-
for state in states:
|
|
105
|
-
if isinstance(state, str):
|
|
106
|
-
self.states.append(state)
|
|
107
|
-
elif isinstance(state, dict):
|
|
108
|
-
state_name = list(state.keys())[0]
|
|
109
|
-
self.states.append(state_name)
|
|
110
|
-
self.state_triggers[state_name] = state[state_name]
|
|
111
|
-
self.states = tuple(self.states)
|
|
112
|
-
|
|
113
|
-
def _extract_from_state(self, kwargs):
|
|
114
|
-
try:
|
|
115
|
-
coming_from = kwargs.pop('from')
|
|
116
|
-
except KeyError:
|
|
117
|
-
raise MachineError("Missing 'from'; must transtion from a state")
|
|
118
|
-
|
|
119
|
-
if isinstance(coming_from, str):
|
|
120
|
-
if coming_from not in self.states and coming_from != '*':
|
|
121
|
-
raise MachineError(f"from: '{coming_from}' is not a registered state")
|
|
122
|
-
elif isinstance(coming_from, list):
|
|
123
|
-
for state in coming_from:
|
|
124
|
-
if state not in self.states:
|
|
125
|
-
raise MachineError(f"from: '{coming_from}' is not a registered state")
|
|
126
|
-
|
|
127
|
-
return coming_from
|
|
128
|
-
|
|
129
|
-
def _extract_to_state(self, kwargs):
|
|
130
|
-
try:
|
|
131
|
-
going_to = kwargs.pop('to')
|
|
132
|
-
except KeyError:
|
|
133
|
-
raise MachineError("Missing 'to'; must transition to a state")
|
|
134
|
-
|
|
135
|
-
if going_to not in self.states and going_to != '<':
|
|
136
|
-
raise MachineError(f"to: '{going_to}' is not a registered state")
|
|
137
|
-
|
|
138
|
-
return going_to
|
|
139
|
-
|
|
140
|
-
def _extract_run_method(self, kwargs):
|
|
141
|
-
run = kwargs.pop('run', None)
|
|
142
|
-
return run
|
|
143
|
-
|
|
144
|
-
def _set_initial(self, initial):
|
|
145
|
-
self._update_model(initial)
|
|
146
|
-
|
|
147
|
-
def _update_state_from_model(self):
|
|
148
|
-
self._update_state(self.model.state)
|
|
149
|
-
|
|
150
|
-
def _update_model(self, state):
|
|
151
|
-
self.model.state = state
|
|
152
|
-
self._update_state(self.model.state)
|
|
153
|
-
|
|
154
|
-
def _update_state(self, new_state):
|
|
155
|
-
self.last_state = self.state if self.state is not None else new_state
|
|
156
|
-
self.state = new_state
|
|
157
|
-
|
|
158
|
-
def action(self, *args, **kwargs):
|
|
159
|
-
name = kwargs.pop('this')
|
|
160
|
-
module_logger.debug(f"Performing action: {name}, current state = {self.state}, last state = {self.last_state}")
|
|
161
|
-
|
|
162
|
-
state = kwargs.pop('to_state')
|
|
163
|
-
if state == '<':
|
|
164
|
-
state = self.last_state
|
|
165
|
-
|
|
166
|
-
run_method = kwargs.pop('run')
|
|
167
|
-
|
|
168
|
-
self._update_state_from_model()
|
|
169
|
-
|
|
170
|
-
from_states = kwargs.pop('from_states')
|
|
171
|
-
from_states = from_states if from_states != "*" else [self.state]
|
|
172
|
-
|
|
173
|
-
response = None
|
|
174
|
-
|
|
175
|
-
if self.state in from_states:
|
|
176
|
-
if state in self.state_triggers and 'enter' in self.state_triggers[state]:
|
|
177
|
-
self.state_triggers[state]['enter']()
|
|
178
|
-
if run_method is not None:
|
|
179
|
-
response = run_method(*args, **kwargs)
|
|
180
|
-
self._update_model(state)
|
|
181
|
-
if state in self.state_triggers and 'leave' in self.state_triggers[state]:
|
|
182
|
-
self.state_triggers[state]['leave']()
|
|
183
|
-
return response
|
|
184
|
-
else:
|
|
185
|
-
module_logger.warning(f"Cannot transition from '{self.state}' to '{state}', nothing changed.")
|
|
186
|
-
|
|
187
|
-
return response
|
|
188
|
-
|
|
189
|
-
def is_state(self, state, *args):
|
|
190
|
-
self._update_state_from_model()
|
|
191
|
-
return self.state == state
|
|
192
|
-
|
|
193
|
-
def get_state(self):
|
|
194
|
-
self._update_state_from_model()
|
|
195
|
-
return self.state
|
|
196
|
-
|
|
197
|
-
def add_transition(self, trigger, source, dest, run=None):
|
|
198
|
-
"""
|
|
199
|
-
Add a transition to the finite state machine.
|
|
200
|
-
|
|
201
|
-
:param str trigger: the name of the trigger method (an action)
|
|
202
|
-
:param str source: the name of the source state, from where the transition starts
|
|
203
|
-
:param str dest: the name of the destination state, where the transition moves to
|
|
204
|
-
:param function run: a function or method reference that will be called during the transition
|
|
205
|
-
"""
|
|
206
|
-
if hasattr(self.model, trigger):
|
|
207
|
-
module_logger.warning(
|
|
208
|
-
f"Cannot overwrite attribute '{trigger}' in '{self.model.__class__.__name__}', no changes made.")
|
|
209
|
-
else:
|
|
210
|
-
setattr(self.model, trigger, curry(self.action, to_state=dest, from_states=source, this=trigger, run=run))
|
|
211
|
-
module_logger.debug(f"Added method {trigger}() to {self.model.__class__.__name__}")
|
|
212
|
-
|
|
213
|
-
if dest != '<':
|
|
214
|
-
is_state = f"is_{dest}"
|
|
215
|
-
|
|
216
|
-
if hasattr(self.model, is_state):
|
|
217
|
-
module_logger.warning(
|
|
218
|
-
f"Attribute '{is_state}' already exists in '{self.model.__class__.__name__}', no changes made.")
|
|
219
|
-
else:
|
|
220
|
-
setattr(self.model, is_state, curry(self.is_state, dest))
|
|
221
|
-
module_logger.debug(f"Added method {is_state}() to {self.model.__class__.__name__}")
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
if __name__ == "__main__":
|
|
225
|
-
|
|
226
|
-
logging.basicConfig(level=logging.DEBUG)
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
class Button(object):
|
|
230
|
-
pass
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
class MyButton(Button):
|
|
234
|
-
|
|
235
|
-
def __init__(self, *args, **kwargs):
|
|
236
|
-
super().__init__(*args, **kwargs)
|
|
237
|
-
|
|
238
|
-
states = (
|
|
239
|
-
'on',
|
|
240
|
-
'off',
|
|
241
|
-
{'disabled': {'enter': self.upon_entry, 'leave': self.upon_leave}},
|
|
242
|
-
'hidden'
|
|
243
|
-
)
|
|
244
|
-
|
|
245
|
-
self.machine = Machine(self, states, initial='on')
|
|
246
|
-
|
|
247
|
-
self.machine.add_transition(trigger='set_on', source='off', dest='on')
|
|
248
|
-
self.machine.add_transition(trigger='set_off', source='on', dest='off')
|
|
249
|
-
self.machine.add_transition(trigger='disable', source=['on', 'off'], dest='disabled')
|
|
250
|
-
self.machine.add_transition(trigger='enable', source='disabled', dest='<')
|
|
251
|
-
self.machine.add_transition(trigger='hide', source='*', dest='hidden', run=self.hide_)
|
|
252
|
-
self.machine.add_transition(trigger='unhide', source='hidden', dest='<')
|
|
253
|
-
|
|
254
|
-
def upon_entry(self):
|
|
255
|
-
module_logger.debug(f"Entring: state = {self.state}")
|
|
256
|
-
|
|
257
|
-
def upon_leave(self):
|
|
258
|
-
module_logger.debug(f"Leaving: state = {self.state}")
|
|
259
|
-
|
|
260
|
-
def hide_(self, *args, **kwargs):
|
|
261
|
-
module_logger.debug(f"Running the {inspect.currentframe().f_code.co_name}() method...")
|
|
262
|
-
module_logger.debug(f"args = {args}")
|
|
263
|
-
module_logger.debug(f"kwargs = {kwargs}")
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
b = MyButton()
|
|
267
|
-
module_logger.debug(f"b.state={b.state}")
|
|
268
|
-
|
|
269
|
-
actions = [b.set_off, b.hide, b.unhide, b.disable, b.enable, b.set_on, b.set_off]
|
|
270
|
-
for action in actions:
|
|
271
|
-
action()
|
|
272
|
-
module_logger.debug(f"b.state={b.state}")
|
|
273
|
-
|
|
274
|
-
b.hide("Hello, World!", type="string")
|