Fix WiZ Light config flow timeout by properly closing UDP connections#168456
Conversation
The WiZ config flow was creating wizlight instances without properly closing them, leaving dangling UDP datagram endpoints in Home Assistant's event loop. This caused subsequent connection attempts to fail with a timeout after exactly 13 seconds (pywizlight's retry limit). The issue manifested as intermittent failures when manually adding WiZ bulbs through the UI, even though the bulbs responded immediately to direct UDP requests. Add await bulb.async_close() in finally blocks to ensure UDP connections are cleaned up in three config flow methods: - _async_connect_discovered_or_abort() - for discovery flows - async_step_pick_device() - for device picking - async_step_user() - for manual IP entry Fixes timeout errors and prevents UDP endpoint accumulation. Tested with WiZ Tunable White (ESP20_SHTWC_01) FW 1.37.0.
There was a problem hiding this comment.
It seems you haven't yet signed a CLA. Please do so here.
Once you do that we will be able to review and accept this pull request.
Thanks!
|
Please take a look at the requested changes, and use the Ready for review button when you are done, thanks 👍 |
|
Hey there @sbidy, @arturpragacz, mind taking a look at this pull request as it has been labeled with an integration ( Code owner commandsCode owners of
|
There was a problem hiding this comment.
Pull request overview
This PR fixes intermittent WiZ config flow connection timeouts by ensuring pywizlight UDP transports are always cleaned up after probe calls during config entry creation.
Changes:
- Close
wizlightUDP connections viaawait bulb.async_close()infinallyblocks for discovery, device-pick, and manual-user steps. - Add config flow tests asserting the bulb connection is closed on both success and failure paths for user and discovery flows.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| homeassistant/components/wiz/config_flow.py | Ensures wizlight instances are always closed after connection/bulb-type checks in config flow steps. |
| tests/components/wiz/test_config_flow.py | Adds/updates tests to verify async_close() is awaited in relevant config flow paths. |
| async def test_user_form_closes_connection(hass: HomeAssistant) -> None: | ||
| """Test the user flow closes the bulb connection after setup.""" | ||
| bulb = _mocked_wizlight(None, None, FAKE_DIMMABLE_BULB) | ||
|
|
||
| result = await hass.config_entries.flow.async_init( | ||
| DOMAIN, context={"source": config_entries.SOURCE_USER} | ||
| ) | ||
|
|
||
| with ( | ||
| _patch_wizlight(device=bulb), | ||
| patch( | ||
| "homeassistant.components.wiz.async_setup_entry", | ||
| return_value=True, | ||
| ), | ||
| patch("homeassistant.components.wiz.async_setup", return_value=True), | ||
| ): | ||
| result2 = await hass.config_entries.flow.async_configure( | ||
| result["flow_id"], | ||
| TEST_CONNECTION, | ||
| ) | ||
| await hass.async_block_till_done() | ||
|
|
||
| assert result2["type"] is FlowResultType.CREATE_ENTRY | ||
| bulb.async_close.assert_awaited_once() |
There was a problem hiding this comment.
I would assume we already have both happy and not-happy flows out there that we can add this one line to to check if async_close has been called
There was a problem hiding this comment.
That makes sense actually. I've taken these new tests out and put the assertions into the existing.
EDIT: Thanks for reviewing this, I really need this fix adding in for my lights 😅
Instead of creating a new set of tests to just test the connection close on wiz bulbs, add the assertion to the existing happy / non-happy path tests.
…2026.5.0 → 2026.5.1) (#411) This PR contains the following updates: | Package | Update | Change | |---|---|---| | [ghcr.io/home-operations/home-assistant](https://ghcr.io/home-operations/home-assistant) ([source](https://github.com/home-assistant/core)) | patch | `2026.5.0` → `2026.5.1` | --- ### Release Notes <details> <summary>home-assistant/core (ghcr.io/home-operations/home-assistant)</summary> ### [`v2026.5.1`](https://github.com/home-assistant/core/releases/tag/2026.5.1) [Compare Source](home-assistant/core@2026.5.0...2026.5.1) - Added wfsens as a occupancy source in wiz ([@​th3spis] - [#​166799]) ([wiz docs]) - Fix WiZ Light config flow timeout by properly closing UDP connections ([@​robwasripped] - [#​168456]) ([wiz docs]) - Fix IntelliFire setup recovery ([@​jeeftor] - [#​169739]) ([intellifire docs]) - Fix hassio auth IndexError on Supervisor Unix socket requests ([@​agners] - [#​169911]) ([hassio docs]) - Update gardena ble to 2.8.1 ([@​elupus] - [#​169914]) ([gardena\_bluetooth docs][gardena_bluetooth docs]) ([husqvarna\_automower\_ble docs][husqvarna_automower_ble docs]) (dependency) - Bump serialx to 1.7.1 ([@​puddly] - [#​169928]) ([serial docs]) ([acer\_projector docs][acer_projector docs]) ([usb docs]) (dependency) - Bump holidays to 0.96 ([@​gjohansson-ST] - [#​169939]) ([workday docs]) ([holiday docs]) (dependency) - Add support for options to todo triggers ([@​emontnemery] - [#​169947]) ([todo docs]) - Bump pyTibber to 0.37.5 ([@​Danielhiversen] - [#​169981]) ([tibber docs]) (dependency) - Bump python-duco-client to 0.4.0 ([@​ronaldvdmeer] - [#​169776]) ([duco docs]) (dependency) - Bump python-duco-client to 0.4.1 ([@​ronaldvdmeer] - [#​169991]) ([duco docs]) (dependency) - Proper handling of malformed data during FRITZ!Box Tools setup ([@​mib1185] - [#​170030]) ([fritz docs]) - Fix websocket certificate verification Bump axis to v70 ([@​Kane610] - [#​170038]) ([axis docs]) (dependency) - Fix `is_closed` state for DynamicGarageDoor in Overkiz ([@​iMicknl] - [#​170052]) ([overkiz docs]) - Fix tilt controls for TiltOnlyVenetianBlind in Overkiz ([@​iMicknl] - [#​170055]) ([overkiz docs]) - Fix cover controls for UpDownBioclimaticPergola in Overkiz ([@​iMicknl] - [#​170058]) ([overkiz docs]) - Bump pyOverkiz to 1.20.3 ([@​iMicknl] - [#​170060]) ([overkiz docs]) (dependency) - Bump deebot-client to 18.3.0 ([@​edenhaus] - [#​170066]) ([ecovacs docs]) (dependency) - Set `is_closed` state to `None` when a cover state returns "unknown" in Overkiz ([@​iMicknl] - [#​170081]) ([overkiz docs]) - Fix sensors getting wrong unit from MeasuredValueType attribute in Overkiz ([@​iMicknl] - [#​170088]) ([overkiz docs]) - Fix Z-Wave discovery crash with unknown node firmware version ([@​TheJulianJES] - [#​170090]) ([zwave\_js docs][zwave_js docs]) - Bump ZHA to 1.3.1 ([@​TheJulianJES] - [#​170095]) ([zha docs]) (dependency) - Bump python-bsblan to 5.2.1 ([@​liudger] - [#​170100]) ([bsblan docs]) (dependency) - Bump blebox\_uniapi to v2.5.3 ([@​bkobus-bbx] - [#​170115]) ([blebox docs]) (dependency) - Fix is\_closed state for DynamicGate covers in Overkiz ([@​iMicknl] - [#​170130]) ([overkiz docs]) - Fix tilt support for UpDownVenetianBlind (rts:VenetianBlindRTSComponent) in Overkiz ([@​iMicknl] - [#​170047]) ([overkiz docs]) [#​166799]: home-assistant/core#166799 [#​168456]: home-assistant/core#168456 [#​169484]: home-assistant/core#169484 [#​169739]: home-assistant/core#169739 [#​169776]: home-assistant/core#169776 [#​169911]: home-assistant/core#169911 [#​169914]: home-assistant/core#169914 [#​169928]: home-assistant/core#169928 [#​169939]: home-assistant/core#169939 [#​169947]: home-assistant/core#169947 [#​169981]: home-assistant/core#169981 [#​169991]: home-assistant/core#169991 [#​170030]: home-assistant/core#170030 [#​170038]: home-assistant/core#170038 [#​170047]: home-assistant/core#170047 [#​170052]: home-assistant/core#170052 [#​170055]: home-assistant/core#170055 [#​170058]: home-assistant/core#170058 [#​170060]: home-assistant/core#170060 [#​170066]: home-assistant/core#170066 [#​170081]: home-assistant/core#170081 [#​170088]: home-assistant/core#170088 [#​170090]: home-assistant/core#170090 [#​170095]: home-assistant/core#170095 [#​170100]: home-assistant/core#170100 [#​170115]: home-assistant/core#170115 [#​170130]: home-assistant/core#170130 [@​Danielhiversen]: https://github.com/Danielhiversen [@​Kane610]: https://github.com/Kane610 [@​TheJulianJES]: https://github.com/TheJulianJES [@​agners]: https://github.com/agners [@​bkobus-bbx]: https://github.com/bkobus-bbx [@​edenhaus]: https://github.com/edenhaus [@​elupus]: https://github.com/elupus [@​emontnemery]: https://github.com/emontnemery [@​frenck]: https://github.com/frenck [@​gjohansson-ST]: https://github.com/gjohansson-ST [@​iMicknl]: https://github.com/iMicknl [@​jeeftor]: https://github.com/jeeftor [@​liudger]: https://github.com/liudger [@​mib1185]: https://github.com/mib1185 [@​puddly]: https://github.com/puddly [@​robwasripped]: https://github.com/robwasripped [@​ronaldvdmeer]: https://github.com/ronaldvdmeer [@​th3spis]: https://github.com/th3spis [acer_projector docs]: https://www.home-assistant.io/integrations/acer_projector/ [axis docs]: https://www.home-assistant.io/integrations/axis/ [blebox docs]: https://www.home-assistant.io/integrations/blebox/ [bsblan docs]: https://www.home-assistant.io/integrations/bsblan/ [duco docs]: https://www.home-assistant.io/integrations/duco/ [ecovacs docs]: https://www.home-assistant.io/integrations/ecovacs/ [fritz docs]: https://www.home-assistant.io/integrations/fritz/ [gardena_bluetooth docs]: https://www.home-assistant.io/integrations/gardena_bluetooth/ [hassio docs]: https://www.home-assistant.io/integrations/hassio/ [holiday docs]: https://www.home-assistant.io/integrations/holiday/ [husqvarna_automower_ble docs]: https://www.home-assistant.io/integrations/husqvarna_automower_ble/ [intellifire docs]: https://www.home-assistant.io/integrations/intellifire/ [overkiz docs]: https://www.home-assistant.io/integrations/overkiz/ [serial docs]: https://www.home-assistant.io/integrations/serial/ [tibber docs]: https://www.home-assistant.io/integrations/tibber/ [todo docs]: https://www.home-assistant.io/integrations/todo/ [usb docs]: https://www.home-assistant.io/integrations/usb/ [wiz docs]: https://www.home-assistant.io/integrations/wiz/ [workday docs]: https://www.home-assistant.io/integrations/workday/ [zha docs]: https://www.home-assistant.io/integrations/zha/ [zwave_js docs]: https://www.home-assistant.io/integrations/zwave_js/ </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDEuMSIsInVwZGF0ZWRJblZlciI6IjQzLjEwMS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZS9jb250YWluZXIiLCJ0eXBlL3BhdGNoIl19--> Reviewed-on: https://git.erwanleboucher.dev/eleboucher/homelab/pulls/411
The WiZ config flow was creating wizlight instances without properly closing them, leaving dangling UDP datagram endpoints in Home Assistant's event loop. This caused subsequent connection attempts to fail with a timeout after exactly 13 seconds (pywizlight's retry limit).
The issue manifested as intermittent failures when manually adding WiZ bulbs through the UI, even though the bulbs responded immediately to direct UDP requests.
Add await bulb.async_close() in finally blocks to ensure UDP connections are cleaned up in three config flow methods:
Fixes timeout errors and prevents UDP endpoint accumulation.
Tested with WiZ Tunable White (ESP20_SHTWC_01) FW 1.37.0.
I believe this fixes the issues spoken about in these locations:
Breaking change
Proposed change
Type of change
Additional information
Checklist
ruff format homeassistant tests)If user exposed functionality or configuration variables are added/changed:
If the code communicates with devices, web services, or third-party tools:
Updated and included derived files by running:
python3 -m script.hassfest.requirements_all.txt.Updated by running
python3 -m script.gen_requirements_all.To help with the load of incoming pull requests: