#!/usr/bin/env python3 """BLE sensor status / log / advertise command (collector UI bridge).""" import json from flask import Blueprint, jsonify from auth import login_required from paths import run_dir sensors_bp = Blueprint("sensors", __name__) STATUS_NAME = "sensors-status.json" LOG_NAME = "sensors-ui.log" CMD_NAME = "sensors-cmd" LOG_LIMIT = 200 def _read_status(): path = run_dir() / STATUS_NAME if not path.exists(): return { "n": 4, "pool_full": False, "period_s": 30, "slots": [], "ts": 0, "available": False, } try: data = json.loads(path.read_text(encoding="utf-8")) data["available"] = True return data except (OSError, ValueError): return {"available": False, "slots": [], "error": "bad status file"} def _read_log(limit=LOG_LIMIT): path = run_dir() / LOG_NAME if not path.exists(): return [] try: lines = path.read_text(encoding="utf-8").splitlines() except OSError: return [] entries = [] for line in lines[-limit:]: line = line.strip() if not line: continue try: entries.append(json.loads(line)) except ValueError: continue entries.reverse() return entries def _write_advertise_cmd(): path = run_dir() / CMD_NAME try: path.write_text(json.dumps({"op": "advertise"}), encoding="utf-8") return True except OSError: return False @sensors_bp.route("/api/sensors", methods=["GET"]) @login_required def api_sensors(): return jsonify(_read_status()) @sensors_bp.route("/api/sensors/log", methods=["GET"]) @login_required def api_sensors_log(): return jsonify({"entries": _read_log()}) @sensors_bp.route("/api/sensors/advertise", methods=["POST"]) @login_required def api_sensors_advertise(): if not _write_advertise_cmd(): return jsonify({"ok": False, "error": "cannot write command"}), 500 return jsonify({"ok": True})