pysio-hermes 0.1.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.
Files changed (57) hide show
  1. pysio_hermes-0.1.0/LICENSE +20 -0
  2. pysio_hermes-0.1.0/PKG-INFO +178 -0
  3. pysio_hermes-0.1.0/README.md +131 -0
  4. pysio_hermes-0.1.0/examples/main.py +223 -0
  5. pysio_hermes-0.1.0/pyproject.toml +64 -0
  6. pysio_hermes-0.1.0/pysio_hermes.egg-info/PKG-INFO +178 -0
  7. pysio_hermes-0.1.0/pysio_hermes.egg-info/SOURCES.txt +55 -0
  8. pysio_hermes-0.1.0/pysio_hermes.egg-info/dependency_links.txt +1 -0
  9. pysio_hermes-0.1.0/pysio_hermes.egg-info/requires.txt +20 -0
  10. pysio_hermes-0.1.0/pysio_hermes.egg-info/top_level.txt +3 -0
  11. pysio_hermes-0.1.0/setup.cfg +4 -0
  12. pysio_hermes-0.1.0/src/hermes/__init__.py +0 -0
  13. pysio_hermes-0.1.0/src/hermes/base/__init__.py +0 -0
  14. pysio_hermes-0.1.0/src/hermes/base/broker/__init__.py +1 -0
  15. pysio_hermes-0.1.0/src/hermes/base/broker/broker.py +362 -0
  16. pysio_hermes-0.1.0/src/hermes/base/broker/broker_interface.py +152 -0
  17. pysio_hermes-0.1.0/src/hermes/base/broker/broker_states.py +350 -0
  18. pysio_hermes-0.1.0/src/hermes/base/delay_estimator.py +53 -0
  19. pysio_hermes-0.1.0/src/hermes/base/nodes/__init__.py +11 -0
  20. pysio_hermes-0.1.0/src/hermes/base/nodes/consumer.py +163 -0
  21. pysio_hermes-0.1.0/src/hermes/base/nodes/consumer_interface.py +32 -0
  22. pysio_hermes-0.1.0/src/hermes/base/nodes/node.py +150 -0
  23. pysio_hermes-0.1.0/src/hermes/base/nodes/node_interface.py +86 -0
  24. pysio_hermes-0.1.0/src/hermes/base/nodes/node_states.py +103 -0
  25. pysio_hermes-0.1.0/src/hermes/base/nodes/pipeline.py +208 -0
  26. pysio_hermes-0.1.0/src/hermes/base/nodes/pipeline_interface.py +52 -0
  27. pysio_hermes-0.1.0/src/hermes/base/nodes/producer.py +168 -0
  28. pysio_hermes-0.1.0/src/hermes/base/nodes/producer_interface.py +69 -0
  29. pysio_hermes-0.1.0/src/hermes/base/state_interface.py +42 -0
  30. pysio_hermes-0.1.0/src/hermes/base/storage/__init__.py +1 -0
  31. pysio_hermes-0.1.0/src/hermes/base/storage/storage.py +837 -0
  32. pysio_hermes-0.1.0/src/hermes/base/storage/storage_interface.py +73 -0
  33. pysio_hermes-0.1.0/src/hermes/base/storage/storage_states.py +93 -0
  34. pysio_hermes-0.1.0/src/hermes/base/stream.py +393 -0
  35. pysio_hermes-0.1.0/src/hermes/datastructures/__init__.py +0 -0
  36. pysio_hermes-0.1.0/src/hermes/datastructures/cache.py +121 -0
  37. pysio_hermes-0.1.0/src/hermes/datastructures/fifo.py +241 -0
  38. pysio_hermes-0.1.0/src/hermes/dummy/__init__.py +4 -0
  39. pysio_hermes-0.1.0/src/hermes/dummy/consumer.py +59 -0
  40. pysio_hermes-0.1.0/src/hermes/dummy/pipeline.py +83 -0
  41. pysio_hermes-0.1.0/src/hermes/dummy/producer.py +99 -0
  42. pysio_hermes-0.1.0/src/hermes/dummy/stream.py +53 -0
  43. pysio_hermes-0.1.0/src/hermes/logger/__init__.py +0 -0
  44. pysio_hermes-0.1.0/src/hermes/logger/consumer.py +66 -0
  45. pysio_hermes-0.1.0/src/hermes/utils/__init__.py +0 -0
  46. pysio_hermes-0.1.0/src/hermes/utils/angle_utils.py +59 -0
  47. pysio_hermes-0.1.0/src/hermes/utils/argparse_utils.py +110 -0
  48. pysio_hermes-0.1.0/src/hermes/utils/dict_utils.py +102 -0
  49. pysio_hermes-0.1.0/src/hermes/utils/mp_utils.py +31 -0
  50. pysio_hermes-0.1.0/src/hermes/utils/msgpack_utils.py +65 -0
  51. pysio_hermes-0.1.0/src/hermes/utils/node_utils.py +62 -0
  52. pysio_hermes-0.1.0/src/hermes/utils/numpy_utils.py +56 -0
  53. pysio_hermes-0.1.0/src/hermes/utils/print_utils.py +186 -0
  54. pysio_hermes-0.1.0/src/hermes/utils/sensor_utils.py +45 -0
  55. pysio_hermes-0.1.0/src/hermes/utils/time_utils.py +139 -0
  56. pysio_hermes-0.1.0/src/hermes/utils/types.py +52 -0
  57. pysio_hermes-0.1.0/src/hermes/utils/zmq_utils.py +66 -0
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2025 Maxim Yudayev [https://yudayev.com] and KU Leuven eMedia Lab.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,178 @@
1
+ Metadata-Version: 2.4
2
+ Name: pysio-hermes
3
+ Version: 0.1.0
4
+ Summary: A realtime physiological sensing and edge AI processing framework
5
+ Author: e-Media Research Lab @ KU Leuven
6
+ Author-email: Maxim Yudayev <maxim.yudayev@gmail.com>
7
+ License-Expression: MIT
8
+ Project-URL: Homepage, https://maximyudayev.github.io/hermes
9
+ Project-URL: Documentation, https://maximyudayev.github.io/hermes
10
+ Project-URL: Repository, https://github.com/maximyudayev/hermes.git
11
+ Project-URL: Issues, https://github.com/maximyudayev/hermes/issues
12
+ Project-URL: Changelog, https://github.com/maximyudayev/hermes/blob/main/CHANGELOG.md
13
+ Keywords: embedded ai,wearables,sensors,streaming,realtime processing,physiology
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Development Status :: 4 - Beta
17
+ Classifier: Intended Audience :: Healthcare Industry
18
+ Classifier: Intended Audience :: Education
19
+ Classifier: Intended Audience :: Developers
20
+ Classifier: Intended Audience :: Science/Research
21
+ Classifier: Topic :: Scientific/Engineering
22
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
23
+ Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
24
+ Classifier: Topic :: System :: Distributed Computing
25
+ Requires-Python: >=3.7
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Requires-Dist: pyzmq
29
+ Requires-Dist: msgpack
30
+ Requires-Dist: ffmpeg-python
31
+ Requires-Dist: h5py
32
+ Requires-Dist: numpy
33
+ Requires-Dist: pandas
34
+ Requires-Dist: pyyaml
35
+ Requires-Dist: pyusb
36
+ Requires-Dist: pyserial
37
+ Requires-Dist: pyperclip
38
+ Requires-Dist: openpyxl
39
+ Requires-Dist: orjson
40
+ Provides-Extra: build
41
+ Requires-Dist: build; extra == "build"
42
+ Requires-Dist: twine; extra == "build"
43
+ Provides-Extra: docs
44
+ Requires-Dist: mkdocs-material; extra == "docs"
45
+ Requires-Dist: mkdocstrings-python; extra == "docs"
46
+ Dynamic: license-file
47
+
48
+ <h1 align="center">
49
+ <img src="https://raw.githubusercontent.com/maximyudayev/hermes/refs/heads/main/images/logo.png" alt="HERMES: Heterogeneous Edge Realtime Measurement and Execution System" width="60%">
50
+
51
+ <br>
52
+ Heterogeneous Edge Realtime Measurement and Execution System
53
+ </h1>
54
+
55
+ <h4 align="center">A Unified Open-Source Framework for Realtime Multimodal Physiological Sensing, Edge AI, and Intervention in Closed-Loop Smart Healthcare Applications
56
+ </h4>
57
+
58
+ <div align="center">
59
+
60
+ ![Windows](https://img.shields.io/badge/Windows-0078D6?style=for-the-badge&logo=windows&logoColor=white)
61
+ ![Linux](https://img.shields.io/badge/Linux-FCC624?style=for-the-badge&logo=linux&logoColor=black)
62
+ ![macOS](https://img.shields.io/badge/mac%20os-000000?style=for-the-badge&logo=macos&logoColor=F0F0F0)
63
+
64
+ </div>
65
+
66
+ <p align="center">
67
+ <a href="#installation">Quickstart</a> •
68
+ <a href="https://maximyudayev.github.io/hermes">Docs</a> •
69
+ <a href="#data-annotation">GUI</a> •
70
+ <a href="#showcase">Showcase</a> •
71
+ <a href="#citation">Cite</a> •
72
+ <a href="#contact">Contact</a>
73
+ </p>
74
+
75
+ HERMES for the Greek mythology analogy of the god of communication and speed, protector of information, the gods' herald. He embodies the nature of smooth and reliable communication. His role accurately resonates with the vision of this framework: facilitate reliable and fast exchange of continuously generated multimodal physiological and external data across distributed wireless and wired multi-sensor hosts for synchronized realtime data collection, in-the-loop AI stream processing, and analysis, in intelligent med- and health-tech (wearable) applications.
76
+
77
+ <div align="center"><img src="https://raw.githubusercontent.com/maximyudayev/hermes/refs/heads/main/images/overview.png" alt="Overview of the system architecture on one of the distributed hosts" width="80%"></div>
78
+ <br>
79
+
80
+ HERMES offers out-of-the-box streaming integrations to a number of commercial sensor devices and systems, high resolution cameras, templates for extension with custom user devices, and a ready-made wrapper for easy PyTorch AI model insertion. It reliably and synchronously captures heterogeneous data across distributed interconnected devices on a local network in a continuous manner, and enables realtime AI processing at the edge toward personalized intelligent closed-loop interventions of the user. All continuously acquired data is periodically flushed to disk for as long as the system has disk space, as MKV/MP4 and HDF5 files, for video and sensor data, respectively.
81
+
82
+ # Quickstart
83
+ ## Core
84
+ Create a Python 3 virtual environment `python -m venv .venv` (python >= 3.7).
85
+
86
+ Activate it with `.venv/bin/activate` for Linux or `.venv\Scripts\activate` for Windows.
87
+
88
+ Single-command install HERMES into your project along other dependendices.
89
+ ```bash
90
+ pip install pysio-hermes
91
+ ```
92
+
93
+ ## Extra
94
+ All the integrated, validated and supported sensor devices are separately installable as `pysio-hermes-<subpackage_name>`, like:
95
+ ```bash
96
+ pip install pysio-hermes-torch
97
+ ```
98
+ Will install the AI processing subpackage to wrap user-specified PyTorch models.
99
+
100
+ <details>
101
+ <summary>List of supported devices <i>(continuously updated)</i></summary>
102
+ Some subpackages require OEM software installation, check each below for detailed prerequisites.
103
+
104
+ - `torch` [Wrapper for PyTorch AI models](https://github.com/maximyudayev/hermes-torch)
105
+ - `pupillabs` [Pupil Labs Core smartglasses](https://github.com/maximyudayev/hermes-pupillabs)
106
+ - `basler` [Basler cameras](https://github.com/maximyudayev/hermes-basler)
107
+ - `dots` [Movella DOTs IMUs](https://github.com/maximyudayev/hermes-dots)
108
+ - `mvn` [Xsens MVN Analyze MoCap suit](https://github.com/maximyudayev/hermes-mvn)
109
+ - `awinda` [Xsens Awinda IMUs](https://github.com/maximyudayev/hermes-awinda)
110
+ - `cometa` [Cometa WavePlus sEMG](https://github.com/maximyudayev/hermes-cometa)
111
+ - `moticon` [Moticon OpenGo pressure insoles](https://github.com/maximyudayev/hermes-moticon)
112
+ - `tmsi` [TMSi SAGA physiological signals](https://github.com/maximyudayev/hermes-tmsi)
113
+ - `vicon` [Vicon Nexus capture system](https://github.com/maximyudayev/hermes-vicon)
114
+ - `moxy` [Moxy muscle oxygenation monitor](https://github.com/maximyudayev/hermes-moxy)
115
+
116
+ The following subpackages are in development.
117
+ - `gui` [Live monitoring dashboard](https://github.com/maximyudayev/hermes-gui)
118
+ - `mic` [PC-attached generic microphone](https://github.com/maximyudayev/hermes-mic)
119
+
120
+ </details>
121
+ <br>
122
+
123
+ # Documentation
124
+ Check out the [full documentation site](https://maximyudayev.github.io/hermes) for more usage examples, architecture overview, detailed extension guide, and FAQs.
125
+
126
+ # Data Annotation
127
+ <div align="center"><img src="https://raw.githubusercontent.com/maximyudayev/hermes/refs/heads/main/images/gui.png" alt="Pysioviz: A dashboard for visualization and annotation of collected multimodal data for AI workflows" width="80%"></div>
128
+ <br>
129
+
130
+ We developed [PysioViz](https://github.com/maximyudayev/pysioviz) a complementary dashboard based on [Dash Plotly](https://dash.plotly.com/) for analysis and annotation of the collected multimodal data. We use it ourselves to generate ground truth labels for the AI training workflows. Check it out and leave feedback!
131
+
132
+ # Showcase
133
+ These are some of our own projects enabled by HERMES to excite you to adopt it in your smart closed-looop healthtech usecases.
134
+
135
+ <details>
136
+ <summary>AI-enabled intent prediction for high-level locomotion mode selection in a smart leg prosthesis</summary>
137
+ </details>
138
+ <br>
139
+
140
+ <details>
141
+ <summary>Realtime automated cueing for freezing-of-gait Parkinson's patients in free-living conditions</summary>
142
+ </details>
143
+ <br>
144
+
145
+ <details>
146
+ <summary>Personalized level of assistance in prolong use rehabilitation and support exoskeletons</summary>
147
+ </details>
148
+ <br>
149
+
150
+ # License
151
+ This project is licensed under the MIT license - see the [LICENSE](/LICENSE) file for details.
152
+
153
+ # Citation
154
+ When using in your project, research, or product, please cite the following and notify us so we can update the index of success stories enabled by HERMES.
155
+
156
+ <!-- <a href="https://arxiv.org/abs/..." style="display:inline-block;">
157
+ <img src="http://img.shields.io/badge/paper-arxiv.x-B31B1B.svg" height="20" >
158
+ </a>
159
+ ```bibtex
160
+ @inproceedings{yudayev2025hermes,
161
+ title={HERMES: A Unified Open-Source Framework for Realtime Multimodal Physiological Sensing, Edge AI, and Intervention in Closed-Loop Smart Healthcare Applications},
162
+ author={Yudayev, Maxim and Carlon, Juha and Lamsal, Diwas and Vanrumste, Bart, and Filtjens, Benjamin},
163
+ booktitle={},
164
+ year={2025}
165
+ }
166
+ ``` -->
167
+
168
+ # Acknowledgement
169
+ This project was primarily written by Maxim Yudayev while at the Department of Electrical Engineering, KU Leuven.
170
+
171
+ This study was funded, in part, by the AidWear project funded by the Federal Public Service for Policy and Support,
172
+ the AID-FOG project by the Michael J. Fox Foundation for Parkinson’s Research under Grant No.: MJFF-024628,
173
+ and the Flemish Government under the Flanders AI Research Program (FAIR).
174
+
175
+ HERMES is a "Ship of Theseus"[[1](https://en.wikipedia.org/wiki/Ship_of_Theseus)] of [ActionSense](https://github.com/delpreto/ActionNet) that started as a fork and became a complete architectural rewrite of the system from the ground up to bridge the fundamental gaps in the state-of-the-art, and to match our research group's needs in realtime deployments and reliable data acquisition.
176
+ Although there is no part of ActionSense in HERMES, we believe that its authors deserve recognition as inspiration for our system.
177
+
178
+ Special thanks for contributions, usage, bug reports, good times, and feature requests to Juha Carlon (KU Leuven), Stefano Nuzzo (VUB), Diwas Lamsal (KU Leuven), Vayalet Stefanova (KU Leuven), Léonore Foguenne (ULiège).
@@ -0,0 +1,131 @@
1
+ <h1 align="center">
2
+ <img src="https://raw.githubusercontent.com/maximyudayev/hermes/refs/heads/main/images/logo.png" alt="HERMES: Heterogeneous Edge Realtime Measurement and Execution System" width="60%">
3
+
4
+ <br>
5
+ Heterogeneous Edge Realtime Measurement and Execution System
6
+ </h1>
7
+
8
+ <h4 align="center">A Unified Open-Source Framework for Realtime Multimodal Physiological Sensing, Edge AI, and Intervention in Closed-Loop Smart Healthcare Applications
9
+ </h4>
10
+
11
+ <div align="center">
12
+
13
+ ![Windows](https://img.shields.io/badge/Windows-0078D6?style=for-the-badge&logo=windows&logoColor=white)
14
+ ![Linux](https://img.shields.io/badge/Linux-FCC624?style=for-the-badge&logo=linux&logoColor=black)
15
+ ![macOS](https://img.shields.io/badge/mac%20os-000000?style=for-the-badge&logo=macos&logoColor=F0F0F0)
16
+
17
+ </div>
18
+
19
+ <p align="center">
20
+ <a href="#installation">Quickstart</a> •
21
+ <a href="https://maximyudayev.github.io/hermes">Docs</a> •
22
+ <a href="#data-annotation">GUI</a> •
23
+ <a href="#showcase">Showcase</a> •
24
+ <a href="#citation">Cite</a> •
25
+ <a href="#contact">Contact</a>
26
+ </p>
27
+
28
+ HERMES for the Greek mythology analogy of the god of communication and speed, protector of information, the gods' herald. He embodies the nature of smooth and reliable communication. His role accurately resonates with the vision of this framework: facilitate reliable and fast exchange of continuously generated multimodal physiological and external data across distributed wireless and wired multi-sensor hosts for synchronized realtime data collection, in-the-loop AI stream processing, and analysis, in intelligent med- and health-tech (wearable) applications.
29
+
30
+ <div align="center"><img src="https://raw.githubusercontent.com/maximyudayev/hermes/refs/heads/main/images/overview.png" alt="Overview of the system architecture on one of the distributed hosts" width="80%"></div>
31
+ <br>
32
+
33
+ HERMES offers out-of-the-box streaming integrations to a number of commercial sensor devices and systems, high resolution cameras, templates for extension with custom user devices, and a ready-made wrapper for easy PyTorch AI model insertion. It reliably and synchronously captures heterogeneous data across distributed interconnected devices on a local network in a continuous manner, and enables realtime AI processing at the edge toward personalized intelligent closed-loop interventions of the user. All continuously acquired data is periodically flushed to disk for as long as the system has disk space, as MKV/MP4 and HDF5 files, for video and sensor data, respectively.
34
+
35
+ # Quickstart
36
+ ## Core
37
+ Create a Python 3 virtual environment `python -m venv .venv` (python >= 3.7).
38
+
39
+ Activate it with `.venv/bin/activate` for Linux or `.venv\Scripts\activate` for Windows.
40
+
41
+ Single-command install HERMES into your project along other dependendices.
42
+ ```bash
43
+ pip install pysio-hermes
44
+ ```
45
+
46
+ ## Extra
47
+ All the integrated, validated and supported sensor devices are separately installable as `pysio-hermes-<subpackage_name>`, like:
48
+ ```bash
49
+ pip install pysio-hermes-torch
50
+ ```
51
+ Will install the AI processing subpackage to wrap user-specified PyTorch models.
52
+
53
+ <details>
54
+ <summary>List of supported devices <i>(continuously updated)</i></summary>
55
+ Some subpackages require OEM software installation, check each below for detailed prerequisites.
56
+
57
+ - `torch` [Wrapper for PyTorch AI models](https://github.com/maximyudayev/hermes-torch)
58
+ - `pupillabs` [Pupil Labs Core smartglasses](https://github.com/maximyudayev/hermes-pupillabs)
59
+ - `basler` [Basler cameras](https://github.com/maximyudayev/hermes-basler)
60
+ - `dots` [Movella DOTs IMUs](https://github.com/maximyudayev/hermes-dots)
61
+ - `mvn` [Xsens MVN Analyze MoCap suit](https://github.com/maximyudayev/hermes-mvn)
62
+ - `awinda` [Xsens Awinda IMUs](https://github.com/maximyudayev/hermes-awinda)
63
+ - `cometa` [Cometa WavePlus sEMG](https://github.com/maximyudayev/hermes-cometa)
64
+ - `moticon` [Moticon OpenGo pressure insoles](https://github.com/maximyudayev/hermes-moticon)
65
+ - `tmsi` [TMSi SAGA physiological signals](https://github.com/maximyudayev/hermes-tmsi)
66
+ - `vicon` [Vicon Nexus capture system](https://github.com/maximyudayev/hermes-vicon)
67
+ - `moxy` [Moxy muscle oxygenation monitor](https://github.com/maximyudayev/hermes-moxy)
68
+
69
+ The following subpackages are in development.
70
+ - `gui` [Live monitoring dashboard](https://github.com/maximyudayev/hermes-gui)
71
+ - `mic` [PC-attached generic microphone](https://github.com/maximyudayev/hermes-mic)
72
+
73
+ </details>
74
+ <br>
75
+
76
+ # Documentation
77
+ Check out the [full documentation site](https://maximyudayev.github.io/hermes) for more usage examples, architecture overview, detailed extension guide, and FAQs.
78
+
79
+ # Data Annotation
80
+ <div align="center"><img src="https://raw.githubusercontent.com/maximyudayev/hermes/refs/heads/main/images/gui.png" alt="Pysioviz: A dashboard for visualization and annotation of collected multimodal data for AI workflows" width="80%"></div>
81
+ <br>
82
+
83
+ We developed [PysioViz](https://github.com/maximyudayev/pysioviz) a complementary dashboard based on [Dash Plotly](https://dash.plotly.com/) for analysis and annotation of the collected multimodal data. We use it ourselves to generate ground truth labels for the AI training workflows. Check it out and leave feedback!
84
+
85
+ # Showcase
86
+ These are some of our own projects enabled by HERMES to excite you to adopt it in your smart closed-looop healthtech usecases.
87
+
88
+ <details>
89
+ <summary>AI-enabled intent prediction for high-level locomotion mode selection in a smart leg prosthesis</summary>
90
+ </details>
91
+ <br>
92
+
93
+ <details>
94
+ <summary>Realtime automated cueing for freezing-of-gait Parkinson's patients in free-living conditions</summary>
95
+ </details>
96
+ <br>
97
+
98
+ <details>
99
+ <summary>Personalized level of assistance in prolong use rehabilitation and support exoskeletons</summary>
100
+ </details>
101
+ <br>
102
+
103
+ # License
104
+ This project is licensed under the MIT license - see the [LICENSE](/LICENSE) file for details.
105
+
106
+ # Citation
107
+ When using in your project, research, or product, please cite the following and notify us so we can update the index of success stories enabled by HERMES.
108
+
109
+ <!-- <a href="https://arxiv.org/abs/..." style="display:inline-block;">
110
+ <img src="http://img.shields.io/badge/paper-arxiv.x-B31B1B.svg" height="20" >
111
+ </a>
112
+ ```bibtex
113
+ @inproceedings{yudayev2025hermes,
114
+ title={HERMES: A Unified Open-Source Framework for Realtime Multimodal Physiological Sensing, Edge AI, and Intervention in Closed-Loop Smart Healthcare Applications},
115
+ author={Yudayev, Maxim and Carlon, Juha and Lamsal, Diwas and Vanrumste, Bart, and Filtjens, Benjamin},
116
+ booktitle={},
117
+ year={2025}
118
+ }
119
+ ``` -->
120
+
121
+ # Acknowledgement
122
+ This project was primarily written by Maxim Yudayev while at the Department of Electrical Engineering, KU Leuven.
123
+
124
+ This study was funded, in part, by the AidWear project funded by the Federal Public Service for Policy and Support,
125
+ the AID-FOG project by the Michael J. Fox Foundation for Parkinson’s Research under Grant No.: MJFF-024628,
126
+ and the Flemish Government under the Flanders AI Research Program (FAIR).
127
+
128
+ HERMES is a "Ship of Theseus"[[1](https://en.wikipedia.org/wiki/Ship_of_Theseus)] of [ActionSense](https://github.com/delpreto/ActionNet) that started as a fork and became a complete architectural rewrite of the system from the ground up to bridge the fundamental gaps in the state-of-the-art, and to match our research group's needs in realtime deployments and reliable data acquisition.
129
+ Although there is no part of ActionSense in HERMES, we believe that its authors deserve recognition as inspiration for our system.
130
+
131
+ Special thanks for contributions, usage, bug reports, good times, and feature requests to Juha Carlon (KU Leuven), Stefano Nuzzo (VUB), Diwas Lamsal (KU Leuven), Vayalet Stefanova (KU Leuven), Léonore Foguenne (ULiège).
@@ -0,0 +1,223 @@
1
+ ############
2
+ #
3
+ # Copyright (c) 2024 Maxim Yudayev and KU Leuven eMedia Lab
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+ #
23
+ # Created 2024-2025 for the KU Leuven AidWear, AidFOG, and RevalExo projects
24
+ # by Maxim Yudayev [https://yudayev.com].
25
+ #
26
+ # ############
27
+
28
+ import threading
29
+ import os
30
+ import yaml
31
+ import argparse
32
+ import sys
33
+
34
+
35
+ sys.path.append("./src")
36
+
37
+ from hermes.base.nodes import Node
38
+ from hermes.base.broker import Broker
39
+ from hermes.utils.mp_utils import launch_callable
40
+ from hermes.utils.node_utils import search_node_class
41
+ from hermes.utils.time_utils import *
42
+ from hermes.utils.zmq_utils import *
43
+ from hermes.utils.argparse_utils import *
44
+
45
+
46
+ __version = 'v0.1.0'
47
+
48
+ HERMES = r"""
49
+ ______ ________________________ ___________________
50
+ ___ / / /__ ____/__ __ \__ |/ /__ ____/_ ___/
51
+ __ /_/ /__ __/ __ /_/ /_ /|_/ /__ __/ _____ \
52
+ _ __ / _ /___ _ _, _/_ / / / _ /___ ____/ /
53
+ /_/ /_/ /_____/ /_/ |_| /_/ /_/ /_____/ /____/
54
+
55
+ """
56
+
57
+ if __name__ == '__main__':
58
+ parser = argparse.ArgumentParser(prog='HERMES',
59
+ description='Heterogeneous edge realtime measurement and execution system '
60
+ 'for continual multimodal data acquisition and processing.',
61
+ epilog='Copyright (c) 2024 Maxim Yudayev and KU Leuven eMedia Lab.\n'
62
+ 'Created 2024-2025 at KU Leuven for the AidWear, AID-FOG, and RevalExo '
63
+ 'projects of prof. Bart Vanrumste, by Maxim Yudayev [https://yudayev.com].',
64
+ formatter_class=argparse.RawTextHelpFormatter)
65
+ parser.add_argument('--verbose', '-v',
66
+ action='count',
67
+ default=0,
68
+ help='increase level of logging verbosity [0,3]')
69
+ parser.add_argument('--version',
70
+ action='version',
71
+ version='%(prog)s ' + __version)
72
+
73
+ parser.add_argument('--experiment',
74
+ nargs='*',
75
+ action=ParseExperimentKwargs,
76
+ help='key-value pair tags detailing the experiment, used for '
77
+ 'directory creation and metadata on files')
78
+ parser.add_argument('--time', '-t',
79
+ type=float,
80
+ dest='log_time_s',
81
+ default=get_time(),
82
+ help='master start time of the system')
83
+ parser.add_argument('--duration', '-d',
84
+ type=int,
85
+ dest='duration_s',
86
+ default=None,
87
+ help='duration in seconds, if using for recording only (to be used only by master)')
88
+ parser.add_argument('--config_file',
89
+ type=validate_path,
90
+ default=None,
91
+ help='path to the configuration file for the current host device, '
92
+ 'instead of the CLI arguments')
93
+
94
+ # parser.add_argument('--host_ip',
95
+ # type=validate_ip,
96
+ # help='LAN IPv4 address of the host device')
97
+ # parser.add_argument('--is_master',
98
+ # dest='is_master_broker',
99
+ # action='store_true',
100
+ # help='flag to set host as Master Broker that others connect to')
101
+ # parser.add_argument('--subscriber_ips',
102
+ # nargs='*',
103
+ # dest='remote_subscriber_ips',
104
+ # type=validate_ip,
105
+ # default=list(),
106
+ # help='list of IPv4 devices listening to data of the host')
107
+ # parser.add_argument('--publisher_ips',
108
+ # nargs='*',
109
+ # dest='remote_publisher_ips',
110
+ # type=validate_ip,
111
+ # default=list(),
112
+ # help='list of IPv4 devices to listen to for their data')
113
+ # parser.add_argument('--kill',
114
+ # dest='is_remote_kill',
115
+ # action='store_true',
116
+ # help='flag to set host to listen to remote KILLSIG (only for slave devices)')
117
+ # parser.add_argument('--kill_ip',
118
+ # dest='remote_kill_ip',
119
+ # type=validate_ip,
120
+ # help='LAN IPv4 address of device delegating KILLSIG (only for slave devices)')
121
+
122
+
123
+ # parser.add_argument('--logging_spec',
124
+ # nargs='*',
125
+ # action=ParseLoggingKwargs,
126
+ # help='key-value pair tags configuring logging modules of each Node')
127
+
128
+ # parser.add_argument('--producer_specs',
129
+ # nargs='*',
130
+ # action=ParseNodeKwargs,
131
+ # default=list(),
132
+ # help='key-value pair tags detailing local producer Nodes of the host')
133
+ # parser.add_argument('--consumer_specs',
134
+ # nargs='*',
135
+ # action=ParseNodeKwargs,
136
+ # default=list(),
137
+ # help='key-value pair tags detailing local consumer Nodes of the host')
138
+ # parser.add_argument('--pipeline_specs',
139
+ # nargs='*',
140
+ # action=ParseNodeKwargs,
141
+ # default=list(),
142
+ # help='key-value pair tags detailing local pipeline Nodes of the host')
143
+
144
+
145
+ # Parse launch arguments.
146
+ args = parser.parse_args()
147
+
148
+ # Override CLI arguments with a config file.
149
+ if args.config_file is not None:
150
+ with open(args.config_file, "r") as f:
151
+ try:
152
+ config: dict = yaml.safe_load(f)
153
+ parser.set_defaults(**config)
154
+ except yaml.YAMLError as e:
155
+ print(e)
156
+ exit('Error parsing CLI inputs.')
157
+ args = parser.parse_args()
158
+
159
+ # Load video codec spec.
160
+ if 'stream_video' in args.logging_spec and args.logging_spec['stream_video']:
161
+ with open(args.logging_spec['video_codec_config_filepath'], "r") as f:
162
+ try:
163
+ args.logging_spec['video_codec'] = yaml.safe_load(f)
164
+ except yaml.YAMLError as e:
165
+ print(e)
166
+
167
+ # Initialize folders and other chore data, and share programmatically across Node specs.
168
+ script_dir: str = os.path.dirname(os.path.realpath(__file__))
169
+ (log_time_str, log_time_s) = get_time_str(time_s=args.log_time_s, return_time_s=True)
170
+ log_dir: str = os.path.join(script_dir,
171
+ 'data',
172
+ *map(lambda tup: '_'.join(tup), args.experiment.items()))
173
+ # Initialize a file for writing the log history of all printouts/messages.
174
+ log_history_filepath: str = os.path.join(log_dir, '%s.log'%args.host_ip)
175
+
176
+ try:
177
+ os.makedirs(log_dir)
178
+ except OSError:
179
+ exit("'%s' already exists. Update experiment YML file with correct data for this subject."%log_dir)
180
+
181
+ args.logging_spec['log_dir'] = log_dir
182
+ args.logging_spec['experiment'] = args.experiment
183
+ args.logging_spec['log_time_s'] = log_time_s
184
+
185
+ node_specs: list[dict] = args.producer_specs + args.consumer_specs + args.pipeline_specs
186
+ for spec in node_specs:
187
+ spec['settings']['logging_spec'] = args.logging_spec
188
+ spec['settings']['log_history_filepath'] = log_history_filepath
189
+ spec['settings']['host_ip'] = args.host_ip
190
+ spec['settings']['port_pub'] = PORT_BACKEND
191
+ spec['settings']['port_sub'] = PORT_FRONTEND
192
+ spec['settings']['port_sync'] = PORT_SYNC_HOST
193
+ spec['settings']['port_killsig'] = PORT_KILL
194
+
195
+ # Create the broker and manage all the components of the experiment.
196
+ local_broker: Broker = Broker(host_ip=args.host_ip,
197
+ node_specs=node_specs,
198
+ is_master_broker=args.is_master_broker)
199
+
200
+ # Connect broker to remote publishers at the wearable PC to get data from the wearable sensors.
201
+ for ip in args.remote_publisher_ips:
202
+ local_broker.connect_to_remote_broker(addr=ip)
203
+
204
+ # Expose local wearable data to remote subscribers (e.g. lab PC in AidFOG project).
205
+ if args.remote_subscriber_ips:
206
+ local_broker.expose_to_remote_broker(args.remote_subscriber_ips)
207
+
208
+ # Subscribe to the KILL signal of a remote machine.
209
+ if args.is_remote_kill:
210
+ local_broker.subscribe_to_killsig(addr=args.remote_kill_ip)
211
+
212
+ # Only the master broker can terminate the experiment via the terminal command.
213
+ if args.is_master_broker:
214
+ is_quit = False
215
+ # Run broker's main until user exits in GUI or 'q' in terminal.
216
+ t = threading.Thread(target=launch_callable, args=(local_broker, args.duration_s))
217
+ t.start()
218
+ while not is_quit:
219
+ is_quit = input("Enter 'q' to exit: ") == 'q'
220
+ local_broker.set_is_quit()
221
+ t.join()
222
+ else:
223
+ local_broker()
@@ -0,0 +1,64 @@
1
+ [build-system]
2
+ requires = ["setuptools"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "pysio-hermes"
7
+ version = "0.1.0"
8
+ requires-python = ">=3.7"
9
+ authors = [
10
+ { name="Maxim Yudayev", email="maxim.yudayev@gmail.com" },
11
+ { name="e-Media Research Lab @ KU Leuven" },
12
+ ]
13
+ description = "A realtime physiological sensing and edge AI processing framework"
14
+ keywords = ["embedded ai", "wearables", "sensors", "streaming", "realtime processing", "physiology"]
15
+ readme = { file = "README.md", content-type = "text/markdown" }
16
+ license = "MIT"
17
+ license-files = ["LICEN[CS]E*", "AUTHORS.md"]
18
+ classifiers = [
19
+ "Programming Language :: Python :: 3",
20
+ "Operating System :: OS Independent",
21
+ "Development Status :: 4 - Beta",
22
+ "Intended Audience :: Healthcare Industry",
23
+ "Intended Audience :: Education",
24
+ "Intended Audience :: Developers",
25
+ "Intended Audience :: Science/Research",
26
+ "Topic :: Scientific/Engineering",
27
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
28
+ "Topic :: Scientific/Engineering :: Medical Science Apps.",
29
+ "Topic :: System :: Distributed Computing"
30
+ ]
31
+ dependencies = [
32
+ "pyzmq",
33
+ "msgpack",
34
+ "ffmpeg-python",
35
+ "h5py",
36
+ "numpy",
37
+ "pandas",
38
+ "pyyaml",
39
+ "pyusb",
40
+ "pyserial",
41
+ "pyperclip",
42
+ "openpyxl",
43
+ "orjson",
44
+ ]
45
+
46
+ [project.optional-dependencies]
47
+ build = [
48
+ "build",
49
+ "twine"
50
+ ]
51
+ docs = [
52
+ "mkdocs-material",
53
+ "mkdocstrings-python"
54
+ ]
55
+
56
+ [tool.setuptools.packages.find]
57
+ exclude = ["docs*", ".vscode*", ".venv*", "images*"]
58
+
59
+ [project.urls]
60
+ Homepage = "https://maximyudayev.github.io/hermes"
61
+ Documentation = "https://maximyudayev.github.io/hermes"
62
+ Repository = "https://github.com/maximyudayev/hermes.git"
63
+ Issues = "https://github.com/maximyudayev/hermes/issues"
64
+ Changelog = "https://github.com/maximyudayev/hermes/blob/main/CHANGELOG.md"