mirror of https://github.com/home-assistant/core
297 lines
8.6 KiB
Python
297 lines
8.6 KiB
Python
"""Tests for the WiZ Platform integration."""
|
|
|
|
from collections.abc import Callable, Generator
|
|
from contextlib import _GeneratorContextManager, contextmanager
|
|
from copy import deepcopy
|
|
import json
|
|
from typing import Any
|
|
from unittest.mock import AsyncMock, MagicMock, patch
|
|
|
|
from pywizlight import SCENES, BulbType, PilotParser, wizlight
|
|
from pywizlight.bulblibrary import BulbClass, Features, KelvinRange
|
|
from pywizlight.discovery import DiscoveredBulb
|
|
|
|
from homeassistant.components.wiz.const import DOMAIN
|
|
from homeassistant.const import CONF_HOST, CONF_NAME
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.setup import async_setup_component
|
|
|
|
from tests.common import MockConfigEntry
|
|
|
|
FAKE_STATE = PilotParser(
|
|
{
|
|
"mac": "a8bb50818e7c",
|
|
"rssi": -55,
|
|
"src": "hb",
|
|
"mqttCd": 0,
|
|
"ts": 1644425347,
|
|
"state": True,
|
|
"sceneId": 0,
|
|
"r": 0,
|
|
"g": 0,
|
|
"b": 255,
|
|
"c": 0,
|
|
"w": 0,
|
|
"dimming": 100,
|
|
}
|
|
)
|
|
FAKE_IP = "1.1.1.1"
|
|
FAKE_MAC = "abcabcabcabc"
|
|
FAKE_BULB_CONFIG = {
|
|
"method": "getSystemConfig",
|
|
"env": "pro",
|
|
"result": {
|
|
"mac": FAKE_MAC,
|
|
"homeId": 653906,
|
|
"roomId": 989983,
|
|
"moduleName": "ESP_0711_STR",
|
|
"fwVersion": "1.21.0",
|
|
"groupId": 0,
|
|
"drvConf": [20, 2],
|
|
"ewf": [255, 0, 255, 255, 0, 0, 0],
|
|
"ewfHex": "ff00ffff000000",
|
|
"ping": 0,
|
|
},
|
|
}
|
|
FAKE_SOCKET_CONFIG = deepcopy(FAKE_BULB_CONFIG)
|
|
FAKE_SOCKET_CONFIG["result"]["moduleName"] = "ESP10_SOCKET_06"
|
|
FAKE_EXTENDED_WHITE_RANGE = [2200, 2700, 6500, 6500]
|
|
TEST_SYSTEM_INFO = {"id": FAKE_MAC, "name": "Test Bulb"}
|
|
TEST_CONNECTION = {CONF_HOST: "1.1.1.1"}
|
|
TEST_NO_IP = {CONF_HOST: "this is no IP input"}
|
|
|
|
FAKE_BULB_CONFIG = json.loads(
|
|
'{"method":"getSystemConfig","env":"pro","result":\
|
|
{"mac":"ABCABCABCABC",\
|
|
"homeId":653906,\
|
|
"roomId":989983,\
|
|
"moduleName":"ESP_0711_STR",\
|
|
"fwVersion":"1.21.0",\
|
|
"groupId":0,"drvConf":[20,2],\
|
|
"ewf":[255,0,255,255,0,0,0],\
|
|
"ewfHex":"ff00ffff000000",\
|
|
"ping":0}}'
|
|
)
|
|
|
|
REAL_BULB_CONFIG = json.loads(
|
|
'{"method":"getSystemConfig","env":"pro","result":\
|
|
{"mac":"ABCABCABCABC",\
|
|
"homeId":653906,\
|
|
"roomId":989983,\
|
|
"moduleName":"ESP01_SHRGB_03",\
|
|
"fwVersion":"1.21.0",\
|
|
"groupId":0,"drvConf":[20,2],\
|
|
"ewf":[255,0,255,255,0,0,0],\
|
|
"ewfHex":"ff00ffff000000",\
|
|
"ping":0}}'
|
|
)
|
|
FAKE_DUAL_HEAD_RGBWW_BULB = BulbType(
|
|
bulb_type=BulbClass.RGB,
|
|
name="ESP01_DHRGB_03",
|
|
features=Features(
|
|
color=True, color_tmp=True, effect=True, brightness=True, dual_head=True
|
|
),
|
|
kelvin_range=KelvinRange(2700, 6500),
|
|
fw_version="1.0.0",
|
|
white_channels=2,
|
|
white_to_color_ratio=80,
|
|
)
|
|
FAKE_RGBWW_BULB = BulbType(
|
|
bulb_type=BulbClass.RGB,
|
|
name="ESP01_SHRGB_03",
|
|
features=Features(
|
|
color=True, color_tmp=True, effect=True, brightness=True, dual_head=False
|
|
),
|
|
kelvin_range=KelvinRange(2700, 6500),
|
|
fw_version="1.0.0",
|
|
white_channels=2,
|
|
white_to_color_ratio=80,
|
|
)
|
|
FAKE_RGBW_BULB = BulbType(
|
|
bulb_type=BulbClass.RGB,
|
|
name="ESP01_SHRGB_03",
|
|
features=Features(
|
|
color=True, color_tmp=True, effect=True, brightness=True, dual_head=False
|
|
),
|
|
kelvin_range=KelvinRange(2700, 6500),
|
|
fw_version="1.0.0",
|
|
white_channels=1,
|
|
white_to_color_ratio=80,
|
|
)
|
|
FAKE_DIMMABLE_BULB = BulbType(
|
|
bulb_type=BulbClass.DW,
|
|
name="ESP01_DW_03",
|
|
features=Features(
|
|
color=False, color_tmp=False, effect=True, brightness=True, dual_head=False
|
|
),
|
|
kelvin_range=KelvinRange(2700, 6500),
|
|
fw_version="1.0.0",
|
|
white_channels=1,
|
|
white_to_color_ratio=80,
|
|
)
|
|
FAKE_TURNABLE_BULB = BulbType(
|
|
bulb_type=BulbClass.TW,
|
|
name="ESP01_TW_03",
|
|
features=Features(
|
|
color=False, color_tmp=True, effect=True, brightness=True, dual_head=False
|
|
),
|
|
kelvin_range=KelvinRange(2700, 6500),
|
|
fw_version="1.0.0",
|
|
white_channels=1,
|
|
white_to_color_ratio=80,
|
|
)
|
|
FAKE_SOCKET = BulbType(
|
|
bulb_type=BulbClass.SOCKET,
|
|
name="ESP01_SOCKET_03",
|
|
features=Features(
|
|
color=False, color_tmp=False, effect=False, brightness=False, dual_head=False
|
|
),
|
|
kelvin_range=KelvinRange(2700, 6500),
|
|
fw_version="1.0.0",
|
|
white_channels=2,
|
|
white_to_color_ratio=80,
|
|
)
|
|
FAKE_SOCKET_WITH_POWER_MONITORING = BulbType(
|
|
bulb_type=BulbClass.SOCKET,
|
|
name="ESP25_SOCKET_01",
|
|
features=Features(
|
|
color=False, color_tmp=False, effect=False, brightness=False, dual_head=False
|
|
),
|
|
kelvin_range=KelvinRange(2700, 6500),
|
|
fw_version="1.26.2",
|
|
white_channels=2,
|
|
white_to_color_ratio=80,
|
|
)
|
|
FAKE_OLD_FIRMWARE_DIMMABLE_BULB = BulbType(
|
|
bulb_type=BulbClass.DW,
|
|
name=None,
|
|
features=Features(
|
|
color=False, color_tmp=False, effect=True, brightness=True, dual_head=False
|
|
),
|
|
kelvin_range=None,
|
|
fw_version="1.8.0",
|
|
white_channels=1,
|
|
white_to_color_ratio=80,
|
|
)
|
|
|
|
|
|
async def setup_integration(hass: HomeAssistant) -> MockConfigEntry:
|
|
"""Mock ConfigEntry in Home Assistant."""
|
|
|
|
entry = MockConfigEntry(
|
|
domain=DOMAIN,
|
|
unique_id=TEST_SYSTEM_INFO["id"],
|
|
data={
|
|
CONF_HOST: "127.0.0.1",
|
|
CONF_NAME: TEST_SYSTEM_INFO["name"],
|
|
},
|
|
)
|
|
|
|
entry.add_to_hass(hass)
|
|
|
|
await hass.config_entries.async_setup(entry.entry_id)
|
|
await hass.async_block_till_done()
|
|
|
|
return entry
|
|
|
|
|
|
def _mocked_wizlight(
|
|
device: dict[str, Any] | None,
|
|
extended_white_range: list[int] | None,
|
|
bulb_type: BulbType | None,
|
|
) -> wizlight:
|
|
bulb = MagicMock(auto_spec=wizlight, name="Mocked wizlight")
|
|
|
|
async def _save_setup_callback(callback: Callable) -> None:
|
|
bulb.push_callback = callback
|
|
|
|
bulb.getBulbConfig = AsyncMock(return_value=device or FAKE_BULB_CONFIG)
|
|
bulb.getExtendedWhiteRange = AsyncMock(
|
|
return_value=extended_white_range or FAKE_EXTENDED_WHITE_RANGE
|
|
)
|
|
bulb.getMac = AsyncMock(return_value=FAKE_MAC)
|
|
bulb.turn_on = AsyncMock()
|
|
bulb.get_power = AsyncMock(return_value=None)
|
|
bulb.turn_off = AsyncMock()
|
|
bulb.power_monitoring = False
|
|
bulb.updateState = AsyncMock(return_value=FAKE_STATE)
|
|
bulb.getSupportedScenes = AsyncMock(return_value=list(SCENES.values()))
|
|
bulb.start_push = AsyncMock(side_effect=_save_setup_callback)
|
|
bulb.async_close = AsyncMock()
|
|
bulb.set_speed = AsyncMock()
|
|
bulb.set_ratio = AsyncMock()
|
|
bulb.diagnostics = {
|
|
"mocked": "mocked",
|
|
"roomId": 123,
|
|
"homeId": 34,
|
|
}
|
|
bulb.state = FAKE_STATE
|
|
bulb.mac = FAKE_MAC
|
|
bulb.bulbtype = bulb_type or FAKE_DIMMABLE_BULB
|
|
bulb.get_bulbtype = AsyncMock(return_value=bulb_type or FAKE_DIMMABLE_BULB)
|
|
|
|
return bulb
|
|
|
|
|
|
def _patch_wizlight(
|
|
device: dict[str, Any] | None = None,
|
|
extended_white_range: list[int] | None = None,
|
|
bulb_type: BulbType | None = None,
|
|
) -> _GeneratorContextManager:
|
|
@contextmanager
|
|
def _patcher() -> Generator[None]:
|
|
bulb = device or _mocked_wizlight(device, extended_white_range, bulb_type)
|
|
with (
|
|
patch("homeassistant.components.wiz.wizlight", return_value=bulb),
|
|
patch(
|
|
"homeassistant.components.wiz.config_flow.wizlight",
|
|
return_value=bulb,
|
|
),
|
|
):
|
|
yield
|
|
|
|
return _patcher()
|
|
|
|
|
|
def _patch_discovery() -> _GeneratorContextManager[None]:
|
|
@contextmanager
|
|
def _patcher() -> Generator[None]:
|
|
with patch(
|
|
"homeassistant.components.wiz.discovery.find_wizlights",
|
|
return_value=[DiscoveredBulb(FAKE_IP, FAKE_MAC)],
|
|
):
|
|
yield
|
|
|
|
return _patcher()
|
|
|
|
|
|
async def async_setup_integration(
|
|
hass: HomeAssistant,
|
|
wizlight: wizlight | None = None,
|
|
device: dict[str, Any] | None = None,
|
|
extended_white_range: list[int] | None = None,
|
|
bulb_type: BulbType | None = None,
|
|
) -> tuple[wizlight, MockConfigEntry]:
|
|
"""Set up the integration with a mock device."""
|
|
entry = MockConfigEntry(
|
|
domain=DOMAIN,
|
|
unique_id=FAKE_MAC,
|
|
data={CONF_HOST: FAKE_IP},
|
|
)
|
|
entry.add_to_hass(hass)
|
|
bulb = wizlight or _mocked_wizlight(device, extended_white_range, bulb_type)
|
|
with _patch_discovery(), _patch_wizlight(device=bulb):
|
|
await async_setup_component(hass, DOMAIN, {DOMAIN: {}})
|
|
await hass.async_block_till_done()
|
|
return bulb, entry
|
|
|
|
|
|
async def async_push_update(
|
|
hass: HomeAssistant, device: wizlight, params: dict[str, Any]
|
|
) -> None:
|
|
"""Push an update to the device."""
|
|
device.state = PilotParser(params)
|
|
device.status = params.get("state")
|
|
device.push_callback(device.state)
|
|
await hass.async_block_till_done()
|