From 7dd3128f6f8f7260ccd976c3e66182ba89537ce2 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 10 Feb 2022 16:17:56 -0600 Subject: [PATCH] Fix reporting available scenes on RGB devices - Add coverage for scenes --- pywizlight/bulb.py | 6 +- pywizlight/bulblibrary.py | 22 +++--- pywizlight/scenes.py | 2 +- pywizlight/tests/fake_bulb.py | 58 +++++++++++++++ pywizlight/tests/test_bulb_dimmable_white.py | 15 ++++ .../tests/test_bulb_light_strip_1_25_0.py | 40 +++++++++++ pywizlight/tests/test_bulb_rgbtw_1_21_4.py | 72 +++++++++++++++++++ pywizlight/tests/test_bulb_socket.py | 6 ++ pywizlight/tests/test_bulb_turnable_white.py | 53 ++++++++++++++ 9 files changed, 264 insertions(+), 10 deletions(-) create mode 100644 pywizlight/tests/test_bulb_rgbtw_1_21_4.py create mode 100644 pywizlight/tests/test_bulb_turnable_white.py diff --git a/pywizlight/bulb.py b/pywizlight/bulb.py index 5362902..e8bdeda 100755 --- a/pywizlight/bulb.py +++ b/pywizlight/bulb.py @@ -6,6 +6,8 @@ import time from typing import Any, Callable, Dict, List, Optional, Tuple, Union, cast +from pywizlight.exceptions import WizLightNotKnownBulb + from pywizlight.bulblibrary import BulbType from pywizlight.exceptions import ( WizLightConnectionError, @@ -453,7 +455,9 @@ async def get_bulbtype(self) -> BulbType: bulb_config = await self.getBulbConfig() result = bulb_config["result"] if "moduleName" not in result: - raise ValueError("Unable to determine bulb type.") + raise WizLightNotKnownBulb( + "Unable to determine the bulb type; moduleName is missing from getSystemConfig" + ) white_range = await self.getExtendedWhiteRange() white_to_color_ratio = None white_channels = None diff --git a/pywizlight/bulblibrary.py b/pywizlight/bulblibrary.py index 0328276..6483498 100644 --- a/pywizlight/bulblibrary.py +++ b/pywizlight/bulblibrary.py @@ -82,19 +82,14 @@ def from_data( white_channels: Optional[int], white_to_color_ratio: Optional[int], ) -> "BulbType": - if kelvin_list: - kelvin_range: Optional[KelvinRange] = KelvinRange( - min=int(min(kelvin_list)), max=int(max(kelvin_list)) - ) - else: - kelvin_range = None - try: # parse the features from name _identifier = module_name.split("_")[1] # Throw exception if index can not be found except IndexError: - raise WizLightNotKnownBulb("The bulb type can not be determined!") + raise WizLightNotKnownBulb( + f"The bulb type could not be determined from the module name: {module_name}" + ) if "RGB" in _identifier: # full RGB bulb bulb_type = BulbClass.RGB @@ -105,6 +100,17 @@ def from_data( else: # Plain brightness-only bulb bulb_type = BulbClass.DW + if kelvin_list: + kelvin_range: Optional[KelvinRange] = KelvinRange( + min=int(min(kelvin_list)), max=int(max(kelvin_list)) + ) + elif bulb_type in (BulbClass.RGB, BulbClass.TW): + raise WizLightNotKnownBulb( + f"Unable to determine required kelvin range for a {bulb_type.value} device" + ) + else: + kelvin_range = None + features = FEATURE_MAP[bulb_type] return BulbType( diff --git a/pywizlight/scenes.py b/pywizlight/scenes.py index c98db9a..6c2fe4b 100755 --- a/pywizlight/scenes.py +++ b/pywizlight/scenes.py @@ -44,7 +44,7 @@ DW_SCENES = [9, 10, 13, 14, 29, 30, 31, 32] SCENES_BY_CLASS: Dict[BulbClass, List[str]] = { - BulbClass.RGB: list(cast(Iterable, SCENES)), + BulbClass.RGB: list(cast(Iterable, SCENES.values())), BulbClass.TW: [SCENES[key] for key in TW_SCENES], BulbClass.DW: [SCENES[key] for key in DW_SCENES], } diff --git a/pywizlight/tests/fake_bulb.py b/pywizlight/tests/fake_bulb.py index c9361fb..0d8687a 100644 --- a/pywizlight/tests/fake_bulb.py +++ b/pywizlight/tests/fake_bulb.py @@ -58,6 +58,20 @@ "drvIface": 0, }, }, + ("ESP21_SHTW_01", "1.25.0"): { + "method": "getModelConfig", + "env": "pro", + "result": { + "ps": 2, + "pwmFreq": 5000, + "pwmRange": [1, 100], + "wcr": 20, + "nowc": 1, + "cctRange": [2700, 2700, 5000, 5000], + "renderFactor": [255, 0, 255, 255, 0, 0, 0, 0, 0, 0], + "drvIface": 0, + }, + }, } SYSTEM_CONFIGS = { @@ -157,6 +171,36 @@ "drvConf": [20, 1], }, }, + ("ESP20_SHRGBC_01", "1.21.4"): { + "method": "getSystemConfig", + "env": "pro", + "result": { + "mac": "6c2990e493bc", + "homeId": 5385975, + "roomId": 8016844, + "moduleName": "ESP20_SHRGBC_01", + "fwVersion": "1.21.4", + "groupId": 0, + "drvConf": [30, 1], + "ewf": [200, 255, 150, 255, 0, 0, 40], + "ewfHex": "c8ff96ff000028", + "ping": 0, + }, + }, + ("ESP21_SHTW_01", "1.25.0"): { + "method": "getSystemConfig", + "env": "pro", + "result": { + "mac": "6c29905a067c", + "homeId": 5385975, + "roomId": 8016844, + "rgn": "eu", + "moduleName": "ESP21_SHTW_01", + "fwVersion": "1.25.0", + "groupId": 0, + "ping": 0, + }, + }, } USER_CONFIGS = { @@ -189,6 +233,20 @@ "po": False, }, }, + ("ESP20_SHRGBC_01", "1.21.4"): { + "method": "getUserConfig", + "env": "pro", + "result": { + "fadeIn": 500, + "fadeOut": 500, + "dftDim": 100, + "pwmRange": [0, 100], + "whiteRange": [2700, 6500], + "extRange": [2200, 6500], + "opMode": 0, + "po": True, + }, + }, } diff --git a/pywizlight/tests/test_bulb_dimmable_white.py b/pywizlight/tests/test_bulb_dimmable_white.py index c095734..52059b9 100644 --- a/pywizlight/tests/test_bulb_dimmable_white.py +++ b/pywizlight/tests/test_bulb_dimmable_white.py @@ -30,3 +30,18 @@ async def test_model_description_dimmable_bulb(dimmable_bulb: wizlight) -> None: white_channels=1, white_to_color_ratio=20, ) + + +@pytest.mark.asyncio +async def test_supported_scenes(dimmable_bulb: wizlight) -> None: + """Test supported scenes.""" + assert await dimmable_bulb.getSupportedScenes() == [ + "Wake up", + "Bedtime", + "Cool white", + "Night light", + "Candlelight", + "Golden white", + "Pulse", + "Steampunk", + ] diff --git a/pywizlight/tests/test_bulb_light_strip_1_25_0.py b/pywizlight/tests/test_bulb_light_strip_1_25_0.py index 43d7ad8..2d6be7c 100644 --- a/pywizlight/tests/test_bulb_light_strip_1_25_0.py +++ b/pywizlight/tests/test_bulb_light_strip_1_25_0.py @@ -25,6 +25,46 @@ async def test_setting_rgbww(light_strip: wizlight) -> None: assert state and state.get_rgbww() == (1, 2, 3, 4, 5) +@pytest.mark.asyncio +async def test_supported_scenes(light_strip: wizlight) -> None: + """Test supported scenes.""" + assert await light_strip.getSupportedScenes() == [ + "Ocean", + "Romance", + "Sunset", + "Party", + "Fireplace", + "Cozy", + "Forest", + "Pastel Colors", + "Wake up", + "Bedtime", + "Warm White", + "Daylight", + "Cool white", + "Night light", + "Focus", + "Relax", + "True colors", + "TV time", + "Plantgrowth", + "Spring", + "Summer", + "Fall", + "Deepdive", + "Jungle", + "Mojito", + "Club", + "Christmas", + "Halloween", + "Candlelight", + "Golden white", + "Pulse", + "Steampunk", + "Rhythm", + ] + + @pytest.mark.asyncio async def test_model_description_light_strip(light_strip: wizlight) -> None: """Test fetching the model description for a light strip.""" diff --git a/pywizlight/tests/test_bulb_rgbtw_1_21_4.py b/pywizlight/tests/test_bulb_rgbtw_1_21_4.py new file mode 100644 index 0000000..a153bf8 --- /dev/null +++ b/pywizlight/tests/test_bulb_rgbtw_1_21_4.py @@ -0,0 +1,72 @@ +"""Tests for the Bulb API with a rgbtw bulb.""" +from typing import AsyncGenerator + +import pytest + +from pywizlight import wizlight +from pywizlight.bulblibrary import BulbClass, BulbType, Features, KelvinRange +from pywizlight.tests.fake_bulb import startup_bulb + + +@pytest.fixture() +async def dimmable_bulb() -> AsyncGenerator[wizlight, None]: + shutdown = startup_bulb(module_name="ESP20_SHRGBC_01", firmware_version="1.21.4") + bulb = wizlight(ip="127.0.0.1") + yield bulb + await bulb.async_close() + shutdown() + + +@pytest.mark.asyncio +async def test_model_description_dimmable_bulb(dimmable_bulb: wizlight) -> None: + """Test fetching the model description dimmable bulb.""" + bulb_type = await dimmable_bulb.get_bulbtype() + assert bulb_type == BulbType( + features=Features(color=True, color_tmp=True, effect=True, brightness=True), + name="ESP20_SHRGBC_01", + kelvin_range=KelvinRange(max=6500, min=2200), + bulb_type=BulbClass.RGB, + fw_version="1.21.4", + white_channels=1, + white_to_color_ratio=30, + ) + + +@pytest.mark.asyncio +async def test_supported_scenes(dimmable_bulb: wizlight) -> None: + """Test supported scenes.""" + assert await dimmable_bulb.getSupportedScenes() == [ + "Ocean", + "Romance", + "Sunset", + "Party", + "Fireplace", + "Cozy", + "Forest", + "Pastel Colors", + "Wake up", + "Bedtime", + "Warm White", + "Daylight", + "Cool white", + "Night light", + "Focus", + "Relax", + "True colors", + "TV time", + "Plantgrowth", + "Spring", + "Summer", + "Fall", + "Deepdive", + "Jungle", + "Mojito", + "Club", + "Christmas", + "Halloween", + "Candlelight", + "Golden white", + "Pulse", + "Steampunk", + "Rhythm", + ] diff --git a/pywizlight/tests/test_bulb_socket.py b/pywizlight/tests/test_bulb_socket.py index d08737b..b2350c6 100644 --- a/pywizlight/tests/test_bulb_socket.py +++ b/pywizlight/tests/test_bulb_socket.py @@ -30,3 +30,9 @@ async def test_model_description_socket(socket: wizlight) -> None: white_channels=2, white_to_color_ratio=20, ) + + +@pytest.mark.asyncio +async def test_supported_scenes(socket: wizlight) -> None: + """Test supported scenes.""" + assert await socket.getSupportedScenes() == [] diff --git a/pywizlight/tests/test_bulb_turnable_white.py b/pywizlight/tests/test_bulb_turnable_white.py new file mode 100644 index 0000000..f5bf59b --- /dev/null +++ b/pywizlight/tests/test_bulb_turnable_white.py @@ -0,0 +1,53 @@ +"""Tests for the Bulb API with a light strip.""" +from typing import AsyncGenerator + +import pytest + +from pywizlight import wizlight +from pywizlight.bulblibrary import BulbClass, BulbType, Features, KelvinRange +from pywizlight.tests.fake_bulb import startup_bulb + + +@pytest.fixture() +async def turnable_bulb() -> AsyncGenerator[wizlight, None]: + shutdown = startup_bulb(module_name="ESP21_SHTW_01", firmware_version="1.25.0") + bulb = wizlight(ip="127.0.0.1") + yield bulb + await bulb.async_close() + shutdown() + + +@pytest.mark.asyncio +async def test_model_description_dimmable_bulb(turnable_bulb: wizlight) -> None: + """Test fetching the model description dimmable bulb.""" + bulb_type = await turnable_bulb.get_bulbtype() + assert bulb_type == BulbType( + features=Features(color=False, color_tmp=True, effect=True, brightness=True), + name="ESP21_SHTW_01", + kelvin_range=KelvinRange(max=5000, min=2700), + bulb_type=BulbClass.TW, + fw_version="1.25.0", + white_channels=1, + white_to_color_ratio=20, + ) + + +@pytest.mark.asyncio +async def test_supported_scenes(turnable_bulb: wizlight) -> None: + """Test supported scenes.""" + assert await turnable_bulb.getSupportedScenes() == [ + "Cozy", + "Wake up", + "Bedtime", + "Warm White", + "Daylight", + "Cool white", + "Night light", + "Focus", + "Relax", + "TV time", + "Candlelight", + "Golden white", + "Pulse", + "Steampunk", + ]