osiris-agent 0.1.3__py3-none-any.whl → 0.1.5__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.
@@ -34,6 +34,7 @@ class WebBridge(Node):
34
34
  raise ValueError("OSIRIS_AUTH_TOKEN environment variable must be set")
35
35
 
36
36
  self.ws_url = f'wss://osiris-gateway.fly.dev?robot=true&token={auth_token}'
37
+ # self.ws_url = f'ws://host.docker.internal:8080?robot=true&token={auth_token}'
37
38
  self.ws = None
38
39
  self._topic_subs = {}
39
40
  self._topic_subs_lock = threading.Lock()
@@ -76,10 +77,10 @@ class WebBridge(Node):
76
77
  logger=self.get_logger()
77
78
  )
78
79
  self._bt_collector.start()
79
- self.get_logger().info("BT Collector started")
80
80
  else:
81
81
  self._bt_collector = None
82
- self.get_logger().info("BT Collector disabled (OSIRIS_BT_COLLECTOR_ENABLED not set)")
82
+
83
+ self.get_logger().info("🚀 Osiris agent running")
83
84
 
84
85
  # Create event loop and queue, run websocket client
85
86
  def _run_ws_client(self):
@@ -95,12 +96,10 @@ class WebBridge(Node):
95
96
 
96
97
  while True:
97
98
  try:
98
- self.get_logger().info("Attempting to connect to gateway...")
99
99
  await self._client_loop()
100
100
  except Exception as e:
101
- self.get_logger().error(f"Connection failed: {e}")
101
+ pass # Silent retry
102
102
 
103
- self.get_logger().info(f"Reconnecting in {reconnect_delay} seconds...")
104
103
  await asyncio.sleep(reconnect_delay)
105
104
 
106
105
  reconnect_delay = min(reconnect_delay * 2, RECONNECT_MAX_DELAY)
@@ -112,12 +111,10 @@ class WebBridge(Node):
112
111
  send_task = None
113
112
  try:
114
113
  async with websockets.connect(self.ws_url) as ws:
115
- self.get_logger().info("Connected to gateway (socket opened)")
116
114
  # Wait for gateway auth response before sending initial state
117
115
  try:
118
116
  auth_msg = await ws.recv()
119
117
  except Exception as e:
120
- self.get_logger().error(f"Failed to receive auth message: {e}")
121
118
  return
122
119
 
123
120
  try:
@@ -125,14 +122,9 @@ class WebBridge(Node):
125
122
  except Exception:
126
123
  auth_data = None
127
124
 
128
- self.get_logger().debug(f"Gateway auth message received: {auth_msg}")
129
-
130
125
  if not auth_data or auth_data.get('type') != 'auth_success':
131
- self.get_logger().error(f"Gateway did not authenticate: parsed={auth_data}")
132
126
  return
133
127
 
134
- self.get_logger().info("Authenticated with gateway")
135
-
136
128
  self.ws = ws
137
129
 
138
130
  send_task = asyncio.create_task(self._send_loop(ws))
@@ -141,7 +133,6 @@ class WebBridge(Node):
141
133
 
142
134
  await self._receive_loop(ws)
143
135
  except Exception as e:
144
- self.get_logger().error(f"Error in client loop: {e}")
145
136
  raise
146
137
  finally:
147
138
  if send_task and not send_task.done():
@@ -980,15 +971,11 @@ class WebBridge(Node):
980
971
  def _on_bt_event(self, event):
981
972
  """Handle behavior tree events from BTCollector and forward to websocket."""
982
973
  event_type = event.get('type')
983
- self.get_logger().info(f"BT event received: {event_type}")
984
974
 
985
975
  # Cache tree events if WS not connected yet
986
976
  if not self.ws or not self.loop:
987
977
  if event_type == 'bt_tree':
988
978
  self._cached_bt_tree_event = event
989
- self.get_logger().info("BT tree event cached (WS not connected yet)")
990
- else:
991
- self.get_logger().warn(f"Dropping BT event {event_type} (WS not connected)")
992
979
  return
993
980
 
994
981
  try:
@@ -996,7 +983,6 @@ class WebBridge(Node):
996
983
  self._send_queue.put(json.dumps(event)),
997
984
  self.loop
998
985
  )
999
- self.get_logger().info(f"BT event {event_type} queued for sending")
1000
986
  except Exception as e:
1001
987
  self.get_logger().error(f"Failed to queue BT event: {e}")
1002
988
 
@@ -1005,7 +991,6 @@ class WebBridge(Node):
1005
991
  # Stop BT collector
1006
992
  if self._bt_collector:
1007
993
  self._bt_collector.stop()
1008
- self.get_logger().info("BT Collector stopped")
1009
994
 
1010
995
  super().destroy_node()
1011
996
 
@@ -22,9 +22,9 @@ import zmq
22
22
  import random # added to support unique_id generation in requests
23
23
 
24
24
  # Default Groot2 configuration (industry standard)
25
- DEFAULT_GROOT_SERVER_PORT = 1667 # REQ/REP for tree structure and status polling
26
- DEFAULT_GROOT_PUBLISHER_PORT = 1668 # PUB/SUB for breakpoint notifications only
27
- DEFAULT_GROOT_HOST = "127.0.0.1"
25
+ DEFAULT_SERVER_PORT = 1667 # REQ/REP for tree structure and status polling
26
+ DEFAULT_PUBLISHER_PORT = 1668 # PUB/SUB for breakpoint notifications only
27
+ DEFAULT_HOST = "127.0.0.1"
28
28
 
29
29
  # ZMQ timeouts
30
30
  ZMQ_RECV_TIMEOUT_MS = 2000
@@ -94,16 +94,16 @@ class BTCollector:
94
94
 
95
95
  Args:
96
96
  event_callback: Function to call with parsed events (dict)
97
- host: Groot2 host address (default: from BT_GROOT_HOST env or 127.0.0.1)
98
- server_port: Groot2 server port (default: from BT_GROOT_SERVER_PORT env or 1667)
99
- publisher_port: Groot2 publisher port (default: from BT_GROOT_PUBLISHER_PORT env or 1668)
97
+ host: Groot2 host address (default: from BT_HOST env or 127.0.0.1)
98
+ server_port: Groot2 server port (default: from BT_SERVER_PORT env or 1667)
99
+ publisher_port: Groot2 publisher port (default: from BT_PUBLISHER_PORT env or 1668)
100
100
  logger: Optional logger (uses print if None)
101
101
  """
102
102
  self._event_callback = event_callback
103
103
  # Read from environment variables with fallback to defaults
104
- self._host = host or os.environ.get('OSIRIS_BT_GROOT_HOST', DEFAULT_GROOT_HOST)
105
- self._server_port = server_port or int(os.environ.get('OSIRIS_BT_GROOT_SERVER_PORT', str(DEFAULT_GROOT_SERVER_PORT)))
106
- self._publisher_port = publisher_port or int(os.environ.get('OSIRIS_BT_GROOT_PUBLISHER_PORT', str(DEFAULT_GROOT_PUBLISHER_PORT)))
104
+ self._host = host or os.environ.get('OSIRIS_BT_HOST', DEFAULT_HOST)
105
+ self._server_port = server_port or int(os.environ.get('OSIRIS_BT_SERVER_PORT', str(DEFAULT_SERVER_PORT)))
106
+ self._publisher_port = publisher_port or int(os.environ.get('OSIRIS_BT_PUBLISHER_PORT', str(DEFAULT_PUBLISHER_PORT)))
107
107
  self._logger = logger
108
108
 
109
109
  self._running = False
@@ -114,14 +114,10 @@ class BTCollector:
114
114
  self._last_statuses: Dict[int, str] = {}
115
115
 
116
116
  def _log_info(self, msg: str):
117
- if self._logger:
118
- self._logger.info(msg)
119
- else:
120
- print(f"[BTCollector INFO] {msg}")
117
+ pass # Logging disabled
121
118
 
122
119
  def _log_debug(self, msg: str):
123
- if self._logger:
124
- self._logger.debug(msg)
120
+ pass # Logging disabled
125
121
 
126
122
  def _log_error(self, msg: str):
127
123
  if self._logger:
@@ -130,10 +126,7 @@ class BTCollector:
130
126
  print(f"[BTCollector ERROR] {msg}")
131
127
 
132
128
  def _log_warn(self, msg: str):
133
- if self._logger:
134
- self._logger.warn(msg)
135
- else:
136
- print(f"[BTCollector WARN] {msg}")
129
+ pass # Logging disabled
137
130
 
138
131
  def start(self):
139
132
  """Start the collector in a background thread."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: osiris_agent
