|
|
|
@@ -1,7 +1,11 @@ |
|
|
|
from fastapi import APIRouter, Depends, HTTPException, Request |
|
|
|
import asyncio |
|
|
|
import json |
|
|
|
from urllib.parse import urlencode |
|
|
|
|
|
|
|
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 +17,7 @@ from schemas.reslevis import ( |
|
|
|
SubjectItem, |
|
|
|
AlarmItem, |
|
|
|
TrackItem, |
|
|
|
TrackHistoryItem, |
|
|
|
TrackerZoneItem, |
|
|
|
SettingItem, |
|
|
|
) |
|
|
|
@@ -33,6 +38,7 @@ from security import get_current_user |
|
|
|
|
|
|
|
#CORE SYNC |
|
|
|
CORE_BASE_URL = config_env.CORE_API_URL.rstrip("/") |
|
|
|
TRACKS_CORE_BASE_URL = "http://localhost:1902" |
|
|
|
CORE_TIMEOUT = 2.0 # secondi |
|
|
|
|
|
|
|
async def sync_core_get(request: Request) -> None: |
|
|
|
@@ -120,6 +126,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 +138,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 |
|
|
|
@@ -146,10 +156,44 @@ 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), |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
async def _fetch_tracks_for_tracker( |
|
|
|
tracker_id: str, |
|
|
|
params: Optional[dict] = None, |
|
|
|
) -> List[dict]: |
|
|
|
query_string = urlencode(params or {}) |
|
|
|
url = f"{TRACKS_CORE_BASE_URL}/reslevis/getTracks/{tracker_id}" |
|
|
|
if query_string: |
|
|
|
url = f"{url}?{query_string}" |
|
|
|
|
|
|
|
process = await asyncio.create_subprocess_exec( |
|
|
|
"curl", |
|
|
|
"-sS", |
|
|
|
"-X", |
|
|
|
"GET", |
|
|
|
url, |
|
|
|
stdout=asyncio.subprocess.PIPE, |
|
|
|
stderr=asyncio.subprocess.PIPE, |
|
|
|
) |
|
|
|
stdout, stderr = await process.communicate() |
|
|
|
|
|
|
|
if process.returncode != 0: |
|
|
|
detail = (stderr or stdout).decode("utf-8", errors="replace").strip() or "CORE curl request failed" |
|
|
|
raise HTTPException(status_code=502, detail=detail) |
|
|
|
|
|
|
|
try: |
|
|
|
payload = json.loads(stdout.decode("utf-8")) |
|
|
|
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.get( |
|
|
|
"/getGateways", |
|
|
|
response_model=List[GatewayItem], |
|
|
|
@@ -319,12 +363,48 @@ def removeTrackerZone(tracker_zone_id: str): |
|
|
|
|
|
|
|
@router.get( |
|
|
|
"/getTracks", |
|
|
|
response_model=List[TrackItem], |
|
|
|
response_model=List[TrackHistoryItem], |
|
|
|
tags=["Reslevis"], |
|
|
|
dependencies=[Depends(get_current_user)], |
|
|
|
) |
|
|
|
async def getTracks( |
|
|
|
tracker_id: str = Query(..., alias="id"), |
|
|
|
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 |
|
|
|
|
|
|
|
return await _fetch_tracks_for_tracker(tracker_id, params) |
|
|
|
|
|
|
|
|
|
|
|
@router.get( |
|
|
|
"/getTracks/{tracker_id}", |
|
|
|
response_model=List[TrackHistoryItem], |
|
|
|
tags=["Reslevis"], |
|
|
|
dependencies=[Depends(get_current_user)], |
|
|
|
) |
|
|
|
def getTracks(): |
|
|
|
return track_repo.list() |
|
|
|
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 |
|
|
|
|
|
|
|
return await _fetch_tracks_for_tracker(tracker_id, params) |
|
|
|
|
|
|
|
|
|
|
|
@router.post("/postTrack", tags=["Reslevis"], dependencies=[Depends(get_current_user)]) |
|
|
|
|