cgse 0.14.0__tar.gz → 0.15.0__tar.gz
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.
- {cgse-0.14.0 → cgse-0.15.0}/PKG-INFO +1 -1
- cgse-0.15.0/docs/libs/cgse-core/notifyhub.md +168 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/pyproject.toml +1 -1
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/log.py +44 -13
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-coordinates/pyproject.toml +1 -1
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/pyproject.toml +4 -3
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/cgse_core/_start.py +14 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/cgse_core/_stop.py +20 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/cgse_core/cgse_explore.py +1 -1
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/cgse_core/services.py +24 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/cgse_core/settings.yaml +7 -1
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/confman/__init__.py +12 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/confman/confman_cs.py +20 -18
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/control.py +29 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/logger/__init__.py +81 -44
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/logger/log_cs.py +21 -13
- cgse-0.15.0/libs/cgse-core/src/egse/notifyhub/__init__.py +63 -0
- cgse-0.15.0/libs/cgse-core/src/egse/notifyhub/client.py +258 -0
- cgse-0.15.0/libs/cgse-core/src/egse/notifyhub/event.py +29 -0
- cgse-0.15.0/libs/cgse-core/src/egse/notifyhub/server.py +355 -0
- cgse-0.15.0/libs/cgse-core/src/egse/notifyhub/services.py +301 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/notifyhub/test.py +16 -9
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/procman/procman_cs.py +14 -12
- cgse-0.15.0/libs/cgse-core/src/egse/registry/__init__.py +41 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/registry/client.py +54 -36
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/registry/server.py +20 -18
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/storage/__init__.py +34 -31
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/storage/storage_cs.py +38 -18
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/tests/fixtures/services.py +2 -0
- cgse-0.15.0/libs/cgse-core/tests/script_subscribe_to_notifyhub.py +29 -0
- cgse-0.15.0/libs/cgse-core/tests/test_event_notification.py +182 -0
- cgse-0.15.0/libs/cgse-core/tests/test_notify_hub.py +170 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/pyproject.toml +1 -1
- {cgse-0.14.0 → cgse-0.15.0}/mkdocs.yml +1 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/cgse-tools/pyproject.toml +1 -1
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/keithley-tempcontrol/pyproject.toml +1 -1
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/lakeshore-tempcontrol/pyproject.toml +1 -1
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/pyproject.toml +1 -1
- {cgse-0.14.0 → cgse-0.15.0}/projects/plato/plato-fits/pyproject.toml +1 -1
- {cgse-0.14.0 → cgse-0.15.0}/projects/plato/plato-hdf5/pyproject.toml +1 -1
- {cgse-0.14.0 → cgse-0.15.0}/projects/plato/plato-spw/pyproject.toml +1 -1
- {cgse-0.14.0 → cgse-0.15.0}/pyproject.toml +1 -1
- {cgse-0.14.0 → cgse-0.15.0}/service_registry.db +0 -0
- cgse-0.14.0/libs/cgse-core/src/egse/notifyhub/__init__.py +0 -8
- cgse-0.14.0/libs/cgse-core/src/egse/notifyhub/event.py +0 -11
- cgse-0.14.0/libs/cgse-core/src/egse/notifyhub/server.py +0 -155
- cgse-0.14.0/libs/cgse-core/src/egse/notifyhub/services.py +0 -179
- cgse-0.14.0/libs/cgse-core/src/egse/registry/__init__.py +0 -22
- {cgse-0.14.0 → cgse-0.15.0}/.github/workflows/ruff-format-check.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/.gitignore +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/README.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/bump.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/conftest.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/api/bits.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/api/calibration.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/api/command.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/api/config.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/api/control.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/api/counter.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/api/decorators.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/api/device.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/api/dicts.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/api/dummy.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/api/env.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/api/exceptions.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/api/heartbeat.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/api/hk.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/api/index.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/api/listener.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/api/metrics.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/api/mixin.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/api/monitoring.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/api/observer.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/api/obsid.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/api/persistence.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/api/plugin.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/api/process.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/api/reload.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/api/settings.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/api/setup.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/api/system.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/custom_theme/main.html +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/dev_guide/coding_style.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/dev_guide/docs.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/dev_guide/index.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/dev_guide/installation.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/dev_guide/monitoring.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/dev_guide/monorepo.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/dev_guide/nox.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/dev_guide/plugins.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/dev_guide/project-configuration.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/dev_guide/unit_testing.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/dev_guide/uv.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/dev_guide/versioning.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/getting_started.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/help.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/images/github-fork-clone-dark.png +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/images/github-fork-clone.png +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/images/grafana-queries.png +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/images/icons/cgse-logo-blue.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/images/icons/cgse-logo.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/index.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/initialize.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/libs/cgse-common/images/load_methods.png +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/libs/cgse-common/index.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/libs/cgse-common/settings.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/libs/cgse-common/setup.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/libs/cgse-coordinates/index.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/libs/cgse-core/index.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/libs/cgse-core/registry.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/libs/cgse-gui/index.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/libs/index.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/package_list.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/projects/cgse-tools.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/projects/index.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/projects/symetrie-hexapod.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/roadmap.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/stylesheets/custom.css +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/stylesheets/extra.css +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/tutorial.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/docs/user_guide/index.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/duckdb_metrics.db +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/duckdb_metrics.db.wal +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/identifier.sqlite +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/justfile +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/README.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/justfile +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/noxfile.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/service_registry.db +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/cgse_common/__init__.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/cgse_common/cgse.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/cgse_common/settings.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/bits.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/calibration.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/config.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/counter.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/decorators.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/device.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/dicts.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/env.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/exceptions.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/heartbeat.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/hk.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/metrics.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/observer.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/obsid.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/persistence.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/plugin.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/plugins/metrics/duckdb.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/plugins/metrics/influxdb.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/plugins/metrics/timescaledb.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/process.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/py.typed +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/randomwalk.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/ratelimit.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/reload.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/resource.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/response.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/scpi.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/settings.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/settings.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/setup.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/signal.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/socketdevice.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/state.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/system.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/task.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/version.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/src/egse/zmq_ser.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/conftest.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/COPYING +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/CSL/conf/SETUP_CSL_00028_201028_155259.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/CSL/conf/SETUP_CSL_00029_201028_155331.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/CSL/conf/SETUP_CSL_00030_210311_134043.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/CSL/conf/SETUP_CSL_00080_210917_105245.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/CSL/conf/SETUP_CSL_00081_210922_142259.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/CSL/conf/SETUP_CSL_00082_210923_094458.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/CSL1/README.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/CSL2/README.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/IAS/README.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/INTA/README.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/LAB23/README.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/SRON/conf/SETUP_SRON_00027_211119_140441.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/SRON/conf/SETUP_SRON_00028_211119_160406.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/SRON/conf/SETUP_SRON_00029_211119_172918.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/SRON/conf/SETUP_SRON_00030_211122_103604.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/SRON/conf/SETUP_SRON_00031_211123_124900.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/common/telemetry/tm-dictionary-default.csv +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/conf/SETUP_20250114_1519.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/conf/config-file.toml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/data/cal_coeff_1234.csv +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/data/calibration.csv +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/data/calibration.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/data/command.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/data/corrupt.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/data/data-file.txt +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/data/empty_data_file.txt +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/data/empty_yaml_file.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/data/local_settings.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/data/new_local_settings.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/data/test_setup.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/icons/hourglass.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/icons/keyboard.png +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/icons/soap_sponge.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/lib/dev1/shared-lib.so +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/data/lib/dev2/shared-lib.so +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/fixtures/default_env.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/fixtures/helpers.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/scripts/empty_process.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/scripts/handle_sigterm.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/scripts/process_with_children.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/scripts/raise_value_error.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/scripts/void-0.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/scripts/void-1.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/test_bits.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/test_config.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/test_decorators.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/test_device.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/test_env.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/test_fixtures.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/test_hk.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/test_influxdb_plugin.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/test_log.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/test_metrics.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/test_plugin.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/test_process.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/test_ratelimit.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/test_resource.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/test_response.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/test_settings.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/test_setup.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/test_signal.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/test_state.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/test_system.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/test_task.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-common/tests/test_zmq_ser.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-coordinates/README.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-coordinates/src/cgse_coordinates/__init__.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-coordinates/src/cgse_coordinates/settings.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-coordinates/src/egse/coordinates/__init__.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-coordinates/src/egse/coordinates/avoidance.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-coordinates/src/egse/coordinates/cslmodel.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-coordinates/src/egse/coordinates/laser_tracker_to_dict.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-coordinates/src/egse/coordinates/point.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-coordinates/src/egse/coordinates/pyplot.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-coordinates/src/egse/coordinates/referenceFrame.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-coordinates/src/egse/coordinates/refmodel.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-coordinates/src/egse/coordinates/rotationMatrix.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-coordinates/src/egse/coordinates/transform3d_addon.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-coordinates/tests/test_avoidance.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-coordinates/tests/test_coordinates_plot.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-coordinates/tests/test_coordinates_serialize.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-coordinates/tests/test_point.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-coordinates/tests/test_ref_model.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-coordinates/tests/test_reference_frames.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-coordinates/tests/test_refmodel.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/.envrc.disabled +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/README.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/service_registry.db +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/cgse_core/__init__.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/cgse_core/_status.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/_setup_core.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/async_control.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/async_control_claude.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/command.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/confman/__main__.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/confman/confman.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/dummy.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/icons/busy.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/icons/operational-mode.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/icons/pm_ui.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/icons/simulator-mode.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/icons/start-process-button.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/icons/stop-process-button.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/icons/user-interface.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/listener.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/logger/__main__.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/metricshub/__init__.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/metricshub/server.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/mixin.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/monitoring.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/procman/__init__.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/procman/procman.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/procman/procman_protocol.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/procman/procman_ui.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/protocol.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/proxy.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/registry/backend.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/registry/service.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/services.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/services.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/storage/__main__.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/storage/persistence.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/src/egse/storage/storage.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/tests/conftest.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/tests/data/local_settings.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/tests/fixtures/default_env.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/tests/fixtures/helpers.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/tests/script_test_async_registry_client.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/tests/script_test_registry_client_server.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/tests/script_test_service_registry_server.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/tests/script_test_sync_registry_client.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/tests/services.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/tests/stress_test_registry_server.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/tests/test_async_control.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/tests/test_client_server_interaction.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/tests/test_cm_cs.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/tests/test_command.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/tests/test_confman_setups.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/tests/test_control.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/tests/test_dummy.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/tests/test_extensions.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/tests/test_listener.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/tests/test_logger.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/tests/test_mixin.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/tests/test_protocol.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/tests/test_registry_backend.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/tests/test_registry_service.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/tests/test_server_running.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/tests/test_server_running_with_fixture.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/tests/test_settings_core.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-core/tests/test_zmq_microservice.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/README.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/__init__.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/buttons.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/aeu-cs-start.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/aeu-cs-stop.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/aeu-cs.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/aeu_cs-started.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/aeu_cs-stopped.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/aeu_cs.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/alert.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/arrow-double-left.png +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/arrow-double-right.png +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/arrow-up.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/backward.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/busy.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/cleaning.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/color-scheme.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/cs-connected-alert.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/cs-connected-disabled.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/cs-connected.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/cs-not-connected.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/double-left-arrow.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/double-right-arrow.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/erase-disabled.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/erase.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/fitsgen-start.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/fitsgen-stop.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/fitsgen.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/forward.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/fov-hk-start.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/fov-hk-stop.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/fov-hk.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/front-desk.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/home-actioned.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/home-disabled.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/home.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/info.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/invalid.png +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/led-green.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/led-grey.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/led-orange.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/led-red.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/led-square-green.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/led-square-grey.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/led-square-orange.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/led-square-red.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/limit-switch-all-green.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/limit-switch-all-red.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/limit-switch-el+.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/limit-switch-el-.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/location-marker.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/logo-dpu.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/logo-gimbal.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/logo-huber.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/logo-ogse.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/logo-puna.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/logo-tcs.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/logo-zonda.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/maximize.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/meter.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/more.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/n-fee-hk-start.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/n-fee-hk-stop.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/n-fee-hk.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/observing-off.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/observing-on.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/open-document-hdf5.png +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/open-document-hdf5.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/ops-mode.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/play-green.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/plugged-disabled.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/plugged.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/pm_ui.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/power-button-green.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/power-button-red.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/power-button.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/radar.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/radioactive.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/reload.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/remote-control-off.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/remote-control-on.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/repeat-blue.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/repeat.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/settings.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/shrink.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/shutter.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/sign-off.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/sign-on.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/sim-mode.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/small-buttons-go.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/small-buttons-minus.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/small-buttons-plus.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/sponge.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/start-button-disabled.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/start-button.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/stop-button-disabled.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/stop-button.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/stop-red.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/stop.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/switch-disabled-square.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/switch-disabled.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/switch-off-square.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/switch-off.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/switch-on-square.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/switch-on.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/temperature-control.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/th_ui_logo.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/unplugged.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/unvalid.png +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/user-interface.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/vacuum.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/valid.png +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/zoom-to-pixel-dark.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/icons/zoom-to-pixel-white.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/led.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/limitswitch.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/states.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/styles/dark.qss +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/styles/default.qss +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/styles.qss +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/libs/cgse-gui/src/egse/gui/switch.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/noxfile.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/overrides/.icons/custom/dbend-dark.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/overrides/.icons/custom/dbend-light.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/overrides/.icons/custom/gear.svg +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/cgse-tools/README.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/cgse-tools/src/cgse_tools/__init__.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/cgse-tools/src/cgse_tools/cgse_clock.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/cgse-tools/src/cgse_tools/cgse_commands.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/cgse-tools/src/cgse_tools/cgse_services.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/cgse-tools/src/egse/tools/status.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/keithley-tempcontrol/README.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/keithley-tempcontrol/justfile +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/keithley-tempcontrol/noxfile.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/keithley-tempcontrol/service_registry.db +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/keithley-tempcontrol/src/egse/tempcontrol/keithley/__init__.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/keithley-tempcontrol/src/egse/tempcontrol/keithley/daq6510.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/keithley-tempcontrol/src/egse/tempcontrol/keithley/daq6510.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/keithley-tempcontrol/src/egse/tempcontrol/keithley/daq6510_adev.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/keithley-tempcontrol/src/egse/tempcontrol/keithley/daq6510_cs.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/keithley-tempcontrol/src/egse/tempcontrol/keithley/daq6510_dev.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/keithley-tempcontrol/src/egse/tempcontrol/keithley/daq6510_mon.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/keithley-tempcontrol/src/egse/tempcontrol/keithley/daq6510_protocol.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/keithley-tempcontrol/src/egse/tempcontrol/keithley/daq6510_sim.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/keithley-tempcontrol/src/keithley_tempcontrol/__init__.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/keithley-tempcontrol/src/keithley_tempcontrol/cgse_explore.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/keithley-tempcontrol/src/keithley_tempcontrol/cgse_services.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/keithley-tempcontrol/src/keithley_tempcontrol/settings.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/keithley-tempcontrol/temperature_readings.log +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/keithley-tempcontrol/tests/script_daq6510_mon.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/keithley-tempcontrol/tests/test_adev.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/keithley-tempcontrol/tests/test_dev.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/lakeshore-tempcontrol/README.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/lakeshore-tempcontrol/src/egse/tempcontrol/lakeshore/lakeshore336.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/lakeshore-tempcontrol/src/egse/tempcontrol/lakeshore/lakeshore336.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/lakeshore-tempcontrol/src/egse/tempcontrol/lakeshore/lakeshore336_cs.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/lakeshore-tempcontrol/src/egse/tempcontrol/lakeshore/lakeshore336_devif.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/lakeshore-tempcontrol/src/egse/tempcontrol/lakeshore/lakeshore336_protocol.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/lakeshore-tempcontrol/src/lakeshore_tempcontrol/__init__.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/lakeshore-tempcontrol/src/lakeshore_tempcontrol/cgse_explore.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/lakeshore-tempcontrol/src/lakeshore_tempcontrol/cgse_services.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/lakeshore-tempcontrol/src/lakeshore_tempcontrol/settings.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/lakeshore-tempcontrol/tests/test_lakeshore336_simulator.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/README.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/src/egse/hexapod/__init__.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/src/egse/hexapod/symetrie/__init__.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/src/egse/hexapod/symetrie/alpha.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/src/egse/hexapod/symetrie/dynalpha.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/src/egse/hexapod/symetrie/hexapod.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/src/egse/hexapod/symetrie/hexapod_ui.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/src/egse/hexapod/symetrie/joran.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/src/egse/hexapod/symetrie/joran.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/src/egse/hexapod/symetrie/joran_cs.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/src/egse/hexapod/symetrie/joran_protocol.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/src/egse/hexapod/symetrie/joran_ui.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/src/egse/hexapod/symetrie/pmac.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/src/egse/hexapod/symetrie/pmac_regex.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/src/egse/hexapod/symetrie/puna.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/src/egse/hexapod/symetrie/puna.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/src/egse/hexapod/symetrie/puna_cs.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/src/egse/hexapod/symetrie/puna_protocol.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/src/egse/hexapod/symetrie/puna_sim.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/src/egse/hexapod/symetrie/puna_ui.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/src/egse/hexapod/symetrie/punaplus.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/src/egse/hexapod/symetrie/zonda.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/src/egse/hexapod/symetrie/zonda.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/src/egse/hexapod/symetrie/zonda_cs.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/src/egse/hexapod/symetrie/zonda_devif.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/src/egse/hexapod/symetrie/zonda_protocol.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/src/egse/hexapod/symetrie/zonda_ui.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/src/symetrie_hexapod/__init__.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/src/symetrie_hexapod/cgse_explore.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/src/symetrie_hexapod/cgse_services.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/src/symetrie_hexapod/settings.yaml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/tests/test_puna.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/tests/test_puna_cs.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/generic/symetrie-hexapod/tests/test_puna_simulator.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/plato/plato-fits/README.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/plato/plato-fits/src/egse/plugins/storage/fits.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/plato/plato-hdf5/README.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/plato/plato-hdf5/src/egse/plugins/storage/hdf5.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/plato/plato-spw/README.md +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/projects/plato/plato-spw/src/egse/spw.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/ruff.toml +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/scratch/advanced-process-monitoring.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/scratch/live-process-monitoring.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/scratch/match-case.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/scratch/processes.json +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/scratch/simple-process-monitoring.py +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/temperature_readings.log +0 -0
- {cgse-0.14.0 → cgse-0.15.0}/test_service_registry.db +0 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# The Notification Hub
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The Notification Hub serves as a centralized event distribution system for the core services and control servers.
|
|
6
|
+
Instead of having services directly subscribe to each other, all services publish their events to the hub, which
|
|
7
|
+
then redistributes them to interested subscribers via ZeroMQ PUB-SUB sockets.
|
|
8
|
+
|
|
9
|
+
## Benefits
|
|
10
|
+
|
|
11
|
+
- **Decoupling**: Services don't need to know about each other directly
|
|
12
|
+
- **Scalability**: Easy to add new subscribers without modifying existing services
|
|
13
|
+
- **Reliability**: Single point of event distribution with consistent delivery
|
|
14
|
+
- **Simplicity**: One subscription endpoint for all system events
|
|
15
|
+
|
|
16
|
+
# Socket Endpoints
|
|
17
|
+
|
|
18
|
+
The Notification Hub exposes three ZeroMQ sockets:
|
|
19
|
+
|
|
20
|
+
| Purpose | Pattern | Your Socket | Endpoint |
|
|
21
|
+
|--------------------|:--------------:|:-------------:|-----------------------------|
|
|
22
|
+
| Event Publishing | PUSH-PULL | PUSH | tcp://notification-hub:4245 |
|
|
23
|
+
| Event Subscription | PUB-SUB | SUB | tcp://notification-hub:4246 |
|
|
24
|
+
| Health Checks | ROUTER-DEALER | DEALER | tcp://notification-hub:4247 |
|
|
25
|
+
|
|
26
|
+
Note: port numbers can be changed in the local settings YAML file.
|
|
27
|
+
|
|
28
|
+
## Events
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
from egse.notifyhub.event import NotificationEvent
|
|
32
|
+
|
|
33
|
+
event = NotificationEvent(
|
|
34
|
+
event_type="new_setup",
|
|
35
|
+
source_service="cm_cs",
|
|
36
|
+
data={"setup_id": "0001234"},
|
|
37
|
+
)
|
|
38
|
+
```
|
|
39
|
+
A `NotificationEvent` also has a `timestamp` and a `correlation_id`
|
|
40
|
+
associated. These fields are automatically filled on creation of the event
|
|
41
|
+
and must not be provided. An event can be converted into a plain dictionary
|
|
42
|
+
with the `.as_dict()` method.
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
>>> print(event.as_dict())
|
|
46
|
+
{
|
|
47
|
+
'event_type': 'new_setup',
|
|
48
|
+
'source_service': 'cm_cs',
|
|
49
|
+
'data': {'setup_id': '0001234'},
|
|
50
|
+
'timestamp': 1756709627.25942,
|
|
51
|
+
'correlation_id': '23b44f16-34f9-498a-85f7-5c57658ea363'
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Publishing Events
|
|
56
|
+
|
|
57
|
+
Any core service, control server, or script can publish events to the notification hub using the EventPublisher class. For convenience, EventPublisher supports usage as a context manager, making it easy to send single events.
|
|
58
|
+
|
|
59
|
+
=== "Synchronous"
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
from egse.notifyhub.services import EventPublisher
|
|
63
|
+
|
|
64
|
+
with EventPublisher() as publisher:
|
|
65
|
+
publisher.publish(event)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
=== "Asynchronous"
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
from egse.notifyhub.services import AsyncEventPublisher
|
|
72
|
+
|
|
73
|
+
async with AsyncEventPublisher() as publisher:
|
|
74
|
+
await publisher.publish(event)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
## Subscribing to Events
|
|
79
|
+
|
|
80
|
+
Listen to events from the notification hub with the EventSubscriber class.
|
|
81
|
+
The usage for this class is quite different for synchronous and asynchronous
|
|
82
|
+
contexts.
|
|
83
|
+
|
|
84
|
+
=== "Synchronous"
|
|
85
|
+
|
|
86
|
+
In a synchronous context, you will need to add code to poll the socket
|
|
87
|
+
and handle the event inside your own event loop. The subscriber socket
|
|
88
|
+
can be retrieved with the `subscriber.socket` property, you can then add
|
|
89
|
+
the socket to a Poller object.
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
from egse.notifyhub.services import EventSubscriber
|
|
93
|
+
|
|
94
|
+
def load_setup(event_data: dict):
|
|
95
|
+
...
|
|
96
|
+
|
|
97
|
+
subscriber = EventSubscriber(["new_setup"])
|
|
98
|
+
subscriber.register_handler("new_setup", load_setup)
|
|
99
|
+
subscriber.connect()
|
|
100
|
+
|
|
101
|
+
while True:
|
|
102
|
+
|
|
103
|
+
...
|
|
104
|
+
|
|
105
|
+
if subscriber.poll():
|
|
106
|
+
subscriber.handle_event()
|
|
107
|
+
|
|
108
|
+
subscriber.disconnect()
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
=== "Asynchronous"
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
from egse.notifyhub.services import AsyncEventSubscriber
|
|
115
|
+
|
|
116
|
+
async def load_setup(event_data: dict):
|
|
117
|
+
...
|
|
118
|
+
|
|
119
|
+
subscriber = AsyncEventSubscriber(["new_setup"])
|
|
120
|
+
subscriber.register_handler("new_setup", load_setup)
|
|
121
|
+
await subscriber.connect()
|
|
122
|
+
|
|
123
|
+
event_listener = asyncio.create_task(subscriber.start_listening())
|
|
124
|
+
|
|
125
|
+
...
|
|
126
|
+
|
|
127
|
+
subscriber.disconnect()
|
|
128
|
+
await event_listener # add a wait_for with a timeout if needed
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Health Checks
|
|
132
|
+
|
|
133
|
+
The Notification Hub provides a health check interface to monitor the status and availability of the hub. This allows services and scripts to verify connectivity and basic hub functionality.
|
|
134
|
+
To perform a health check, use the NotificationHubClient class. The client
|
|
135
|
+
connects to the hub's ROUTER-DEALER socket and sends a health check request.
|
|
136
|
+
If the hub is available, it responds True. In case of an error or when the
|
|
137
|
+
hub is not available, False is returned.
|
|
138
|
+
|
|
139
|
+
=== "Synchronous"
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
from egse.notifyhub.client import NotificationHubClient
|
|
143
|
+
|
|
144
|
+
with NotificationHubClient() as client:
|
|
145
|
+
if not client.health_check():
|
|
146
|
+
... # notification hub not available
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
=== "Asynchronous"
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
from egse.notifyhub.client import AsyncNotificationHubClient
|
|
153
|
+
|
|
154
|
+
with AsyncNotificationHubClient() as client:
|
|
155
|
+
if not await client.health_check():
|
|
156
|
+
... # notification hub not available
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
The health check has a default timeout of 5 seconds. If this is too long for
|
|
160
|
+
your needs, provide a `request_timeout` argument as a float in seconds to
|
|
161
|
+
the `NotificationHubClient` call.
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
## Monitoring
|
|
165
|
+
|
|
166
|
+
Every 30s, the hub provides basic connection and event statistics to the log.
|
|
167
|
+
|
|
168
|
+
TODO: this should also go on the PUB channel as a StatsEvent.
|
|
@@ -13,34 +13,70 @@ Environment variables that affect logging:
|
|
|
13
13
|
|
|
14
14
|
__all__ = [
|
|
15
15
|
"LOG_FORMAT_FULL",
|
|
16
|
+
"LOG_FORMAT_CLEAN",
|
|
17
|
+
"LOG_FORMAT_STYLE",
|
|
18
|
+
"LOG_DATE_FORMAT_FULL",
|
|
19
|
+
"LOG_DATE_FORMAT_CLEAN",
|
|
16
20
|
"logger",
|
|
17
21
|
"root_logger",
|
|
18
22
|
"egse_logger",
|
|
23
|
+
"get_log_level_from_env",
|
|
24
|
+
"PackageFilter",
|
|
19
25
|
]
|
|
20
26
|
|
|
21
27
|
import logging
|
|
22
28
|
import os
|
|
23
29
|
import textwrap
|
|
30
|
+
from pathlib import Path
|
|
24
31
|
|
|
25
32
|
import rich
|
|
26
33
|
|
|
34
|
+
# The format for the log messages.
|
|
35
|
+
# The log record attributes are listed: https://docs.python.org/3.12/library/logging.html#logrecord-attributes
|
|
36
|
+
|
|
27
37
|
LOG_FORMAT_STYLE = "{"
|
|
28
38
|
LOG_FORMAT_FULL = (
|
|
29
39
|
"{asctime:19s}.{msecs:03.0f} : {processName:20s} : {levelname:8s} : {name:^25s} : {lineno:6d} : {filename:20s} : {"
|
|
30
40
|
"message}"
|
|
31
41
|
)
|
|
32
|
-
LOG_FORMAT_CLEAN =
|
|
42
|
+
LOG_FORMAT_CLEAN = (
|
|
43
|
+
"{asctime} [{levelname:>8s}] {message} ({processName}[{process}]:{package_name}:{filename}:{lineno:d})"
|
|
44
|
+
)
|
|
33
45
|
|
|
34
46
|
LOG_DATE_FORMAT_FULL = "%Y-%m-%d %H:%M:%S"
|
|
35
47
|
LOG_DATE_FORMAT_CLEAN = "%Y-%m-%d %H:%M:%S"
|
|
36
48
|
|
|
37
49
|
|
|
38
|
-
class
|
|
50
|
+
class PackageFilter(logging.Filter):
|
|
51
|
+
"""Adds 'package_name' to the log record.
|
|
52
|
+
|
|
53
|
+
When this filter is added to a handler of a logger, the formatter of that
|
|
54
|
+
logger can use the 'package_name' attribute.
|
|
55
|
+
|
|
56
|
+
When the package name can not be determined, is will contain 'n/a'.
|
|
57
|
+
|
|
58
|
+
NOTE: this filer assumes the root package is 'egse'.
|
|
59
|
+
"""
|
|
60
|
+
|
|
39
61
|
def filter(self, record):
|
|
40
|
-
|
|
62
|
+
if hasattr(record, "pathname"):
|
|
63
|
+
parts = Path(record.pathname).parent.parts
|
|
64
|
+
try:
|
|
65
|
+
egse_index = parts.index("egse")
|
|
66
|
+
package_name = ".".join(parts[egse_index:])
|
|
67
|
+
except ValueError:
|
|
68
|
+
package_name = "n/a"
|
|
69
|
+
|
|
70
|
+
record.package_name = package_name
|
|
71
|
+
else:
|
|
72
|
+
record.package_name = "n/a"
|
|
41
73
|
|
|
74
|
+
return True
|
|
42
75
|
|
|
43
|
-
|
|
76
|
+
|
|
77
|
+
class EGSEFilter(logging.Filter):
|
|
78
|
+
def filter(self, record):
|
|
79
|
+
return record.name.startswith("egse")
|
|
44
80
|
|
|
45
81
|
|
|
46
82
|
class NonEGSEFilter(logging.Filter):
|
|
@@ -48,9 +84,6 @@ class NonEGSEFilter(logging.Filter):
|
|
|
48
84
|
return not record.name.startswith("egse")
|
|
49
85
|
|
|
50
86
|
|
|
51
|
-
root_filter = NonEGSEFilter()
|
|
52
|
-
|
|
53
|
-
|
|
54
87
|
def get_log_level_from_env(env_var: str = "LOG_LEVEL", default: int = logging.INFO):
|
|
55
88
|
"""Read the log level from an environment variable."""
|
|
56
89
|
log_level_str = os.getenv(env_var, default)
|
|
@@ -89,21 +122,19 @@ else:
|
|
|
89
122
|
egse_formatter = logging.Formatter(fmt=LOG_FORMAT_CLEAN, datefmt=LOG_DATE_FORMAT_CLEAN, style=LOG_FORMAT_STYLE)
|
|
90
123
|
|
|
91
124
|
egse_handler.setFormatter(egse_formatter)
|
|
92
|
-
egse_handler.addFilter(
|
|
125
|
+
egse_handler.addFilter(EGSEFilter())
|
|
126
|
+
egse_handler.addFilter(PackageFilter())
|
|
93
127
|
|
|
94
128
|
root_logger.addHandler(egse_handler)
|
|
95
129
|
|
|
96
130
|
for handler in root_logger.handlers:
|
|
97
131
|
if handler != egse_handler: # Don't filter our new handler
|
|
98
|
-
handler.addFilter(
|
|
132
|
+
handler.addFilter(NonEGSEFilter())
|
|
133
|
+
handler.addFilter(PackageFilter())
|
|
99
134
|
|
|
100
135
|
logger = egse_logger
|
|
101
136
|
|
|
102
137
|
if __name__ == "__main__":
|
|
103
|
-
logging.basicConfig(
|
|
104
|
-
level=get_log_level_from_env(), format=LOG_FORMAT_CLEAN, datefmt=LOG_DATE_FORMAT_CLEAN, style="{"
|
|
105
|
-
)
|
|
106
|
-
|
|
107
138
|
root_logger = logging.getLogger()
|
|
108
139
|
|
|
109
140
|
rich.print(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "cgse-core"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.15.0"
|
|
4
4
|
description = "Core services for the CGSE framework"
|
|
5
5
|
authors = [
|
|
6
6
|
{name = "IvS KU Leuven"}
|
|
@@ -49,6 +49,7 @@ log = 'cgse_core.services:log_cs'
|
|
|
49
49
|
cm = 'cgse_core.services:cm_cs'
|
|
50
50
|
sm = 'cgse_core.services:sm_cs'
|
|
51
51
|
pm = 'cgse_core.services:pm_cs'
|
|
52
|
+
notify = 'cgse_core.services:notifyhub'
|
|
52
53
|
|
|
53
54
|
[project.entry-points."cgse.explore"]
|
|
54
55
|
explore = "cgse_core.cgse_explore"
|
|
@@ -73,8 +74,8 @@ filterwarnings = [
|
|
|
73
74
|
"ignore::DeprecationWarning"
|
|
74
75
|
]
|
|
75
76
|
log_cli = true
|
|
76
|
-
log_cli_level = "
|
|
77
|
-
log_cli_format = "%(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s)"
|
|
77
|
+
log_cli_level = "DEBUG"
|
|
78
|
+
#log_cli_format = "%(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s)"
|
|
78
79
|
log_cli_date_format = "%Y-%m-%d %H:%M:%S"
|
|
79
80
|
|
|
80
81
|
[tool.coverage.run]
|
|
@@ -73,3 +73,17 @@ def start_pm_cs():
|
|
|
73
73
|
stdin=subprocess.DEVNULL,
|
|
74
74
|
close_fds=True,
|
|
75
75
|
)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def start_notifyhub():
|
|
79
|
+
rich.print("Starting the notification hub core service...")
|
|
80
|
+
|
|
81
|
+
out = open(Path("~/.notifyhub.start.out").expanduser(), "w")
|
|
82
|
+
|
|
83
|
+
subprocess.Popen(
|
|
84
|
+
[sys.executable, "-m", "egse.notifyhub.server", "start"],
|
|
85
|
+
stdout=out,
|
|
86
|
+
stderr=out,
|
|
87
|
+
stdin=subprocess.DEVNULL,
|
|
88
|
+
close_fds=True,
|
|
89
|
+
)
|
|
@@ -103,3 +103,23 @@ def stop_pm_cs():
|
|
|
103
103
|
waiting_for(lambda: not is_process_running(["procman_cs", "start"]), timeout=5.0)
|
|
104
104
|
except TimeoutError:
|
|
105
105
|
logger.warning("pm_cs should not be running anymore...")
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def stop_notifyhub():
|
|
109
|
+
rich.print("Terminating the notification hub core service...")
|
|
110
|
+
|
|
111
|
+
out = open(Path("~/.notifyhub.stop.out").expanduser(), "w")
|
|
112
|
+
|
|
113
|
+
subprocess.Popen(
|
|
114
|
+
[sys.executable, "-m", "egse.notifyhub.server", "stop"],
|
|
115
|
+
stdout=out,
|
|
116
|
+
stderr=out,
|
|
117
|
+
stdin=subprocess.DEVNULL,
|
|
118
|
+
close_fds=True,
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
try:
|
|
122
|
+
with Timer("notifyhub stop timer", log_level=logging.DEBUG):
|
|
123
|
+
waiting_for(lambda: not is_process_running(["egse.notifyhub.server", "start"]), timeout=5.0)
|
|
124
|
+
except TimeoutError:
|
|
125
|
+
logger.warning("notifyhub should not be running anymore...")
|
|
@@ -12,7 +12,7 @@ def show_processes():
|
|
|
12
12
|
"""Returns of list of ProcessInfo data classes for matching processes from this package."""
|
|
13
13
|
|
|
14
14
|
def filter_procs(pi: ProcessInfo):
|
|
15
|
-
pattern = r"(log|confman|storage|procman)_cs|registry\.server"
|
|
15
|
+
pattern = r"(log|confman|storage|procman)_cs|registry\.server|notifyhub\.server"
|
|
16
16
|
|
|
17
17
|
return re.search(pattern, pi.command)
|
|
18
18
|
|
|
@@ -12,6 +12,7 @@ from egse.signal import create_signal_command_file
|
|
|
12
12
|
from egse.system import TyperAsyncCommand
|
|
13
13
|
from ._start import start_cm_cs
|
|
14
14
|
from ._start import start_log_cs
|
|
15
|
+
from ._start import start_notifyhub
|
|
15
16
|
from ._start import start_pm_cs
|
|
16
17
|
from ._start import start_rm_cs
|
|
17
18
|
from ._start import start_sm_cs
|
|
@@ -23,6 +24,7 @@ from ._status import status_rm_cs
|
|
|
23
24
|
from ._status import status_sm_cs
|
|
24
25
|
from ._stop import stop_cm_cs
|
|
25
26
|
from ._stop import stop_log_cs
|
|
27
|
+
from ._stop import stop_notifyhub
|
|
26
28
|
from ._stop import stop_pm_cs
|
|
27
29
|
from ._stop import stop_rm_cs
|
|
28
30
|
from ._stop import stop_sm_cs
|
|
@@ -41,6 +43,7 @@ def start_core_services(log_level: str = "WARNING"):
|
|
|
41
43
|
|
|
42
44
|
start_rm_cs(log_level)
|
|
43
45
|
start_log_cs()
|
|
46
|
+
start_notifyhub()
|
|
44
47
|
start_sm_cs()
|
|
45
48
|
start_cm_cs()
|
|
46
49
|
start_pm_cs()
|
|
@@ -55,9 +58,12 @@ def stop_core_services():
|
|
|
55
58
|
stop_pm_cs()
|
|
56
59
|
stop_cm_cs()
|
|
57
60
|
stop_sm_cs()
|
|
61
|
+
stop_notifyhub()
|
|
62
|
+
|
|
58
63
|
# We need the logger for logging the termination process for other services, so leave it running for a while
|
|
59
64
|
time.sleep(1.0)
|
|
60
65
|
stop_log_cs()
|
|
66
|
+
|
|
61
67
|
# We need the registry server to stop other core services, so leave it running for a while
|
|
62
68
|
time.sleep(1.0)
|
|
63
69
|
stop_rm_cs()
|
|
@@ -274,3 +280,21 @@ def pm_cs_reregister(force: bool = False):
|
|
|
274
280
|
app_name,
|
|
275
281
|
{"action": "reregister", "params": {"force": force}},
|
|
276
282
|
)
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
notifyhub = typer.Typer(
|
|
286
|
+
name="notifyhub",
|
|
287
|
+
help="handle notification hub: start, stop, status, re-register",
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
@notifyhub.command(name="start")
|
|
292
|
+
def notifyhub_start():
|
|
293
|
+
"""Start the Process Manager."""
|
|
294
|
+
start_notifyhub()
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
@notifyhub.command(name="stop")
|
|
298
|
+
def notifyhub_stop():
|
|
299
|
+
"""Stop the Process Manager."""
|
|
300
|
+
stop_notifyhub()
|
|
@@ -3,9 +3,13 @@ PACKAGES:
|
|
|
3
3
|
|
|
4
4
|
Logging Control Server: # LOG_CS
|
|
5
5
|
|
|
6
|
-
SERVICE_TYPE:
|
|
6
|
+
SERVICE_TYPE: LOG_CS
|
|
7
7
|
MAX_NR_LOG_FILES: 20 # The maximum number of log files that will be maintained in a roll-over
|
|
8
8
|
MAX_SIZE_LOG_FILES: 20 # The maximum size one log file can become
|
|
9
|
+
# PROTOCOL: tcp
|
|
10
|
+
# HOSTNAME: localhost
|
|
11
|
+
RECEIVER_PORT: 4248
|
|
12
|
+
COMMANDER_PORT: 4249
|
|
9
13
|
TEXTUALOG_IP_ADDRESS: 127.0.0.1 # The IP address of the textualog listening server
|
|
10
14
|
TEXTUALOG_LISTENING_PORT: 19996 # The port number on which the textualog server is listening
|
|
11
15
|
|
|
@@ -27,9 +31,11 @@ Process Manager Control Server: # PM_CS
|
|
|
27
31
|
STORAGE_MNEMONIC: PM # The mnemonic to be used in the filename storing the housekeeping data
|
|
28
32
|
|
|
29
33
|
Notify Hub:
|
|
34
|
+
|
|
30
35
|
SERVICE_TYPE: NOTIFY_HUB
|
|
31
36
|
COLLECTOR_PORT: 4245
|
|
32
37
|
PUBLISHER_PORT: 4246
|
|
38
|
+
REQUESTS_PORT: 4247
|
|
33
39
|
|
|
34
40
|
Metrics Hub:
|
|
35
41
|
SERVICE_TYPE: METRICS_HUB
|
|
@@ -139,6 +139,8 @@ from egse.env import get_site_id
|
|
|
139
139
|
from egse.exceptions import InternalError
|
|
140
140
|
from egse.listener import EVENT_ID
|
|
141
141
|
from egse.log import logger
|
|
142
|
+
from egse.notifyhub.event import NotificationEvent
|
|
143
|
+
from egse.notifyhub.services import EventPublisher
|
|
142
144
|
from egse.obsid import ObservationIdentifier
|
|
143
145
|
from egse.plugin import entry_points
|
|
144
146
|
from egse.protocol import CommandProtocol
|
|
@@ -757,6 +759,11 @@ class ConfigurationManagerController(ConfigurationManagerInterface):
|
|
|
757
759
|
EVENT_ID.SETUP, {"event_type": "new_setup", "setup_id": self._setup_id}
|
|
758
760
|
)
|
|
759
761
|
|
|
762
|
+
with EventPublisher() as pub:
|
|
763
|
+
pub.publish(
|
|
764
|
+
NotificationEvent(event_type="new_setup", source_service="cm_cs", data={"setup_id": self._setup_id})
|
|
765
|
+
)
|
|
766
|
+
|
|
760
767
|
return self._setup
|
|
761
768
|
except SettingsError as exc:
|
|
762
769
|
return Failure(f"The Setup file can not be loaded from {setup_file}.", exc)
|
|
@@ -941,6 +948,11 @@ class ConfigurationManagerController(ConfigurationManagerInterface):
|
|
|
941
948
|
EVENT_ID.SETUP, {"event_type": "new_setup", "setup_id": setup_id}
|
|
942
949
|
)
|
|
943
950
|
|
|
951
|
+
with EventPublisher() as pub:
|
|
952
|
+
pub.publish(
|
|
953
|
+
NotificationEvent(event_type="new_setup", source_service="cm_cs", data={"setup_id": self._setup_id})
|
|
954
|
+
)
|
|
955
|
+
|
|
944
956
|
return setup
|
|
945
957
|
|
|
946
958
|
def get_next_setup_id_for_site(self, site: str) -> int:
|
|
@@ -23,6 +23,7 @@ from egse.confman import ConfigurationManagerProtocol
|
|
|
23
23
|
from egse.confman import ConfigurationManagerProxy
|
|
24
24
|
from egse.control import ControlServer
|
|
25
25
|
from egse.env import get_conf_data_location
|
|
26
|
+
from egse.logger import remote_logging
|
|
26
27
|
from egse.process import SubProcess
|
|
27
28
|
from egse.registry.client import RegistryClient
|
|
28
29
|
from egse.response import Failure
|
|
@@ -136,24 +137,25 @@ def start():
|
|
|
136
137
|
|
|
137
138
|
multiprocessing.current_process().name = "cm_cs"
|
|
138
139
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
140
|
+
with remote_logging():
|
|
141
|
+
try:
|
|
142
|
+
check_prerequisites()
|
|
143
|
+
except RuntimeError as exc:
|
|
144
|
+
logger.info(exc)
|
|
145
|
+
return 0
|
|
146
|
+
|
|
147
|
+
try:
|
|
148
|
+
control_server = ConfigurationManagerControlServer()
|
|
149
|
+
control_server.serve()
|
|
150
|
+
except KeyboardInterrupt:
|
|
151
|
+
print("Shutdown requested...exiting")
|
|
152
|
+
except SystemExit as exit_code:
|
|
153
|
+
print(f"System Exit with code {exit_code}.")
|
|
154
|
+
sys.exit(exit_code.code)
|
|
155
|
+
except Exception:
|
|
156
|
+
import traceback
|
|
157
|
+
|
|
158
|
+
traceback.print_exc(file=sys.stdout)
|
|
157
159
|
|
|
158
160
|
return 0
|
|
159
161
|
|
|
@@ -25,12 +25,14 @@ from egse.listener import Listeners
|
|
|
25
25
|
from egse.log import logger
|
|
26
26
|
from egse.logger import close_all_zmq_handlers
|
|
27
27
|
from egse.metrics import get_metrics_repo
|
|
28
|
+
from egse.notifyhub.services import EventSubscriber
|
|
28
29
|
from egse.process import ProcessStatus
|
|
29
30
|
from egse.registry.client import RegistryClient
|
|
30
31
|
from egse.settings import Settings
|
|
31
32
|
from egse.settings import get_site_id
|
|
32
33
|
from egse.signal import FileBasedSignaling
|
|
33
34
|
from egse.system import SignalCatcher
|
|
35
|
+
from egse.system import Timer
|
|
34
36
|
from egse.system import camel_to_kebab
|
|
35
37
|
from egse.system import camel_to_snake
|
|
36
38
|
from egse.system import do_every
|
|
@@ -165,10 +167,16 @@ class ControlServer(metaclass=abc.ABCMeta):
|
|
|
165
167
|
|
|
166
168
|
self.dev_ctrl_cmd_sock = self.zcontext.socket(zmq.REP)
|
|
167
169
|
|
|
170
|
+
# Set up the event subscription
|
|
171
|
+
|
|
172
|
+
self.event_subscription = EventSubscriber(subscriptions=self.get_event_subscriptions())
|
|
173
|
+
self.event_subscription.connect()
|
|
174
|
+
|
|
168
175
|
# Initialise the poll set
|
|
169
176
|
|
|
170
177
|
self.poller.register(self.dev_ctrl_service_sock, zmq.POLLIN)
|
|
171
178
|
self.poller.register(self.dev_ctrl_mon_sock, zmq.POLLIN) # FIXME: I think this should not be registered
|
|
179
|
+
self.poller.register(self.event_subscription.socket, zmq.POLLIN)
|
|
172
180
|
|
|
173
181
|
token = os.getenv("INFLUXDB3_AUTH_TOKEN")
|
|
174
182
|
project = os.getenv("PROJECT")
|
|
@@ -186,6 +194,14 @@ class ControlServer(metaclass=abc.ABCMeta):
|
|
|
186
194
|
"Metrics will not be propagated to InfluxDB."
|
|
187
195
|
)
|
|
188
196
|
|
|
197
|
+
def get_event_subscriptions(self) -> list[str]:
|
|
198
|
+
"""Override this in the subclass to actually subscribe to events."""
|
|
199
|
+
return []
|
|
200
|
+
|
|
201
|
+
def get_event_handlers(self) -> dict[str, Callable]:
|
|
202
|
+
"""Override this in the subclass to provide methods to handle each of the subscriptions."""
|
|
203
|
+
return {}
|
|
204
|
+
|
|
189
205
|
@abc.abstractmethod
|
|
190
206
|
def get_communication_protocol(self) -> str:
|
|
191
207
|
"""Returns the communication protocol used by the Control Server.
|
|
@@ -451,6 +467,11 @@ class ControlServer(metaclass=abc.ABCMeta):
|
|
|
451
467
|
|
|
452
468
|
self.scheduled_tasks.append({"task": callback, "name": name, "after": scheduled_time, "when": when})
|
|
453
469
|
|
|
470
|
+
def setup_event_subscription(self):
|
|
471
|
+
for event_type, handler in self.get_event_handlers().items():
|
|
472
|
+
self.logger.info(f"Registering handler {type_name(handler)} for {event_type}")
|
|
473
|
+
self.event_subscription.register_handler(event_type, handler)
|
|
474
|
+
|
|
454
475
|
def serve(self) -> None:
|
|
455
476
|
"""Activation of the Control Server.
|
|
456
477
|
|
|
@@ -474,6 +495,8 @@ class ControlServer(metaclass=abc.ABCMeta):
|
|
|
474
495
|
|
|
475
496
|
self.before_serve()
|
|
476
497
|
|
|
498
|
+
self.setup_event_subscription()
|
|
499
|
+
|
|
477
500
|
# check if Storage Manager is available
|
|
478
501
|
|
|
479
502
|
storage_manager = self.is_storage_manager_active()
|
|
@@ -508,6 +531,10 @@ class ControlServer(metaclass=abc.ABCMeta):
|
|
|
508
531
|
if self.dev_ctrl_service_sock in socks:
|
|
509
532
|
self.service_protocol.execute()
|
|
510
533
|
|
|
534
|
+
if self.event_subscription.socket in socks:
|
|
535
|
+
with Timer("Handling notification event"):
|
|
536
|
+
self.event_subscription.handle_event()
|
|
537
|
+
|
|
511
538
|
# Handle sending out monitoring information periodically, based on the MON_DELAY time that is specified in
|
|
512
539
|
# the YAML configuration file for the device
|
|
513
540
|
|
|
@@ -581,6 +608,8 @@ class ControlServer(metaclass=abc.ABCMeta):
|
|
|
581
608
|
self.dev_ctrl_service_sock.close(linger=0)
|
|
582
609
|
self.dev_ctrl_cmd_sock.close(linger=0)
|
|
583
610
|
|
|
611
|
+
self.event_subscription.disconnect()
|
|
612
|
+
|
|
584
613
|
close_all_zmq_handlers()
|
|
585
614
|
|
|
586
615
|
# Since we closed all ZeroMQ handlers, we shall use standard logging from here.
|