From 2f905f451ef00b538c86815b5db545dffec42d35 Mon Sep 17 00:00:00 2001 From: Teemu Rytilahti Date: Tue, 7 May 2024 01:43:22 +0200 Subject: [PATCH 1/5] Improve categorization of features --- kasa/iot/iotdimmer.py | 2 ++ kasa/iot/modules/ambientlight.py | 2 ++ kasa/iot/modules/cloud.py | 1 + kasa/iot/modules/emeter.py | 6 ++++++ kasa/smart/modules/autooffmodule.py | 6 +++++- kasa/smart/modules/battery.py | 3 +++ kasa/smart/modules/cloudmodule.py | 1 + kasa/smart/modules/energymodule.py | 3 +++ kasa/smart/modules/firmware.py | 1 + kasa/smart/modules/humidity.py | 2 ++ kasa/smart/modules/temperature.py | 1 + kasa/smart/smartdevice.py | 4 ++-- 12 files changed, 29 insertions(+), 3 deletions(-) diff --git a/kasa/iot/iotdimmer.py b/kasa/iot/iotdimmer.py index 672b22656..0cbf49165 100644 --- a/kasa/iot/iotdimmer.py +++ b/kasa/iot/iotdimmer.py @@ -96,7 +96,9 @@ async def _initialize_features(self): attribute_setter="set_brightness", minimum_value=1, maximum_value=100, + unit="%", type=Feature.Type.Number, + category=Feature.Category.Primary, ) ) diff --git a/kasa/iot/modules/ambientlight.py b/kasa/iot/modules/ambientlight.py index 2d7d679ba..ea8bfdf1f 100644 --- a/kasa/iot/modules/ambientlight.py +++ b/kasa/iot/modules/ambientlight.py @@ -26,6 +26,8 @@ def __init__(self, device, module): icon="mdi:brightness-percent", attribute_getter="ambientlight_brightness", type=Feature.Type.Sensor, + category=Feature.Category.Primary, + unit="%", ) ) diff --git a/kasa/iot/modules/cloud.py b/kasa/iot/modules/cloud.py index 41d2cbf54..46dc6e0e3 100644 --- a/kasa/iot/modules/cloud.py +++ b/kasa/iot/modules/cloud.py @@ -34,6 +34,7 @@ def __init__(self, device, module): icon="mdi:cloud", attribute_getter="is_connected", type=Feature.Type.BinarySensor, + category=Feature.Category.Info, ) ) diff --git a/kasa/iot/modules/emeter.py b/kasa/iot/modules/emeter.py index 1542e66ab..6380ed1f3 100644 --- a/kasa/iot/modules/emeter.py +++ b/kasa/iot/modules/emeter.py @@ -24,6 +24,7 @@ def __init__(self, device: Device, module: str): unit="W", id="current_power_w", # for homeassistant backwards compat precision_hint=1, + category=Feature.Category.Primary, ) ) self._add_feature( @@ -35,6 +36,7 @@ def __init__(self, device: Device, module: str): unit="kWh", id="today_energy_kwh", # for homeassistant backwards compat precision_hint=3, + category=Feature.Category.Info, ) ) self._add_feature( @@ -45,6 +47,7 @@ def __init__(self, device: Device, module: str): container=self, unit="kWh", precision_hint=3, + category=Feature.Category.Info, ) ) self._add_feature( @@ -56,6 +59,7 @@ def __init__(self, device: Device, module: str): unit="kWh", id="total_energy_kwh", # for homeassistant backwards compat precision_hint=3, + category=Feature.Category.Info, ) ) self._add_feature( @@ -67,6 +71,7 @@ def __init__(self, device: Device, module: str): unit="V", id="voltage", # for homeassistant backwards compat precision_hint=1, + category=Feature.Category.Primary, ) ) self._add_feature( @@ -78,6 +83,7 @@ def __init__(self, device: Device, module: str): unit="A", id="current_a", # for homeassistant backwards compat precision_hint=2, + category=Feature.Category.Primary, ) ) diff --git a/kasa/smart/modules/autooffmodule.py b/kasa/smart/modules/autooffmodule.py index 8977719c4..c171adc5f 100644 --- a/kasa/smart/modules/autooffmodule.py +++ b/kasa/smart/modules/autooffmodule.py @@ -42,7 +42,11 @@ def __init__(self, device: SmartDevice, module: str): ) self._add_feature( Feature( - device, "Auto off at", container=self, attribute_getter="auto_off_at" + device, + "Auto off at", + container=self, + attribute_getter="auto_off_at", + category=Feature.Category.Info, ) ) diff --git a/kasa/smart/modules/battery.py b/kasa/smart/modules/battery.py index 20bca34b2..c9c965e94 100644 --- a/kasa/smart/modules/battery.py +++ b/kasa/smart/modules/battery.py @@ -26,6 +26,8 @@ def __init__(self, device: SmartDevice, module: str): container=self, attribute_getter="battery", icon="mdi:battery", + unit="%", + category=Feature.Category.Info, ) ) self._add_feature( @@ -36,6 +38,7 @@ def __init__(self, device: SmartDevice, module: str): attribute_getter="battery_low", icon="mdi:alert", type=Feature.Type.BinarySensor, + category=Feature.Category.Debug, ) ) diff --git a/kasa/smart/modules/cloudmodule.py b/kasa/smart/modules/cloudmodule.py index 55338f269..b7b229479 100644 --- a/kasa/smart/modules/cloudmodule.py +++ b/kasa/smart/modules/cloudmodule.py @@ -29,6 +29,7 @@ def __init__(self, device: SmartDevice, module: str): attribute_getter="is_connected", icon="mdi:cloud", type=Feature.Type.BinarySensor, + category=Feature.Category.Info, ) ) diff --git a/kasa/smart/modules/energymodule.py b/kasa/smart/modules/energymodule.py index 6a75299e2..0ab4b4a33 100644 --- a/kasa/smart/modules/energymodule.py +++ b/kasa/smart/modules/energymodule.py @@ -27,6 +27,7 @@ def __init__(self, device: SmartDevice, module: str): container=self, unit="W", precision_hint=1, + category=Feature.Category.Primary, ) ) self._add_feature( @@ -37,6 +38,7 @@ def __init__(self, device: SmartDevice, module: str): container=self, unit="Wh", precision_hint=2, + category=Feature.Category.Info, ) ) self._add_feature( @@ -47,6 +49,7 @@ def __init__(self, device: SmartDevice, module: str): container=self, unit="Wh", precision_hint=2, + category=Feature.Category.Info, ) ) diff --git a/kasa/smart/modules/firmware.py b/kasa/smart/modules/firmware.py index 5f0c8bb03..897a5bc22 100644 --- a/kasa/smart/modules/firmware.py +++ b/kasa/smart/modules/firmware.py @@ -66,6 +66,7 @@ def __init__(self, device: SmartDevice, module: str): container=self, attribute_getter="update_available", type=Feature.Type.BinarySensor, + category=Feature.Category.Info, ) ) diff --git a/kasa/smart/modules/humidity.py b/kasa/smart/modules/humidity.py index ad2bd8c96..40c819a16 100644 --- a/kasa/smart/modules/humidity.py +++ b/kasa/smart/modules/humidity.py @@ -27,6 +27,7 @@ def __init__(self, device: SmartDevice, module: str): attribute_getter="humidity", icon="mdi:water-percent", unit="%", + category=Feature.Category.Primary, ) ) self._add_feature( @@ -37,6 +38,7 @@ def __init__(self, device: SmartDevice, module: str): attribute_getter="humidity_warning", type=Feature.Type.BinarySensor, icon="mdi:alert", + category=Feature.Category.Debug, ) ) diff --git a/kasa/smart/modules/temperature.py b/kasa/smart/modules/temperature.py index 49ffe046d..bd8b2ee68 100644 --- a/kasa/smart/modules/temperature.py +++ b/kasa/smart/modules/temperature.py @@ -38,6 +38,7 @@ def __init__(self, device: SmartDevice, module: str): attribute_getter="temperature_warning", type=Feature.Type.BinarySensor, icon="mdi:alert", + category=Feature.Category.Debug, ) ) self._add_feature( diff --git a/kasa/smart/smartdevice.py b/kasa/smart/smartdevice.py index 98c5f7efe..890ac7d74 100644 --- a/kasa/smart/smartdevice.py +++ b/kasa/smart/smartdevice.py @@ -283,7 +283,7 @@ async def _initialize_features(self): attribute_getter=lambda x: x._info["overheated"], icon="mdi:heat-wave", type=Feature.Type.BinarySensor, - category=Feature.Category.Debug, + category=Feature.Category.Info, ) ) @@ -296,7 +296,7 @@ async def _initialize_features(self): name="On since", attribute_getter="on_since", icon="mdi:clock", - category=Feature.Category.Debug, + category=Feature.Category.Info, ) ) From 681f7ac341f759eb3ba73e394d1d2e38f537e59f Mon Sep 17 00:00:00 2001 From: Teemu Rytilahti Date: Tue, 7 May 2024 02:04:43 +0200 Subject: [PATCH 2/5] Make 'id' mandatory for features --- kasa/feature.py | 5 ++--- kasa/iot/iotbulb.py | 2 ++ kasa/iot/iotdevice.py | 2 ++ kasa/iot/iotdimmer.py | 1 + kasa/iot/iotplug.py | 1 + kasa/iot/modules/ambientlight.py | 1 + kasa/iot/modules/cloud.py | 1 + kasa/iot/modules/emeter.py | 1 + kasa/smart/modules/alarmmodule.py | 18 ++++++++++++------ kasa/smart/modules/autooffmodule.py | 9 ++++++--- kasa/smart/modules/battery.py | 2 ++ kasa/smart/modules/brightness.py | 3 ++- kasa/smart/modules/cloudmodule.py | 3 ++- kasa/smart/modules/colormodule.py | 1 + kasa/smart/modules/colortemp.py | 1 + kasa/smart/modules/energymodule.py | 3 +++ kasa/smart/modules/fanmodule.py | 6 ++++-- kasa/smart/modules/firmware.py | 6 ++++-- kasa/smart/modules/frostprotection.py | 1 + kasa/smart/modules/humidity.py | 6 ++++-- kasa/smart/modules/ledmodule.py | 1 + kasa/smart/modules/lighteffectmodule.py | 3 ++- kasa/smart/modules/lighttransitionmodule.py | 7 +++++-- kasa/smart/modules/reportmodule.py | 3 ++- kasa/smart/modules/temperature.py | 9 ++++++--- kasa/smart/modules/temperaturecontrol.py | 12 ++++++++---- kasa/smart/modules/timemodule.py | 1 + kasa/smart/modules/waterleak.py | 6 ++++-- kasa/smart/smartdevice.py | 17 ++++++++++++----- kasa/tests/test_feature.py | 3 +++ 30 files changed, 97 insertions(+), 38 deletions(-) diff --git a/kasa/feature.py b/kasa/feature.py index 2000b21af..6b2dfa5e6 100644 --- a/kasa/feature.py +++ b/kasa/feature.py @@ -62,6 +62,8 @@ class Category(Enum): #: Device instance required for getting and setting values device: Device + #: Identifier + id: str #: User-friendly short description name: str #: Name of the property that allows accessing the value @@ -99,9 +101,6 @@ class Category(Enum): #: If set, this property will be used to set *choices*. choices_getter: str | None = None - #: Identifier - id: str | None = None - def __post_init__(self): """Handle late-binding of members.""" # Set id, if unset diff --git a/kasa/iot/iotbulb.py b/kasa/iot/iotbulb.py index d9456e969..6819d94ba 100644 --- a/kasa/iot/iotbulb.py +++ b/kasa/iot/iotbulb.py @@ -213,6 +213,7 @@ async def _initialize_features(self): self._add_feature( Feature( device=self, + id="brightness", name="Brightness", attribute_getter="brightness", attribute_setter="set_brightness", @@ -227,6 +228,7 @@ async def _initialize_features(self): self._add_feature( Feature( device=self, + id="color_temperature", name="Color temperature", container=self, attribute_getter="color_temp", diff --git a/kasa/iot/iotdevice.py b/kasa/iot/iotdevice.py index e69de80cd..29ba31554 100755 --- a/kasa/iot/iotdevice.py +++ b/kasa/iot/iotdevice.py @@ -334,6 +334,7 @@ async def _initialize_features(self): self._add_feature( Feature( device=self, + id="rssi", name="RSSI", attribute_getter="rssi", icon="mdi:signal", @@ -344,6 +345,7 @@ async def _initialize_features(self): self._add_feature( Feature( device=self, + id="on_since", name="On since", attribute_getter="on_since", icon="mdi:clock", diff --git a/kasa/iot/iotdimmer.py b/kasa/iot/iotdimmer.py index 0cbf49165..cfe937b8a 100644 --- a/kasa/iot/iotdimmer.py +++ b/kasa/iot/iotdimmer.py @@ -91,6 +91,7 @@ async def _initialize_features(self): self._add_feature( Feature( device=self, + id="brightness", name="Brightness", attribute_getter="brightness", attribute_setter="set_brightness", diff --git a/kasa/iot/iotplug.py b/kasa/iot/iotplug.py index ecf73e035..dadb38f2a 100644 --- a/kasa/iot/iotplug.py +++ b/kasa/iot/iotplug.py @@ -65,6 +65,7 @@ async def _initialize_features(self): self._add_feature( Feature( device=self, + id="led", name="LED", icon="mdi:led-{state}", attribute_getter="led", diff --git a/kasa/iot/modules/ambientlight.py b/kasa/iot/modules/ambientlight.py index ea8bfdf1f..d49768ef8 100644 --- a/kasa/iot/modules/ambientlight.py +++ b/kasa/iot/modules/ambientlight.py @@ -22,6 +22,7 @@ def __init__(self, device, module): Feature( device=device, container=self, + id="ambient_light", name="Ambient Light", icon="mdi:brightness-percent", attribute_getter="ambientlight_brightness", diff --git a/kasa/iot/modules/cloud.py b/kasa/iot/modules/cloud.py index 46dc6e0e3..5022a68e7 100644 --- a/kasa/iot/modules/cloud.py +++ b/kasa/iot/modules/cloud.py @@ -30,6 +30,7 @@ def __init__(self, device, module): Feature( device=device, container=self, + id="cloud_connection", name="Cloud connection", icon="mdi:cloud", attribute_getter="is_connected", diff --git a/kasa/iot/modules/emeter.py b/kasa/iot/modules/emeter.py index 6380ed1f3..53fb20da5 100644 --- a/kasa/iot/modules/emeter.py +++ b/kasa/iot/modules/emeter.py @@ -42,6 +42,7 @@ def __init__(self, device: Device, module: str): self._add_feature( Feature( device, + id="consumption_this_month", name="This month's consumption", attribute_getter="emeter_this_month", container=self, diff --git a/kasa/smart/modules/alarmmodule.py b/kasa/smart/modules/alarmmodule.py index a3c67ef2c..f42aacd09 100644 --- a/kasa/smart/modules/alarmmodule.py +++ b/kasa/smart/modules/alarmmodule.py @@ -27,7 +27,8 @@ def _initialize_features(self): self._add_feature( Feature( device, - "Alarm", + id="alarm", + name="Alarm", container=self, attribute_getter="active", icon="mdi:bell", @@ -37,7 +38,8 @@ def _initialize_features(self): self._add_feature( Feature( device, - "Alarm source", + id="alarm_source", + name="Alarm source", container=self, attribute_getter="source", icon="mdi:bell", @@ -46,7 +48,8 @@ def _initialize_features(self): self._add_feature( Feature( device, - "Alarm sound", + id="alarm_sound", + name="Alarm sound", container=self, attribute_getter="alarm_sound", attribute_setter="set_alarm_sound", @@ -58,7 +61,8 @@ def _initialize_features(self): self._add_feature( Feature( device, - "Alarm volume", + id="alarm_volume", + name="Alarm volume", container=self, attribute_getter="alarm_volume", attribute_setter="set_alarm_volume", @@ -70,7 +74,8 @@ def _initialize_features(self): self._add_feature( Feature( device, - "Test alarm", + id="test_alarm", + name="Test alarm", container=self, attribute_setter="play", type=Feature.Type.Action, @@ -79,7 +84,8 @@ def _initialize_features(self): self._add_feature( Feature( device, - "Stop alarm", + id="stop_alarm", + name="Stop alarm", container=self, attribute_setter="stop", type=Feature.Type.Action, diff --git a/kasa/smart/modules/autooffmodule.py b/kasa/smart/modules/autooffmodule.py index c171adc5f..cb8d5e57c 100644 --- a/kasa/smart/modules/autooffmodule.py +++ b/kasa/smart/modules/autooffmodule.py @@ -23,7 +23,8 @@ def __init__(self, device: SmartDevice, module: str): self._add_feature( Feature( device, - "Auto off enabled", + id="auto_off_enabled", + name="Auto off enabled", container=self, attribute_getter="enabled", attribute_setter="set_enabled", @@ -33,7 +34,8 @@ def __init__(self, device: SmartDevice, module: str): self._add_feature( Feature( device, - "Auto off minutes", + id="auto_off_minutes", + name="Auto off minutes", container=self, attribute_getter="delay", attribute_setter="set_delay", @@ -43,7 +45,8 @@ def __init__(self, device: SmartDevice, module: str): self._add_feature( Feature( device, - "Auto off at", + id="auto_off_at", + name="Auto off at", container=self, attribute_getter="auto_off_at", category=Feature.Category.Info, diff --git a/kasa/smart/modules/battery.py b/kasa/smart/modules/battery.py index c9c965e94..6f914bdf2 100644 --- a/kasa/smart/modules/battery.py +++ b/kasa/smart/modules/battery.py @@ -22,6 +22,7 @@ def __init__(self, device: SmartDevice, module: str): self._add_feature( Feature( device, + "battery_level", "Battery level", container=self, attribute_getter="battery", @@ -33,6 +34,7 @@ def __init__(self, device: SmartDevice, module: str): self._add_feature( Feature( device, + "battery_low", "Battery low", container=self, attribute_getter="battery_low", diff --git a/kasa/smart/modules/brightness.py b/kasa/smart/modules/brightness.py index b12098488..b0b58c077 100644 --- a/kasa/smart/modules/brightness.py +++ b/kasa/smart/modules/brightness.py @@ -25,7 +25,8 @@ def __init__(self, device: SmartDevice, module: str): self._add_feature( Feature( device, - "Brightness", + id="brightness", + name="Brightness", container=self, attribute_getter="brightness", attribute_setter="set_brightness", diff --git a/kasa/smart/modules/cloudmodule.py b/kasa/smart/modules/cloudmodule.py index b7b229479..8b9d8f418 100644 --- a/kasa/smart/modules/cloudmodule.py +++ b/kasa/smart/modules/cloudmodule.py @@ -24,7 +24,8 @@ def __init__(self, device: SmartDevice, module: str): self._add_feature( Feature( device, - "Cloud connection", + id="cloud_connection", + name="Cloud connection", container=self, attribute_getter="is_connected", icon="mdi:cloud", diff --git a/kasa/smart/modules/colormodule.py b/kasa/smart/modules/colormodule.py index 3adf0b4ef..716d4c444 100644 --- a/kasa/smart/modules/colormodule.py +++ b/kasa/smart/modules/colormodule.py @@ -22,6 +22,7 @@ def __init__(self, device: SmartDevice, module: str): self._add_feature( Feature( device, + "hsv", "HSV", container=self, attribute_getter="hsv", diff --git a/kasa/smart/modules/colortemp.py b/kasa/smart/modules/colortemp.py index 1392775cc..d6b43d029 100644 --- a/kasa/smart/modules/colortemp.py +++ b/kasa/smart/modules/colortemp.py @@ -28,6 +28,7 @@ def __init__(self, device: SmartDevice, module: str): self._add_feature( Feature( device, + "color_temperature", "Color temperature", container=self, attribute_getter="color_temp", diff --git a/kasa/smart/modules/energymodule.py b/kasa/smart/modules/energymodule.py index 0ab4b4a33..9cfe8cfb5 100644 --- a/kasa/smart/modules/energymodule.py +++ b/kasa/smart/modules/energymodule.py @@ -22,6 +22,7 @@ def __init__(self, device: SmartDevice, module: str): self._add_feature( Feature( device, + "consumption_current", name="Current consumption", attribute_getter="current_power", container=self, @@ -33,6 +34,7 @@ def __init__(self, device: SmartDevice, module: str): self._add_feature( Feature( device, + "consumption_today", name="Today's consumption", attribute_getter="emeter_today", container=self, @@ -44,6 +46,7 @@ def __init__(self, device: SmartDevice, module: str): self._add_feature( Feature( device, + "consumption_this_month", name="This month's consumption", attribute_getter="emeter_this_month", container=self, diff --git a/kasa/smart/modules/fanmodule.py b/kasa/smart/modules/fanmodule.py index 08a681e7e..6eeaa4d43 100644 --- a/kasa/smart/modules/fanmodule.py +++ b/kasa/smart/modules/fanmodule.py @@ -22,7 +22,8 @@ def __init__(self, device: SmartDevice, module: str): self._add_feature( Feature( device, - "Fan speed level", + id="fan_speed_level", + name="Fan speed level", container=self, attribute_getter="fan_speed_level", attribute_setter="set_fan_speed_level", @@ -36,7 +37,8 @@ def __init__(self, device: SmartDevice, module: str): self._add_feature( Feature( device, - "Fan sleep mode", + id="fan_sleep_mode", + name="Fan sleep mode", container=self, attribute_getter="sleep_mode", attribute_setter="set_sleep_mode", diff --git a/kasa/smart/modules/firmware.py b/kasa/smart/modules/firmware.py index 897a5bc22..626add0f6 100644 --- a/kasa/smart/modules/firmware.py +++ b/kasa/smart/modules/firmware.py @@ -52,7 +52,8 @@ def __init__(self, device: SmartDevice, module: str): self._add_feature( Feature( device, - "Auto update enabled", + id="auto_update_enabled", + name="Auto update enabled", container=self, attribute_getter="auto_update_enabled", attribute_setter="set_auto_update_enabled", @@ -62,7 +63,8 @@ def __init__(self, device: SmartDevice, module: str): self._add_feature( Feature( device, - "Update available", + id="update_available", + name="Update available", container=self, attribute_getter="update_available", type=Feature.Type.BinarySensor, diff --git a/kasa/smart/modules/frostprotection.py b/kasa/smart/modules/frostprotection.py index 07363279c..cedaf78be 100644 --- a/kasa/smart/modules/frostprotection.py +++ b/kasa/smart/modules/frostprotection.py @@ -27,6 +27,7 @@ def __init__(self, device: SmartDevice, module: str): self._add_feature( Feature( device, + "frost_protection_enabled", name="Frost protection enabled", container=self, attribute_getter="enabled", diff --git a/kasa/smart/modules/humidity.py b/kasa/smart/modules/humidity.py index 40c819a16..ec7d51a7a 100644 --- a/kasa/smart/modules/humidity.py +++ b/kasa/smart/modules/humidity.py @@ -22,7 +22,8 @@ def __init__(self, device: SmartDevice, module: str): self._add_feature( Feature( device, - "Humidity", + id="humidity", + name="Humidity", container=self, attribute_getter="humidity", icon="mdi:water-percent", @@ -33,7 +34,8 @@ def __init__(self, device: SmartDevice, module: str): self._add_feature( Feature( device, - "Humidity warning", + id="humidity_warning", + name="Humidity warning", container=self, attribute_getter="humidity_warning", type=Feature.Type.BinarySensor, diff --git a/kasa/smart/modules/ledmodule.py b/kasa/smart/modules/ledmodule.py index 6fd0d637d..e31131590 100644 --- a/kasa/smart/modules/ledmodule.py +++ b/kasa/smart/modules/ledmodule.py @@ -23,6 +23,7 @@ def __init__(self, device: SmartDevice, module: str): Feature( device=device, container=self, + id="led", name="LED", icon="mdi:led-{state}", attribute_getter="led", diff --git a/kasa/smart/modules/lighteffectmodule.py b/kasa/smart/modules/lighteffectmodule.py index 7f03b8ff6..bd0eea0ad 100644 --- a/kasa/smart/modules/lighteffectmodule.py +++ b/kasa/smart/modules/lighteffectmodule.py @@ -34,7 +34,8 @@ def _initialize_features(self): self._add_feature( Feature( device, - "Light effect", + id="light_effect", + name="Light effect", container=self, attribute_getter="effect", attribute_setter="set_effect", diff --git a/kasa/smart/modules/lighttransitionmodule.py b/kasa/smart/modules/lighttransitionmodule.py index 1cb7f48a6..f213d9ac1 100644 --- a/kasa/smart/modules/lighttransitionmodule.py +++ b/kasa/smart/modules/lighttransitionmodule.py @@ -31,6 +31,7 @@ def _create_features(self): Feature( device=self._device, container=self, + id="smooth_transitions", name="Smooth transitions", icon=icon, attribute_getter="enabled_v1", @@ -46,7 +47,8 @@ def _create_features(self): self._add_feature( Feature( self._device, - "Smooth transition on", + id="smooth_transition_on", + name="Smooth transition on", container=self, attribute_getter="turn_on_transition", attribute_setter="set_turn_on_transition", @@ -58,7 +60,8 @@ def _create_features(self): self._add_feature( Feature( self._device, - "Smooth transition off", + id="smooth_transition_off", + name="Smooth transition off", container=self, attribute_getter="turn_off_transition", attribute_setter="set_turn_off_transition", diff --git a/kasa/smart/modules/reportmodule.py b/kasa/smart/modules/reportmodule.py index 99d95fec1..16827a8c5 100644 --- a/kasa/smart/modules/reportmodule.py +++ b/kasa/smart/modules/reportmodule.py @@ -22,7 +22,8 @@ def __init__(self, device: SmartDevice, module: str): self._add_feature( Feature( device, - "Report interval", + id="report_interval", + name="Report interval", container=self, attribute_getter="report_interval", category=Feature.Category.Debug, diff --git a/kasa/smart/modules/temperature.py b/kasa/smart/modules/temperature.py index bd8b2ee68..4880fc301 100644 --- a/kasa/smart/modules/temperature.py +++ b/kasa/smart/modules/temperature.py @@ -22,7 +22,8 @@ def __init__(self, device: SmartDevice, module: str): self._add_feature( Feature( device, - "Temperature", + id="temperature", + name="Temperature", container=self, attribute_getter="temperature", icon="mdi:thermometer", @@ -33,7 +34,8 @@ def __init__(self, device: SmartDevice, module: str): self._add_feature( Feature( device, - "Temperature warning", + id="temperature_warning", + name="Temperature warning", container=self, attribute_getter="temperature_warning", type=Feature.Type.BinarySensor, @@ -44,7 +46,8 @@ def __init__(self, device: SmartDevice, module: str): self._add_feature( Feature( device, - "Temperature unit", + id="temperature_unit", + name="Temperature unit", container=self, attribute_getter="temperature_unit", attribute_setter="set_temperature_unit", diff --git a/kasa/smart/modules/temperaturecontrol.py b/kasa/smart/modules/temperaturecontrol.py index 69847002b..ae487bdf2 100644 --- a/kasa/smart/modules/temperaturecontrol.py +++ b/kasa/smart/modules/temperaturecontrol.py @@ -36,7 +36,8 @@ def __init__(self, device: SmartDevice, module: str): self._add_feature( Feature( device, - "Target temperature", + id="target_temperature", + name="Target temperature", container=self, attribute_getter="target_temperature", attribute_setter="set_target_temperature", @@ -50,7 +51,8 @@ def __init__(self, device: SmartDevice, module: str): self._add_feature( Feature( device, - "Temperature offset", + id="temperature_offset", + name="Temperature offset", container=self, attribute_getter="temperature_offset", attribute_setter="set_temperature_offset", @@ -64,7 +66,8 @@ def __init__(self, device: SmartDevice, module: str): self._add_feature( Feature( device, - "State", + id="state", + name="State", container=self, attribute_getter="state", attribute_setter="set_state", @@ -76,7 +79,8 @@ def __init__(self, device: SmartDevice, module: str): self._add_feature( Feature( device, - "Mode", + id="mode", + name="Mode", container=self, attribute_getter="mode", category=Feature.Category.Primary, diff --git a/kasa/smart/modules/timemodule.py b/kasa/smart/modules/timemodule.py index 80f1308e5..23814f571 100644 --- a/kasa/smart/modules/timemodule.py +++ b/kasa/smart/modules/timemodule.py @@ -25,6 +25,7 @@ def __init__(self, device: SmartDevice, module: str): self._add_feature( Feature( device=device, + id="time", name="Time", attribute_getter="time", container=self, diff --git a/kasa/smart/modules/waterleak.py b/kasa/smart/modules/waterleak.py index 1809c5560..019dadc9a 100644 --- a/kasa/smart/modules/waterleak.py +++ b/kasa/smart/modules/waterleak.py @@ -30,7 +30,8 @@ def __init__(self, device: SmartDevice, module: str): self._add_feature( Feature( device, - "Water leak", + id="water_leak", + name="Water leak", container=self, attribute_getter="status", icon="mdi:water", @@ -39,7 +40,8 @@ def __init__(self, device: SmartDevice, module: str): self._add_feature( Feature( device, - "Water alert", + id="water_alert", + name="Water alert", container=self, attribute_getter="alert", icon="mdi:water-alert", diff --git a/kasa/smart/smartdevice.py b/kasa/smart/smartdevice.py index 890ac7d74..194426206 100644 --- a/kasa/smart/smartdevice.py +++ b/kasa/smart/smartdevice.py @@ -225,7 +225,8 @@ async def _initialize_features(self): self._add_feature( Feature( self, - "Device ID", + id="device_id", + name="Device ID", attribute_getter="device_id", category=Feature.Category.Debug, ) @@ -234,7 +235,8 @@ async def _initialize_features(self): self._add_feature( Feature( self, - "State", + id="state", + name="State", attribute_getter="is_on", attribute_setter="set_state", type=Feature.Type.Switch, @@ -246,7 +248,8 @@ async def _initialize_features(self): self._add_feature( Feature( self, - "Signal Level", + id="signal_level", + name="Signal Level", attribute_getter=lambda x: x._info["signal_level"], icon="mdi:signal", category=Feature.Category.Info, @@ -257,7 +260,8 @@ async def _initialize_features(self): self._add_feature( Feature( self, - "RSSI", + id="rssi", + name="RSSI", attribute_getter=lambda x: x._info["rssi"], icon="mdi:signal", category=Feature.Category.Debug, @@ -268,6 +272,7 @@ async def _initialize_features(self): self._add_feature( Feature( device=self, + id="ssid", name="SSID", attribute_getter="ssid", icon="mdi:wifi", @@ -279,7 +284,8 @@ async def _initialize_features(self): self._add_feature( Feature( self, - "Overheated", + id="overheated", + name="Overheated", attribute_getter=lambda x: x._info["overheated"], icon="mdi:heat-wave", type=Feature.Type.BinarySensor, @@ -293,6 +299,7 @@ async def _initialize_features(self): self._add_feature( Feature( device=self, + id="on_since", name="On since", attribute_getter="on_since", icon="mdi:clock", diff --git a/kasa/tests/test_feature.py b/kasa/tests/test_feature.py index fe6ba7f21..101a21c0a 100644 --- a/kasa/tests/test_feature.py +++ b/kasa/tests/test_feature.py @@ -19,6 +19,7 @@ def dummy_feature() -> Feature: feat = Feature( device=DummyDevice(), # type: ignore[arg-type] + id="dummy_feature", name="dummy_feature", attribute_getter="dummygetter", attribute_setter="dummysetter", @@ -47,6 +48,7 @@ def test_feature_missing_type(): with pytest.raises(ValueError): Feature( device=DummyDevice(), # type: ignore[arg-type] + id="dummy_error", name="dummy error", attribute_getter="dummygetter", attribute_setter="dummysetter", @@ -104,6 +106,7 @@ async def test_feature_action(mocker): """Test that setting value on button calls the setter.""" feat = Feature( device=DummyDevice(), # type: ignore[arg-type] + id="dummy_feature", name="dummy_feature", attribute_setter="call_action", container=None, From dd46103da2f5123092129d650888135ae6d03f39 Mon Sep 17 00:00:00 2001 From: Teemu Rytilahti Date: Tue, 7 May 2024 02:31:35 +0200 Subject: [PATCH 3/5] Remove unnecessary id generation --- kasa/feature.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/kasa/feature.py b/kasa/feature.py index 6b2dfa5e6..3d0702134 100644 --- a/kasa/feature.py +++ b/kasa/feature.py @@ -103,10 +103,6 @@ class Category(Enum): def __post_init__(self): """Handle late-binding of members.""" - # Set id, if unset - if self.id is None: - self.id = self.name.lower().replace(" ", "_") - # Populate minimum & maximum values, if range_getter is given container = self.container if self.container is not None else self.device if self.range_getter is not None: From d7f024d237b4f9f4f7b76f49128eac50d647d2f8 Mon Sep 17 00:00:00 2001 From: Teemu Rytilahti Date: Tue, 7 May 2024 02:40:40 +0200 Subject: [PATCH 4/5] Add category to waterleak sensor, alert being the primary given its the main function of the sensor --- kasa/smart/modules/waterleak.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kasa/smart/modules/waterleak.py b/kasa/smart/modules/waterleak.py index 019dadc9a..6dbc00eb3 100644 --- a/kasa/smart/modules/waterleak.py +++ b/kasa/smart/modules/waterleak.py @@ -35,6 +35,7 @@ def __init__(self, device: SmartDevice, module: str): container=self, attribute_getter="status", icon="mdi:water", + category=Feature.Category.Debug, ) ) self._add_feature( @@ -45,6 +46,7 @@ def __init__(self, device: SmartDevice, module: str): container=self, attribute_getter="alert", icon="mdi:water-alert", + category=Feature.Category.Primary, ) ) From 96bab0b490aa3b976d7c2af7ffab6cdb9e083789 Mon Sep 17 00:00:00 2001 From: Teemu Rytilahti Date: Tue, 7 May 2024 02:59:49 +0200 Subject: [PATCH 5/5] Use feature id for module features --- kasa/module.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/kasa/module.py b/kasa/module.py index 5b6354a9c..3da0c1ad2 100644 --- a/kasa/module.py +++ b/kasa/module.py @@ -53,14 +53,10 @@ def _initialize_features(self): # noqa: B027 def _add_feature(self, feature: Feature): """Add module feature.""" - - def _slugified_name(name): - return name.lower().replace(" ", "_").replace("'", "_") - - feat_name = _slugified_name(feature.name) - if feat_name in self._module_features: - raise KasaException("Duplicate name detected %s" % feat_name) - self._module_features[feat_name] = feature + id_ = feature.id + if id_ in self._module_features: + raise KasaException("Duplicate id detected %s" % id_) + self._module_features[id_] = feature def __repr__(self) -> str: return (