first commit
This commit is contained in:
commit
4b98219bf7
144 changed files with 31561 additions and 0 deletions
57
backend/api/routes/leak.py
Normal file
57
backend/api/routes/leak.py
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
from fastapi import APIRouter, Depends, Query
|
||||
from sqlalchemy import text
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from core.database import get_session
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
# Static topology metadata — mirrors simulator config
|
||||
LEAK_SENSORS = {
|
||||
"sg-01": [
|
||||
{"sensor_id": "leak-01", "floor_zone": "crac-zone-a", "under_floor": True, "near_crac": True, "room_id": "hall-a"},
|
||||
{"sensor_id": "leak-02", "floor_zone": "server-row-b1", "under_floor": True, "near_crac": False, "room_id": "hall-b"},
|
||||
{"sensor_id": "leak-03", "floor_zone": "ups-room", "under_floor": False, "near_crac": False, "room_id": None},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@router.get("/status")
|
||||
async def leak_status(
|
||||
site_id: str = Query(...),
|
||||
session: AsyncSession = Depends(get_session),
|
||||
):
|
||||
"""Latest state for all leak sensors, enriched with location metadata."""
|
||||
result = await session.execute(text("""
|
||||
SELECT DISTINCT ON (sensor_id)
|
||||
sensor_id, value, recorded_at
|
||||
FROM readings
|
||||
WHERE site_id = :site_id
|
||||
AND sensor_type = 'leak'
|
||||
AND recorded_at > NOW() - INTERVAL '5 minutes'
|
||||
ORDER BY sensor_id, recorded_at DESC
|
||||
"""), {"site_id": site_id})
|
||||
|
||||
# sensor_id format: {site_id}/leak/{sensor_id}
|
||||
state_map: dict[str, dict] = {}
|
||||
for row in result.mappings().all():
|
||||
parts = row["sensor_id"].split("/")
|
||||
if len(parts) < 3:
|
||||
continue
|
||||
sid = parts[2]
|
||||
state_map[sid] = {
|
||||
"state": "detected" if float(row["value"]) > 0.5 else "clear",
|
||||
"recorded_at": str(row["recorded_at"]),
|
||||
}
|
||||
|
||||
out = []
|
||||
for cfg in LEAK_SENSORS.get(site_id, []):
|
||||
sid = cfg["sensor_id"]
|
||||
entry = {**cfg}
|
||||
if sid in state_map:
|
||||
entry["state"] = state_map[sid]["state"]
|
||||
entry["recorded_at"] = state_map[sid]["recorded_at"]
|
||||
else:
|
||||
entry["state"] = "unknown"
|
||||
entry["recorded_at"] = None
|
||||
out.append(entry)
|
||||
return out
|
||||
Loading…
Add table
Add a link
Reference in a new issue