"""MLAT (Multilateration) API routes.""" import time from flask import Blueprint, jsonify, request def create_mlat_blueprint(server_config): """ Create the MLAT API blueprint. Args: server_config: Dict with keys: - get_mlat_engine: Callable returning MLAT engine - require_api_auth: Auth decorator """ bp = Blueprint("api_mlat", __name__, url_prefix="/api/mlat") get_engine = server_config["get_mlat_engine"] require_api_auth = server_config["require_api_auth"] @bp.route("/collect", methods=["POST"]) @require_api_auth def collect(): """Receive MLAT readings from scanners.""" engine = get_engine() raw_data = request.get_data(as_text=True) count = engine.parse_data(raw_data) if count > 0: engine.calculate_position() return jsonify({ "status": "ok", "readings_processed": count }) @bp.route("/state") @require_api_auth def state(): """Get current MLAT state (scanners + target position).""" engine = get_engine() state = engine.get_state() # Auto-calculate if we have enough scanners but no target if state["target"] is None and state["scanners_count"] >= 3: result = engine.calculate_position() if "position" in result: state["target"] = { "position": result["position"], "confidence": result.get("confidence", 0), "calculated_at": result.get("calculated_at", time.time()), "age_seconds": 0 } return jsonify(state) @bp.route("/config", methods=["GET", "POST"]) @require_api_auth def config(): """Get or update MLAT configuration.""" engine = get_engine() if request.method == "POST": data = request.get_json() or {} engine.update_config( rssi_at_1m=data.get("rssi_at_1m"), path_loss_n=data.get("path_loss_n"), smoothing_window=data.get("smoothing_window") ) return jsonify({ "rssi_at_1m": engine.rssi_at_1m, "path_loss_n": engine.path_loss_n, "smoothing_window": engine.smoothing_window }) @bp.route("/clear", methods=["POST"]) @require_api_auth def clear(): """Clear all scanner data.""" engine = get_engine() engine.clear() return jsonify({"status": "ok"}) return bp