from fastapi import APIRouter, Depends, HTTPException, Request import httpx import config_env from typing import List from schemas.reslevis import ( BuildingItem, FloorItem, ZoneItem, GatewayItem, TrackerItem, OperatorItem, SubjectItem, AlarmItem, TrackItem, TrackerZoneItem, ) from logica_reslevis.gateway import GatewayJsonRepository from logica_reslevis.building import BuildingJsonRepository from logica_reslevis.floor import FloorJsonRepository from logica_reslevis.zone import ZoneJsonRepository from logica_reslevis.tracker import TrackerJsonRepository from logica_reslevis.operator import OperatorJsonRepository from logica_reslevis.subject import SubjectJsonRepository from logica_reslevis.alarm import AlarmJsonRepository from logica_reslevis.track import TrackJsonRepository from logica_reslevis.tracker_zone import TrackerZoneJsonRepository from security import get_current_user #CORE SYNC CORE_BASE_URL = config_env.CORE_API_URL.rstrip("/") CORE_TIMEOUT = 2.0 # secondi async def sync_core_get(request: Request) -> None: if request.method != "GET": return sync = CORE_GET_SYNC.get(request.url.path) if sync is None: return repo, normalizer = sync try: async with httpx.AsyncClient(timeout=CORE_TIMEOUT) as client: resp = await client.get( f"{CORE_BASE_URL}{request.url.path}", params=request.query_params, ) if 200 <= resp.status_code < 300: data = resp.json() if isinstance(data, list): if normalizer: data = [normalizer(r) for r in data if isinstance(r, dict)] repo._write_all(data) # aggiorna i file locali except (httpx.RequestError, ValueError): # CORE giù o risposta non valida -> uso il file locale pass router = APIRouter(dependencies=[Depends(sync_core_get)]) gateway_repo = GatewayJsonRepository() building_repo = BuildingJsonRepository() floor_repo = FloorJsonRepository() zone_repo = ZoneJsonRepository() tracker_repo = TrackerJsonRepository() operator_repo = OperatorJsonRepository() subject_repo = SubjectJsonRepository() alarm_repo = AlarmJsonRepository() track_repo = TrackJsonRepository() tracker_zone_repo = TrackerZoneJsonRepository() def _none_if_empty(v): return None if v in ("", None, 0, "0") else v def _str_or_none(v): if v in ("", None): return None if isinstance(v, (int, float, bool)): return str(v) return v def _uuid_list(values): if values in ("", None): return [] if isinstance(values, str): values = [v for v in values.split(",") if v] if isinstance(values, (list, tuple, set)): cleaned = [] for v in values: if isinstance(v, dict): v = v.get("id") or v.get("uuid") if v in ("", None, 0, "0"): continue cleaned.append(v) return cleaned return [values] if values not in ("", None, 0, "0") else [] def _normalize_gateway(row: dict) -> dict: row = dict(row) row["floor"] = _none_if_empty(row.get("floor")) row["building"] = _none_if_empty(row.get("building")) return row def _normalize_tracker(row: dict) -> dict: row = dict(row) row["floor"] = _none_if_empty(row.get("floor")) row["building"] = _none_if_empty(row.get("building")) row["battery"] = _str_or_none(row.get("battery")) row["temperature"] = _str_or_none(row.get("temperature")) row["acceleration"] = _str_or_none(row.get("acceleration")) row["heartRate"] = _str_or_none(row.get("heartRate")) return row def _normalize_track(row: dict) -> dict: row = dict(row) row["gateway"] = _none_if_empty(row.get("gateway")) row["tracker"] = _none_if_empty(row.get("tracker")) row["subject"] = _none_if_empty(row.get("subject")) row["floor"] = _none_if_empty(row.get("floor")) row["building"] = _none_if_empty(row.get("building")) row["timestamp"] = _str_or_none(row.get("timestamp")) row["type"] = _str_or_none(row.get("type")) row["status"] = _str_or_none(row.get("status")) row["gatewayMac"] = _str_or_none(row.get("gatewayMac")) row["trackerMac"] = _str_or_none(row.get("trackerMac")) row["subjectName"] = _str_or_none(row.get("subjectName")) # signal resta float o None row["signal"] = None if row.get("signal") in ("", None) else row.get("signal") return row def _normalize_zone(row: dict) -> dict: row = dict(row) row["floor"] = _none_if_empty(row.get("floor")) row["building"] = _none_if_empty(row.get("building")) row["groups"] = _uuid_list(row.get("groups")) return row CORE_GET_SYNC = { "/reslevis/getGateways": (gateway_repo, _normalize_gateway), "/reslevis/getZones": (zone_repo, _normalize_zone), "/reslevis/getTrackers": (tracker_repo, _normalize_tracker), "/reslevis/getTracks": (track_repo, _normalize_track), } @router.get( "/getGateways", response_model=List[GatewayItem], tags=["Reslevis"], dependencies=[Depends(get_current_user)], ) def getGateways(): return gateway_repo.list() @router.post("/postGateway", tags=["Reslevis"], dependencies=[Depends(get_current_user)]) def postGateway(item: GatewayItem): gateway_repo.add(item) return {"message": "OK"} @router.put("/updateGateway", tags=["Reslevis"], dependencies=[Depends(get_current_user)]) def updateGateway(item: GatewayItem): gateway_repo.update(item) return {"message": "OK"} @router.delete("/removeGateway/{gateway_id}", tags=["Reslevis"], dependencies=[Depends(get_current_user)]) def removeGateway(gateway_id: str): gateway_repo.remove(gateway_id) return {"message": "OK"} @router.get( "/getBuildings", response_model=List[BuildingItem], tags=["Reslevis"], dependencies=[Depends(get_current_user)], ) def getBuildings(): return building_repo.list() @router.post("/postBuilding", tags=["Reslevis"], dependencies=[Depends(get_current_user)]) def postBuilding(item: BuildingItem): building_repo.add(item) return {"message": "OK"} @router.put("/updateBuilding", tags=["Reslevis"], dependencies=[Depends(get_current_user)]) def updateBuilding(item: BuildingItem): building_repo.update(item) return {"message": "OK"} @router.delete("/removeBuilding/{building_id}", tags=["Reslevis"], dependencies=[Depends(get_current_user)]) def removeBuilding(building_id: str): building_repo.remove(building_id) return {"message": "OK"} @router.get( "/getFloors", response_model=List[FloorItem], tags=["Reslevis"], dependencies=[Depends(get_current_user)], ) def getFloors(): return floor_repo.list() @router.post("/postFloor", tags=["Reslevis"], dependencies=[Depends(get_current_user)]) def postFloor(item: FloorItem): floor_repo.add(item) return {"message": "OK"} @router.put("/updateFloor", tags=["Reslevis"], dependencies=[Depends(get_current_user)]) def updateFloor(item: FloorItem): floor_repo.update(item) return {"message": "OK"} @router.delete("/removeFloor/{floor_id}", tags=["Reslevis"], dependencies=[Depends(get_current_user)]) def removeFloor(floor_id: str): floor_repo.remove(floor_id) return {"message": "OK"} @router.get( "/getZones", response_model=List[ZoneItem], tags=["Reslevis"], dependencies=[Depends(get_current_user)], ) def getZones(): return zone_repo.list() @router.post("/postZone", tags=["Reslevis"], dependencies=[Depends(get_current_user)]) def postZone(item: ZoneItem): zone_repo.add(item) return {"message": "OK"} @router.put("/updateZone", tags=["Reslevis"], dependencies=[Depends(get_current_user)]) def updateZone(item: ZoneItem): zone_repo.update(item) return {"message": "OK"} @router.delete("/removeZone/{zone_id}", tags=["Reslevis"], dependencies=[Depends(get_current_user)]) def removeZone(zone_id: str): zone_repo.remove(zone_id) return {"message": "OK"} @router.get( "/getTrackers", response_model=List[TrackerItem], tags=["Reslevis"], dependencies=[Depends(get_current_user)], ) def getTrackers(): return tracker_repo.list() @router.post("/postTracker", tags=["Reslevis"], dependencies=[Depends(get_current_user)]) def postTracker(item: TrackerItem): tracker_repo.add(item) return {"message": "OK"} @router.put("/updateTracker", tags=["Reslevis"], dependencies=[Depends(get_current_user)]) def updateTracker(item: TrackerItem): tracker_repo.update(item) return {"message": "OK"} @router.delete("/removeTracker/{tracker_id}", tags=["Reslevis"], dependencies=[Depends(get_current_user)]) def removeTracker(tracker_id: str): tracker_repo.remove(tracker_id) return {"message": "OK"} @router.get( "/getTrackerZones", response_model=List[TrackerZoneItem], tags=["Reslevis"], dependencies=[Depends(get_current_user)], ) def getTrackerZones(): return tracker_zone_repo.list() @router.post("/postTrackerZone", tags=["Reslevis"], dependencies=[Depends(get_current_user)]) def postTrackerZone(item: TrackerZoneItem): tracker_zone_repo.add(item) return {"message": "OK"} @router.put("/updateTrackerZone", tags=["Reslevis"], dependencies=[Depends(get_current_user)]) def updateTrackerZone(item: TrackerZoneItem): tracker_zone_repo.update(item) return {"message": "OK"} @router.delete("/removeTrackerZone/{tracker_zone_id}", tags=["Reslevis"], dependencies=[Depends(get_current_user)]) def removeTrackerZone(tracker_zone_id: str): tracker_zone_repo.remove(tracker_zone_id) return {"message": "OK"} @router.get( "/getTracks", response_model=List[TrackItem], tags=["Reslevis"], dependencies=[Depends(get_current_user)], ) def getTracks(): return track_repo.list() @router.post("/postTrack", tags=["Reslevis"], dependencies=[Depends(get_current_user)]) def postTrack(item: TrackItem): track_repo.add(item) return {"message": "OK"} @router.put("/updateTrack", tags=["Reslevis"], dependencies=[Depends(get_current_user)]) def updateTrack(item: TrackItem): track_repo.update(item) return {"message": "OK"} @router.delete("/removeTrack/{track_id}", tags=["Reslevis"], dependencies=[Depends(get_current_user)]) def removeTrack(track_id: str): track_repo.remove(track_id) return {"message": "OK"} @router.get( "/getOperators", response_model=List[OperatorItem], tags=["Reslevis"], dependencies=[Depends(get_current_user)], ) def getOperators(): return operator_repo.list() @router.post("/postOperator", tags=["Reslevis"], dependencies=[Depends(get_current_user)]) def postOperator(item: OperatorItem): operator_repo.add(item) return {"message": "OK"} @router.put("/updateOperator", tags=["Reslevis"], dependencies=[Depends(get_current_user)]) def updateOperator(item: OperatorItem): operator_repo.update(item) return {"message": "OK"} @router.delete("/removeOperator/{operator_id}", tags=["Reslevis"], dependencies=[Depends(get_current_user)]) def removeOperator(operator_id: str): operator_repo.remove(operator_id) return {"message": "OK"} @router.get( "/getSubjects", response_model=List[SubjectItem], tags=["Reslevis"], dependencies=[Depends(get_current_user)], ) def getSubjects(): return subject_repo.list() @router.post("/postSubject", tags=["Reslevis"], dependencies=[Depends(get_current_user)]) def postSubject(item: SubjectItem): subject_repo.add(item) return {"message": "OK"} @router.put("/updateSubject", tags=["Reslevis"], dependencies=[Depends(get_current_user)]) def updateSubject(item: SubjectItem): subject_repo.update(item) return {"message": "OK"} @router.delete("/removeSubject/{subject_id}", tags=["Reslevis"], dependencies=[Depends(get_current_user)]) def removeSubject(subject_id: str): subject_repo.remove(subject_id) return {"message": "OK"}