Files
AidsMonitoring/backend/routers/lamps.py
T

91 lines
2.9 KiB
Python

"""
CRUD for the lamp catalog. Each Aid references a lamp by id; the lamp's
voltage_min / voltage_max determine that aid's battery warning/alarm
thresholds (see compute_thresholds).
"""
from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel, Field
from sqlalchemy.orm import Session
from typing import Optional
import uuid
from database import get_db
from models.lamp import Lamp
from models.aid import Aid
router = APIRouter(prefix="/lamps", tags=["lamps"])
class LampIn(BaseModel):
manufacturer: str
model: str
lamp_count: int = 1
voltage_min: float = Field(..., gt=0)
voltage_max: float = Field(..., gt=0)
notes: Optional[str] = None
def compute_thresholds(vmin: float, vmax: float) -> dict:
rng = vmax - vmin
return {
"warn_v": round(vmin + rng * 0.20, 3),
"alarm_v": round(vmin + rng * 0.10, 3),
}
def _lamp_dict(l: Lamp) -> dict:
th = compute_thresholds(l.voltage_min, l.voltage_max)
return {
"id": l.id,
"manufacturer": l.manufacturer,
"model": l.model,
"lamp_count": l.lamp_count,
"voltage_min": l.voltage_min,
"voltage_max": l.voltage_max,
"notes": l.notes,
"warn_v": th["warn_v"],
"alarm_v": th["alarm_v"],
}
@router.get("/")
def list_lamps(db: Session = Depends(get_db)):
return [_lamp_dict(l) for l in db.query(Lamp).order_by(Lamp.manufacturer, Lamp.model).all()]
@router.post("/")
def create_lamp(data: LampIn, db: Session = Depends(get_db)):
if data.voltage_max <= data.voltage_min:
raise HTTPException(400, "voltage_max must be greater than voltage_min")
lamp = Lamp(id=str(uuid.uuid4()), **data.model_dump())
db.add(lamp)
db.commit(); db.refresh(lamp)
return _lamp_dict(lamp)
@router.put("/{lamp_id}")
def update_lamp(lamp_id: str, data: LampIn, db: Session = Depends(get_db)):
lamp = db.query(Lamp).filter(Lamp.id == lamp_id).first()
if not lamp:
raise HTTPException(404, "Lamp not found")
if data.voltage_max <= data.voltage_min:
raise HTTPException(400, "voltage_max must be greater than voltage_min")
for k, v in data.model_dump().items():
setattr(lamp, k, v)
db.commit(); db.refresh(lamp)
return _lamp_dict(lamp)
@router.delete("/{lamp_id}")
def delete_lamp(lamp_id: str, force: bool = False, db: Session = Depends(get_db)):
in_use = db.query(Aid).filter(Aid.lamp_id == lamp_id).count()
if in_use and not force:
# Frontend will retry with force=true after user confirms
raise HTTPException(409, f"Lamp is in use by {in_use} aid(s)")
if in_use and force:
# Unassign all aids that point at this lamp
db.query(Aid).filter(Aid.lamp_id == lamp_id).update({"lamp_id": None})
db.query(Lamp).filter(Lamp.id == lamp_id).delete()
db.commit()
return {"deleted": lamp_id, "unassigned_from": in_use}