From 6eb945dd6475434eeca65e8f59795937aab49ad6 Mon Sep 17 00:00:00 2001 From: pollutri Date: Tue, 24 Mar 2026 17:59:21 +0100 Subject: [PATCH] Tracks API added --- routes/reslevis.py | 53 +++++++++++++++++++++++++++++++++++++++++++-- schemas/reslevis.py | 24 +++++++++++++++++++- 2 files changed, 74 insertions(+), 3 deletions(-) diff --git a/routes/reslevis.py b/routes/reslevis.py index 01af603..b58c407 100644 --- a/routes/reslevis.py +++ b/routes/reslevis.py @@ -1,7 +1,7 @@ -from fastapi import APIRouter, Depends, HTTPException, Request +from fastapi import APIRouter, Depends, HTTPException, Query, Request import httpx import config_env -from typing import List +from typing import List, Optional from schemas.reslevis import ( BuildingItem, @@ -13,6 +13,7 @@ from schemas.reslevis import ( SubjectItem, AlarmItem, TrackItem, + TrackHistoryItem, TrackerZoneItem, SettingItem, ) @@ -120,6 +121,7 @@ def _normalize_tracker(row: dict) -> dict: def _normalize_track(row: dict) -> dict: row = dict(row) + row["ID"] = row.get("ID") row["gateway"] = _none_if_empty(row.get("gateway")) row["tracker"] = _none_if_empty(row.get("tracker")) row["subject"] = _none_if_empty(row.get("subject")) @@ -131,6 +133,9 @@ def _normalize_track(row: dict) -> dict: row["gatewayMac"] = _str_or_none(row.get("gatewayMac")) row["trackerMac"] = _str_or_none(row.get("trackerMac")) row["subjectName"] = _str_or_none(row.get("subjectName")) + row["x"] = None if row.get("x") in ("", None) else row.get("x") + row["y"] = None if row.get("y") in ("", None) else row.get("y") + row["z"] = None if row.get("z") in ("", None) else row.get("z") # signal resta float o None row["signal"] = None if row.get("signal") in ("", None) else row.get("signal") return row @@ -327,6 +332,50 @@ def getTracks(): return track_repo.list() +@router.get( + "/getTracks/{tracker_id}", + response_model=List[TrackHistoryItem], + tags=["Reslevis"], + dependencies=[Depends(get_current_user)], +) +async def getTrack( + tracker_id: str, + limit: Optional[int] = Query(None, ge=1), + from_: Optional[str] = Query(None, alias="from"), + to: Optional[str] = Query(None), +): + params = {} + if limit is not None: + params["limit"] = limit + if from_: + params["from"] = from_ + if to: + params["to"] = to + + try: + async with httpx.AsyncClient(timeout=30.0, verify=False) as client: + resp = await client.get( + f"{CORE_BASE_URL}/reslevis/getTracks/{tracker_id}", + params=params, + ) + except httpx.RequestError as exc: + raise HTTPException(status_code=502, detail=f"CORE request failed: {exc}") from exc + + if resp.status_code >= 400: + detail = resp.text.strip() or "CORE request failed" + raise HTTPException(status_code=resp.status_code, detail=detail) + + try: + payload = resp.json() + except ValueError as exc: + raise HTTPException(status_code=502, detail="Invalid CORE response") from exc + + if not isinstance(payload, list): + raise HTTPException(status_code=502, detail="Unexpected CORE response type") + + return [_normalize_track(row) for row in payload if isinstance(row, dict)] + + @router.post("/postTrack", tags=["Reslevis"], dependencies=[Depends(get_current_user)]) def postTrack(item: TrackItem): track_repo.add(item) diff --git a/schemas/reslevis.py b/schemas/reslevis.py index 05da507..178bac7 100644 --- a/schemas/reslevis.py +++ b/schemas/reslevis.py @@ -119,6 +119,28 @@ class TrackItem(BaseModel): subject: Optional[UUID] = None subjectName: Optional[str] = None floor: Optional[UUID] = None + x: Optional[float] = None + y: Optional[float] = None + z: Optional[float] = None + signal: Optional[float] = None + building: Optional[UUID] = None + +class TrackHistoryItem(BaseModel): + ID: Optional[int] = None + id: UUID + timestamp: Optional[str] = None + type: Optional[str] = None + status: Optional[str] = None + gateway: Optional[UUID] = None + gatewayMac: Optional[str] = None + tracker: Optional[UUID] = None + trackerMac: Optional[str] = None + subject: Optional[UUID] = None + subjectName: Optional[str] = None + floor: Optional[UUID] = None + x: Optional[float] = None + y: Optional[float] = None + z: Optional[float] = None signal: Optional[float] = None building: Optional[UUID] = None @@ -147,4 +169,4 @@ class CalibrationMetadata(BaseModel): #??? Da verificate ??? class DownloadFileImmage(): name : str - immage_path : str \ No newline at end of file + immage_path : str