Skip to content

Commit 232eb02

Browse files
committed
fix: adding telemetry
1 parent 55844af commit 232eb02

2 files changed

Lines changed: 57 additions & 2 deletions

File tree

intercomclient/telemetry.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import logging
2+
3+
import requests
4+
5+
from .config import Config
6+
from .token_store import TokenStore
7+
8+
LOG = logging.getLogger(__name__)
9+
10+
11+
class TelemetryClient:
12+
def __init__(self, config: Config, token_store: TokenStore):
13+
self.config = config
14+
self.token_store = token_store
15+
16+
def send(self, event: str, message: str = "", level: str = "INFO") -> None:
17+
try:
18+
tokens = self.token_store.load_tokens()
19+
access_token = tokens["access"]["token_value"]
20+
device_code = tokens["device_code"]
21+
url = f"{self.config.http_api_base_url}/api/v1/devices/{device_code}/telemetry/"
22+
requests.post(
23+
url,
24+
json={"event": event, "message": message, "level": level},
25+
headers={"Authorization": f"Bearer {access_token}"},
26+
timeout=5,
27+
).raise_for_status()
28+
except Exception as e:
29+
LOG.debug("Telemetry send failed (%s): %s", event, e)

main.py

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
poll_for_token,
1717
refresh_tokens,
1818
)
19+
from intercomclient.telemetry import TelemetryClient
1920
from intercomclient.token_store import TokenStatus, TokenStore
2021

2122
logging.basicConfig(level=logging.INFO)
@@ -26,6 +27,7 @@ class PiClient:
2627
def __init__(self, config: Config):
2728
self.config = config
2829
self.token_store = TokenStore(config)
30+
self.telemetry = TelemetryClient(config, self.token_store)
2931
self.pc: RTCPeerConnection | None = None
3032
self.ws = None
3133
self.running = True
@@ -136,8 +138,14 @@ async def setup_peer_connection(self):
136138
async def on_connectionstatechange():
137139
if pc is not self.pc:
138140
return # stale event from a replaced PC
139-
LOG.info("WebRTC state: %s", pc.connectionState)
140-
if pc.connectionState == "failed":
141+
state = pc.connectionState
142+
LOG.info("WebRTC state: %s", state)
143+
if state == "connected":
144+
await asyncio.to_thread(self.telemetry.send, "streaming")
145+
elif state == "failed":
146+
await asyncio.to_thread(
147+
self.telemetry.send, "error", "WebRTC connection failed", "WARNING"
148+
)
141149
# Reset the PC so we're ready for the next offer.
142150
# The signaling WebSocket stays alive — don't close it here.
143151
await self.setup_peer_connection()
@@ -184,6 +192,7 @@ async def signaling_loop(self):
184192

185193
await self.setup_peer_connection()
186194
self._register_ice_handler()
195+
await asyncio.to_thread(self.telemetry.send, "connected")
187196

188197
async for message in ws:
189198
data = json.loads(message)
@@ -205,6 +214,9 @@ async def signaling_loop(self):
205214
LOG.warning(
206215
"Camera unavailable (%s), sending answer without video", e
207216
)
217+
await asyncio.to_thread(
218+
self.telemetry.send, "error", str(e), "WARNING"
219+
)
208220

209221
answer = await self.pc.createAnswer()
210222

@@ -236,25 +248,39 @@ async def signaling_loop(self):
236248
LOG.info(
237249
"Viewer disconnected; resetting peer connection for new offer"
238250
)
251+
await asyncio.to_thread(
252+
self.telemetry.send, "disconnected", "Viewer disconnected"
253+
)
239254
await self.setup_peer_connection()
240255
self._register_ice_handler()
256+
await asyncio.to_thread(self.telemetry.send, "connected")
241257

242258
# =========================
243259
# Lifecycle
244260
# =========================
245261

262+
async def _heartbeat_loop(self):
263+
while self.running:
264+
await asyncio.sleep(30)
265+
await asyncio.to_thread(self.telemetry.send, "heartbeat")
266+
246267
async def run(self):
268+
asyncio.create_task(self._heartbeat_loop())
247269
while self.running:
248270
try:
249271
await self.ensure_valid_tokens()
250272
await self.signaling_loop()
251273
except Exception as e:
252274
LOG.exception("Client error: %s", e)
275+
await asyncio.to_thread(self.telemetry.send, "error", str(e), "ERROR")
253276
await asyncio.sleep(5)
254277

255278
async def shutdown(self):
256279
LOG.info("Shutting down client...")
257280
self.running = False
281+
await asyncio.to_thread(
282+
self.telemetry.send, "disconnected", "Client shutting down"
283+
)
258284

259285
if self.pc:
260286
await self.pc.close()

0 commit comments

Comments
 (0)