meter.py 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. """Meter parser."""
  2. from __future__ import annotations
  3. import struct
  4. from typing import Any
  5. CO2_UNPACK = struct.Struct(">H").unpack_from
  6. def process_wosensorth(data: bytes | None, mfr_data: bytes | None) -> dict[str, Any]:
  7. """Process woSensorTH/Temp sensor services data."""
  8. temp_data: bytes | None = None
  9. battery: bytes | None = None
  10. if mfr_data:
  11. temp_data = mfr_data[8:11]
  12. if data:
  13. if not temp_data:
  14. temp_data = data[3:6]
  15. battery = data[2] & 0b01111111
  16. if not temp_data:
  17. return {}
  18. _temp_sign = 1 if temp_data[1] & 0b10000000 else -1
  19. _temp_c = _temp_sign * (
  20. (temp_data[1] & 0b01111111) + ((temp_data[0] & 0b00001111) / 10)
  21. )
  22. _temp_f = (_temp_c * 9 / 5) + 32
  23. _temp_f = (_temp_f * 10) / 10
  24. humidity = temp_data[2] & 0b01111111
  25. if _temp_c == 0 and humidity == 0 and battery == 0:
  26. return {}
  27. _wosensorth_data = {
  28. # Data should be flat, but we keep the original structure for now
  29. "temp": {"c": _temp_c, "f": _temp_f},
  30. "temperature": _temp_c,
  31. "fahrenheit": bool(temp_data[2] & 0b10000000),
  32. "humidity": humidity,
  33. "battery": battery,
  34. }
  35. return _wosensorth_data
  36. def process_wosensorth_c(data: bytes | None, mfr_data: bytes | None) -> dict[str, Any]:
  37. """Process woSensorTH/Temp sensor services data with CO2."""
  38. _wosensorth_data = process_wosensorth(data, mfr_data)
  39. if _wosensorth_data and mfr_data and len(mfr_data) >= 15:
  40. co2_data = mfr_data[13:15]
  41. _wosensorth_data["co2"] = CO2_UNPACK(co2_data)[0]
  42. return _wosensorth_data