first commit
This commit is contained in:
commit
4b98219bf7
144 changed files with 31561 additions and 0 deletions
75
backend/api/routes/fire.py
Normal file
75
backend/api/routes/fire.py
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
from fastapi import APIRouter, Depends, Query
|
||||
from sqlalchemy import text
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from core.database import get_session
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
VESDA_ZONES = {
|
||||
"sg-01": [
|
||||
{"zone_id": "vesda-hall-a", "room_id": "hall-a"},
|
||||
{"zone_id": "vesda-hall-b", "room_id": "hall-b"},
|
||||
]
|
||||
}
|
||||
|
||||
LEVEL_MAP = {0: "normal", 1: "alert", 2: "action", 3: "fire"}
|
||||
|
||||
VESDA_TYPES = ("vesda_level", "vesda_obscuration", "vesda_det1", "vesda_det2",
|
||||
"vesda_power", "vesda_flow")
|
||||
|
||||
|
||||
@router.get("/status")
|
||||
async def fire_status(
|
||||
site_id: str = Query(...),
|
||||
session: AsyncSession = Depends(get_session),
|
||||
):
|
||||
"""Latest VESDA readings per fire zone."""
|
||||
types_sql = ", ".join(f"'{t}'" for t in VESDA_TYPES)
|
||||
result = await session.execute(text(f"""
|
||||
SELECT DISTINCT ON (sensor_id)
|
||||
sensor_id, sensor_type, value
|
||||
FROM readings
|
||||
WHERE site_id = :site_id
|
||||
AND sensor_type IN ({types_sql})
|
||||
AND recorded_at > NOW() - INTERVAL '2 minutes'
|
||||
ORDER BY sensor_id, recorded_at DESC
|
||||
"""), {"site_id": site_id})
|
||||
|
||||
zone_data: dict[str, dict] = {}
|
||||
for row in result.mappings().all():
|
||||
parts = row["sensor_id"].split("/")
|
||||
if len(parts) < 3:
|
||||
continue
|
||||
zone_id = parts[2]
|
||||
if zone_id not in zone_data:
|
||||
zone_data[zone_id] = {"zone_id": zone_id}
|
||||
v = float(row["value"])
|
||||
s_type = row["sensor_type"]
|
||||
if s_type == "vesda_level":
|
||||
zone_data[zone_id]["level"] = LEVEL_MAP.get(round(v), "normal")
|
||||
elif s_type == "vesda_obscuration":
|
||||
zone_data[zone_id]["obscuration_pct_m"] = round(v, 3)
|
||||
elif s_type == "vesda_det1":
|
||||
zone_data[zone_id]["detector_1_ok"] = v > 0.5
|
||||
elif s_type == "vesda_det2":
|
||||
zone_data[zone_id]["detector_2_ok"] = v > 0.5
|
||||
elif s_type == "vesda_power":
|
||||
zone_data[zone_id]["power_ok"] = v > 0.5
|
||||
elif s_type == "vesda_flow":
|
||||
zone_data[zone_id]["flow_ok"] = v > 0.5
|
||||
|
||||
zone_room_map = {z["zone_id"]: z["room_id"] for z in VESDA_ZONES.get(site_id, [])}
|
||||
|
||||
out = []
|
||||
for zone_cfg in VESDA_ZONES.get(site_id, []):
|
||||
zone_id = zone_cfg["zone_id"]
|
||||
d = zone_data.get(zone_id, {"zone_id": zone_id})
|
||||
d.setdefault("level", "normal")
|
||||
d.setdefault("obscuration_pct_m", None)
|
||||
d.setdefault("detector_1_ok", True)
|
||||
d.setdefault("detector_2_ok", True)
|
||||
d.setdefault("power_ok", True)
|
||||
d.setdefault("flow_ok", True)
|
||||
d["room_id"] = zone_room_map.get(zone_id)
|
||||
out.append(d)
|
||||
return out
|
||||
Loading…
Add table
Add a link
Reference in a new issue