3
- Version: 0.1.3
3
+ Version: 0.1.5
4
4
  Summary: OSIRIS agent for ROS2/Humble
5
5
  Home-page: https://github.com/nicolaselielll/osiris_agent
6
6
  Author: Nicolas Tuomaala
@@ -44,45 +44,63 @@ A ROS2 Humble node that bridges your robot to the OSIRIS remote monitoring platf
44
44
 
45
45
  ## Install
46
46
 
47
- From PyPI:
47
+ Install the OSIRIS agent on your robot:
48
48
  ```bash
49
- python -m pip install --upgrade pip
50
- python -m pip install osiris_agent
49
+ pip3 install osiris-agent
51
50
  ```
52
51
 
53
- Editable / development install:
52
+ ## Quick Start
53
+
54
+ ### 1. Add token to your environment
55
+
54
56
  ```bash
55
- git clone https://github.com/nicolaselielll/osiris_agent.git
56
- cd osiris_agent
57
- python -m pip install -e .
57
+ export OSIRIS_AUTH_TOKEN=your-token-here
58
58
  ```
59
59
 
60
- ## Quick Start
60
+ ### 2. (Optional) Enable behaviour tree collector
61
+
62
+ If you're using BT.CPP with Groot2 monitoring:
61
63
 
62
- Set the auth token and run the agent:
63
64
  ```bash
64
- export OSIRIS_AUTH_TOKEN="your-robot-token-here"
65
- agent_node
65
+ export OSIRIS_BT_COLLECTOR_ENABLED=true
66
66
  ```
67
67
 
68
- Verify installation:
68
+ Default host is `127.0.0.1`. Default port for server is `1667` and for publisher `1668`. To change these:
69
+
69
70
  ```bash
70
- python -c "import importlib.metadata as m; print(m.version('osiris_agent'))"
71
+ export OSIRIS_BT_HOST=127.0.0.1
72
+ export OSIRIS_BT_SERVER_PORT=1667
73
+ export OSIRIS_BT_PUBLISHER_PORT=1668
74
+ ```
75
+
76
+ ### 3. Start agent
77
+
78
+ ```bash
79
+ osiris_node
71
80
  ```
72
81
 
73
82
  ## Usage & Configuration
74
83
 
75
- - Environment: OSIRIS_AUTH_TOKEN — your robot token.
76
- - Editable install reflects code changes immediately.
77
- - Common constants are in `osiris_agent/agent_node.py`:
78
- - MAX_SUBSCRIPTIONS, ALLOWED_TOPIC_PREFIXES, GRAPH_CHECK_INTERVAL, PARAMETER_REFRESH_INTERVAL, TELEMETRY_INTERVAL
84
+ ### Required Environment Variables
85
+
86
+ - `OSIRIS_AUTH_TOKEN` Your robot authentication token from the OSIRIS platform
87
+
88
+ ### Optional Environment Variables
89
+
90
+ **Behaviour Tree Monitoring (BT.CPP + Groot2):**
91
+ - `OSIRIS_BT_COLLECTOR_ENABLED` — Set to `true` to enable BT.CPP tree monitoring (default: `false`)
92
+ - `OSIRIS_BT_HOST` — Groot2 ZMQ host address (default: `127.0.0.1`)
93
+ - `OSIRIS_BT_SERVER_PORT` — Groot2 REQ/REP server port (default: `1667`)
94
+ - `OSIRIS_BT_PUBLISHER_PORT` — Groot2 PUB/SUB publisher port (default: `1668`)
95
+
96
+ ## BT.CPP Integration
97
+
98
+ The agent automatically collects behaviour tree events from BT.CPP when `OSIRIS_BT_COLLECTOR_ENABLED=true`. Your BT.CPP application must:
79
99
 
