Fix flux_led discovery with older models (#61413)

This commit is contained in:
J. Nick Koston 2021-12-09 21:29:27 -10:00 committed by GitHub
parent 8383da6a5e
commit 8d483e2206
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 71 additions and 24 deletions

View file

@ -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:

View file

@ -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):

View file

@ -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."""

View file

@ -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()

View file

@ -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()

View file

@ -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()