Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 
 

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