Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 

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