added refference point

This commit is contained in:
2026-06-25 14:17:36 +03:00
parent 27f2a3fd5d
commit a8999f1369
6 changed files with 264 additions and 2 deletions
+126 -2
View File
@@ -551,6 +551,68 @@ def _metric_stats(values: list[float]) -> dict[str, Any]:
}
_TX_PARAM_KEYS = (
"frequency_hz",
"power_dbm",
"spreading_factor",
"bandwidth_khz",
"code_rate",
"preamble_length",
"tx_timeout_ms",
"crc_enabled",
)
def _role_from_row(row: dict[str, Any]) -> Optional[str]:
role = row.get("role")
if role:
return str(role)
meta = _json_load(row.get("meta"))
if isinstance(meta, dict) and meta.get("role"):
return str(meta["role"])
return None
def _tx_params_from_meta(meta: Any) -> dict[str, Any]:
data = _json_load(meta)
if not isinstance(data, dict):
return {}
return {key: data[key] for key in _TX_PARAM_KEYS if data.get(key) is not None}
def _reference_context(rows: list[dict[str, Any]]) -> dict[str, Any]:
tx_params = None
tx_device = None
rx_position = None
roles: set[str] = set()
devices: set[str] = set()
for row in sorted(rows, key=lambda r: float(r.get("ts") or 0)):
role = _role_from_row(row)
if role:
roles.add(role)
device_id = row.get("device_id")
if device_id:
devices.add(str(device_id))
params = _tx_params_from_meta(row.get("meta"))
if params and (role == "TX" or tx_params is None):
tx_params = params
tx_device = device_id
if role == "RX" and row.get("lat") is not None and row.get("lon") is not None:
rx_position = {
"device_id": device_id,
"lat": row.get("lat"),
"lon": row.get("lon"),
"ts": row.get("ts"),
}
return {
"tx_params": tx_params,
"tx_device_id": tx_device,
"rx_position": rx_position,
"roles": sorted(roles),
"devices": sorted(devices),
}
def _reference_stats(samples: list[dict[str, Any]]) -> dict[str, Any]:
per = [_metric_from_meta(s.get("meta"), "per_percent") for s in samples]
quality = [_metric_from_meta(s.get("meta"), "rx_quality_percent") for s in samples]
@@ -634,13 +696,47 @@ def add_reference_point_samples(
def finish_reference_point_session(session_id: int) -> dict[str, Any]:
ts = time.time()
with _db() as conn:
session = conn.execute(
"""
SELECT id, device_id, started_at, meta
FROM reference_point_sessions WHERE id = ?
""",
(session_id,),
).fetchone()
if not session:
raise ValueError(f"reference point session {session_id} not found")
sample_rows = conn.execute(
"""
SELECT ? AS device_id, ts, lat, lon, rssi, role, meta
FROM reference_point_samples
WHERE session_id = ?
ORDER BY ts ASC
""",
(session["device_id"], session_id),
).fetchall()
telemetry_rows = conn.execute(
"""
SELECT device_id, ts, lat, lon, rssi, role, meta
FROM telemetry
WHERE source = 'android' AND ts >= ? AND ts <= ?
ORDER BY ts ASC
LIMIT 1000
""",
(session["started_at"], ts),
).fetchall()
meta = _json_load(session["meta"]) if session["meta"] else {}
if not isinstance(meta, dict):
meta = {}
meta["reference_context"] = _reference_context(
[dict(r) for r in sample_rows] + [dict(r) for r in telemetry_rows]
)
cur = conn.execute(
"""
UPDATE reference_point_sessions
SET ended_at = ?, status = 'finished'
SET ended_at = ?, status = 'finished', meta = ?
WHERE id = ? AND status = 'recording'
""",
(ts, session_id),
(ts, _json_or_none(meta), session_id),
)
if cur.rowcount == 0:
raise ValueError(f"reference point session {session_id} not found or inactive")
@@ -711,6 +807,34 @@ def get_reference_point_session(session_id: int) -> dict[str, Any]:
result["sample_count"] = len(samples)
result["samples"] = samples
result["stats"] = _reference_stats(samples)
meta = _json_load(result.get("meta"))
if not isinstance(meta, dict):
meta = {}
context = meta.get("reference_context")
if not isinstance(context, dict):
telemetry_rows = []
with _db() as conn:
telemetry_rows = conn.execute(
"""
SELECT device_id, ts, lat, lon, rssi, role, meta
FROM telemetry
WHERE source = 'android' AND ts >= ? AND ts <= ?
ORDER BY ts ASC
LIMIT 1000
""",
(
result["started_at"],
result["ended_at"] if result["ended_at"] is not None else time.time(),
),
).fetchall()
context = _reference_context(
[
{"device_id": result["device_id"], **sample}
for sample in samples
]
+ [dict(r) for r in telemetry_rows]
)
result["reference_context"] = context
return result