Browse Source

Add light level to ambient luminance conversion for Hub2 Illuminate entity (#290)

* feat: calculate hub2 light intensity

(cherry picked from commit be2a418fcbfa769608a9a8441ede48c467a3418d)

* checkout

* feat: refactor light intensity calculation using a constant map

* fix: light intensity calculation and update tests

* docs: add docstring for light intensity mapping in hub2.py
Huyuwei 6 days ago
parent
commit
98c1311512
4 changed files with 64 additions and 0 deletions
  1. 16 0
      switchbot/adv_parsers/hub2.py
  2. 29 0
      switchbot/const/hub2.py
  3. 1 0
      tests/test_adv_parser.py
  4. 18 0
      tests/test_hub2.py

+ 16 - 0
switchbot/adv_parsers/hub2.py

@@ -4,6 +4,8 @@ from __future__ import annotations
 
 from typing import Any
 
+from ..const.hub2 import LIGHT_INTENSITY_MAP
+
 
 def process_wohub2(data: bytes | None, mfr_data: bytes | None) -> dict[str, Any]:
     """Process woHub2 sensor manufacturer data."""
@@ -35,6 +37,20 @@ def process_wohub2(data: bytes | None, mfr_data: bytes | None) -> dict[str, Any]
         "fahrenheit": bool(temp_data[2] & 0b10000000),
         "humidity": humidity,
         "lightLevel": light_level,
+        "illuminance": calculate_light_intensity(light_level),
     }
 
     return _wohub2_data
+
+
+def calculate_light_intensity(light_level: int) -> int:
+    """
+    Convert Hub 2 light level (1-21) to actual light intensity value
+    Args:
+        light_level: Integer from 1-21
+    Returns:
+        Corresponding light intensity value or 0 if invalid input
+    """
+    if not light_level:
+        return 0
+    return LIGHT_INTENSITY_MAP.get(max(0, min(light_level, 22)), 0)

+ 29 - 0
switchbot/const/hub2.py

@@ -0,0 +1,29 @@
+"""
+Mapping of light levels to lux measurement values for SwitchBot Hub 2.
+
+Source: After-sales consultation, line chart data provided by switchbot developers
+"""
+
+LIGHT_INTENSITY_MAP = {
+    1: 0,
+    2: 10,
+    3: 20,
+    4: 30,
+    5: 40,
+    6: 50,
+    7: 60,
+    8: 70,
+    9: 80,
+    10: 90,
+    11: 105,
+    12: 205,
+    13: 317,
+    14: 416,
+    15: 510,
+    16: 610,
+    17: 707,
+    18: 801,
+    19: 897,
+    20: 1023,
+    21: 1091,
+}

+ 1 - 0
tests/test_adv_parser.py

@@ -947,6 +947,7 @@ def test_wohub2_passive_and_active():
                 "fahrenheit": False,
                 "humidity": 50,
                 "lightLevel": 2,
+                "illuminance": 10,
                 "temp": {"c": 26.7, "f": 80.06},
                 "temperature": 26.7,
             },

+ 18 - 0
tests/test_hub2.py

@@ -0,0 +1,18 @@
+from switchbot.adv_parsers.hub2 import calculate_light_intensity
+
+
+def test_calculate_light_intensity():
+    """Test calculating light intensity from Hub 2 light level."""
+    # Test valid inputs
+    assert calculate_light_intensity(1) == 0
+    assert calculate_light_intensity(2) == 10
+    assert calculate_light_intensity(10) == 90
+    assert calculate_light_intensity(15) == 510
+    assert calculate_light_intensity(21) == 1091
+
+    # Test invalid inputs
+    assert calculate_light_intensity(0) == 0
+    assert calculate_light_intensity(22) == 0
+    assert calculate_light_intensity(-1) == 0
+    assert calculate_light_intensity(3.5) == 0
+    assert calculate_light_intensity(None) == 0