Fix flux_led discovery with older models (#61413)
This commit is contained in:
parent
8383da6a5e
commit
8d483e2206
6 changed files with 71 additions and 24 deletions
|
@ -238,7 +238,14 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
||||||
) -> FluxLEDDiscovery:
|
) -> FluxLEDDiscovery:
|
||||||
"""Try to connect."""
|
"""Try to connect."""
|
||||||
self._async_abort_entries_match({CONF_HOST: host})
|
self._async_abort_entries_match({CONF_HOST: host})
|
||||||
if device := await async_discover_device(self.hass, host):
|
if (device := await async_discover_device(self.hass, host)) and device[
|
||||||
|
ATTR_MODEL_DESCRIPTION
|
||||||
|
]:
|
||||||
|
# Older models do not return enough information
|
||||||
|
# to build the model description via UDP so we have
|
||||||
|
# to fallback to making a tcp connection to avoid
|
||||||
|
# identifying the device as the chip model number
|
||||||
|
# AKA `HF-LPB100-ZJ200`
|
||||||
return device
|
return device
|
||||||
bulb = async_wifi_bulb_for_host(host)
|
bulb = async_wifi_bulb_for_host(host)
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
from contextlib import contextmanager
|
||||||
import datetime
|
import datetime
|
||||||
from typing import Callable
|
from typing import Callable
|
||||||
from unittest.mock import AsyncMock, MagicMock, patch
|
from unittest.mock import AsyncMock, MagicMock, patch
|
||||||
|
@ -162,11 +163,20 @@ def _patch_discovery(device=None, no_device=False):
|
||||||
async def _discovery(*args, **kwargs):
|
async def _discovery(*args, **kwargs):
|
||||||
if no_device:
|
if no_device:
|
||||||
raise OSError
|
raise OSError
|
||||||
return [FLUX_DISCOVERY]
|
return [] if no_device else [device or FLUX_DISCOVERY]
|
||||||
|
|
||||||
return patch(
|
@contextmanager
|
||||||
"homeassistant.components.flux_led.AIOBulbScanner.async_scan", new=_discovery
|
def _patcher():
|
||||||
)
|
with patch(
|
||||||
|
"homeassistant.components.flux_led.AIOBulbScanner.async_scan",
|
||||||
|
new=_discovery,
|
||||||
|
), patch(
|
||||||
|
"homeassistant.components.flux_led.AIOBulbScanner.getBulbInfo",
|
||||||
|
return_value=[] if no_device else [device or FLUX_DISCOVERY],
|
||||||
|
):
|
||||||
|
yield
|
||||||
|
|
||||||
|
return _patcher()
|
||||||
|
|
||||||
|
|
||||||
def _patch_wifibulb(device=None, no_device=False):
|
def _patch_wifibulb(device=None, no_device=False):
|
||||||
|
|
|
@ -31,6 +31,7 @@ from . import (
|
||||||
DEFAULT_ENTRY_TITLE,
|
DEFAULT_ENTRY_TITLE,
|
||||||
DHCP_DISCOVERY,
|
DHCP_DISCOVERY,
|
||||||
FLUX_DISCOVERY,
|
FLUX_DISCOVERY,
|
||||||
|
FLUX_DISCOVERY_PARTIAL,
|
||||||
IP_ADDRESS,
|
IP_ADDRESS,
|
||||||
MAC_ADDRESS,
|
MAC_ADDRESS,
|
||||||
MODULE,
|
MODULE,
|
||||||
|
@ -435,6 +436,35 @@ async def test_discovered_by_dhcp_no_udp_response(hass):
|
||||||
assert mock_async_setup_entry.called
|
assert mock_async_setup_entry.called
|
||||||
|
|
||||||
|
|
||||||
|
async def test_discovered_by_dhcp_partial_udp_response_fallback_tcp(hass):
|
||||||
|
"""Test we can setup when discovered from dhcp but part of the udp response is missing."""
|
||||||
|
|
||||||
|
with _patch_discovery(no_device=True), _patch_wifibulb():
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN, context={"source": config_entries.SOURCE_DHCP}, data=DHCP_DISCOVERY
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert result["type"] == RESULT_TYPE_FORM
|
||||||
|
assert result["errors"] is None
|
||||||
|
|
||||||
|
with _patch_discovery(device=FLUX_DISCOVERY_PARTIAL), _patch_wifibulb(), patch(
|
||||||
|
f"{MODULE}.async_setup", return_value=True
|
||||||
|
) as mock_async_setup, patch(
|
||||||
|
f"{MODULE}.async_setup_entry", return_value=True
|
||||||
|
) as mock_async_setup_entry:
|
||||||
|
result2 = await hass.config_entries.flow.async_configure(result["flow_id"], {})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert result2["type"] == "create_entry"
|
||||||
|
assert result2["data"] == {
|
||||||
|
CONF_HOST: IP_ADDRESS,
|
||||||
|
CONF_NAME: DEFAULT_ENTRY_TITLE,
|
||||||
|
}
|
||||||
|
assert mock_async_setup.called
|
||||||
|
assert mock_async_setup_entry.called
|
||||||
|
|
||||||
|
|
||||||
async def test_discovered_by_dhcp_no_udp_response_or_tcp_response(hass):
|
async def test_discovered_by_dhcp_no_udp_response_or_tcp_response(hass):
|
||||||
"""Test we can setup when discovered from dhcp but no udp response or tcp response."""
|
"""Test we can setup when discovered from dhcp but no udp response or tcp response."""
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,7 @@ async def test_light_unique_id(hass: HomeAssistant) -> None:
|
||||||
)
|
)
|
||||||
config_entry.add_to_hass(hass)
|
config_entry.add_to_hass(hass)
|
||||||
bulb = _mocked_bulb()
|
bulb = _mocked_bulb()
|
||||||
with _patch_discovery(device=bulb), _patch_wifibulb(device=bulb):
|
with _patch_discovery(), _patch_wifibulb(device=bulb):
|
||||||
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ async def test_light_goes_unavailable_and_recovers(hass: HomeAssistant) -> None:
|
||||||
)
|
)
|
||||||
config_entry.add_to_hass(hass)
|
config_entry.add_to_hass(hass)
|
||||||
bulb = _mocked_bulb()
|
bulb = _mocked_bulb()
|
||||||
with _patch_discovery(device=bulb), _patch_wifibulb(device=bulb):
|
with _patch_discovery(), _patch_wifibulb(device=bulb):
|
||||||
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
@ -190,7 +190,7 @@ async def test_rgb_light(hass: HomeAssistant) -> None:
|
||||||
bulb.raw_state = bulb.raw_state._replace(model_num=0x33) # RGB only model
|
bulb.raw_state = bulb.raw_state._replace(model_num=0x33) # RGB only model
|
||||||
bulb.color_modes = {FLUX_COLOR_MODE_RGB}
|
bulb.color_modes = {FLUX_COLOR_MODE_RGB}
|
||||||
bulb.color_mode = FLUX_COLOR_MODE_RGB
|
bulb.color_mode = FLUX_COLOR_MODE_RGB
|
||||||
with _patch_discovery(device=bulb), _patch_wifibulb(device=bulb):
|
with _patch_discovery(no_device=True), _patch_wifibulb(device=bulb):
|
||||||
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
@ -294,7 +294,7 @@ async def test_rgb_light_auto_on(hass: HomeAssistant) -> None:
|
||||||
bulb.raw_state = bulb.raw_state._replace(model_num=0x33) # RGB only model
|
bulb.raw_state = bulb.raw_state._replace(model_num=0x33) # RGB only model
|
||||||
bulb.color_modes = {FLUX_COLOR_MODE_RGB}
|
bulb.color_modes = {FLUX_COLOR_MODE_RGB}
|
||||||
bulb.color_mode = FLUX_COLOR_MODE_RGB
|
bulb.color_mode = FLUX_COLOR_MODE_RGB
|
||||||
with _patch_discovery(device=bulb), _patch_wifibulb(device=bulb):
|
with _patch_discovery(), _patch_wifibulb(device=bulb):
|
||||||
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
@ -407,7 +407,7 @@ async def test_rgb_cct_light(hass: HomeAssistant) -> None:
|
||||||
bulb.raw_state = bulb.raw_state._replace(model_num=0x35) # RGB & CCT model
|
bulb.raw_state = bulb.raw_state._replace(model_num=0x35) # RGB & CCT model
|
||||||
bulb.color_modes = {FLUX_COLOR_MODE_RGB, FLUX_COLOR_MODE_CCT}
|
bulb.color_modes = {FLUX_COLOR_MODE_RGB, FLUX_COLOR_MODE_CCT}
|
||||||
bulb.color_mode = FLUX_COLOR_MODE_RGB
|
bulb.color_mode = FLUX_COLOR_MODE_RGB
|
||||||
with _patch_discovery(device=bulb), _patch_wifibulb(device=bulb):
|
with _patch_discovery(), _patch_wifibulb(device=bulb):
|
||||||
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
@ -526,7 +526,7 @@ async def test_rgbw_light(hass: HomeAssistant) -> None:
|
||||||
bulb = _mocked_bulb()
|
bulb = _mocked_bulb()
|
||||||
bulb.color_modes = {FLUX_COLOR_MODE_RGBW}
|
bulb.color_modes = {FLUX_COLOR_MODE_RGBW}
|
||||||
bulb.color_mode = FLUX_COLOR_MODE_RGBW
|
bulb.color_mode = FLUX_COLOR_MODE_RGBW
|
||||||
with _patch_discovery(device=bulb), _patch_wifibulb(device=bulb):
|
with _patch_discovery(), _patch_wifibulb(device=bulb):
|
||||||
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
@ -628,7 +628,7 @@ async def test_rgb_or_w_light(hass: HomeAssistant) -> None:
|
||||||
bulb = _mocked_bulb()
|
bulb = _mocked_bulb()
|
||||||
bulb.color_modes = FLUX_COLOR_MODES_RGB_W
|
bulb.color_modes = FLUX_COLOR_MODES_RGB_W
|
||||||
bulb.color_mode = FLUX_COLOR_MODE_RGB
|
bulb.color_mode = FLUX_COLOR_MODE_RGB
|
||||||
with _patch_discovery(device=bulb), _patch_wifibulb(device=bulb):
|
with _patch_discovery(), _patch_wifibulb(device=bulb):
|
||||||
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
@ -739,7 +739,7 @@ async def test_rgbcw_light(hass: HomeAssistant) -> None:
|
||||||
bulb.raw_state = bulb.raw_state._replace(warm_white=1, cool_white=2)
|
bulb.raw_state = bulb.raw_state._replace(warm_white=1, cool_white=2)
|
||||||
bulb.color_modes = {FLUX_COLOR_MODE_RGBWW, FLUX_COLOR_MODE_CCT}
|
bulb.color_modes = {FLUX_COLOR_MODE_RGBWW, FLUX_COLOR_MODE_CCT}
|
||||||
bulb.color_mode = FLUX_COLOR_MODE_RGBWW
|
bulb.color_mode = FLUX_COLOR_MODE_RGBWW
|
||||||
with _patch_discovery(device=bulb), _patch_wifibulb(device=bulb):
|
with _patch_discovery(), _patch_wifibulb(device=bulb):
|
||||||
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
@ -879,7 +879,7 @@ async def test_white_light(hass: HomeAssistant) -> None:
|
||||||
bulb.protocol = None
|
bulb.protocol = None
|
||||||
bulb.color_modes = {FLUX_COLOR_MODE_DIM}
|
bulb.color_modes = {FLUX_COLOR_MODE_DIM}
|
||||||
bulb.color_mode = FLUX_COLOR_MODE_DIM
|
bulb.color_mode = FLUX_COLOR_MODE_DIM
|
||||||
with _patch_discovery(device=bulb), _patch_wifibulb(device=bulb):
|
with _patch_discovery(), _patch_wifibulb(device=bulb):
|
||||||
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
@ -930,7 +930,7 @@ async def test_no_color_modes(hass: HomeAssistant) -> None:
|
||||||
bulb.protocol = None
|
bulb.protocol = None
|
||||||
bulb.color_modes = set()
|
bulb.color_modes = set()
|
||||||
bulb.color_mode = None
|
bulb.color_mode = None
|
||||||
with _patch_discovery(device=bulb), _patch_wifibulb(device=bulb):
|
with _patch_discovery(), _patch_wifibulb(device=bulb):
|
||||||
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
@ -974,7 +974,7 @@ async def test_rgb_light_custom_effects(hass: HomeAssistant) -> None:
|
||||||
bulb = _mocked_bulb()
|
bulb = _mocked_bulb()
|
||||||
bulb.color_modes = {FLUX_COLOR_MODE_RGB}
|
bulb.color_modes = {FLUX_COLOR_MODE_RGB}
|
||||||
bulb.color_mode = FLUX_COLOR_MODE_RGB
|
bulb.color_mode = FLUX_COLOR_MODE_RGB
|
||||||
with _patch_discovery(device=bulb), _patch_wifibulb(device=bulb):
|
with _patch_discovery(), _patch_wifibulb(device=bulb):
|
||||||
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
@ -1056,7 +1056,7 @@ async def test_rgb_light_custom_effects_invalid_colors(
|
||||||
bulb = _mocked_bulb()
|
bulb = _mocked_bulb()
|
||||||
bulb.color_modes = {FLUX_COLOR_MODE_RGB}
|
bulb.color_modes = {FLUX_COLOR_MODE_RGB}
|
||||||
bulb.color_mode = FLUX_COLOR_MODE_RGB
|
bulb.color_mode = FLUX_COLOR_MODE_RGB
|
||||||
with _patch_discovery(device=bulb), _patch_wifibulb(device=bulb):
|
with _patch_discovery(), _patch_wifibulb(device=bulb):
|
||||||
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
@ -1085,7 +1085,7 @@ async def test_rgb_light_custom_effect_via_service(
|
||||||
bulb = _mocked_bulb()
|
bulb = _mocked_bulb()
|
||||||
bulb.color_modes = {FLUX_COLOR_MODE_RGB}
|
bulb.color_modes = {FLUX_COLOR_MODE_RGB}
|
||||||
bulb.color_mode = FLUX_COLOR_MODE_RGB
|
bulb.color_mode = FLUX_COLOR_MODE_RGB
|
||||||
with _patch_discovery(device=bulb), _patch_wifibulb(device=bulb):
|
with _patch_discovery(), _patch_wifibulb(device=bulb):
|
||||||
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
@ -1230,7 +1230,7 @@ async def test_addressable_light(hass: HomeAssistant) -> None:
|
||||||
bulb.raw_state = bulb.raw_state._replace(model_num=0x33) # RGB only model
|
bulb.raw_state = bulb.raw_state._replace(model_num=0x33) # RGB only model
|
||||||
bulb.color_modes = {FLUX_COLOR_MODE_ADDRESSABLE}
|
bulb.color_modes = {FLUX_COLOR_MODE_ADDRESSABLE}
|
||||||
bulb.color_mode = FLUX_COLOR_MODE_ADDRESSABLE
|
bulb.color_mode = FLUX_COLOR_MODE_ADDRESSABLE
|
||||||
with _patch_discovery(device=bulb), _patch_wifibulb(device=bulb):
|
with _patch_discovery(), _patch_wifibulb(device=bulb):
|
||||||
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ async def test_number_unique_id(hass: HomeAssistant) -> None:
|
||||||
)
|
)
|
||||||
config_entry.add_to_hass(hass)
|
config_entry.add_to_hass(hass)
|
||||||
bulb = _mocked_bulb()
|
bulb = _mocked_bulb()
|
||||||
with _patch_discovery(device=bulb), _patch_wifibulb(device=bulb):
|
with _patch_discovery(), _patch_wifibulb(device=bulb):
|
||||||
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ async def test_rgb_light_effect_speed(hass: HomeAssistant) -> None:
|
||||||
bulb.color_modes = {FLUX_COLOR_MODE_RGB}
|
bulb.color_modes = {FLUX_COLOR_MODE_RGB}
|
||||||
bulb.color_mode = FLUX_COLOR_MODE_RGB
|
bulb.color_mode = FLUX_COLOR_MODE_RGB
|
||||||
|
|
||||||
with _patch_discovery(device=bulb), _patch_wifibulb(device=bulb):
|
with _patch_discovery(), _patch_wifibulb(device=bulb):
|
||||||
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ async def test_original_addressable_light_effect_speed(hass: HomeAssistant) -> N
|
||||||
bulb.color_mode = FLUX_COLOR_MODE_RGB
|
bulb.color_mode = FLUX_COLOR_MODE_RGB
|
||||||
bulb.effect = "7 colors change gradually"
|
bulb.effect = "7 colors change gradually"
|
||||||
bulb.speed = 50
|
bulb.speed = 50
|
||||||
with _patch_discovery(device=bulb), _patch_wifibulb(device=bulb):
|
with _patch_discovery(), _patch_wifibulb(device=bulb):
|
||||||
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
@ -186,7 +186,7 @@ async def test_addressable_light_effect_speed(hass: HomeAssistant) -> None:
|
||||||
bulb.color_mode = FLUX_COLOR_MODE_RGB
|
bulb.color_mode = FLUX_COLOR_MODE_RGB
|
||||||
bulb.effect = "RBM 1"
|
bulb.effect = "RBM 1"
|
||||||
bulb.speed = 50
|
bulb.speed = 50
|
||||||
with _patch_discovery(device=bulb), _patch_wifibulb(device=bulb):
|
with _patch_discovery(), _patch_wifibulb(device=bulb):
|
||||||
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ async def test_switch_on_off(hass: HomeAssistant) -> None:
|
||||||
)
|
)
|
||||||
config_entry.add_to_hass(hass)
|
config_entry.add_to_hass(hass)
|
||||||
switch = _mocked_switch()
|
switch = _mocked_switch()
|
||||||
with _patch_discovery(device=switch), _patch_wifibulb(device=switch):
|
with _patch_discovery(), _patch_wifibulb(device=switch):
|
||||||
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue