""" ClearPilot telemetry client library. Usage from any process: from openpilot.selfdrive.clearpilot.telemetry import tlog tlog("canbus", {"speed": 45.2, "speed_limit": 60}) Sends JSON packets over ZMQ PUSH to telemetryd, which diffs and writes CSV. Only sends when TelemetryEnabled memory param is set — zero cost when disabled. """ import json import os import time import zmq TELEMETRY_SOCK = "ipc:///tmp/clearpilot_telemetry" _PARAM_PATH = "/dev/shm/params/d/TelemetryEnabled" _ctx = None _sock = None _last_check = 0 _enabled = False def tlog(group: str, data: dict): """Log a telemetry packet. Only changed values will be written to CSV by telemetryd.""" global _ctx, _sock, _last_check, _enabled # Check param at most once per second to avoid filesystem overhead now = time.monotonic() if now - _last_check > 1.0: _last_check = now try: with open(_PARAM_PATH, 'r') as f: _enabled = f.read().strip() == "1" except (FileNotFoundError, IOError): _enabled = False if not _enabled: return if _sock is None: _ctx = zmq.Context.instance() _sock = _ctx.socket(zmq.PUSH) _sock.setsockopt(zmq.LINGER, 0) _sock.setsockopt(zmq.SNDHWM, 100) _sock.connect(TELEMETRY_SOCK) msg = json.dumps({"ts": time.time(), "group": group, "data": data}) try: _sock.send_string(msg, zmq.NOBLOCK) except zmq.Again: pass # drop if collector isn't running or queue full