diff --git a/custom_components/localthings/registry/capabilities/airconditioner.py b/custom_components/localthings/registry/capabilities/airconditioner.py index 5958018..47c402c 100644 --- a/custom_components/localthings/registry/capabilities/airconditioner.py +++ b/custom_components/localthings/registry/capabilities/airconditioner.py @@ -210,14 +210,20 @@ def _humidity(rep): (51% observed, matching what the same unit's cloud integration reported at that moment), then zeroes the field and switches Air monitoring back off by itself. So 0 reads as "not measuring" and is reported as unknown rather than - as 0% humidity, which would poison long-term history -- which is also why - the boards that do have fivepercentHumidity read a permanent 0 here. + as 0% humidity, which would poison long-term history. + + That zero-as-"not measuring" carve-out is specific to the ARTIK051 + fallback field's hardware quirk -- every other board's fivepercentHumidity + has never been documented getting stuck at zero, and collapsing a + genuine 0% reading there to unknown is a regression, not a safeguard + (issue #160). So fivepercentHumidity passes 0 through unchanged; only the + humidity fallback applies the zero-collapse. """ - for field in ('x.com.samsung.da.fivepercentHumidity', - 'x.com.samsung.da.humidity'): - if field in rep: - value = _num(rep[field]) - return value if value else None + if 'x.com.samsung.da.fivepercentHumidity' in rep: + return _num(rep['x.com.samsung.da.fivepercentHumidity']) + if 'x.com.samsung.da.humidity' in rep: + value = _num(rep['x.com.samsung.da.humidity']) + return value if value else None return None diff --git a/tests/test_airconditioner_capabilities.py b/tests/test_airconditioner_capabilities.py index f513be7..8bbb1d1 100644 --- a/tests/test_airconditioner_capabilities.py +++ b/tests/test_airconditioner_capabilities.py @@ -415,3 +415,14 @@ def test_humidity_falls_back_to_the_plain_field_where_five_percent_is_absent(): assert desc.rep_fn({'x.com.samsung.da.humidity': '51'}) == 51.0 assert desc.rep_fn({'x.com.samsung.da.humidity': '0'}) is None assert desc.rep_fn({}) is None + + +def test_humidity_five_percent_field_passes_a_genuine_zero_through(): + """issue #160: fivepercentHumidity's zero-as-"not measuring" carve-out + (added in #146 to cover ARTIK051's plain humidity field) was + over-applied to fivepercentHumidity too, silently turning a real 0% + reading on every other AC board into unknown. Only the humidity + fallback field collapses 0 -- fivepercentHumidity's 0 is a real + reading.""" + desc = airconditioner.HUMIDITY.entities[0] + assert desc.rep_fn({'x.com.samsung.da.fivepercentHumidity': '0'}) == 0.0