Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.
 
 
 
 

70 rindas
1.9 KiB

  1. """mqtt_parser.py
  2. Parser del topic/payload MQTT in formato publish_out/<gateway> con payload JSON list.
  3. Esempio payload:
  4. [
  5. {"timestamp":"...","type":"Gateway","mac":"AC233FC1DD3C","nums":9},
  6. {"timestamp":"...","mac":"C3000057B9F4","rssi":-56,"rawData":"..."},
  7. ...
  8. ]
  9. Restituisce eventi normalizzati (gateway_mac_compact, beacon_mac_compact, rssi, timestamp_iso).
  10. """
  11. from __future__ import annotations
  12. import json
  13. from typing import List, Optional, Tuple
  14. from .normalize import mac_to_compact
  15. MqttEvent = Tuple[str, str, float, Optional[str]] # (gw_compact, beacon_compact, rssi, ts_iso)
  16. def parse_publish_out(topic: str, payload: bytes) -> List[MqttEvent]:
  17. try:
  18. obj = json.loads(payload.decode("utf-8", errors="strict"))
  19. except Exception:
  20. return []
  21. if not isinstance(obj, list) or not obj:
  22. return []
  23. # Gateway MAC: preferisci il primo elemento "type: Gateway" se presente, altrimenti usa il topic.
  24. gw_compact: str = ""
  25. first = obj[0]
  26. if isinstance(first, dict) and str(first.get("type", "")).lower() == "gateway" and "mac" in first:
  27. gw_compact = mac_to_compact(first.get("mac"))
  28. if not gw_compact:
  29. # topic: publish_out/<gw>
  30. gw_compact = mac_to_compact(topic.split("/")[-1])
  31. out: List[MqttEvent] = []
  32. for item in obj:
  33. if not isinstance(item, dict):
  34. continue
  35. if str(item.get("type", "")).lower() == "gateway":
  36. continue
  37. mac = item.get("mac")
  38. rssi = item.get("rssi")
  39. if mac is None or rssi is None:
  40. continue
  41. b_compact = mac_to_compact(mac)
  42. if len(b_compact) != 12:
  43. continue
  44. try:
  45. rssi_f = float(rssi)
  46. except Exception:
  47. continue
  48. ts = item.get("timestamp")
  49. out.append((gw_compact, b_compact, rssi_f, ts if isinstance(ts, str) else None))
  50. return out