From f6d2c2848df7de644b5fe8cac32546c9347270c2 Mon Sep 17 00:00:00 2001 From: Adrian Dorr Date: Sat, 20 Apr 2024 11:54:37 +0100 Subject: [PATCH 1/4] Added support for kasa hub. Just needed device type mapping --- kasa/device_factory.py | 1 + kasa/deviceconfig.py | 1 + 2 files changed, 2 insertions(+) diff --git a/kasa/device_factory.py b/kasa/device_factory.py index 3c0ae7164..29cc36ffd 100755 --- a/kasa/device_factory.py +++ b/kasa/device_factory.py @@ -166,6 +166,7 @@ def get_device_class_from_family(device_type: str) -> type[Device] | None: "SMART.TAPOSWITCH": SmartBulb, "SMART.KASAPLUG": SmartDevice, "SMART.TAPOHUB": SmartDevice, + "SMART.KASAHUB": SmartDevice, "SMART.KASASWITCH": SmartBulb, "IOT.SMARTPLUGSWITCH": IotPlug, "IOT.SMARTBULB": IotBulb, diff --git a/kasa/deviceconfig.py b/kasa/deviceconfig.py index 6ddff6ade..4144b784d 100644 --- a/kasa/deviceconfig.py +++ b/kasa/deviceconfig.py @@ -39,6 +39,7 @@ class DeviceFamilyType(Enum): SmartTapoBulb = "SMART.TAPOBULB" SmartTapoSwitch = "SMART.TAPOSWITCH" SmartTapoHub = "SMART.TAPOHUB" + SmartKasaHub = "SMART.KASAHUB" def _dataclass_from_dict(klass, in_val): From 80f133e39de6dd9732aae29d0be0d7fd37550d9b Mon Sep 17 00:00:00 2001 From: Adrian Dorr Date: Sat, 20 Apr 2024 11:56:10 +0100 Subject: [PATCH 2/4] Added test fixtures for KH100 kasa hub, KE100 thermostatic valves and T310 thermostat sensor --- .../fixtures/smart/KH100(UK)_1.0_1.5.6.json | 1557 +++++++++++++++++ .../smart/child/KE100(EU)_1.0_2.8.0.json | 59 + .../smart/child/KE100(UK)_1.0_2.8.0.json | 59 + .../smart/child/T310(EU)_1.0_1.5.0.json | 454 +++++ 4 files changed, 2129 insertions(+) create mode 100644 kasa/tests/fixtures/smart/KH100(UK)_1.0_1.5.6.json create mode 100644 kasa/tests/fixtures/smart/child/KE100(EU)_1.0_2.8.0.json create mode 100644 kasa/tests/fixtures/smart/child/KE100(UK)_1.0_2.8.0.json create mode 100644 kasa/tests/fixtures/smart/child/T310(EU)_1.0_1.5.0.json diff --git a/kasa/tests/fixtures/smart/KH100(UK)_1.0_1.5.6.json b/kasa/tests/fixtures/smart/KH100(UK)_1.0_1.5.6.json new file mode 100644 index 000000000..d9ca8e3de --- /dev/null +++ b/kasa/tests/fixtures/smart/KH100(UK)_1.0_1.5.6.json @@ -0,0 +1,1557 @@ + { + "component_nego": { + "component_list": [ + { + "id": "device", + "ver_code": 2 + }, + { + "id": "firmware", + "ver_code": 2 + }, + { + "id": "quick_setup", + "ver_code": 3 + }, + { + "id": "inherit", + "ver_code": 1 + }, + { + "id": "time", + "ver_code": 1 + }, + { + "id": "wireless", + "ver_code": 1 + }, + { + "id": "account", + "ver_code": 1 + }, + { + "id": "synchronize", + "ver_code": 1 + }, + { + "id": "sunrise_sunset", + "ver_code": 1 + }, + { + "id": "led", + "ver_code": 1 + }, + { + "id": "cloud_connect", + "ver_code": 1 + }, + { + "id": "iot_cloud", + "ver_code": 1 + }, + { + "id": "child_device", + "ver_code": 1 + }, + { + "id": "child_quick_setup", + "ver_code": 1 + }, + { + "id": "child_inherit", + "ver_code": 1 + }, + { + "id": "control_child", + "ver_code": 1 + }, + { + "id": "alarm", + "ver_code": 1 + }, + { + "id": "device_load", + "ver_code": 1 + }, + { + "id": "device_local_time", + "ver_code": 1 + }, + { + "id": "alarm_logs", + "ver_code": 1 + }, + { + "id": "localSmart", + "ver_code": 1 + } + ] + }, + "discovery_result": { + "device_id": "00000000000000000000000000000000", + "device_model": "KH100(UK)", + "device_type": "SMART.KASAHUB", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "F0-A7-31-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "AES", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + }, + "get_alarm_configure": { + "duration": 300, + "type": "Doorbell Ring 1", + "volume": "high" + }, + "get_auto_update_info": { + "enable": true, + "random_range": 120, + "time": 900 + }, + "get_child_device_component_list": { + "child_component_list": [ + { + "component_list": [ + { + "id": "device", + "ver_code": 2 + }, + { + "id": "quick_setup", + "ver_code": 3 + }, + { + "id": "trigger_log", + "ver_code": 1 + }, + { + "id": "time", + "ver_code": 1 + }, + { + "id": "device_local_time", + "ver_code": 1 + }, + { + "id": "account", + "ver_code": 1 + }, + { + "id": "synchronize", + "ver_code": 1 + }, + { + "id": "cloud_connect", + "ver_code": 1 + }, + { + "id": "iot_cloud", + "ver_code": 1 + }, + { + "id": "firmware", + "ver_code": 1 + }, + { + "id": "localSmart", + "ver_code": 1 + }, + { + "id": "battery_detect", + "ver_code": 1 + }, + { + "id": "temperature", + "ver_code": 1 + }, + { + "id": "humidity", + "ver_code": 1 + }, + { + "id": "temp_humidity_record", + "ver_code": 1 + }, + { + "id": "comfort_temperature", + "ver_code": 1 + }, + { + "id": "comfort_humidity", + "ver_code": 1 + }, + { + "id": "report_mode", + "ver_code": 1 + } + ], + "device_id": "SCRUBBED_CHILD_DEVICE_ID_1" + }, + { + "component_list": [ + { + "id": "device", + "ver_code": 2 + }, + { + "id": "quick_setup", + "ver_code": 3 + }, + { + "id": "trigger_log", + "ver_code": 1 + }, + { + "id": "time", + "ver_code": 1 + }, + { + "id": "device_local_time", + "ver_code": 1 + }, + { + "id": "account", + "ver_code": 1 + }, + { + "id": "synchronize", + "ver_code": 1 + }, + { + "id": "cloud_connect", + "ver_code": 1 + }, + { + "id": "iot_cloud", + "ver_code": 1 + }, + { + "id": "firmware", + "ver_code": 1 + }, + { + "id": "localSmart", + "ver_code": 1 + }, + { + "id": "battery_detect", + "ver_code": 1 + }, + { + "id": "temperature", + "ver_code": 1 + }, + { + "id": "humidity", + "ver_code": 1 + }, + { + "id": "temp_humidity_record", + "ver_code": 1 + }, + { + "id": "comfort_temperature", + "ver_code": 1 + }, + { + "id": "comfort_humidity", + "ver_code": 1 + }, + { + "id": "report_mode", + "ver_code": 1 + } + ], + "device_id": "SCRUBBED_CHILD_DEVICE_ID_2" + }, + { + "component_list": [ + { + "id": "device", + "ver_code": 2 + }, + { + "id": "quick_setup", + "ver_code": 3 + }, + { + "id": "time", + "ver_code": 1 + }, + { + "id": "device_local_time", + "ver_code": 1 + }, + { + "id": "schedule", + "ver_code": 2 + }, + { + "id": "countdown", + "ver_code": 2 + }, + { + "id": "account", + "ver_code": 1 + }, + { + "id": "synchronize", + "ver_code": 1 + }, + { + "id": "sunrise_sunset", + "ver_code": 1 + }, + { + "id": "cloud_connect", + "ver_code": 1 + }, + { + "id": "iot_cloud", + "ver_code": 1 + }, + { + "id": "frost_protection", + "ver_code": 1 + }, + { + "id": "child_protection", + "ver_code": 1 + }, + { + "id": "temperature", + "ver_code": 1 + }, + { + "id": "temp_control", + "ver_code": 1 + }, + { + "id": "remove_scale", + "ver_code": 1 + }, + { + "id": "shutdown_mode", + "ver_code": 1 + }, + { + "id": "progress_calibration", + "ver_code": 1 + }, + { + "id": "early_start", + "ver_code": 1 + }, + { + "id": "temp_record", + "ver_code": 1 + }, + { + "id": "screen_setting", + "ver_code": 1 + }, + { + "id": "night_mode", + "ver_code": 1 + }, + { + "id": "smart_control_schedule", + "ver_code": 1 + }, + { + "id": "firmware", + "ver_code": 1 + }, + { + "id": "battery_detect", + "ver_code": 1 + }, + { + "id": "temperature_correction", + "ver_code": 1 + }, + { + "id": "window_open_detect", + "ver_code": 2 + } + ], + "device_id": "SCRUBBED_CHILD_DEVICE_ID_3" + }, + { + "component_list": [ + { + "id": "device", + "ver_code": 2 + }, + { + "id": "quick_setup", + "ver_code": 3 + }, + { + "id": "time", + "ver_code": 1 + }, + { + "id": "device_local_time", + "ver_code": 1 + }, + { + "id": "schedule", + "ver_code": 2 + }, + { + "id": "countdown", + "ver_code": 2 + }, + { + "id": "account", + "ver_code": 1 + }, + { + "id": "synchronize", + "ver_code": 1 + }, + { + "id": "sunrise_sunset", + "ver_code": 1 + }, + { + "id": "cloud_connect", + "ver_code": 1 + }, + { + "id": "iot_cloud", + "ver_code": 1 + }, + { + "id": "frost_protection", + "ver_code": 1 + }, + { + "id": "child_protection", + "ver_code": 1 + }, + { + "id": "temperature", + "ver_code": 1 + }, + { + "id": "temp_control", + "ver_code": 1 + }, + { + "id": "remove_scale", + "ver_code": 1 + }, + { + "id": "shutdown_mode", + "ver_code": 1 + }, + { + "id": "progress_calibration", + "ver_code": 1 + }, + { + "id": "early_start", + "ver_code": 1 + }, + { + "id": "temp_record", + "ver_code": 1 + }, + { + "id": "screen_setting", + "ver_code": 1 + }, + { + "id": "night_mode", + "ver_code": 1 + }, + { + "id": "smart_control_schedule", + "ver_code": 1 + }, + { + "id": "firmware", + "ver_code": 1 + }, + { + "id": "battery_detect", + "ver_code": 1 + }, + { + "id": "temperature_correction", + "ver_code": 1 + }, + { + "id": "window_open_detect", + "ver_code": 2 + } + ], + "device_id": "SCRUBBED_CHILD_DEVICE_ID_4" + }, + { + "component_list": [ + { + "id": "device", + "ver_code": 2 + }, + { + "id": "quick_setup", + "ver_code": 3 + }, + { + "id": "time", + "ver_code": 1 + }, + { + "id": "device_local_time", + "ver_code": 1 + }, + { + "id": "schedule", + "ver_code": 2 + }, + { + "id": "countdown", + "ver_code": 2 + }, + { + "id": "account", + "ver_code": 1 + }, + { + "id": "synchronize", + "ver_code": 1 + }, + { + "id": "sunrise_sunset", + "ver_code": 1 + }, + { + "id": "cloud_connect", + "ver_code": 1 + }, + { + "id": "iot_cloud", + "ver_code": 1 + }, + { + "id": "frost_protection", + "ver_code": 1 + }, + { + "id": "child_protection", + "ver_code": 1 + }, + { + "id": "temperature", + "ver_code": 1 + }, + { + "id": "temp_control", + "ver_code": 1 + }, + { + "id": "remove_scale", + "ver_code": 1 + }, + { + "id": "shutdown_mode", + "ver_code": 1 + }, + { + "id": "progress_calibration", + "ver_code": 1 + }, + { + "id": "early_start", + "ver_code": 1 + }, + { + "id": "temp_record", + "ver_code": 1 + }, + { + "id": "screen_setting", + "ver_code": 1 + }, + { + "id": "night_mode", + "ver_code": 1 + }, + { + "id": "smart_control_schedule", + "ver_code": 1 + }, + { + "id": "firmware", + "ver_code": 1 + }, + { + "id": "battery_detect", + "ver_code": 1 + }, + { + "id": "temperature_correction", + "ver_code": 1 + }, + { + "id": "window_open_detect", + "ver_code": 2 + } + ], + "device_id": "SCRUBBED_CHILD_DEVICE_ID_5" + }, + { + "component_list": [ + { + "id": "device", + "ver_code": 2 + }, + { + "id": "quick_setup", + "ver_code": 3 + }, + { + "id": "time", + "ver_code": 1 + }, + { + "id": "device_local_time", + "ver_code": 1 + }, + { + "id": "schedule", + "ver_code": 2 + }, + { + "id": "countdown", + "ver_code": 2 + }, + { + "id": "account", + "ver_code": 1 + }, + { + "id": "synchronize", + "ver_code": 1 + }, + { + "id": "sunrise_sunset", + "ver_code": 1 + }, + { + "id": "cloud_connect", + "ver_code": 1 + }, + { + "id": "iot_cloud", + "ver_code": 1 + }, + { + "id": "frost_protection", + "ver_code": 1 + }, + { + "id": "child_protection", + "ver_code": 1 + }, + { + "id": "temperature", + "ver_code": 1 + }, + { + "id": "temp_control", + "ver_code": 1 + }, + { + "id": "remove_scale", + "ver_code": 1 + }, + { + "id": "shutdown_mode", + "ver_code": 1 + }, + { + "id": "progress_calibration", + "ver_code": 1 + }, + { + "id": "early_start", + "ver_code": 1 + }, + { + "id": "temp_record", + "ver_code": 1 + }, + { + "id": "screen_setting", + "ver_code": 1 + }, + { + "id": "night_mode", + "ver_code": 1 + }, + { + "id": "smart_control_schedule", + "ver_code": 1 + }, + { + "id": "firmware", + "ver_code": 1 + }, + { + "id": "battery_detect", + "ver_code": 1 + }, + { + "id": "temperature_correction", + "ver_code": 1 + }, + { + "id": "window_open_detect", + "ver_code": 2 + } + ], + "device_id": "SCRUBBED_CHILD_DEVICE_ID_6" + }, + { + "component_list": [ + { + "id": "device", + "ver_code": 2 + }, + { + "id": "quick_setup", + "ver_code": 3 + }, + { + "id": "time", + "ver_code": 1 + }, + { + "id": "device_local_time", + "ver_code": 1 + }, + { + "id": "schedule", + "ver_code": 2 + }, + { + "id": "countdown", + "ver_code": 2 + }, + { + "id": "account", + "ver_code": 1 + }, + { + "id": "synchronize", + "ver_code": 1 + }, + { + "id": "sunrise_sunset", + "ver_code": 1 + }, + { + "id": "cloud_connect", + "ver_code": 1 + }, + { + "id": "iot_cloud", + "ver_code": 1 + }, + { + "id": "frost_protection", + "ver_code": 1 + }, + { + "id": "child_protection", + "ver_code": 1 + }, + { + "id": "temperature", + "ver_code": 1 + }, + { + "id": "temp_control", + "ver_code": 1 + }, + { + "id": "remove_scale", + "ver_code": 1 + }, + { + "id": "shutdown_mode", + "ver_code": 1 + }, + { + "id": "progress_calibration", + "ver_code": 1 + }, + { + "id": "early_start", + "ver_code": 1 + }, + { + "id": "temp_record", + "ver_code": 1 + }, + { + "id": "screen_setting", + "ver_code": 1 + }, + { + "id": "night_mode", + "ver_code": 1 + }, + { + "id": "smart_control_schedule", + "ver_code": 1 + }, + { + "id": "firmware", + "ver_code": 1 + }, + { + "id": "battery_detect", + "ver_code": 1 + }, + { + "id": "temperature_correction", + "ver_code": 1 + }, + { + "id": "window_open_detect", + "ver_code": 2 + } + ], + "device_id": "SCRUBBED_CHILD_DEVICE_ID_7" + }, + { + "component_list": [ + { + "id": "device", + "ver_code": 2 + }, + { + "id": "quick_setup", + "ver_code": 3 + }, + { + "id": "trigger_log", + "ver_code": 1 + }, + { + "id": "time", + "ver_code": 1 + }, + { + "id": "device_local_time", + "ver_code": 1 + }, + { + "id": "account", + "ver_code": 1 + }, + { + "id": "synchronize", + "ver_code": 1 + }, + { + "id": "cloud_connect", + "ver_code": 1 + }, + { + "id": "iot_cloud", + "ver_code": 1 + }, + { + "id": "firmware", + "ver_code": 1 + }, + { + "id": "localSmart", + "ver_code": 1 + }, + { + "id": "battery_detect", + "ver_code": 1 + }, + { + "id": "temperature", + "ver_code": 1 + }, + { + "id": "humidity", + "ver_code": 1 + }, + { + "id": "temp_humidity_record", + "ver_code": 1 + }, + { + "id": "comfort_temperature", + "ver_code": 1 + }, + { + "id": "comfort_humidity", + "ver_code": 1 + }, + { + "id": "report_mode", + "ver_code": 1 + } + ], + "device_id": "SCRUBBED_CHILD_DEVICE_ID_8" + }, + { + "component_list": [ + { + "id": "device", + "ver_code": 2 + }, + { + "id": "quick_setup", + "ver_code": 3 + }, + { + "id": "trigger_log", + "ver_code": 1 + }, + { + "id": "time", + "ver_code": 1 + }, + { + "id": "device_local_time", + "ver_code": 1 + }, + { + "id": "account", + "ver_code": 1 + }, + { + "id": "synchronize", + "ver_code": 1 + }, + { + "id": "cloud_connect", + "ver_code": 1 + }, + { + "id": "iot_cloud", + "ver_code": 1 + }, + { + "id": "firmware", + "ver_code": 1 + }, + { + "id": "localSmart", + "ver_code": 1 + }, + { + "id": "battery_detect", + "ver_code": 1 + }, + { + "id": "temperature", + "ver_code": 1 + }, + { + "id": "humidity", + "ver_code": 1 + }, + { + "id": "temp_humidity_record", + "ver_code": 1 + }, + { + "id": "comfort_temperature", + "ver_code": 1 + }, + { + "id": "comfort_humidity", + "ver_code": 1 + }, + { + "id": "report_mode", + "ver_code": 1 + } + ], + "device_id": "SCRUBBED_CHILD_DEVICE_ID_9" + }, + { + "component_list": [ + { + "id": "device", + "ver_code": 2 + }, + { + "id": "quick_setup", + "ver_code": 3 + }, + { + "id": "trigger_log", + "ver_code": 1 + }, + { + "id": "time", + "ver_code": 1 + }, + { + "id": "device_local_time", + "ver_code": 1 + }, + { + "id": "account", + "ver_code": 1 + }, + { + "id": "synchronize", + "ver_code": 1 + }, + { + "id": "cloud_connect", + "ver_code": 1 + }, + { + "id": "iot_cloud", + "ver_code": 1 + }, + { + "id": "firmware", + "ver_code": 1 + }, + { + "id": "localSmart", + "ver_code": 1 + }, + { + "id": "battery_detect", + "ver_code": 1 + }, + { + "id": "temperature", + "ver_code": 1 + }, + { + "id": "humidity", + "ver_code": 1 + }, + { + "id": "temp_humidity_record", + "ver_code": 1 + }, + { + "id": "comfort_temperature", + "ver_code": 1 + }, + { + "id": "comfort_humidity", + "ver_code": 1 + }, + { + "id": "report_mode", + "ver_code": 1 + } + ], + "device_id": "SCRUBBED_CHILD_DEVICE_ID_10" + } + ], + "start_index": 0, + "sum": 12 + }, + "get_child_device_list": { + "child_device_list": [ + { + "at_low_battery": false, + "avatar": "kasa_trv", + "bind_count": 1, + "category": "subg.trv", + "child_protection": false, + "current_temp": 20.1, + "device_id": "SCRUBBED_CHILD_DEVICE_ID_3", + "frost_protection_on": false, + "fw_ver": "2.8.0 Build 240202 Rel.135229", + "hw_id": "00000000000000000000000000000000", + "hw_ver": "1.0", + "jamming_rssi": -117, + "jamming_signal_level": 1, + "location": "", + "mac": "F0A731000000", + "max_control_temp": 30, + "min_control_temp": 5, + "model": "KE100", + "nickname": "I01BU0tFRF9OQU1FIw==", + "oem_id": "00000000000000000000000000000000", + "parent_device_id": "0000000000000000000000000000000000000000", + "region": "Europe/London", + "rssi": -45, + "signal_level": 3, + "specs": "UK", + "status": "online", + "status_follow_edge": false, + "target_temp": 21.0, + "temp_offset": 0, + "temp_unit": "celsius", + "trv_states": [ + "heating" + ], + "type": "SMART.KASAENERGY" + }, + { + "at_low_battery": false, + "avatar": "kasa_trv", + "bind_count": 1, + "category": "subg.trv", + "child_protection": false, + "current_temp": 19.5, + "device_id": "SCRUBBED_CHILD_DEVICE_ID_4", + "frost_protection_on": false, + "fw_ver": "2.8.0 Build 240202 Rel.135229", + "hw_id": "00000000000000000000000000000000", + "hw_ver": "1.0", + "jamming_rssi": -117, + "jamming_signal_level": 1, + "location": "", + "mac": "F0A731000000", + "max_control_temp": 30, + "min_control_temp": 5, + "model": "KE100", + "nickname": "I01BU0tFRF9OQU1FIw==", + "oem_id": "00000000000000000000000000000000", + "parent_device_id": "0000000000000000000000000000000000000000", + "region": "Europe/London", + "rssi": -52, + "signal_level": 3, + "specs": "EU", + "status": "online", + "status_follow_edge": false, + "target_temp": 21.0, + "temp_offset": 0, + "temp_unit": "celsius", + "trv_states": [ + "heating" + ], + "type": "SMART.KASAENERGY" + }, + { + "at_low_battery": false, + "avatar": "kasa_trv", + "bind_count": 1, + "category": "subg.trv", + "child_protection": false, + "current_temp": 18.1, + "device_id": "SCRUBBED_CHILD_DEVICE_ID_5", + "frost_protection_on": false, + "fw_ver": "2.8.0 Build 240202 Rel.135229", + "hw_id": "00000000000000000000000000000000", + "hw_ver": "1.0", + "jamming_rssi": -120, + "jamming_signal_level": 1, + "location": "", + "mac": "F0A731000000", + "max_control_temp": 30, + "min_control_temp": 5, + "model": "KE100", + "nickname": "I01BU0tFRF9OQU1FIw==", + "oem_id": "00000000000000000000000000000000", + "parent_device_id": "0000000000000000000000000000000000000000", + "region": "Europe/London", + "rssi": -46, + "signal_level": 3, + "specs": "EU", + "status": "online", + "status_follow_edge": false, + "target_temp": 21.0, + "temp_offset": 0, + "temp_unit": "celsius", + "trv_states": [ + "heating" + ], + "type": "SMART.KASAENERGY" + }, + { + "at_low_battery": false, + "avatar": "kasa_trv", + "bind_count": 1, + "category": "subg.trv", + "child_protection": false, + "current_temp": 20.0, + "device_id": "SCRUBBED_CHILD_DEVICE_ID_6", + "frost_protection_on": false, + "fw_ver": "2.8.0 Build 240202 Rel.135229", + "hw_id": "00000000000000000000000000000000", + "hw_ver": "1.0", + "jamming_rssi": -114, + "jamming_signal_level": 1, + "location": "", + "mac": "A842A1000000", + "max_control_temp": 30, + "min_control_temp": 5, + "model": "KE100", + "nickname": "I01BU0tFRF9OQU1FIw==", + "oem_id": "00000000000000000000000000000000", + "parent_device_id": "0000000000000000000000000000000000000000", + "region": "Europe/London", + "rssi": -40, + "signal_level": 3, + "specs": "EU", + "status": "online", + "status_follow_edge": false, + "target_temp": 21.0, + "temp_offset": 0, + "temp_unit": "celsius", + "trv_states": [ + "heating" + ], + "type": "SMART.KASAENERGY" + }, + { + "at_low_battery": false, + "avatar": "kasa_trv", + "bind_count": 1, + "category": "subg.trv", + "child_protection": false, + "current_temp": 19.2, + "device_id": "SCRUBBED_CHILD_DEVICE_ID_7", + "frost_protection_on": false, + "fw_ver": "2.8.0 Build 240202 Rel.135229", + "hw_id": "00000000000000000000000000000000", + "hw_ver": "1.0", + "jamming_rssi": -121, + "jamming_signal_level": 1, + "location": "", + "mac": "F0A731000000", + "max_control_temp": 30, + "min_control_temp": 5, + "model": "KE100", + "nickname": "I01BU0tFRF9OQU1FIw==", + "oem_id": "00000000000000000000000000000000", + "parent_device_id": "0000000000000000000000000000000000000000", + "region": "Europe/London", + "rssi": -73, + "signal_level": 2, + "specs": "EU", + "status": "online", + "status_follow_edge": false, + "target_temp": 21.0, + "temp_offset": 0, + "temp_unit": "celsius", + "trv_states": [ + "heating" + ], + "type": "SMART.KASAENERGY" + }, + { + "at_low_battery": false, + "avatar": "balcony", + "bind_count": 1, + "category": "subg.trigger.temp-hmdt-sensor", + "current_humidity": 63, + "current_humidity_exception": 3, + "current_temp": 11.9, + "current_temp_exception": -8.1, + "device_id": "SCRUBBED_CHILD_DEVICE_ID_1", + "fw_ver": "1.5.0 Build 230105 Rel.150707", + "hw_id": "00000000000000000000000000000000", + "hw_ver": "1.0", + "jamming_rssi": -118, + "jamming_signal_level": 1, + "lastOnboardingTimestamp": 1713199738, + "mac": "40AE30000000", + "model": "T310", + "nickname": "I01BU0tFRF9OQU1FIw==", + "oem_id": "00000000000000000000000000000000", + "parent_device_id": "0000000000000000000000000000000000000000", + "region": "Europe/London", + "report_interval": 16, + "rssi": -63, + "signal_level": 3, + "specs": "EU", + "status": "online", + "status_follow_edge": false, + "temp_unit": "celsius", + "type": "SMART.TAPOSENSOR" + }, + { + "at_low_battery": false, + "avatar": "sensor_t310", + "bind_count": 1, + "category": "subg.trigger.temp-hmdt-sensor", + "current_humidity": 54, + "current_humidity_exception": 0, + "current_temp": 19.1, + "current_temp_exception": -0.9, + "device_id": "SCRUBBED_CHILD_DEVICE_ID_2", + "fw_ver": "1.5.0 Build 230105 Rel.150707", + "hw_id": "00000000000000000000000000000000", + "hw_ver": "1.0", + "jamming_rssi": -123, + "jamming_signal_level": 1, + "lastOnboardingTimestamp": 1712755472, + "mac": "40AE30000000", + "model": "T310", + "nickname": "I01BU0tFRF9OQU1FIw==", + "oem_id": "00000000000000000000000000000000", + "parent_device_id": "0000000000000000000000000000000000000000", + "region": "Europe/London", + "report_interval": 16, + "rssi": -57, + "signal_level": 3, + "specs": "EU", + "status": "online", + "status_follow_edge": false, + "temp_unit": "celsius", + "type": "SMART.TAPOSENSOR" + }, + { + "at_low_battery": false, + "avatar": "sensor_t310", + "bind_count": 1, + "category": "subg.trigger.temp-hmdt-sensor", + "current_humidity": 52, + "current_humidity_exception": 0, + "current_temp": 20.0, + "current_temp_exception": 0, + "device_id": "SCRUBBED_CHILD_DEVICE_ID_8", + "fw_ver": "1.5.0 Build 230105 Rel.150707", + "hw_id": "00000000000000000000000000000000", + "hw_ver": "1.0", + "jamming_rssi": -119, + "jamming_signal_level": 1, + "lastOnboardingTimestamp": 1706550338, + "mac": "E4FAC4000000", + "model": "T310", + "nickname": "I01BU0tFRF9OQU1FIw==", + "oem_id": "00000000000000000000000000000000", + "parent_device_id": "0000000000000000000000000000000000000000", + "region": "Europe/London", + "report_interval": 16, + "rssi": -68, + "signal_level": 3, + "specs": "EU", + "status": "online", + "status_follow_edge": false, + "temp_unit": "celsius", + "type": "SMART.TAPOSENSOR" + }, + { + "at_low_battery": false, + "avatar": "sensor_t310", + "bind_count": 1, + "category": "subg.trigger.temp-hmdt-sensor", + "current_humidity": 60, + "current_humidity_exception": 0, + "current_temp": 20.1, + "current_temp_exception": 0.1, + "device_id": "SCRUBBED_CHILD_DEVICE_ID_9", + "fw_ver": "1.5.0 Build 230105 Rel.150707", + "hw_id": "00000000000000000000000000000000", + "hw_ver": "1.0", + "jamming_rssi": -116, + "jamming_signal_level": 1, + "lastOnboardingTimestamp": 1706551426, + "mac": "E4FAC4000000", + "model": "T310", + "nickname": "I01BU0tFRF9OQU1FIw==", + "oem_id": "00000000000000000000000000000000", + "parent_device_id": "0000000000000000000000000000000000000000", + "region": "Europe/London", + "report_interval": 16, + "rssi": -70, + "signal_level": 2, + "specs": "EU", + "status": "online", + "status_follow_edge": false, + "temp_unit": "celsius", + "type": "SMART.TAPOSENSOR" + }, + { + "at_low_battery": false, + "avatar": "sensor_t310", + "bind_count": 1, + "category": "subg.trigger.temp-hmdt-sensor", + "current_humidity": 54, + "current_humidity_exception": 0, + "current_temp": 19.3, + "current_temp_exception": 0, + "device_id": "SCRUBBED_CHILD_DEVICE_ID_10", + "fw_ver": "1.5.0 Build 230105 Rel.150707", + "hw_id": "00000000000000000000000000000000", + "hw_ver": "1.0", + "jamming_rssi": -120, + "jamming_signal_level": 1, + "lastOnboardingTimestamp": 1706789728, + "mac": "E4FAC4000000", + "model": "T310", + "nickname": "I01BU0tFRF9OQU1FIw==", + "oem_id": "00000000000000000000000000000000", + "parent_device_id": "0000000000000000000000000000000000000000", + "region": "Europe/London", + "report_interval": 16, + "rssi": -81, + "signal_level": 1, + "specs": "EU", + "status": "online", + "status_follow_edge": false, + "temp_unit": "celsius", + "type": "SMART.TAPOSENSOR" + } + ], + "start_index": 0, + "sum": 12 + }, + "get_connect_cloud_state": { + "status": 0 + }, + "get_device_info": { + "avatar": "kasa_hub", + "device_id": "0000000000000000000000000000000000000000", + "fw_id": "00000000000000000000000000000000", + "fw_ver": "1.5.6 Build 240202 Rel.164142", + "has_set_location_info": true, + "hw_id": "00000000000000000000000000000000", + "hw_ver": "1.0", + "in_alarm": false, + "in_alarm_source": "", + "ip": "127.0.0.123", + "lang": "en_US", + "latitude": 0, + "longitude": 0, + "mac": "F0-A7-31-00-00-00", + "model": "KH100", + "nickname": "I01BU0tFRF9OQU1FIw==", + "oem_id": "00000000000000000000000000000000", + "overheated": false, + "region": "Europe/London", + "rssi": -37, + "signal_level": 3, + "specs": "UK", + "ssid": "I01BU0tFRF9TU0lEIw==", + "time_diff": 0, + "type": "SMART.KASAHUB" + }, + "get_device_load_info": { + "cur_load_num": 24, + "load_level": "light", + "max_load_num": 64, + "total_memory": 4352, + "used_memory": 1581 + }, + "get_device_time": { + "region": "Europe/London", + "time_diff": 0, + "timestamp": 1713550228 + }, + "get_device_usage": {}, + "get_fw_download_state": { + "auto_upgrade": false, + "download_progress": 0, + "reboot_time": 5, + "status": 0, + "upgrade_time": 5 + }, + "get_inherit_info": null, + "get_latest_fw": { + "fw_size": 0, + "fw_ver": "1.5.6 Build 240202 Rel.164142", + "hw_id": "", + "need_to_upgrade": false, + "oem_id": "", + "release_date": "", + "release_note": "", + "type": 0 + }, + "get_led_info": { + "led_rule": "always", + "led_status": true, + "night_mode": { + "end_time": 358, + "night_mode_type": "sunrise_sunset", + "start_time": 1210, + "sunrise_offset": 0, + "sunset_offset": 0 + } + }, + "get_support_alarm_type_list": { + "alarm_type_list": [ + "Doorbell Ring 1", + "Doorbell Ring 2", + "Doorbell Ring 3", + "Doorbell Ring 4", + "Doorbell Ring 5", + "Doorbell Ring 6", + "Doorbell Ring 7", + "Doorbell Ring 8", + "Doorbell Ring 9", + "Doorbell Ring 10", + "Phone Ring", + "Alarm 1", + "Alarm 2", + "Alarm 3", + "Alarm 4", + "Dripping Tap", + "Alarm 5", + "Connection 1", + "Connection 2" + ] + }, + "get_support_child_device_category": { + "device_category_list": [ + { + "category": "subg.trv" + }, + { + "category": "subg.trigger" + }, + { + "category": "subg.plugswitch" + } + ] + }, + "get_wireless_scan_info": { + "ap_list": [], + "start_index": 0, + "sum": 0, + "wep_supported": false + }, + "qs_component_nego": { + "component_list": [ + { + "id": "quick_setup", + "ver_code": 3 + }, + { + "id": "sunrise_sunset", + "ver_code": 1 + }, + { + "id": "iot_cloud", + "ver_code": 1 + }, + { + "id": "inherit", + "ver_code": 1 + }, + { + "id": "firmware", + "ver_code": 2 + } + ], + "extra_info": { + "device_model": "KH100", + "device_type": "SMART.KASAHUB", + "is_klap": false + } + } +} diff --git a/kasa/tests/fixtures/smart/child/KE100(EU)_1.0_2.8.0.json b/kasa/tests/fixtures/smart/child/KE100(EU)_1.0_2.8.0.json new file mode 100644 index 000000000..61a2ce495 --- /dev/null +++ b/kasa/tests/fixtures/smart/child/KE100(EU)_1.0_2.8.0.json @@ -0,0 +1,59 @@ +{ + "get_connect_cloud_state": { + "status": 0 + }, + "get_device_info": { + "at_low_battery": false, + "avatar": "kasa_trv", + "battery_percentage": 100, + "bind_count": 1, + "category": "subg.trv", + "child_protection": false, + "current_temp": 19.2, + "device_id": "SCRUBBED_CHILD_DEVICE_ID_7", + "frost_protection_on": false, + "fw_ver": "2.8.0 Build 240202 Rel.135229", + "hw_id": "00000000000000000000000000000000", + "hw_ver": "1.0", + "jamming_rssi": -121, + "jamming_signal_level": 1, + "lastOnboardingTimestamp": 1705684116, + "location": "", + "mac": "F0A731000000", + "max_control_temp": 30, + "min_control_temp": 5, + "model": "KE100", + "nickname": "I01BU0tFRF9OQU1FIw==", + "oem_id": "00000000000000000000000000000000", + "parent_device_id": "0000000000000000000000000000000000000000", + "region": "Europe/London", + "rssi": -73, + "signal_level": 2, + "specs": "EU", + "status": "online", + "target_temp": 21.0, + "temp_offset": 0, + "temp_unit": "celsius", + "trv_states": [ + "heating" + ], + "type": "SMART.KASAENERGY" + }, + "get_fw_download_state": { + "cloud_cache_seconds": 1, + "download_progress": 0, + "reboot_time": 5, + "status": 0, + "upgrade_time": 5 + }, + "get_latest_fw": { + "fw_size": 0, + "fw_ver": "2.8.0 Build 240202 Rel.135229", + "hw_id": "", + "need_to_upgrade": false, + "oem_id": "", + "release_date": "", + "release_note": "", + "type": 0 + } +} diff --git a/kasa/tests/fixtures/smart/child/KE100(UK)_1.0_2.8.0.json b/kasa/tests/fixtures/smart/child/KE100(UK)_1.0_2.8.0.json new file mode 100644 index 000000000..c421e034f --- /dev/null +++ b/kasa/tests/fixtures/smart/child/KE100(UK)_1.0_2.8.0.json @@ -0,0 +1,59 @@ +{ + "get_connect_cloud_state": { + "status": 0 + }, + "get_device_info": { + "at_low_battery": false, + "avatar": "kasa_trv", + "battery_percentage": 100, + "bind_count": 1, + "category": "subg.trv", + "child_protection": false, + "current_temp": 20.1, + "device_id": "SCRUBBED_CHILD_DEVICE_ID_3", + "frost_protection_on": false, + "fw_ver": "2.8.0 Build 240202 Rel.135229", + "hw_id": "00000000000000000000000000000000", + "hw_ver": "1.0", + "jamming_rssi": -117, + "jamming_signal_level": 1, + "lastOnboardingTimestamp": 1705677078, + "location": "", + "mac": "F0A731000000", + "max_control_temp": 30, + "min_control_temp": 5, + "model": "KE100", + "nickname": "I01BU0tFRF9OQU1FIw==", + "oem_id": "00000000000000000000000000000000", + "parent_device_id": "0000000000000000000000000000000000000000", + "region": "Europe/London", + "rssi": -45, + "signal_level": 3, + "specs": "UK", + "status": "online", + "target_temp": 21.0, + "temp_offset": 0, + "temp_unit": "celsius", + "trv_states": [ + "heating" + ], + "type": "SMART.KASAENERGY" + }, + "get_fw_download_state": { + "cloud_cache_seconds": 1, + "download_progress": 0, + "reboot_time": 5, + "status": 0, + "upgrade_time": 5 + }, + "get_latest_fw": { + "fw_size": 0, + "fw_ver": "2.8.0 Build 240202 Rel.135229", + "hw_id": "", + "need_to_upgrade": false, + "oem_id": "", + "release_date": "", + "release_note": "", + "type": 0 + } +} diff --git a/kasa/tests/fixtures/smart/child/T310(EU)_1.0_1.5.0.json b/kasa/tests/fixtures/smart/child/T310(EU)_1.0_1.5.0.json new file mode 100644 index 000000000..c6d75790b --- /dev/null +++ b/kasa/tests/fixtures/smart/child/T310(EU)_1.0_1.5.0.json @@ -0,0 +1,454 @@ +{ + "get_connect_cloud_state": { + "status": 0 + }, + "get_device_info": { + "at_low_battery": false, + "avatar": "sensor_t310", + "bind_count": 1, + "category": "subg.trigger.temp-hmdt-sensor", + "current_humidity": 54, + "current_humidity_exception": 0, + "current_temp": 19.3, + "current_temp_exception": 0, + "device_id": "SCRUBBED_CHILD_DEVICE_ID_10", + "fw_ver": "1.5.0 Build 230105 Rel.150707", + "hw_id": "00000000000000000000000000000000", + "hw_ver": "1.0", + "jamming_rssi": -120, + "jamming_signal_level": 1, + "lastOnboardingTimestamp": 1706789728, + "mac": "E4FAC4000000", + "model": "T310", + "nickname": "I01BU0tFRF9OQU1FIw==", + "oem_id": "00000000000000000000000000000000", + "parent_device_id": "0000000000000000000000000000000000000000", + "region": "Europe/London", + "report_interval": 16, + "rssi": -81, + "signal_level": 1, + "specs": "EU", + "status": "online", + "status_follow_edge": false, + "temp_unit": "celsius", + "type": "SMART.TAPOSENSOR" + }, + "get_fw_download_state": { + "cloud_cache_seconds": 1, + "download_progress": 0, + "reboot_time": 5, + "status": 0, + "upgrade_time": 5 + }, + "get_latest_fw": { + "fw_size": 0, + "fw_ver": "1.5.0 Build 230105 Rel.150707", + "hw_id": "", + "need_to_upgrade": false, + "oem_id": "", + "release_date": "", + "release_note": "", + "type": 0 + }, + "get_temp_humidity_records": { + "local_time": 1713550233, + "past24h_humidity": [ + 60, + 60, + 60, + 60, + 60, + 60, + 60, + 60, + 60, + 61, + 61, + 61, + 61, + 61, + 61, + 61, + 61, + 61, + 61, + 61, + 61, + 62, + 61, + 61, + 62, + 61, + 60, + 61, + 61, + 61, + 61, + 61, + 61, + 61, + 61, + 61, + 61, + 62, + 62, + 62, + 62, + 62, + 62, + 62, + 62, + 62, + 62, + 62, + 62, + 62, + 62, + 63, + 63, + 63, + 64, + 63, + 63, + 63, + 63, + 62, + 63, + 63, + 62, + 62, + 62, + 62, + 62, + 61, + 62, + 61, + 61, + 61, + 61, + 61, + 61, + 60, + 61, + 64, + 64, + 61, + 61, + 63, + 60, + 60, + 60, + 60, + 59, + 59, + 59, + 59, + 59, + 58, + 58, + 58, + 57, + 55 + ], + "past24h_humidity_exception": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 2, + 1, + 1, + 2, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 3, + 3, + 3, + 4, + 3, + 3, + 3, + 3, + 2, + 3, + 3, + 2, + 2, + 2, + 2, + 2, + 1, + 2, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 4, + 4, + 1, + 1, + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "past24h_temp": [ + 175, + 175, + 174, + 174, + 173, + 172, + 172, + 171, + 170, + 169, + 169, + 167, + 167, + 166, + 165, + 164, + 163, + 163, + 162, + 162, + 162, + 162, + 163, + 163, + 162, + 162, + 161, + 160, + 159, + 159, + 159, + 159, + 158, + 158, + 159, + 159, + 158, + 159, + 159, + 159, + 159, + 159, + 159, + 159, + 159, + 159, + 158, + 158, + 158, + 158, + 158, + 158, + 159, + 159, + 160, + 161, + 161, + 162, + 162, + 162, + 162, + 162, + 163, + 163, + 166, + 168, + 170, + 172, + 174, + 175, + 176, + 177, + 179, + 181, + 183, + 184, + 185, + 187, + 189, + 190, + 190, + 193, + 194, + 194, + 194, + 194, + 194, + 194, + 195, + 195, + 195, + 196, + 196, + 196, + 195, + 193 + ], + "past24h_temp_exception": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -1, + -1, + -1, + -1, + -2, + -2, + -1, + -1, + -2, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -2, + -2, + -2, + -2, + -2, + -2, + -1, + -1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "temp_unit": "celsius" + }, + "get_trigger_logs": { + "logs": [], + "start_id": 0, + "sum": 0 + } +} From 12621df5082f094c7ebe8e94689b88c34091df51 Mon Sep 17 00:00:00 2001 From: sdb9696 Date: Mon, 22 Apr 2024 13:30:31 +0100 Subject: [PATCH 3/4] Add test configuration for new devices --- README.md | 1 + SUPPORTED.md | 5 + kasa/smart/modules/temperature.py | 23 ++-- kasa/smart/modules/temperaturecontrol.py | 8 +- kasa/tests/device_fixtures.py | 17 ++- .../fixtures/smart/KH100(UK)_1.0_1.5.6.json | 4 +- .../smart/child/KE100(EU)_1.0_2.8.0.json | 112 ++++++++++++++++++ .../smart/child/KE100(UK)_1.0_2.8.0.json | 112 ++++++++++++++++++ .../smart/child/T310(EU)_1.0_1.5.0.json | 76 ++++++++++++ kasa/tests/smart/modules/test_temperature.py | 20 +++- .../smart/modules/test_temperaturecontrol.py | 6 +- 11 files changed, 361 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 91235102f..c4dd918cb 100644 --- a/README.md +++ b/README.md @@ -231,6 +231,7 @@ The following devices have been tested and confirmed as working. If your device - **Wall Switches**: ES20M, HS200, HS210, HS220, KP405, KS200M, KS205\*, KS220M, KS225\*, KS230 - **Bulbs**: KL110, KL120, KL125, KL130, KL135, KL50, KL60, LB110 - **Light Strips**: KL400L5, KL420L5, KL430 +- **Hubs**: KH100\* ### Supported Tapo\* devices diff --git a/SUPPORTED.md b/SUPPORTED.md index 16fdb0e1d..1587e9663 100644 --- a/SUPPORTED.md +++ b/SUPPORTED.md @@ -126,6 +126,11 @@ Some newer Kasa devices require authentication. These are marked with *\* + ## Tapo devices diff --git a/kasa/smart/modules/temperature.py b/kasa/smart/modules/temperature.py index 2a5d73ba7..4956f035a 100644 --- a/kasa/smart/modules/temperature.py +++ b/kasa/smart/modules/temperature.py @@ -28,16 +28,17 @@ def __init__(self, device: SmartDevice, module: str): icon="mdi:thermometer", ) ) - self._add_feature( - Feature( - device, - "Temperature warning", - container=self, - attribute_getter="temperature_warning", - type=FeatureType.BinarySensor, - icon="mdi:alert", + if "current_temp_exception" in device.sys_info: + self._add_feature( + Feature( + device, + "Temperature warning", + container=self, + attribute_getter="temperature_warning", + type=FeatureType.BinarySensor, + icon="mdi:alert", + ) ) - ) self._add_feature( Feature( device, @@ -57,7 +58,9 @@ def temperature(self): @property def temperature_warning(self) -> bool: """Return True if temperature is outside of the wanted range.""" - return self._device.sys_info["current_temp_exception"] != 0 + if "current_temp_exception" in self._device.sys_info: + return self._device.sys_info["current_temp_exception"] != 0 + return False @property def temperature_unit(self): diff --git a/kasa/smart/modules/temperaturecontrol.py b/kasa/smart/modules/temperaturecontrol.py index 8babf1164..9106a56fa 100644 --- a/kasa/smart/modules/temperaturecontrol.py +++ b/kasa/smart/modules/temperaturecontrol.py @@ -14,7 +14,7 @@ class TemperatureControl(SmartModule): """Implementation of temperature module.""" - REQUIRED_COMPONENT = "temperature_control" + REQUIRED_COMPONENT = "temp_control" def __init__(self, device: SmartDevice, module: str): super().__init__(device, module) @@ -57,11 +57,11 @@ def maximum_target_temperature(self) -> int: return self._device.sys_info["max_control_temp"] @property - def target_temperature(self) -> int: + def target_temperature(self) -> float: """Return target temperature.""" - return self._device.sys_info["target_temperature"] + return self._device.sys_info["target_temp"] - async def set_target_temperature(self, target: int): + async def set_target_temperature(self, target: float): """Set target temperature.""" if ( target < self.minimum_target_temperature diff --git a/kasa/tests/device_fixtures.py b/kasa/tests/device_fixtures.py index 362015db9..3cad6357e 100644 --- a/kasa/tests/device_fixtures.py +++ b/kasa/tests/device_fixtures.py @@ -107,8 +107,9 @@ *DIMMERS_SMART, } -HUBS_SMART = {"H100"} -SENSORS_SMART = {"T315"} +HUBS_SMART = {"H100", "KH100"} +SENSORS_SMART = {"T310", "T315"} +THERMOSTATS_SMART = {"KE100"} WITH_EMETER_IOT = {"HS110", "HS300", "KP115", "KP125", *BULBS_IOT} WITH_EMETER_SMART = {"P110", "KP125M", "EP25"} @@ -126,6 +127,7 @@ .union(HUBS_SMART) .union(SENSORS_SMART) .union(SWITCHES_SMART) + .union(THERMOSTATS_SMART) ) ALL_DEVICES = ALL_DEVICES_IOT.union(ALL_DEVICES_SMART) @@ -275,6 +277,9 @@ def parametrize( sensors_smart = parametrize( "sensors smart", model_filter=SENSORS_SMART, protocol_filter={"SMART.CHILD"} ) +thermostats_smart = parametrize( + "thermostats smart", model_filter=THERMOSTATS_SMART, protocol_filter={"SMART.CHILD"} +) device_smart = parametrize( "devices smart", model_filter=ALL_DEVICES_SMART, protocol_filter={"SMART"} ) @@ -296,6 +301,7 @@ def check_categories(): + dimmers_smart.args[1] + hubs_smart.args[1] + sensors_smart.args[1] + + thermostats_smart.args[1] ) diffs: set[FixtureInfo] = set(FIXTURE_DATA) - set(categorized_fixtures) if diffs: @@ -313,7 +319,12 @@ def check_categories(): def device_for_fixture_name(model, protocol): if "SMART" in protocol: for d in chain( - PLUGS_SMART, SWITCHES_SMART, STRIPS_SMART, HUBS_SMART, SENSORS_SMART + PLUGS_SMART, + SWITCHES_SMART, + STRIPS_SMART, + HUBS_SMART, + SENSORS_SMART, + THERMOSTATS_SMART, ): if d in model: return SmartDevice diff --git a/kasa/tests/fixtures/smart/KH100(UK)_1.0_1.5.6.json b/kasa/tests/fixtures/smart/KH100(UK)_1.0_1.5.6.json index d9ca8e3de..33e4cec68 100644 --- a/kasa/tests/fixtures/smart/KH100(UK)_1.0_1.5.6.json +++ b/kasa/tests/fixtures/smart/KH100(UK)_1.0_1.5.6.json @@ -1068,7 +1068,7 @@ } ], "start_index": 0, - "sum": 12 + "sum": 10 }, "get_child_device_list": { "child_device_list": [ @@ -1409,7 +1409,7 @@ } ], "start_index": 0, - "sum": 12 + "sum": 10 }, "get_connect_cloud_state": { "status": 0 diff --git a/kasa/tests/fixtures/smart/child/KE100(EU)_1.0_2.8.0.json b/kasa/tests/fixtures/smart/child/KE100(EU)_1.0_2.8.0.json index 61a2ce495..14bb10c97 100644 --- a/kasa/tests/fixtures/smart/child/KE100(EU)_1.0_2.8.0.json +++ b/kasa/tests/fixtures/smart/child/KE100(EU)_1.0_2.8.0.json @@ -1,4 +1,116 @@ { + "component_nego": { + "component_list": [ + { + "id": "device", + "ver_code": 2 + }, + { + "id": "quick_setup", + "ver_code": 3 + }, + { + "id": "time", + "ver_code": 1 + }, + { + "id": "device_local_time", + "ver_code": 1 + }, + { + "id": "schedule", + "ver_code": 2 + }, + { + "id": "countdown", + "ver_code": 2 + }, + { + "id": "account", + "ver_code": 1 + }, + { + "id": "synchronize", + "ver_code": 1 + }, + { + "id": "sunrise_sunset", + "ver_code": 1 + }, + { + "id": "cloud_connect", + "ver_code": 1 + }, + { + "id": "iot_cloud", + "ver_code": 1 + }, + { + "id": "frost_protection", + "ver_code": 1 + }, + { + "id": "child_protection", + "ver_code": 1 + }, + { + "id": "temperature", + "ver_code": 1 + }, + { + "id": "temp_control", + "ver_code": 1 + }, + { + "id": "remove_scale", + "ver_code": 1 + }, + { + "id": "shutdown_mode", + "ver_code": 1 + }, + { + "id": "progress_calibration", + "ver_code": 1 + }, + { + "id": "early_start", + "ver_code": 1 + }, + { + "id": "temp_record", + "ver_code": 1 + }, + { + "id": "screen_setting", + "ver_code": 1 + }, + { + "id": "night_mode", + "ver_code": 1 + }, + { + "id": "smart_control_schedule", + "ver_code": 1 + }, + { + "id": "firmware", + "ver_code": 1 + }, + { + "id": "battery_detect", + "ver_code": 1 + }, + { + "id": "temperature_correction", + "ver_code": 1 + }, + { + "id": "window_open_detect", + "ver_code": 2 + } + ] + }, "get_connect_cloud_state": { "status": 0 }, diff --git a/kasa/tests/fixtures/smart/child/KE100(UK)_1.0_2.8.0.json b/kasa/tests/fixtures/smart/child/KE100(UK)_1.0_2.8.0.json index c421e034f..199d572a6 100644 --- a/kasa/tests/fixtures/smart/child/KE100(UK)_1.0_2.8.0.json +++ b/kasa/tests/fixtures/smart/child/KE100(UK)_1.0_2.8.0.json @@ -1,4 +1,116 @@ { + "component_nego": { + "component_list": [ + { + "id": "device", + "ver_code": 2 + }, + { + "id": "quick_setup", + "ver_code": 3 + }, + { + "id": "time", + "ver_code": 1 + }, + { + "id": "device_local_time", + "ver_code": 1 + }, + { + "id": "schedule", + "ver_code": 2 + }, + { + "id": "countdown", + "ver_code": 2 + }, + { + "id": "account", + "ver_code": 1 + }, + { + "id": "synchronize", + "ver_code": 1 + }, + { + "id": "sunrise_sunset", + "ver_code": 1 + }, + { + "id": "cloud_connect", + "ver_code": 1 + }, + { + "id": "iot_cloud", + "ver_code": 1 + }, + { + "id": "frost_protection", + "ver_code": 1 + }, + { + "id": "child_protection", + "ver_code": 1 + }, + { + "id": "temperature", + "ver_code": 1 + }, + { + "id": "temp_control", + "ver_code": 1 + }, + { + "id": "remove_scale", + "ver_code": 1 + }, + { + "id": "shutdown_mode", + "ver_code": 1 + }, + { + "id": "progress_calibration", + "ver_code": 1 + }, + { + "id": "early_start", + "ver_code": 1 + }, + { + "id": "temp_record", + "ver_code": 1 + }, + { + "id": "screen_setting", + "ver_code": 1 + }, + { + "id": "night_mode", + "ver_code": 1 + }, + { + "id": "smart_control_schedule", + "ver_code": 1 + }, + { + "id": "firmware", + "ver_code": 1 + }, + { + "id": "battery_detect", + "ver_code": 1 + }, + { + "id": "temperature_correction", + "ver_code": 1 + }, + { + "id": "window_open_detect", + "ver_code": 2 + } + ] + }, "get_connect_cloud_state": { "status": 0 }, diff --git a/kasa/tests/fixtures/smart/child/T310(EU)_1.0_1.5.0.json b/kasa/tests/fixtures/smart/child/T310(EU)_1.0_1.5.0.json index c6d75790b..d48875e5f 100644 --- a/kasa/tests/fixtures/smart/child/T310(EU)_1.0_1.5.0.json +++ b/kasa/tests/fixtures/smart/child/T310(EU)_1.0_1.5.0.json @@ -1,4 +1,80 @@ { + "component_nego" : { + "component_list": [ + { + "id": "device", + "ver_code": 2 + }, + { + "id": "quick_setup", + "ver_code": 3 + }, + { + "id": "trigger_log", + "ver_code": 1 + }, + { + "id": "time", + "ver_code": 1 + }, + { + "id": "device_local_time", + "ver_code": 1 + }, + { + "id": "account", + "ver_code": 1 + }, + { + "id": "synchronize", + "ver_code": 1 + }, + { + "id": "cloud_connect", + "ver_code": 1 + }, + { + "id": "iot_cloud", + "ver_code": 1 + }, + { + "id": "firmware", + "ver_code": 1 + }, + { + "id": "localSmart", + "ver_code": 1 + }, + { + "id": "battery_detect", + "ver_code": 1 + }, + { + "id": "temperature", + "ver_code": 1 + }, + { + "id": "humidity", + "ver_code": 1 + }, + { + "id": "temp_humidity_record", + "ver_code": 1 + }, + { + "id": "comfort_temperature", + "ver_code": 1 + }, + { + "id": "comfort_humidity", + "ver_code": 1 + }, + { + "id": "report_mode", + "ver_code": 1 + } + ] + }, "get_connect_cloud_state": { "status": 0 }, diff --git a/kasa/tests/smart/modules/test_temperature.py b/kasa/tests/smart/modules/test_temperature.py index 3b9ab50e2..a7d20dac6 100644 --- a/kasa/tests/smart/modules/test_temperature.py +++ b/kasa/tests/smart/modules/test_temperature.py @@ -7,13 +7,18 @@ "has temperature", component_filter="temperature", protocol_filter={"SMART.CHILD"} ) +temperature_warning = parametrize( + "has temperature warning", + component_filter="comfort_temperature", + protocol_filter={"SMART.CHILD"}, +) + @temperature @pytest.mark.parametrize( "feature, type", [ ("temperature", float), - ("temperature_warning", bool), ("temperature_unit", str), ], ) @@ -27,3 +32,16 @@ async def test_temperature_features(dev, feature, type): feat = temp_module._module_features[feature] assert feat.value == prop assert isinstance(feat.value, type) + + +@temperature_warning +async def test_temperature_warning(dev): + """Test that features are registered and work as expected.""" + temp_module: TemperatureSensor = dev.modules["TemperatureSensor"] + + assert hasattr(temp_module, "temperature_warning") + assert isinstance(temp_module.temperature_warning, bool) + + feat = temp_module._module_features["temperature_warning"] + assert feat.value == temp_module.temperature_warning + assert isinstance(feat.value, bool) diff --git a/kasa/tests/smart/modules/test_temperaturecontrol.py b/kasa/tests/smart/modules/test_temperaturecontrol.py index 5768a4820..5f6e3b56e 100644 --- a/kasa/tests/smart/modules/test_temperaturecontrol.py +++ b/kasa/tests/smart/modules/test_temperaturecontrol.py @@ -1,7 +1,7 @@ import pytest from kasa.smart.modules import TemperatureSensor -from kasa.tests.device_fixtures import parametrize +from kasa.tests.device_fixtures import parametrize, thermostats_smart temperature = parametrize( "has temperature control", @@ -10,11 +10,11 @@ ) -@temperature +@thermostats_smart @pytest.mark.parametrize( "feature, type", [ - ("target_temperature", int), + ("target_temperature", float), ("temperature_offset", int), ], ) From f377a3bb4001fb9efaa23d8249767c9948a6f9fa Mon Sep 17 00:00:00 2001 From: Steven B <51370195+sdb9696@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:23:21 +0100 Subject: [PATCH 4/4] Simplify temperature_warning check --- kasa/smart/modules/temperature.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/kasa/smart/modules/temperature.py b/kasa/smart/modules/temperature.py index 4956f035a..3cec427b5 100644 --- a/kasa/smart/modules/temperature.py +++ b/kasa/smart/modules/temperature.py @@ -58,9 +58,7 @@ def temperature(self): @property def temperature_warning(self) -> bool: """Return True if temperature is outside of the wanted range.""" - if "current_temp_exception" in self._device.sys_info: - return self._device.sys_info["current_temp_exception"] != 0 - return False + return self._device.sys_info.get("current_temp_exception", 0) != 0 @property def temperature_unit(self):