Support dehumidifier devices in WinixDeviceWrapper#169
Merged
Conversation
iprak
requested changes
Apr 26, 2026
The two methods had near-identical bodies that only differed in which mode constant was written and which driver method was called. Folding them into a single `async_set_mode(mode)` removes the duplication and gives the dehumidifier rebase a place to add its own modes (continuous/auto/quiet/clothes/shoes/turbo) as another branch in the same function. - Replace `async_auto` / `async_manual` with `async_set_mode(mode)`. `MODE_AUTO` and `MODE_MANUAL` keep their existing flag/state/driver behaviour; any other mode value is logged and ignored without raising, so an unrecognised input never crashes the integration. - Update internal callers — `async_turn_on`, `async_set_speed`, and `async_set_preset_mode` — to call the new method. - Update existing tests to drive the new method, and add `test_async_set_mode_unsupported` covering the silent-ignore path.
`is_on`, `async_ensure_on`, and `async_turn_off` work the same way on every Winix product type. Reword their docstrings to match.
Some fields update() refreshes are read the same way on every Winix product (power, child lock, plasma, brightness). The `_auto`/`_manual`/`_sleep` trio is shaped to the air purifier — it matches the purifier's mode constants and infers sleep from the airflow value. Splitting the two leaves a clean seam for other product types to plug their own helper. - Move `_on`, `_child_lock_on`, `_plasma_on`, and `_brightness_level` into a new `_update_common_flags()`. - Move `_auto`, `_manual`, and `_sleep` into a new `_update_air_purifier_flags()`.
With the driver in place, the wrapper now recognises dehumidifier devices and routes control calls through it. The `product_group` prefix `"deh"` mirrors the `"air"` pattern already used for air purifiers. - `_select_driver` routes `"deh*"` to `DehumidifierDriver`; add `is_air_purifier` / `is_dehumidifier` properties for dispatch. - `update()` dispatches to a new `_update_dehumidifier_flags()` helper, with separate debug logs per device type. - `async_set_mode` and `async_set_speed` gain a dehumidifier branch. `async_set_mode` validates `mode` against `driver.state_keys[ATTR_MODE]` up front and ignores unsupported values for both device types. - `async_turn_on` enters Auto mode only for air purifiers. - New dehumidifier methods: `async_uv_sanitize_on/off`, `is_uv_sanitize_on`, `is_water_tank_available`, `async_set_humidity`, `async_set_timer`. - UV sanitize is gated on a new `Features.supports_uv_sanitize` flag, detected from the presence of `ATTR_UV_SANITIZE` in device state, so dehumidifiers without UV sanitize fall back to no-op control methods. - New `is_auto_dry` flag tracks the dehumidifier `AUTO_DRY_VALUE` power state (a third state alongside on/off). `async_turn_off` still optimistically writes `OFF_VALUE`; the next coordinator refresh reconciles when the device transitions to auto-dry instead. - Add `build_mock_dehumidifier_wrapper` and tests for the new paths.
db47256 to
b736aea
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related Issue, PR: #151, #154
This PR is the fourth split from PR #154. It adds dehumidifier support to deivce wrapper, along with a small refactor. If you'd prefer to split it further, I can have the refactoring commits 1~3 reviewed first and move the dehumidifier support (commit 4) to a follow-up PR.
Unlike driver, deivce wrapper is not split by device type (product group) into separate classes. As discussed in the previous PR (#168 (comment)), not only the basic functionality (power/mode/airflow) but also features like child lock, plasma, and brightness are shared across device types. So I kept everything in a single class that handles multiple device types.
On the air purifier side, the interplay between power/mode/airflow is carefully implemented — for example, changing the airflow (speed) automatically switches the mode to manual. The initial dehumidifier implementation does not yet replicate this kind of cross-state behavior. Once the HA entity work is finished, I will test these state interactions on a real device and refine the implementation accordingly.
10 unit tests were added (109 → 119). They all pass.
(0db) ~/ws/winix $ uv run --python 3.13 --with pytest-homeassistant-custom-component --with winix --with pycryptodome pytest tests/ -p asyncio --asyncio-mode=auto Test session starts (platform: linux, Python 3.13.7, pytest 9.0.0, pytest-sugar 1.0.0) rootdir: /home/kyet/ws/winix plugins: asyncio-1.3.0, pytest_freezer-0.4.9, github-actions-annotate-failures-0.3.0, aiohttp-1.1.0, syrupy-5.0.0, xdist-3.8.0, timeout-2.4.0, cov-7.0.0, sugar-1.0.0, respx-0.22.0, requests-mock-1.12.1, unordered-0.7.0, anyio-4.13.0, homeassistant-custom-component-0.13.316, picked-0.5.1, socket-0.7.0 asyncio: mode=Mode.AUTO, debug=False, asyncio_default_fixture_loop_scope=None, asyncio_default_test_loop_scope=function collected 119 items tests/test_config_flow.py ✓✓✓✓ 3% ▍ tests/test_device_wrapper.py ✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓ 33% ███▍ tests/test_driver.py ✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓ 69% ██████▉ ✓ 70% ███████ tests/test_fan.py ✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓ 96% █████████▋ tests/test_sensor.py ✓✓✓✓✓ 100% ██████████ Results (0.76s): 119 passedruff check also passes.