resolve()/for_device_by_model() return DeviceRegistry | None; four new
test files used reg.capabilities/reg.pattern_capabilities without
narrowing away None first. Add the same 'assert reg is not None' idiom
test_dehumidifier_tp1x_dhm01001_capabilities.py already uses.
Verified against a clean venv running the exact CI commands (ruff format
--check, ruff check, ty check, pytest) rather than trusting a stale local
venv that had picked up a mismatched python3.11/3.13 site-packages split.
- Fix a real bug: airconditioner.SOUND_MODE had no exists_fn, so on
boards (issue #319's FAC) that never report a live 'mode' value,
entity.py's default field-presence gate silently kept the select from
ever registering in HA -- while adapter.flatten() (what the golden/tests
read) has no such gate, so the tests passed while documenting behavior
the opposite of what shipped. Gate on supportedModes' presence instead.
- Add airconditioner.MDS_ABSENCE_CLEAN for the CAC-class board's
/mds/absenceclean/vs/0 -- byte-identical shape to issue #319's
/csi/absenceclean/vs/0, confirmed rather than guessed, closing one more
of that board's documented coverage-gap hrefs.
- Add missing translation state labels (all 6 languages) for
edge_lighting_mode/edge_lighting_color/indicator_light_mode's raw device
codes, so they render as real words instead of a raw '3000K' -> '3000 K'
fallback.
- Fix an orphaned comment above SOUND_MODE that actually described the
unrelated DISPLAY reuse, and correct two inaccurate rationale comments:
the sound/voice ignore reason claimed a distinction from SOUND_MODE that
this same dump contradicts, and the /csi/* ignore block's 'same
reasoning as air_purifier.COVERAGE' precedent only actually covers 1 of
its 5 hrefs.
- Correct the false 'no board-token match' claim in the FAC test file and
golden-regression docstring -- 'FAC' is a real _BOARD_TOKEN_TO_KEY entry
(for_device_by_model alone already resolves this board); add a test
that actually exercises that path, which nothing previously did despite
the docstring's claim.
- Drop a tautological burner-slot test that only re-asserted what the
golden regression test already covers via the same code path.
This board routes purely via /oic/d's oic.d.airconditioner type (no
board-token match) and reports several resources the sibling
TP1X_DA-AC-CAC-01001 board (issue #191) left as a documented gap:
- /display/vs/0, /settings/sound/output/vs/0, /settings/sound/volume/vs/0
now reuse air_purifier.py's identical-shape capabilities instead of
duplicating them.
- /settings/sound/mode/vs/0 gets a new airconditioner.SOUND_MODE reading
the live supportedModes field, sharing laundry.py's existing
voice/tone/mute translation catalog since the value vocabulary matches.
- /csi/absenceclean/vs/0 and /csi/energysaving/vs/0 are new, genuinely
useful controls (absence auto-clean toggle, energy-saving mode select
plus its state/operatingStatus diagnostics).
- /dnd/autosleep/vs/0, /outdoorsharing/vs/0, /lifestyle/survey/vs/0,
/settings/sound/voice/vs/0 and /csi/information/vs/0 are ignored as
plumbing/unconfirmed data with no user-actionable state.
Also fixes a latent bug in air_purifier.SOUND_VOLUME: boards that report
minLevel/resolution but no maxLevel (this one) would have produced a
min=0/max=0 number entity instead of self-gating off.
Updates test_airconditioner_cac.py's documented coverage gap now that
sound_mode/sound_output/sound_volume are covered there too.