Skip to content

Commit 520156a

Browse files
authored
Handle unsupported version in WLED (home-assistant#157778)
Co-authored-by: mik-laj <[email protected]>
1 parent e3b5342 commit 520156a

File tree

5 files changed

+93
-4
lines changed

5 files changed

+93
-4
lines changed

homeassistant/components/wled/config_flow.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from typing import Any
66

77
import voluptuous as vol
8-
from wled import WLED, Device, WLEDConnectionError
8+
from wled import WLED, Device, WLEDConnectionError, WLEDUnsupportedVersionError
99

1010
from homeassistant.components import onboarding
1111
from homeassistant.config_entries import (
@@ -48,6 +48,8 @@ async def async_step_user(
4848
if user_input is not None:
4949
try:
5050
device = await self._async_get_device(user_input[CONF_HOST])
51+
except WLEDUnsupportedVersionError:
52+
errors["base"] = "unsupported_version"
5153
except WLEDConnectionError:
5254
errors["base"] = "cannot_connect"
5355
else:
@@ -110,6 +112,8 @@ async def async_step_zeroconf(
110112
self.discovered_host = discovery_info.host
111113
try:
112114
self.discovered_device = await self._async_get_device(discovery_info.host)
115+
except WLEDUnsupportedVersionError:
116+
return self.async_abort(reason="unsupported_version")
113117
except WLEDConnectionError:
114118
return self.async_abort(reason="cannot_connect")
115119

homeassistant/components/wled/coordinator.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
WLEDConnectionClosedError,
1010
WLEDError,
1111
WLEDReleases,
12+
WLEDUnsupportedVersionError,
1213
)
1314

1415
from homeassistant.config_entries import ConfigEntry
@@ -115,6 +116,14 @@ async def _async_update_data(self) -> WLEDDevice:
115116
"""Fetch data from WLED."""
116117
try:
117118
device = await self.wled.update()
119+
except WLEDUnsupportedVersionError as error:
120+
# Error message from WLED library contains version info
121+
# better to show that to user, but it is not translatable.
122+
raise ConfigEntryError(
123+
translation_domain=DOMAIN,
124+
translation_key="unsupported_version",
125+
translation_placeholders={"error": str(error)},
126+
) from error
118127
except WLEDError as error:
119128
raise UpdateFailed(
120129
translation_domain=DOMAIN,

homeassistant/components/wled/strings.json

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
{
2+
"common": {
3+
"unsupported_version": "The WLED device's firmware version is not supported."
4+
},
25
"config": {
36
"abort": {
47
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
58
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
69
"reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]",
7-
"unique_id_mismatch": "MAC address does not match the configured device. Expected to connect to device with MAC: `{expected_mac}`, but connected to device with MAC: `{actual_mac}`. \n\nPlease ensure you reconfigure against the same device."
10+
"unique_id_mismatch": "MAC address does not match the configured device. Expected to connect to device with MAC: `{expected_mac}`, but connected to device with MAC: `{actual_mac}`. \n\nPlease ensure you reconfigure against the same device.",
11+
"unsupported_version": "[%key:component::wled::common::unsupported_version%]"
812
},
913
"error": {
10-
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]"
14+
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
15+
"unsupported_version": "[%key:component::wled::common::unsupported_version%]"
1116
},
1217
"flow_title": "{name}",
1318
"step": {
@@ -138,6 +143,9 @@
138143
},
139144
"mac_address_mismatch": {
140145
"message": "MAC address does not match the configured device. Expected to connect to device with MAC: {expected_mac}, but connected to device with MAC: {actual_mac}."
146+
},
147+
"unsupported_version": {
148+
"message": "The WLED device's firmware version is not supported: {error}"
141149
}
142150
},
143151
"options": {

tests/components/wled/test_config_flow.py

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from unittest.mock import AsyncMock, MagicMock
55

66
import pytest
7-
from wled import WLEDConnectionError
7+
from wled import WLEDConnectionError, WLEDUnsupportedVersionError
88

99
from homeassistant.components.wled.const import CONF_KEEP_MAIN_LIGHT, DOMAIN
1010
from homeassistant.config_entries import SOURCE_USER, SOURCE_ZEROCONF
@@ -215,6 +215,23 @@ async def test_connection_error(hass: HomeAssistant, mock_wled: MagicMock) -> No
215215
assert result.get("errors") == {"base": "cannot_connect"}
216216

217217

218+
async def test_unsupported_version_error(
219+
hass: HomeAssistant, mock_wled: MagicMock
220+
) -> None:
221+
"""Test we show user form on WLED unsupported version error."""
222+
mock_wled.update.side_effect = WLEDUnsupportedVersionError
223+
224+
result = await hass.config_entries.flow.async_init(
225+
DOMAIN,
226+
context={"source": SOURCE_USER},
227+
data={CONF_HOST: "example.com"},
228+
)
229+
230+
assert result.get("type") is FlowResultType.FORM
231+
assert result.get("step_id") == "user"
232+
assert result.get("errors") == {"base": "unsupported_version"}
233+
234+
218235
async def test_zeroconf_connection_error(
219236
hass: HomeAssistant, mock_wled: MagicMock
220237
) -> None:
@@ -239,6 +256,30 @@ async def test_zeroconf_connection_error(
239256
assert result.get("reason") == "cannot_connect"
240257

241258

259+
async def test_zeroconf_unsupported_version_error(
260+
hass: HomeAssistant, mock_wled: MagicMock
261+
) -> None:
262+
"""Test we abort zeroconf flow on WLED unsupported version error."""
263+
mock_wled.update.side_effect = WLEDUnsupportedVersionError
264+
265+
result = await hass.config_entries.flow.async_init(
266+
DOMAIN,
267+
context={"source": SOURCE_ZEROCONF},
268+
data=ZeroconfServiceInfo(
269+
ip_address=ip_address("192.168.1.123"),
270+
ip_addresses=[ip_address("192.168.1.123")],
271+
hostname="example.local.",
272+
name="mock_name",
273+
port=None,
274+
properties={CONF_MAC: "aabbccddeeff"},
275+
type="mock_type",
276+
),
277+
)
278+
279+
assert result.get("type") is FlowResultType.ABORT
280+
assert result.get("reason") == "unsupported_version"
281+
282+
242283
@pytest.mark.usefixtures("mock_wled")
243284
async def test_user_device_exists_abort(
244285
hass: HomeAssistant,

tests/components/wled/test_coordinator.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
WLEDConnectionClosedError,
1212
WLEDConnectionError,
1313
WLEDError,
14+
WLEDUnsupportedVersionError,
1415
)
1516

1617
from homeassistant.components.wled.const import SCAN_INTERVAL
@@ -218,3 +219,29 @@ async def test_fail_when_other_device(
218219
assert (
219220
"MAC address does not match the configured device." in mock_config_entry.reason
220221
)
222+
223+
224+
async def test_fail_when_unsupported_version(
225+
hass: HomeAssistant,
226+
mock_config_entry: MockConfigEntry,
227+
mock_wled: MagicMock,
228+
) -> None:
229+
"""Ensure entry fails to setup when unsupported version."""
230+
mock_wled.update.side_effect = WLEDUnsupportedVersionError(
231+
"Unsupported firmware version 0.14.0-b1. Minimum required version is 0.14.0. "
232+
"Please update your WLED device."
233+
)
234+
235+
mock_config_entry.add_to_hass(hass)
236+
237+
await hass.config_entries.async_setup(mock_config_entry.entry_id)
238+
239+
await hass.async_block_till_done()
240+
241+
assert mock_config_entry.state == ConfigEntryState.SETUP_ERROR
242+
assert mock_config_entry.reason
243+
assert (
244+
"The WLED device's firmware version is not supported:"
245+
in mock_config_entry.reason
246+
)
247+
assert "0.14.0-b1" in mock_config_entry.reason

0 commit comments

Comments
 (0)