hub2.py 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. """Hub2 parser."""
  2. from __future__ import annotations
  3. from typing import Any
  4. from ..const.hub2 import LIGHT_INTENSITY_MAP
  5. def process_wohub2(data: bytes | None, mfr_data: bytes | None) -> dict[str, Any]:
  6. """Process woHub2 sensor manufacturer data."""
  7. temp_data = None
  8. if mfr_data:
  9. status = mfr_data[12]
  10. temp_data = mfr_data[13:16]
  11. if not temp_data:
  12. return {}
  13. _temp_sign = 1 if temp_data[1] & 0b10000000 else -1
  14. _temp_c = _temp_sign * (
  15. (temp_data[1] & 0b01111111) + ((temp_data[0] & 0b00001111) / 10)
  16. )
  17. _temp_f = (_temp_c * 9 / 5) + 32
  18. _temp_f = (_temp_f * 10) / 10
  19. humidity = temp_data[2] & 0b01111111
  20. light_level = status & 0b11111
  21. if _temp_c == 0 and humidity == 0:
  22. return {}
  23. _wohub2_data = {
  24. # Data should be flat, but we keep the original structure for now
  25. "temp": {"c": _temp_c, "f": _temp_f},
  26. "temperature": _temp_c,
  27. "fahrenheit": bool(temp_data[2] & 0b10000000),
  28. "humidity": humidity,
  29. "lightLevel": light_level,
  30. "illuminance": calculate_light_intensity(light_level),
  31. }
  32. return _wohub2_data
  33. def calculate_light_intensity(light_level: int) -> int:
  34. """
  35. Convert Hub 2 light level (1-21) to actual light intensity value
  36. Args:
  37. light_level: Integer from 1-21
  38. Returns:
  39. Corresponding light intensity value or 0 if invalid input
  40. """
  41. if not light_level:
  42. return 0
  43. return LIGHT_INTENSITY_MAP.get(max(0, min(light_level, 22)), 0)