Apply issue #56 field reports: filter direction, drop Blooming_*
Incorporates confirmed answers from the issue thread: - FilterProgress counts down as the filter wears (100 = fresh), so the sensor is renamed filter_progress -> filter_life to match the direction instead of implying "usage" like the AC/range_hood filterUsage sensors. - Blooming_* has no corresponding SmartThings app setting, so it's dropped entirely rather than kept as an unexplained diagnostic. - OptionCode_60282 and the missing humidity sensor are confirmed correct as already modeled (not user-facing / genuinely absent on this model). Five running-state diagnostics dumps (Auto/Sleep/Low/Medium/High) rule out the original guess that Comode_* is the fan-speed selector -- it reads 'Off' on every one of them. /airflow's speed field doesn't map monotonically to the five settings either (0 for both Auto and High, 3 for Low/Medium/ Sleep), and all five dumps were captured within about three minutes of each other -- one poll cycle at this integration's 30s summary interval -- so fan-speed modeling stays unbuilt pending a cleaner capture.
This commit is contained in:
+1
-2
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"state_keys": [
|
||||
"alarm_code",
|
||||
"blooming_level",
|
||||
"clean_level",
|
||||
"device_active",
|
||||
"diagnosis_status",
|
||||
@@ -13,7 +12,7 @@
|
||||
"energy_this_month_kwh",
|
||||
"fan_direction",
|
||||
"fan_speed_level",
|
||||
"filter_progress",
|
||||
"filter_life",
|
||||
"fine_dust",
|
||||
"odor",
|
||||
"operating_mode",
|
||||
|
||||
@@ -40,9 +40,9 @@ def test_expected_entities_present():
|
||||
state = _state()
|
||||
for key in (
|
||||
'power_switch', 'alarm_code', 'dust', 'fine_dust', 'super_fine_dust',
|
||||
'odor', 'clean_level', 'filter_progress', 'device_active',
|
||||
'odor', 'clean_level', 'filter_life', 'device_active',
|
||||
'diagnosis_status', 'fan_speed_level', 'fan_direction',
|
||||
'display_light', 'operating_mode', 'blooming_level',
|
||||
'display_light', 'operating_mode',
|
||||
):
|
||||
assert key in state, key
|
||||
|
||||
@@ -58,8 +58,10 @@ def test_air_quality_sensor_values():
|
||||
assert state['clean_level'] == 0
|
||||
|
||||
|
||||
def test_filter_progress_reads_named_consumable_item():
|
||||
assert _state()['filter_progress'] == 100
|
||||
def test_filter_life_reads_named_consumable_item():
|
||||
"""FilterProgress is confirmed (issue #56) to count down as the filter
|
||||
wears -- 100 means fresh, not "100% used"."""
|
||||
assert _state()['filter_life'] == 100
|
||||
|
||||
|
||||
def test_diagnosis_reuses_dishwasher_capability():
|
||||
@@ -76,29 +78,36 @@ def test_light_switch_write_contract():
|
||||
the other flags and the list order untouched."""
|
||||
desc = next(e for e in air_purifier.MODE.entities if e.key == 'display_light')
|
||||
rep = {'x.com.samsung.da.options': [
|
||||
'Comode_Off', 'Blooming_0', 'Light_On', 'OptionCode_60282',
|
||||
'Comode_Off', 'Light_On', 'OptionCode_60282',
|
||||
]}
|
||||
assert desc.rep_fn(rep) is True
|
||||
assert desc.write_fn('Off', rep) == (
|
||||
['mode', 'vs', '0'],
|
||||
{'x.com.samsung.da.options': [
|
||||
'Comode_Off', 'Blooming_0', 'Light_Off', 'OptionCode_60282',
|
||||
'Comode_Off', 'Light_Off', 'OptionCode_60282',
|
||||
]},
|
||||
)
|
||||
|
||||
|
||||
def test_mode_tokens_are_read_only_diagnostics():
|
||||
"""Comode_/Blooming_ tokens surface as raw diagnostic sensors rather than
|
||||
a select/control -- their valid value ranges aren't confirmed yet (see
|
||||
the air_purifier.py module docstring and the issue #56 follow-up)."""
|
||||
def test_operating_mode_is_a_read_only_diagnostic():
|
||||
"""Comode_* surfaces as a raw diagnostic sensor rather than a select/
|
||||
control -- issue #56's five running-state dumps confirmed it reads 'Off'
|
||||
regardless of the device's actual fan setting, ruling out the original
|
||||
guess that it was the fan-speed selector; its real purpose is still
|
||||
unconfirmed (see the air_purifier.py module docstring)."""
|
||||
operating_mode = next(e for e in air_purifier.MODE.entities if e.key == 'operating_mode')
|
||||
blooming = next(e for e in air_purifier.MODE.entities if e.key == 'blooming_level')
|
||||
rep = {'x.com.samsung.da.options': ['Comode_Off', 'Blooming_6']}
|
||||
rep = {'x.com.samsung.da.options': ['Comode_Off']}
|
||||
assert operating_mode.rep_fn(rep) == 'Off'
|
||||
assert blooming.rep_fn(rep) == '6'
|
||||
assert not hasattr(operating_mode, 'write_fn')
|
||||
|
||||
|
||||
def test_blooming_not_modeled():
|
||||
"""Confirmed (issue #56) to have no corresponding SmartThings app
|
||||
setting -- dropped entirely rather than kept as an unexplained
|
||||
diagnostic."""
|
||||
assert not any(e.key == 'blooming_level' for e in air_purifier.MODE.entities)
|
||||
|
||||
|
||||
def test_airflow_vs_fallback_only_binds_without_generic():
|
||||
"""/airflow/vs/0 is a match_fn fallback -- it must not bind when the
|
||||
OCF-standard /airflow/0 is also present (both are on every dump seen)."""
|
||||
|
||||
Reference in New Issue
Block a user