Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 
 

399 righe
12 KiB

  1. from fastapi import APIRouter, Depends, HTTPException, Request
  2. import httpx
  3. import config_env
  4. from typing import List
  5. from schemas.reslevis import (
  6. BuildingItem,
  7. FloorItem,
  8. ZoneItem,
  9. GatewayItem,
  10. TrackerItem,
  11. OperatorItem,
  12. SubjectItem,
  13. AlarmItem,
  14. TrackItem,
  15. TrackerZoneItem,
  16. )
  17. from logica_reslevis.gateway import GatewayJsonRepository
  18. from logica_reslevis.building import BuildingJsonRepository
  19. from logica_reslevis.floor import FloorJsonRepository
  20. from logica_reslevis.zone import ZoneJsonRepository
  21. from logica_reslevis.tracker import TrackerJsonRepository
  22. from logica_reslevis.operator import OperatorJsonRepository
  23. from logica_reslevis.subject import SubjectJsonRepository
  24. from logica_reslevis.alarm import AlarmJsonRepository
  25. from logica_reslevis.track import TrackJsonRepository
  26. from logica_reslevis.tracker_zone import TrackerZoneJsonRepository
  27. from security import get_current_user
  28. #CORE SYNC
  29. CORE_BASE_URL = config_env.CORE_API_URL.rstrip("/")
  30. CORE_TIMEOUT = 2.0 # secondi
  31. async def sync_core_get(request: Request) -> None:
  32. if request.method != "GET":
  33. return
  34. sync = CORE_GET_SYNC.get(request.url.path)
  35. if sync is None:
  36. return
  37. repo, normalizer = sync
  38. try:
  39. async with httpx.AsyncClient(timeout=CORE_TIMEOUT) as client:
  40. resp = await client.get(
  41. f"{CORE_BASE_URL}{request.url.path}",
  42. params=request.query_params,
  43. )
  44. if 200 <= resp.status_code < 300:
  45. data = resp.json()
  46. if isinstance(data, list):
  47. if normalizer:
  48. data = [normalizer(r) for r in data if isinstance(r, dict)]
  49. repo._write_all(data) # aggiorna i file locali
  50. except (httpx.RequestError, ValueError):
  51. # CORE giù o risposta non valida -> uso il file locale
  52. pass
  53. router = APIRouter(dependencies=[Depends(sync_core_get)])
  54. gateway_repo = GatewayJsonRepository()
  55. building_repo = BuildingJsonRepository()
  56. floor_repo = FloorJsonRepository()
  57. zone_repo = ZoneJsonRepository()
  58. tracker_repo = TrackerJsonRepository()
  59. operator_repo = OperatorJsonRepository()
  60. subject_repo = SubjectJsonRepository()
  61. alarm_repo = AlarmJsonRepository()
  62. track_repo = TrackJsonRepository()
  63. tracker_zone_repo = TrackerZoneJsonRepository()
  64. def _none_if_empty(v):
  65. return None if v in ("", None, 0, "0") else v
  66. def _str_or_none(v):
  67. if v in ("", None):
  68. return None
  69. if isinstance(v, (int, float, bool)):
  70. return str(v)
  71. return v
  72. def _uuid_list(values):
  73. if values in ("", None):
  74. return []
  75. if isinstance(values, str):
  76. values = [v for v in values.split(",") if v]
  77. if isinstance(values, (list, tuple, set)):
  78. cleaned = []
  79. for v in values:
  80. if isinstance(v, dict):
  81. v = v.get("id") or v.get("uuid")
  82. if v in ("", None, 0, "0"):
  83. continue
  84. cleaned.append(v)
  85. return cleaned
  86. return [values] if values not in ("", None, 0, "0") else []
  87. def _normalize_gateway(row: dict) -> dict:
  88. row = dict(row)
  89. row["floor"] = _none_if_empty(row.get("floor"))
  90. row["building"] = _none_if_empty(row.get("building"))
  91. return row
  92. def _normalize_tracker(row: dict) -> dict:
  93. row = dict(row)
  94. row["floor"] = _none_if_empty(row.get("floor"))
  95. row["building"] = _none_if_empty(row.get("building"))
  96. row["battery"] = _str_or_none(row.get("battery"))
  97. row["temperature"] = _str_or_none(row.get("temperature"))
  98. row["acceleration"] = _str_or_none(row.get("acceleration"))
  99. row["heartRate"] = _str_or_none(row.get("heartRate"))
  100. return row
  101. def _normalize_track(row: dict) -> dict:
  102. row = dict(row)
  103. row["gateway"] = _none_if_empty(row.get("gateway"))
  104. row["tracker"] = _none_if_empty(row.get("tracker"))
  105. row["subject"] = _none_if_empty(row.get("subject"))
  106. row["floor"] = _none_if_empty(row.get("floor"))
  107. row["building"] = _none_if_empty(row.get("building"))
  108. row["timestamp"] = _str_or_none(row.get("timestamp"))
  109. row["type"] = _str_or_none(row.get("type"))
  110. row["status"] = _str_or_none(row.get("status"))
  111. row["gatewayMac"] = _str_or_none(row.get("gatewayMac"))
  112. row["trackerMac"] = _str_or_none(row.get("trackerMac"))
  113. row["subjectName"] = _str_or_none(row.get("subjectName"))
  114. # signal resta float o None
  115. row["signal"] = None if row.get("signal") in ("", None) else row.get("signal")
  116. return row
  117. def _normalize_zone(row: dict) -> dict:
  118. row = dict(row)
  119. row["floor"] = _none_if_empty(row.get("floor"))
  120. row["building"] = _none_if_empty(row.get("building"))
  121. row["groups"] = _uuid_list(row.get("groups"))
  122. return row
  123. CORE_GET_SYNC = {
  124. "/reslevis/getGateways": (gateway_repo, _normalize_gateway),
  125. "/reslevis/getZones": (zone_repo, _normalize_zone),
  126. "/reslevis/getTrackers": (tracker_repo, _normalize_tracker),
  127. "/reslevis/getTracks": (track_repo, _normalize_track),
  128. }
  129. @router.get(
  130. "/getGateways",
  131. response_model=List[GatewayItem],
  132. tags=["Reslevis"],
  133. dependencies=[Depends(get_current_user)],
  134. )
  135. def getGateways():
  136. return gateway_repo.list()
  137. @router.post("/postGateway", tags=["Reslevis"], dependencies=[Depends(get_current_user)])
  138. def postGateway(item: GatewayItem):
  139. gateway_repo.add(item)
  140. return {"message": "OK"}
  141. @router.put("/updateGateway", tags=["Reslevis"], dependencies=[Depends(get_current_user)])
  142. def updateGateway(item: GatewayItem):
  143. gateway_repo.update(item)
  144. return {"message": "OK"}
  145. @router.delete("/removeGateway/{gateway_id}", tags=["Reslevis"], dependencies=[Depends(get_current_user)])
  146. def removeGateway(gateway_id: str):
  147. gateway_repo.remove(gateway_id)
  148. return {"message": "OK"}
  149. @router.get(
  150. "/getBuildings",
  151. response_model=List[BuildingItem],
  152. tags=["Reslevis"],
  153. dependencies=[Depends(get_current_user)],
  154. )
  155. def getBuildings():
  156. return building_repo.list()
  157. @router.post("/postBuilding", tags=["Reslevis"], dependencies=[Depends(get_current_user)])
  158. def postBuilding(item: BuildingItem):
  159. building_repo.add(item)
  160. return {"message": "OK"}
  161. @router.put("/updateBuilding", tags=["Reslevis"], dependencies=[Depends(get_current_user)])
  162. def updateBuilding(item: BuildingItem):
  163. building_repo.update(item)
  164. return {"message": "OK"}
  165. @router.delete("/removeBuilding/{building_id}", tags=["Reslevis"], dependencies=[Depends(get_current_user)])
  166. def removeBuilding(building_id: str):
  167. building_repo.remove(building_id)
  168. return {"message": "OK"}
  169. @router.get(
  170. "/getFloors",
  171. response_model=List[FloorItem],
  172. tags=["Reslevis"],
  173. dependencies=[Depends(get_current_user)],
  174. )
  175. def getFloors():
  176. return floor_repo.list()
  177. @router.post("/postFloor", tags=["Reslevis"], dependencies=[Depends(get_current_user)])
  178. def postFloor(item: FloorItem):
  179. floor_repo.add(item)
  180. return {"message": "OK"}
  181. @router.put("/updateFloor", tags=["Reslevis"], dependencies=[Depends(get_current_user)])
  182. def updateFloor(item: FloorItem):
  183. floor_repo.update(item)
  184. return {"message": "OK"}
  185. @router.delete("/removeFloor/{floor_id}", tags=["Reslevis"], dependencies=[Depends(get_current_user)])
  186. def removeFloor(floor_id: str):
  187. floor_repo.remove(floor_id)
  188. return {"message": "OK"}
  189. @router.get(
  190. "/getZones",
  191. response_model=List[ZoneItem],
  192. tags=["Reslevis"],
  193. dependencies=[Depends(get_current_user)],
  194. )
  195. def getZones():
  196. return zone_repo.list()
  197. @router.post("/postZone", tags=["Reslevis"], dependencies=[Depends(get_current_user)])
  198. def postZone(item: ZoneItem):
  199. zone_repo.add(item)
  200. return {"message": "OK"}
  201. @router.put("/updateZone", tags=["Reslevis"], dependencies=[Depends(get_current_user)])
  202. def updateZone(item: ZoneItem):
  203. zone_repo.update(item)
  204. return {"message": "OK"}
  205. @router.delete("/removeZone/{zone_id}", tags=["Reslevis"], dependencies=[Depends(get_current_user)])
  206. def removeZone(zone_id: str):
  207. zone_repo.remove(zone_id)
  208. return {"message": "OK"}
  209. @router.get(
  210. "/getTrackers",
  211. response_model=List[TrackerItem],
  212. tags=["Reslevis"],
  213. dependencies=[Depends(get_current_user)],
  214. )
  215. def getTrackers():
  216. return tracker_repo.list()
  217. @router.post("/postTracker", tags=["Reslevis"], dependencies=[Depends(get_current_user)])
  218. def postTracker(item: TrackerItem):
  219. tracker_repo.add(item)
  220. return {"message": "OK"}
  221. @router.put("/updateTracker", tags=["Reslevis"], dependencies=[Depends(get_current_user)])
  222. def updateTracker(item: TrackerItem):
  223. tracker_repo.update(item)
  224. return {"message": "OK"}
  225. @router.delete("/removeTracker/{tracker_id}", tags=["Reslevis"], dependencies=[Depends(get_current_user)])
  226. def removeTracker(tracker_id: str):
  227. tracker_repo.remove(tracker_id)
  228. return {"message": "OK"}
  229. @router.get(
  230. "/getTrackerZones",
  231. response_model=List[TrackerZoneItem],
  232. tags=["Reslevis"],
  233. dependencies=[Depends(get_current_user)],
  234. )
  235. def getTrackerZones():
  236. return tracker_zone_repo.list()
  237. @router.post("/postTrackerZone", tags=["Reslevis"], dependencies=[Depends(get_current_user)])
  238. def postTrackerZone(item: TrackerZoneItem):
  239. tracker_zone_repo.add(item)
  240. return {"message": "OK"}
  241. @router.put("/updateTrackerZone", tags=["Reslevis"], dependencies=[Depends(get_current_user)])
  242. def updateTrackerZone(item: TrackerZoneItem):
  243. tracker_zone_repo.update(item)
  244. return {"message": "OK"}
  245. @router.delete("/removeTrackerZone/{tracker_zone_id}", tags=["Reslevis"], dependencies=[Depends(get_current_user)])
  246. def removeTrackerZone(tracker_zone_id: str):
  247. tracker_zone_repo.remove(tracker_zone_id)
  248. return {"message": "OK"}
  249. @router.get(
  250. "/getTracks",
  251. response_model=List[TrackItem],
  252. tags=["Reslevis"],
  253. dependencies=[Depends(get_current_user)],
  254. )
  255. def getTracks():
  256. return track_repo.list()
  257. @router.post("/postTrack", tags=["Reslevis"], dependencies=[Depends(get_current_user)])
  258. def postTrack(item: TrackItem):
  259. track_repo.add(item)
  260. return {"message": "OK"}
  261. @router.put("/updateTrack", tags=["Reslevis"], dependencies=[Depends(get_current_user)])
  262. def updateTrack(item: TrackItem):
  263. track_repo.update(item)
  264. return {"message": "OK"}
  265. @router.delete("/removeTrack/{track_id}", tags=["Reslevis"], dependencies=[Depends(get_current_user)])
  266. def removeTrack(track_id: str):
  267. track_repo.remove(track_id)
  268. return {"message": "OK"}
  269. @router.get(
  270. "/getOperators",
  271. response_model=List[OperatorItem],
  272. tags=["Reslevis"],
  273. dependencies=[Depends(get_current_user)],
  274. )
  275. def getOperators():
  276. return operator_repo.list()
  277. @router.post("/postOperator", tags=["Reslevis"], dependencies=[Depends(get_current_user)])
  278. def postOperator(item: OperatorItem):
  279. operator_repo.add(item)
  280. return {"message": "OK"}
  281. @router.put("/updateOperator", tags=["Reslevis"], dependencies=[Depends(get_current_user)])
  282. def updateOperator(item: OperatorItem):
  283. operator_repo.update(item)
  284. return {"message": "OK"}
  285. @router.delete("/removeOperator/{operator_id}", tags=["Reslevis"], dependencies=[Depends(get_current_user)])
  286. def removeOperator(operator_id: str):
  287. operator_repo.remove(operator_id)
  288. return {"message": "OK"}
  289. @router.get(
  290. "/getSubjects",
  291. response_model=List[SubjectItem],
  292. tags=["Reslevis"],
  293. dependencies=[Depends(get_current_user)],
  294. )
  295. def getSubjects():
  296. return subject_repo.list()
  297. @router.post("/postSubject", tags=["Reslevis"], dependencies=[Depends(get_current_user)])
  298. def postSubject(item: SubjectItem):
  299. subject_repo.add(item)
  300. return {"message": "OK"}
  301. @router.put("/updateSubject", tags=["Reslevis"], dependencies=[Depends(get_current_user)])
  302. def updateSubject(item: SubjectItem):
  303. subject_repo.update(item)
  304. return {"message": "OK"}
  305. @router.delete("/removeSubject/{subject_id}", tags=["Reslevis"], dependencies=[Depends(get_current_user)])
  306. def removeSubject(subject_id: str):
  307. subject_repo.remove(subject_id)
  308. return {"message": "OK"}