mirror of
https://github.com/python-kasa/python-kasa.git
synced 2025-11-05 15:11:55 +00:00
Refactor devices into subpackages and deprecate old names (#716)
* Refactor devices into subpackages and deprecate old names * Tweak and add tests * Fix linting * Remove duplicate implementations affecting project coverage * Update post review * Add device base class attributes and rename subclasses * Rename Module to BaseModule * Remove has_emeter_history * Fix missing _time in init * Update post review * Fix test_readmeexamples * Fix erroneously duped files * Clean up iot and smart imports * Update post latest review * Tweak Device docstring
This commit is contained in:
@@ -7,7 +7,8 @@ from voluptuous import (
|
||||
Schema,
|
||||
)
|
||||
|
||||
from kasa import DeviceType, SmartBulb, SmartBulbPreset, SmartDeviceException
|
||||
from kasa import Bulb, BulbPreset, DeviceType, SmartDeviceException
|
||||
from kasa.iot import IotBulb
|
||||
|
||||
from .conftest import (
|
||||
bulb,
|
||||
@@ -27,7 +28,7 @@ from .test_smartdevice import SYSINFO_SCHEMA
|
||||
|
||||
|
||||
@bulb
|
||||
async def test_bulb_sysinfo(dev: SmartBulb):
|
||||
async def test_bulb_sysinfo(dev: Bulb):
|
||||
assert dev.sys_info is not None
|
||||
SYSINFO_SCHEMA_BULB(dev.sys_info)
|
||||
|
||||
@@ -40,7 +41,7 @@ async def test_bulb_sysinfo(dev: SmartBulb):
|
||||
|
||||
|
||||
@bulb
|
||||
async def test_state_attributes(dev: SmartBulb):
|
||||
async def test_state_attributes(dev: Bulb):
|
||||
assert "Brightness" in dev.state_information
|
||||
assert dev.state_information["Brightness"] == dev.brightness
|
||||
|
||||
@@ -49,7 +50,7 @@ async def test_state_attributes(dev: SmartBulb):
|
||||
|
||||
|
||||
@bulb_iot
|
||||
async def test_light_state_without_update(dev: SmartBulb, monkeypatch):
|
||||
async def test_light_state_without_update(dev: IotBulb, monkeypatch):
|
||||
with pytest.raises(SmartDeviceException):
|
||||
monkeypatch.setitem(
|
||||
dev._last_update["system"]["get_sysinfo"], "light_state", None
|
||||
@@ -58,13 +59,13 @@ async def test_light_state_without_update(dev: SmartBulb, monkeypatch):
|
||||
|
||||
|
||||
@bulb_iot
|
||||
async def test_get_light_state(dev: SmartBulb):
|
||||
async def test_get_light_state(dev: IotBulb):
|
||||
LIGHT_STATE_SCHEMA(await dev.get_light_state())
|
||||
|
||||
|
||||
@color_bulb
|
||||
@turn_on
|
||||
async def test_hsv(dev: SmartBulb, turn_on):
|
||||
async def test_hsv(dev: Bulb, turn_on):
|
||||
await handle_turn_on(dev, turn_on)
|
||||
assert dev.is_color
|
||||
|
||||
@@ -83,8 +84,8 @@ async def test_hsv(dev: SmartBulb, turn_on):
|
||||
|
||||
|
||||
@color_bulb_iot
|
||||
async def test_set_hsv_transition(dev: SmartBulb, mocker):
|
||||
set_light_state = mocker.patch("kasa.SmartBulb.set_light_state")
|
||||
async def test_set_hsv_transition(dev: IotBulb, mocker):
|
||||
set_light_state = mocker.patch("kasa.iot.IotBulb.set_light_state")
|
||||
await dev.set_hsv(10, 10, 100, transition=1000)
|
||||
|
||||
set_light_state.assert_called_with(
|
||||
@@ -95,31 +96,31 @@ async def test_set_hsv_transition(dev: SmartBulb, mocker):
|
||||
|
||||
@color_bulb
|
||||
@turn_on
|
||||
async def test_invalid_hsv(dev: SmartBulb, turn_on):
|
||||
async def test_invalid_hsv(dev: Bulb, turn_on):
|
||||
await handle_turn_on(dev, turn_on)
|
||||
assert dev.is_color
|
||||
|
||||
for invalid_hue in [-1, 361, 0.5]:
|
||||
with pytest.raises(ValueError):
|
||||
await dev.set_hsv(invalid_hue, 0, 0)
|
||||
await dev.set_hsv(invalid_hue, 0, 0) # type: ignore[arg-type]
|
||||
|
||||
for invalid_saturation in [-1, 101, 0.5]:
|
||||
with pytest.raises(ValueError):
|
||||
await dev.set_hsv(0, invalid_saturation, 0)
|
||||
await dev.set_hsv(0, invalid_saturation, 0) # type: ignore[arg-type]
|
||||
|
||||
for invalid_brightness in [-1, 101, 0.5]:
|
||||
with pytest.raises(ValueError):
|
||||
await dev.set_hsv(0, 0, invalid_brightness)
|
||||
await dev.set_hsv(0, 0, invalid_brightness) # type: ignore[arg-type]
|
||||
|
||||
|
||||
@color_bulb
|
||||
async def test_color_state_information(dev: SmartBulb):
|
||||
async def test_color_state_information(dev: Bulb):
|
||||
assert "HSV" in dev.state_information
|
||||
assert dev.state_information["HSV"] == dev.hsv
|
||||
|
||||
|
||||
@non_color_bulb
|
||||
async def test_hsv_on_non_color(dev: SmartBulb):
|
||||
async def test_hsv_on_non_color(dev: Bulb):
|
||||
assert not dev.is_color
|
||||
|
||||
with pytest.raises(SmartDeviceException):
|
||||
@@ -129,7 +130,7 @@ async def test_hsv_on_non_color(dev: SmartBulb):
|
||||
|
||||
|
||||
@variable_temp
|
||||
async def test_variable_temp_state_information(dev: SmartBulb):
|
||||
async def test_variable_temp_state_information(dev: Bulb):
|
||||
assert "Color temperature" in dev.state_information
|
||||
assert dev.state_information["Color temperature"] == dev.color_temp
|
||||
|
||||
@@ -141,7 +142,7 @@ async def test_variable_temp_state_information(dev: SmartBulb):
|
||||
|
||||
@variable_temp
|
||||
@turn_on
|
||||
async def test_try_set_colortemp(dev: SmartBulb, turn_on):
|
||||
async def test_try_set_colortemp(dev: Bulb, turn_on):
|
||||
await handle_turn_on(dev, turn_on)
|
||||
await dev.set_color_temp(2700)
|
||||
await dev.update()
|
||||
@@ -149,15 +150,15 @@ async def test_try_set_colortemp(dev: SmartBulb, turn_on):
|
||||
|
||||
|
||||
@variable_temp_iot
|
||||
async def test_set_color_temp_transition(dev: SmartBulb, mocker):
|
||||
set_light_state = mocker.patch("kasa.SmartBulb.set_light_state")
|
||||
async def test_set_color_temp_transition(dev: IotBulb, mocker):
|
||||
set_light_state = mocker.patch("kasa.iot.IotBulb.set_light_state")
|
||||
await dev.set_color_temp(2700, transition=100)
|
||||
|
||||
set_light_state.assert_called_with({"color_temp": 2700}, transition=100)
|
||||
|
||||
|
||||
@variable_temp_iot
|
||||
async def test_unknown_temp_range(dev: SmartBulb, monkeypatch, caplog):
|
||||
async def test_unknown_temp_range(dev: IotBulb, monkeypatch, caplog):
|
||||
monkeypatch.setitem(dev._sys_info, "model", "unknown bulb")
|
||||
|
||||
assert dev.valid_temperature_range == (2700, 5000)
|
||||
@@ -165,7 +166,7 @@ async def test_unknown_temp_range(dev: SmartBulb, monkeypatch, caplog):
|
||||
|
||||
|
||||
@variable_temp
|
||||
async def test_out_of_range_temperature(dev: SmartBulb):
|
||||
async def test_out_of_range_temperature(dev: Bulb):
|
||||
with pytest.raises(ValueError):
|
||||
await dev.set_color_temp(1000)
|
||||
with pytest.raises(ValueError):
|
||||
@@ -173,7 +174,7 @@ async def test_out_of_range_temperature(dev: SmartBulb):
|
||||
|
||||
|
||||
@non_variable_temp
|
||||
async def test_non_variable_temp(dev: SmartBulb):
|
||||
async def test_non_variable_temp(dev: Bulb):
|
||||
with pytest.raises(SmartDeviceException):
|
||||
await dev.set_color_temp(2700)
|
||||
|
||||
@@ -186,7 +187,7 @@ async def test_non_variable_temp(dev: SmartBulb):
|
||||
|
||||
@dimmable
|
||||
@turn_on
|
||||
async def test_dimmable_brightness(dev: SmartBulb, turn_on):
|
||||
async def test_dimmable_brightness(dev: Bulb, turn_on):
|
||||
await handle_turn_on(dev, turn_on)
|
||||
assert dev.is_dimmable
|
||||
|
||||
@@ -199,12 +200,12 @@ async def test_dimmable_brightness(dev: SmartBulb, turn_on):
|
||||
assert dev.brightness == 10
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
await dev.set_brightness("foo")
|
||||
await dev.set_brightness("foo") # type: ignore[arg-type]
|
||||
|
||||
|
||||
@bulb_iot
|
||||
async def test_turn_on_transition(dev: SmartBulb, mocker):
|
||||
set_light_state = mocker.patch("kasa.SmartBulb.set_light_state")
|
||||
async def test_turn_on_transition(dev: IotBulb, mocker):
|
||||
set_light_state = mocker.patch("kasa.iot.IotBulb.set_light_state")
|
||||
await dev.turn_on(transition=1000)
|
||||
|
||||
set_light_state.assert_called_with({"on_off": 1}, transition=1000)
|
||||
@@ -215,15 +216,15 @@ async def test_turn_on_transition(dev: SmartBulb, mocker):
|
||||
|
||||
|
||||
@bulb_iot
|
||||
async def test_dimmable_brightness_transition(dev: SmartBulb, mocker):
|
||||
set_light_state = mocker.patch("kasa.SmartBulb.set_light_state")
|
||||
async def test_dimmable_brightness_transition(dev: IotBulb, mocker):
|
||||
set_light_state = mocker.patch("kasa.iot.IotBulb.set_light_state")
|
||||
await dev.set_brightness(10, transition=1000)
|
||||
|
||||
set_light_state.assert_called_with({"brightness": 10}, transition=1000)
|
||||
|
||||
|
||||
@dimmable
|
||||
async def test_invalid_brightness(dev: SmartBulb):
|
||||
async def test_invalid_brightness(dev: Bulb):
|
||||
assert dev.is_dimmable
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
@@ -234,7 +235,7 @@ async def test_invalid_brightness(dev: SmartBulb):
|
||||
|
||||
|
||||
@non_dimmable
|
||||
async def test_non_dimmable(dev: SmartBulb):
|
||||
async def test_non_dimmable(dev: Bulb):
|
||||
assert not dev.is_dimmable
|
||||
|
||||
with pytest.raises(SmartDeviceException):
|
||||
@@ -245,9 +246,9 @@ async def test_non_dimmable(dev: SmartBulb):
|
||||
|
||||
@bulb_iot
|
||||
async def test_ignore_default_not_set_without_color_mode_change_turn_on(
|
||||
dev: SmartBulb, mocker
|
||||
dev: IotBulb, mocker
|
||||
):
|
||||
query_helper = mocker.patch("kasa.SmartBulb._query_helper")
|
||||
query_helper = mocker.patch("kasa.iot.IotBulb._query_helper")
|
||||
# When turning back without settings, ignore default to restore the state
|
||||
await dev.turn_on()
|
||||
args, kwargs = query_helper.call_args_list[0]
|
||||
@@ -259,7 +260,7 @@ async def test_ignore_default_not_set_without_color_mode_change_turn_on(
|
||||
|
||||
|
||||
@bulb_iot
|
||||
async def test_list_presets(dev: SmartBulb):
|
||||
async def test_list_presets(dev: IotBulb):
|
||||
presets = dev.presets
|
||||
assert len(presets) == len(dev.sys_info["preferred_state"])
|
||||
|
||||
@@ -272,7 +273,7 @@ async def test_list_presets(dev: SmartBulb):
|
||||
|
||||
|
||||
@bulb_iot
|
||||
async def test_modify_preset(dev: SmartBulb, mocker):
|
||||
async def test_modify_preset(dev: IotBulb, mocker):
|
||||
"""Verify that modifying preset calls the and exceptions are raised properly."""
|
||||
if not dev.presets:
|
||||
pytest.skip("Some strips do not support presets")
|
||||
@@ -284,7 +285,7 @@ async def test_modify_preset(dev: SmartBulb, mocker):
|
||||
"saturation": 0,
|
||||
"color_temp": 0,
|
||||
}
|
||||
preset = SmartBulbPreset(**data)
|
||||
preset = BulbPreset(**data)
|
||||
|
||||
assert preset.index == 0
|
||||
assert preset.brightness == 10
|
||||
@@ -297,7 +298,7 @@ async def test_modify_preset(dev: SmartBulb, mocker):
|
||||
|
||||
with pytest.raises(SmartDeviceException):
|
||||
await dev.save_preset(
|
||||
SmartBulbPreset(index=5, hue=0, brightness=0, saturation=0, color_temp=0)
|
||||
BulbPreset(index=5, hue=0, brightness=0, saturation=0, color_temp=0)
|
||||
)
|
||||
|
||||
|
||||
@@ -306,21 +307,21 @@ async def test_modify_preset(dev: SmartBulb, mocker):
|
||||
("preset", "payload"),
|
||||
[
|
||||
(
|
||||
SmartBulbPreset(index=0, hue=0, brightness=1, saturation=0),
|
||||
BulbPreset(index=0, hue=0, brightness=1, saturation=0),
|
||||
{"index": 0, "hue": 0, "brightness": 1, "saturation": 0},
|
||||
),
|
||||
(
|
||||
SmartBulbPreset(index=0, brightness=1, id="testid", mode=2, custom=0),
|
||||
BulbPreset(index=0, brightness=1, id="testid", mode=2, custom=0),
|
||||
{"index": 0, "brightness": 1, "id": "testid", "mode": 2, "custom": 0},
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_modify_preset_payloads(dev: SmartBulb, preset, payload, mocker):
|
||||
async def test_modify_preset_payloads(dev: IotBulb, preset, payload, mocker):
|
||||
"""Test that modify preset payloads ignore none values."""
|
||||
if not dev.presets:
|
||||
pytest.skip("Some strips do not support presets")
|
||||
|
||||
query_helper = mocker.patch("kasa.SmartBulb._query_helper")
|
||||
query_helper = mocker.patch("kasa.iot.IotBulb._query_helper")
|
||||
await dev.save_preset(preset)
|
||||
query_helper.assert_called_with(dev.LIGHT_SERVICE, "set_preferred_state", payload)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user