80
- ## Badge suggestions
100
+ 1. Enable Groot2 monitoring in your code
101
+ 2. Use the standard Groot2 ZMQ ports (1667/1668) or configure custom ports via environment variables
81
102
 
82
- - PyPI: https://img.shields.io/pypi/v/osiris_agent.svg
83
- - Python versions: https://img.shields.io/pypi/pyversions/osiris_agent.svg
84
- - License: https://img.shields.io/pypi/l/osiris_agent.svg
85
- - GitHub Actions CI: https://github.com/<user>/osiris_agent/actions
103
+ The collector uses BT.CPP's standardized Groot2 protocol, so it works with any behaviour tree without custom configuration.
86
104
 
87
105
  ## Contributing
88
106
 
@@ -0,0 +1,9 @@
1
+ osiris_agent/__init__.py,sha256=E0YxGzSMUelxIPB6kRPKL-2Da_QaYCZeOd8fEaLtQ5c,73
2
+ osiris_agent/agent_node.py,sha256=Rx1IXKCL7tRhLwZQS4YaJTKuE9A47pRayMSC_plezZ8,39973
3
+ osiris_agent/bt_collector.py,sha256=lFfrjObFnZKgrAb9HUpEpWAROc52QdqPXBjAtRDpkjg,20976
4
+ osiris_agent-0.1.5.dist-info/licenses/LICENSE,sha256=tv_rYfXPsDuLDPIrpAFFZfgaO15H-gz89GW1TfyCQ48,10758
5
+ osiris_agent-0.1.5.dist-info/METADATA,sha256=CZyg3IW7ndtZM-uX2c6aVcr5VKVKqC53Hjex5QNzKsQ,3230
6
+ osiris_agent-0.1.5.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
7
+ osiris_agent-0.1.5.dist-info/entry_points.txt,sha256=eIDN_LuzMOpqZgGnMz8MGqYxZSJ7bS76sm2xv2zwdcU,61
8
+ osiris_agent-0.1.5.dist-info/top_level.txt,sha256=qT-C0LRSrwlNjTuA7bVsTmwYJzhONP18wuyAXwUBZnU,13
9
+ osiris_agent-0.1.5.dist-info/RECORD,,
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ osiris_node = osiris_agent.agent_node:main
@@ -1,9 +0,0 @@
1
- osiris_agent/__init__.py,sha256=E0YxGzSMUelxIPB6kRPKL-2Da_QaYCZeOd8fEaLtQ5c,73
2
- osiris_agent/agent_node.py,sha256=yEnYln1iDahrRILVeeQ3bRHTlWEYj9mLgPbhaKE9ZrY,41051
3
- osiris_agent/bt_collector.py,sha256=-VkEIkHoL1WNWNU8waMbehjakJywHr6sibbpa015PZQ,21252
4
- osiris_agent-0.1.3.dist-info/licenses/LICENSE,sha256=tv_rYfXPsDuLDPIrpAFFZfgaO15H-gz89GW1TfyCQ48,10758
5
- osiris_agent-0.1.3.dist-info/METADATA,sha256=ijbKyI_Vlyl7y6tcFk4Vujz7QWRvdrjZAl6o-dW-TPE,2702
6
- osiris_agent-0.1.3.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
7
- osiris_agent-0.1.3.dist-info/entry_points.txt,sha256=ff4USKDLj8unIsvb7iQrVvfhP52Fhp3QAR5AchypnuE,60
8
- osiris_agent-0.1.3.dist-info/top_level.txt,sha256=qT-C0LRSrwlNjTuA7bVsTmwYJzhONP18wuyAXwUBZnU,13
9
- osiris_agent-0.1.3.dist-info/RECORD,,
@@ -1,2 +0,0 @@
1
- [console_scripts]
2
- agent_node = osiris_agent.agent_node:main