osiris-agent 0.1.0__py3-none-any.whl → 0.1.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -938,7 +938,10 @@ class WebBridge(Node):
938
938
  def _get_telemetry_snapshot(self):
939
939
  """Return a snapshot of system telemetry (CPU, RAM, disk)."""
940
940
  return {
941
- 'cpu': psutil.cpu_percent(interval=None),
941
+ 'cpu': {
942
+ 'percent': psutil.cpu_percent(interval=None),
943
+ 'cores': psutil.cpu_count(logical=False),
944
+ },
942
945
  'ram': {
943
946
  'percent': psutil.virtual_memory().percent,
944
947
  'used_mb': psutil.virtual_memory().used / (1024 * 1024),
@@ -0,0 +1,96 @@
1
+ Metadata-Version: 2.4
2
+ Name: osiris_agent
3
+ Version: 0.1.2
4
+ Summary: OSIRIS agent for ROS2/Humble
5
+ Home-page: https://github.com/nicolaselielll/osiris_agent
6
+ Author: Nicolas Tuomaala
7
+ Author-email: nicolas.tuomaala00@gmail.com
8
+ License: Apache-2.0
9
+ Keywords: ros2 humble agent
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: Apache Software License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Classifier: Operating System :: OS Independent
16
+ Description-Content-Type: text/markdown
17
+ License-File: LICENSE
18
+ Requires-Dist: websockets
19
+ Requires-Dist: psutil
20
+ Provides-Extra: ros
21
+ Requires-Dist: rclpy; extra == "ros"
22
+ Dynamic: author
23
+ Dynamic: author-email
24
+ Dynamic: classifier
25
+ Dynamic: description
26
+ Dynamic: description-content-type
27
+ Dynamic: home-page
28
+ Dynamic: keywords
29
+ Dynamic: license
30
+ Dynamic: license-file
31
+ Dynamic: provides-extra
32
+ Dynamic: requires-dist
33
+ Dynamic: summary
34
+
35
+ # OSIRIS Agent
36
+
37
+ ![PyPI](https://img.shields.io/pypi/v/osiris_agent.svg)
38
+ ![Python](https://img.shields.io/pypi/pyversions/osiris_agent.svg)
39
+ ![License](https://img.shields.io/pypi/l/osiris_agent.svg)
40
+ ![CI](https://github.com/nicolaselielll/osiris_agent/actions/workflows/ci.yml/badge.svg)
41
+
42
+ A ROS2 Humble node that bridges your robot to the OSIRIS remote monitoring platform via WebSocket.
43
+
44
+ ## Install
45
+
46
+ From PyPI:
47
+ ```bash
48
+ python -m pip install --upgrade pip
49
+ python -m pip install osiris_agent
50
+ ```
51
+
52
+ Editable / development install:
53
+ ```bash
54
+ git clone https://github.com/nicolaselielll/osiris_agent.git
55
+ cd osiris_agent
56
+ python -m pip install -e .
57
+ ```
58
+
59
+ ## Quick Start
60
+
61
+ Set the auth token and run the agent:
62
+ ```bash
63
+ export OSIRIS_AUTH_TOKEN="your-robot-token-here"
64
+ agent_node
65
+ ```
66
+
67
+ Verify installation:
68
+ ```bash
69
+ python -c "import importlib.metadata as m; print(m.version('osiris_agent'))"
70
+ ```
71
+
72
+ ## Usage & Configuration
73
+
74
+ - Environment: OSIRIS_AUTH_TOKEN — your robot token.
75
+ - Editable install reflects code changes immediately.
76
+ - Common constants are in `osiris_agent/agent_node.py`:
77
+ - MAX_SUBSCRIPTIONS, ALLOWED_TOPIC_PREFIXES, GRAPH_CHECK_INTERVAL, PARAMETER_REFRESH_INTERVAL, TELEMETRY_INTERVAL
78
+
79
+ ## Badge suggestions
80
+
81
+ - PyPI: https://img.shields.io/pypi/v/osiris_agent.svg
82
+ - Python versions: https://img.shields.io/pypi/pyversions/osiris_agent.svg
83
+ - License: https://img.shields.io/pypi/l/osiris_agent.svg
84
+ - GitHub Actions CI: https://github.com/<user>/osiris_agent/actions
85
+
86
+ ## Contributing
87
+
88
+ Open issues and PRs at: https://github.com/nicolaselielll/osiris_agent
89
+
90
+ ## License
91
+
92
+ Apache-2.0 — see the LICENSE file.
93
+
94
+ ## Changelog
95
+
96
+ See release notes on GitHub Releases for v0.1.0 and future versions.
@@ -0,0 +1,8 @@
1
+ osiris_agent/__init__.py,sha256=E0YxGzSMUelxIPB6kRPKL-2Da_QaYCZeOd8fEaLtQ5c,73
2
+ osiris_agent/agent_node.py,sha256=4412uLiIWPkv0XikSwOoVxJJmNvJIWRerfTQmdQfcuo,38740
3
+ osiris_agent-0.1.2.dist-info/licenses/LICENSE,sha256=tv_rYfXPsDuLDPIrpAFFZfgaO15H-gz89GW1TfyCQ48,10758
4
+ osiris_agent-0.1.2.dist-info/METADATA,sha256=c9rX-hOlaZChpJySHvOg6VNCI0gy4mqbXIjbh9tMhgQ,2681
5
+ osiris_agent-0.1.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
6
+ osiris_agent-0.1.2.dist-info/entry_points.txt,sha256=ff4USKDLj8unIsvb7iQrVvfhP52Fhp3QAR5AchypnuE,60
7
+ osiris_agent-0.1.2.dist-info/top_level.txt,sha256=qT-C0LRSrwlNjTuA7bVsTmwYJzhONP18wuyAXwUBZnU,13
8
+ osiris_agent-0.1.2.dist-info/RECORD,,
@@ -1,315 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: osiris_agent
3
- Version: 0.1.0
4
- Summary: OSIRIS agent for ROS2/Humble
5
- Home-page: https://github.com/nicolaselielll/osiris_agent
6
- Author: Nicolas Tuomaala
7
- Author-email: nicolas.tuomaala00@gmail.com
8
- License: Apache-2.0
9
- Keywords: ros2 humble agent
10
- Classifier: Development Status :: 4 - Beta
11
- Classifier: Intended Audience :: Developers
12
- Classifier: License :: OSI Approved :: Apache Software License
13
- Classifier: Programming Language :: Python :: 3
14
- Classifier: Programming Language :: Python :: 3 :: Only
15
- Classifier: Operating System :: OS Independent
16
- Description-Content-Type: text/markdown
17
- License-File: LICENSE
18
- Requires-Dist: websockets
19
- Requires-Dist: psutil
20
- Provides-Extra: ros
21
- Requires-Dist: rclpy; extra == "ros"
22
- Dynamic: author
23
- Dynamic: author-email
24
- Dynamic: classifier
25
- Dynamic: description
26
- Dynamic: description-content-type
27
- Dynamic: home-page
28
- Dynamic: keywords
29
- Dynamic: license
30
- Dynamic: license-file
31
- Dynamic: provides-extra
32
- Dynamic: requires-dist
33
- Dynamic: summary
34
-
35
- # OSIRIS Agent
36
-
37
- A ROS2 Humble node that bridges your robot to the OSIRIS remote monitoring platform via WebSocket.
38
-
39
- ## Overview
40
-
41
- The OSIRIS Agent (`osiris_agent`) is a ROS2 node that provides real-time bidirectional communication between your ROS2 robot and a remote WebSocket gateway. It monitors the ROS2 graph, collects system telemetry, and enables dynamic topic subscription from the remote platform.
42
-
43
- ## Features
44
-
45
- ### Real-time Graph Monitoring
46
- - **Node Detection**: Automatically detects when ROS2 nodes start/stop
47
- - **Topic Tracking**: Monitors topic creation, destruction, and subscription changes
48
- - **Action Discovery**: Tracks ROS2 actions and their lifecycle
49
- - **Service Discovery**: Detects available services and their endpoints
50
- - **Publisher/Subscriber Relations**: Maps which nodes publish to and subscribe from each topic
51
-
52
- ### Dynamic Topic Subscription
53
- - Subscribe to any ROS2 topic remotely via WebSocket commands
54
- - Automatic message type resolution and serialization
55
- - Configurable subscription limits (default: 100 concurrent subscriptions)
56
- - Thread-safe subscription management
57
- - Topic publishing rate calculation
58
-
59
- ### Node Parameters
60
- - Automatic discovery of node parameters
61
- - Periodic parameter refresh (every 5 seconds)
62
- - Asynchronous parameter fetching to avoid blocking
63
-
64
- ### System Telemetry
65
- - CPU usage monitoring
66
- - Memory (RAM) utilization tracking
67
- - Disk space monitoring
68
- - Enable/disable telemetry on demand
69
-
70
- ### Quality of Service (QoS) Support
71
- - Full QoS profile inspection for publishers and subscribers
72
- - Reliability, durability, history policy, depth, and liveliness information
73
-
74
- ### Robust Connection Management
75
- - Automatic reconnection with exponential backoff
76
- - Initial delay: 1 second, max delay: 10 seconds
77
- - Secure WebSocket (WSS) connection
78
- - Token-based authentication
79
-
80
- ## Architecture
81
-
82
- ```
83
- WebBridge Node (osiris_agent)
84
-
85
- ├─ Main Thread (rclpy.spin)
86
- │ ├─ ROS2 Node Callbacks
87
- │ ├─ Graph Change Detector (timer: 100ms)
88
- │ ├─ Parameter Refresh (timer: 5s)
89
- │ └─ Telemetry Collector (timer: 1s)
90
-
91
- └─ Daemon Thread (WebSocket Client)
92
- └─ Asyncio Event Loop
93
- ├─ Send Loop (queue consumer)
94
- ├─ Receive Loop (command handler)
95
- └─ Reconnection Logic (exponential backoff)
96
- ```
97
-
98
- **Key Components:**
99
- - **Graph Monitor**: Polls ROS2 graph for changes (nodes, topics, actions, services)
100
- - **Subscription Manager**: Handles dynamic topic subscriptions with `threading.Lock()` for thread-safe access to the subscription dictionary
101
- - **Telemetry Collector**: Gathers CPU, RAM, and disk metrics using `psutil`
102
- - **WebSocket Client**: Maintains persistent connection with automatic reconnection
103
- - **Message Queue**: `asyncio.Queue` created on the websocket event loop for serializing all outgoing messages
104
-
105
- **Threading Model:**
106
- - Main thread runs ROS2 executor (`rclpy.spin`) with timers and callbacks
107
- - Daemon thread runs asyncio event loop with websocket client (send/receive coroutines)
108
- - Shared data (`_topic_subs`) protected by `threading.Lock` to prevent race conditions
109
- - Cross-thread communication via `asyncio.run_coroutine_threadsafe()` to schedule coroutines from ROS thread onto websocket loop
110
-
111
- ## Installation
112
-
113
- ```bash
114
- # Clone the repository into your workspace
115
- cd ~/ros2_ws/src
116
- git clone https://github.com/nicolaselielll/osiris_agent.git
117
-
118
- # Install the package
119
- cd osiris_agent
120
- pip3 install -e .
121
- ```
122
-
123
- The `-e` flag installs in editable mode so changes to the code are reflected immediately.
124
-
125
- ## Configuration
126
-
127
- Set your authentication token as an environment variable:
128
-
129
- ```bash
130
- export OSIRIS_AUTH_TOKEN="your-robot-token-here"
131
- ```
132
-
133
- **Tip**: Add to `~/.bashrc` to persist across sessions:
134
- ```bash
135
- echo 'export OSIRIS_AUTH_TOKEN="your-token"' >> ~/.bashrc
136
- ```
137
-
138
- ### Optional: Customize Behavior
139
-
140
- Edit constants in `osiris_agent/agent_node.py`:
141
-
142
- - `MAX_SUBSCRIPTIONS = 100`: Maximum concurrent topic subscriptions
143
- - `ALLOWED_TOPIC_PREFIXES = ['/']`: Restrict subscribable topics (e.g., `['/robot/', '/sensors/']`)
144
- - `GRAPH_CHECK_INTERVAL = 0.1`: Graph polling interval (seconds)
145
- - `PARAMETER_REFRESH_INTERVAL = 5.0`: Parameter refresh interval (seconds)
146
- - `TELEMETRY_INTERVAL = 1.0`: Telemetry collection interval (seconds)
147
-
148
- ## Running
149
-
150
- ```bash
151
- export OSIRIS_AUTH_TOKEN="your-token"
152
- agent_node
153
- ```
154
-
155
- You should see:
156
- ```
157
- [INFO] [bridge_node]: Attempting to connect to gateway...
158
- [INFO] [bridge_node]: Connected to gateway
159
- [INFO] [bridge_node]: Sent initial state: 5 nodes, 12 topics, 0 actions, 8 services
160
- ```
161
-
162
- ## Updating
163
-
164
- ```bash
165
- cd ~/ros2_ws/src/osiris_agent
166
- git pull
167
- # Changes apply immediately if installed with -e
168
- ```
169
-
170
- ## WebSocket Protocol
171
-
172
- ### Commands (Gateway → Agent)
173
-
174
- **Subscribe to Topic**
175
- ```json
176
- {"type": "subscribe", "topic": "/cmd_vel"}
177
- ```
178
-
179
- **Unsubscribe**
180
- ```json
181
- {"type": "unsubscribe", "topic": "/cmd_vel"}
182
- ```
183
-
184
- **Control Telemetry**
185
- ```json
186
- {"type": "start_telemetry"}
187
- {"type": "stop_telemetry"}
188
- ```
189
-
190
- ### Events (Agent → Gateway)
191
-
192
- **Initial State** (on connect)
193
- ```json
194
- {
195
- "type": "initial_state",
196
- "timestamp": 1234567890.123,
197
- "data": {
198
- "nodes": {},
199
- "topics": {},
200
- "actions": {},
201
- "services": {},
202
- "telemetry": {}
203
- }
204
- }
205
- ```
206
-
207
- **Graph Changes**
208
- ```json
209
- {"type": "node_event", "node": "/my_node", "event": "started", "timestamp": 123}
210
- {"type": "topic_event", "topic": "/my_topic", "event": "created", "timestamp": 123}
211
- {"type": "action_event", "action": "/my_action", "event": "created", "timestamp": 123}
212
- {"type": "service_event", "service": "/my_service", "event": "created", "timestamp": 123}
213
- ```
214
-
215
- **Topic Data**
216
- ```json
217
- {
218
- "type": "topic_data",
219
- "topic": "/cmd_vel",
220
- "data": {"linear": {"x": 1.0}, "angular": {"z": 0.5}},
221
- "rate_hz": 10.0,
222
- "timestamp": 123
223
- }
224
- ```
225
-
226
- **Telemetry**
227
- ```json
228
- {
229
- "type": "telemetry",
230
- "data": {
231
- "cpu": 45.2,
232
- "ram": {"percent": 62.5, "used_mb": 5000, "total_mb": 8000},
233
- "disk": {"percent": 75.0, "used_gb": 150, "total_gb": 200}
234
- },
235
- "timestamp": 123
236
- }
237
- ```
238
-
239
- **Bridge Subscriptions**
240
- ```json
241
- {
242
- "type": "bridge_subscriptions",
243
- "subscriptions": ["/topic1", "/topic2"],
244
- "timestamp": 123
245
- }
246
- ```
247
-
248
- ## Troubleshooting
249
-
250
- **ModuleNotFoundError: websockets or psutil**
251
- ```bash
252
- pip3 install -e .
253
- ```
254
-
255
- **Connection drops**
256
- - Check firewall allows outbound HTTPS to `osiris-gateway.fly.dev:443`
257
- - View logs: `journalctl -u osiris-agent -f`
258
-
259
- **High CPU usage**
260
- - Increase `GRAPH_CHECK_INTERVAL` to `0.5` or `1.0`
261
- - Reduce `PARAMETER_REFRESH_INTERVAL` to `10.0`
262
- - Disable telemetry when not needed
263
-
264
- **Topics not appearing**
265
- - Verify topic exists: `ros2 topic list`
266
- - Check logs for validation warnings
267
- - Ensure under `MAX_SUBSCRIPTIONS` limit
268
-
269
- ## Performance Tuning
270
-
271
- **Large graphs (100+ nodes/topics)**
272
- ```python
273
- GRAPH_CHECK_INTERVAL = 0.5
274
- PARAMETER_REFRESH_INTERVAL = 10.0
275
- MAX_SUBSCRIPTIONS = 50
276
- ```
277
-
278
- **Resource-constrained robots**
279
- ```python
280
- GRAPH_CHECK_INTERVAL = 1.0
281
- PARAMETER_REFRESH_INTERVAL = 15.0
282
- TELEMETRY_INTERVAL = 2.0
283
- ```
284
-
285
- **Restrict topic access**
286
- ```python
287
- ALLOWED_TOPIC_PREFIXES = ['/robot/', '/sensors/']
288
- ```
289
-
290
- ## Security
291
-
292
- - Auth token sent via WSS (encrypted in transit)
293
- - **Never log `self.ws_url`** - it contains the authentication token in the query parameter
294
- - Set `ALLOWED_TOPIC_PREFIXES` to restrict which topics can be remotely subscribed
295
- - `MAX_SUBSCRIPTIONS` prevents resource exhaustion from excessive subscriptions
296
- - Ensure gateway scrubs tokens from access logs
297
-
298
- ## License
299
-
300
- This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.
301
-
302
- ## Contributing
303
-
304
- Issues and PRs welcome at [github.com/nicolaselielll/osiris_agent](https://github.com/nicolaselielll/osiris_agent)
305
-
306
- ## Changelog
307
-
308
- ### v0.1.0
309
- - WebSocket bridge with secure WSS connection
310
- - Real-time graph monitoring
311
- - Dynamic topic subscription
312
- - System telemetry (CPU/RAM/disk)
313
- - Auto-reconnect with exponential backoff
314
- - Parameter discovery
315
- - QoS profile inspection
@@ -1,8 +0,0 @@
1
- osiris_agent/__init__.py,sha256=E0YxGzSMUelxIPB6kRPKL-2Da_QaYCZeOd8fEaLtQ5c,73
2
- osiris_agent/agent_node.py,sha256=JkMC1KH--hwuG3Tlu_Lu34mFHvyrrgV7WKtRAYhVlQ4,38638
3
- osiris_agent-0.1.0.dist-info/licenses/LICENSE,sha256=tv_rYfXPsDuLDPIrpAFFZfgaO15H-gz89GW1TfyCQ48,10758
4
- osiris_agent-0.1.0.dist-info/METADATA,sha256=VWSzkuBuvzpW2fPXU7JF8DxjesW8iRUbOpuDAueTDmU,8871
5
- osiris_agent-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
6
- osiris_agent-0.1.0.dist-info/entry_points.txt,sha256=ff4USKDLj8unIsvb7iQrVvfhP52Fhp3QAR5AchypnuE,60
7
- osiris_agent-0.1.0.dist-info/top_level.txt,sha256=qT-C0LRSrwlNjTuA7bVsTmwYJzhONP18wuyAXwUBZnU,13
8
- osiris_agent-0.1.0.dist-info/RECORD,,