mirror of
https://github.com/python-kasa/python-kasa.git
synced 2025-08-06 18:54:08 +00:00
Support for new ks240 fan/light wall switch (#839)
In order to support the ks240 which has children for the fan and light components, this PR adds those modules at the parent level and hides the children so it looks like a single device to consumers. It also decides which modules not to take from the child because the child does not support them even though it say it does. It does this for now via a fixed list, e.g. `Time`, `Firmware` etc. Also adds fixtures from two versions and corresponding tests.
This commit is contained in:
@@ -92,6 +92,7 @@ SWITCHES_IOT = {
|
||||
SWITCHES_SMART = {
|
||||
"KS205",
|
||||
"KS225",
|
||||
"KS240",
|
||||
"S500D",
|
||||
"S505",
|
||||
}
|
||||
|
@@ -139,10 +139,29 @@ class FakeSmartTransport(BaseTransport):
|
||||
|
||||
# We only support get & set device info for now.
|
||||
if child_method == "get_device_info":
|
||||
return {"result": info, "error_code": 0}
|
||||
result = copy.deepcopy(info)
|
||||
return {"result": result, "error_code": 0}
|
||||
elif child_method == "set_device_info":
|
||||
info.update(child_params)
|
||||
return {"error_code": 0}
|
||||
elif (
|
||||
# FIXTURE_MISSING is for service calls not in place when
|
||||
# SMART fixtures started to be generated
|
||||
missing_result := self.FIXTURE_MISSING_MAP.get(child_method)
|
||||
) and missing_result[0] in self.components:
|
||||
result = copy.deepcopy(missing_result[1])
|
||||
retval = {"result": result, "error_code": 0}
|
||||
return retval
|
||||
else:
|
||||
# PARAMS error returned for KS240 when get_device_usage called
|
||||
# on parent device. Could be any error code though.
|
||||
# TODO: Try to figure out if there's a way to prevent the KS240 smartdevice
|
||||
# calling the unsupported device in the first place.
|
||||
retval = {
|
||||
"error_code": SmartErrorCode.PARAMS_ERROR.value,
|
||||
"method": child_method,
|
||||
}
|
||||
return retval
|
||||
|
||||
raise NotImplementedError(
|
||||
"Method %s not implemented for children" % child_method
|
||||
|
482
kasa/tests/fixtures/smart/KS240(US)_1.0_1.0.4.json
vendored
Normal file
482
kasa/tests/fixtures/smart/KS240(US)_1.0_1.0.4.json
vendored
Normal file
@@ -0,0 +1,482 @@
|
||||
{
|
||||
"component_nego": {
|
||||
"component_list": [
|
||||
{
|
||||
"id": "device",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "firmware",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "quick_setup",
|
||||
"ver_code": 3
|
||||
},
|
||||
{
|
||||
"id": "time",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "wireless",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "schedule",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "countdown",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "antitheft",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "account",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "synchronize",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "sunrise_sunset",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "led",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "cloud_connect",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "iot_cloud",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "device_local_time",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "default_states",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "control_child",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "child_device",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "localSmart",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "brightness",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "preset",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "on_off_gradually",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "dimmer_calibration",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "fan_control",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "homekit",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "overheat_protection",
|
||||
"ver_code": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"discovery_result": {
|
||||
"device_id": "00000000000000000000000000000000",
|
||||
"device_model": "KS240(US)",
|
||||
"device_type": "SMART.KASASWITCH",
|
||||
"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_auto_update_info": {
|
||||
"enable": false,
|
||||
"random_range": 120,
|
||||
"time": 180
|
||||
},
|
||||
"get_child_device_component_list": {
|
||||
"child_component_list": [
|
||||
{
|
||||
"component_list": [
|
||||
{
|
||||
"id": "device",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "firmware",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "quick_setup",
|
||||
"ver_code": 3
|
||||
},
|
||||
{
|
||||
"id": "time",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "schedule",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "countdown",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "antitheft",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"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": "device_local_time",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "default_states",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "brightness",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "preset",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "on_off_gradually",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "dimmer_calibration",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "overheat_protection",
|
||||
"ver_code": 1
|
||||
}
|
||||
],
|
||||
"device_id": "000000000000000000000000000000000000000001"
|
||||
},
|
||||
{
|
||||
"component_list": [
|
||||
{
|
||||
"id": "device",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "firmware",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "quick_setup",
|
||||
"ver_code": 3
|
||||
},
|
||||
{
|
||||
"id": "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": "device_local_time",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "fan_control",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "overheat_protection",
|
||||
"ver_code": 1
|
||||
}
|
||||
],
|
||||
"device_id": "000000000000000000000000000000000000000000"
|
||||
}
|
||||
],
|
||||
"start_index": 0,
|
||||
"sum": 2
|
||||
},
|
||||
"get_child_device_list": {
|
||||
"child_device_list": [
|
||||
{
|
||||
"avatar": "switch_ks240",
|
||||
"bind_count": 1,
|
||||
"category": "kasa.switch.outlet.sub-fan",
|
||||
"device_id": "000000000000000000000000000000000000000000",
|
||||
"device_on": false,
|
||||
"fan_sleep_mode_on": false,
|
||||
"fan_speed_level": 1,
|
||||
"fw_id": "00000000000000000000000000000000",
|
||||
"fw_ver": "1.0.4 Build 230721 Rel.184322",
|
||||
"has_set_location_info": true,
|
||||
"hw_id": "00000000000000000000000000000000",
|
||||
"hw_ver": "1.0",
|
||||
"lang": "en_US",
|
||||
"latitude": 0,
|
||||
"longitude": 0,
|
||||
"mac": "F0A731000000",
|
||||
"model": "KS240",
|
||||
"nickname": "I01BU0tFRF9OQU1FIw==",
|
||||
"oem_id": "00000000000000000000000000000000",
|
||||
"original_device_id": "0000000000000000000000000000000000000000",
|
||||
"overheat_status": "normal",
|
||||
"region": "America/Chicago",
|
||||
"specs": "",
|
||||
"status_follow_edge": true,
|
||||
"type": "SMART.KASASWITCH"
|
||||
},
|
||||
{
|
||||
"avatar": "switch_ks240",
|
||||
"bind_count": 1,
|
||||
"brightness": 100,
|
||||
"category": "kasa.switch.outlet.sub-dimmer",
|
||||
"default_states": {
|
||||
"re_power_type": "always_off",
|
||||
"re_power_type_capability": [
|
||||
"last_states",
|
||||
"always_on",
|
||||
"always_off"
|
||||
],
|
||||
"type": "last_states"
|
||||
},
|
||||
"device_id": "000000000000000000000000000000000000000001",
|
||||
"device_on": false,
|
||||
"fade_off_time": 1,
|
||||
"fade_on_time": 1,
|
||||
"fw_id": "00000000000000000000000000000000",
|
||||
"fw_ver": "1.0.4 Build 230721 Rel.184322",
|
||||
"gradually_off_mode": 1,
|
||||
"gradually_on_mode": 1,
|
||||
"has_set_location_info": true,
|
||||
"hw_id": "00000000000000000000000000000000",
|
||||
"hw_ver": "1.0",
|
||||
"lang": "en_US",
|
||||
"latitude": 0,
|
||||
"led_off": 0,
|
||||
"longitude": 0,
|
||||
"mac": "F0A731000000",
|
||||
"max_fade_off_time": 60,
|
||||
"max_fade_on_time": 60,
|
||||
"model": "KS240",
|
||||
"nickname": "I01BU0tFRF9OQU1FIw==",
|
||||
"oem_id": "00000000000000000000000000000000",
|
||||
"on_off": 0,
|
||||
"on_time": 0,
|
||||
"original_device_id": "0000000000000000000000000000000000000000",
|
||||
"overheat_status": "normal",
|
||||
"preset_state": [
|
||||
{
|
||||
"brightness": 100
|
||||
},
|
||||
{
|
||||
"brightness": 75
|
||||
},
|
||||
{
|
||||
"brightness": 50
|
||||
},
|
||||
{
|
||||
"brightness": 25
|
||||
},
|
||||
{
|
||||
"brightness": 1
|
||||
}
|
||||
],
|
||||
"region": "America/Chicago",
|
||||
"specs": "",
|
||||
"status_follow_edge": true,
|
||||
"type": "SMART.KASASWITCH"
|
||||
}
|
||||
],
|
||||
"start_index": 0,
|
||||
"sum": 2
|
||||
},
|
||||
"get_connect_cloud_state": {
|
||||
"status": 0
|
||||
},
|
||||
"get_device_info": {
|
||||
"avatar": "",
|
||||
"device_id": "0000000000000000000000000000000000000000",
|
||||
"fw_id": "00000000000000000000000000000000",
|
||||
"fw_ver": "1.0.4 Build 230721 Rel.184322",
|
||||
"has_set_location_info": true,
|
||||
"hw_id": "00000000000000000000000000000000",
|
||||
"hw_ver": "1.0",
|
||||
"ip": "127.0.0.123",
|
||||
"lang": "en_US",
|
||||
"latitude": 0,
|
||||
"longitude": 0,
|
||||
"mac": "F0-A7-31-00-00-00",
|
||||
"model": "KS240",
|
||||
"nickname": "I01BU0tFRF9OQU1FIw==",
|
||||
"oem_id": "00000000000000000000000000000000",
|
||||
"region": "America/Chicago",
|
||||
"rssi": -39,
|
||||
"signal_level": 3,
|
||||
"specs": "",
|
||||
"ssid": "I01BU0tFRF9TU0lEIw==",
|
||||
"time_diff": -360,
|
||||
"type": "SMART.KASASWITCH"
|
||||
},
|
||||
"get_device_time": {
|
||||
"region": "America/Chicago",
|
||||
"time_diff": -360,
|
||||
"timestamp": 1708643384
|
||||
},
|
||||
"get_fw_download_state": {
|
||||
"auto_upgrade": false,
|
||||
"download_progress": 0,
|
||||
"reboot_time": 5,
|
||||
"status": 0,
|
||||
"upgrade_time": 5
|
||||
},
|
||||
"get_latest_fw": {
|
||||
"fw_size": 786432,
|
||||
"fw_ver": "1.0.5 Build 231204 Rel.172150",
|
||||
"hw_id": "00000000000000000000000000000000",
|
||||
"need_to_upgrade": true,
|
||||
"oem_id": "00000000000000000000000000000000",
|
||||
"release_date": "2024-01-12",
|
||||
"release_note": "Modifications and Bug Fixes:\n1. Improved time synchronization accuracy.\n2. Enhanced stability and performance.\n3. Fixed some minor bugs.",
|
||||
"type": 2
|
||||
},
|
||||
"get_led_info": {
|
||||
"bri_config": {
|
||||
"bri_type": "overall",
|
||||
"overall_bri": 50
|
||||
},
|
||||
"led_rule": "auto",
|
||||
"led_status": false,
|
||||
"night_mode": {
|
||||
"end_time": 420,
|
||||
"night_mode_type": "custom",
|
||||
"start_time": 1320
|
||||
}
|
||||
},
|
||||
"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": "ble_whole_setup",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "iot_cloud",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "inherit",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "firmware",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "control_child",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "child_device",
|
||||
"ver_code": 2
|
||||
}
|
||||
],
|
||||
"extra_info": {
|
||||
"device_model": "KS240",
|
||||
"device_type": "SMART.KASASWITCH"
|
||||
}
|
||||
}
|
||||
}
|
479
kasa/tests/fixtures/smart/KS240(US)_1.0_1.0.5.json
vendored
Normal file
479
kasa/tests/fixtures/smart/KS240(US)_1.0_1.0.5.json
vendored
Normal file
@@ -0,0 +1,479 @@
|
||||
{
|
||||
"component_nego": {
|
||||
"component_list": [
|
||||
{
|
||||
"id": "device",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "firmware",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "quick_setup",
|
||||
"ver_code": 3
|
||||
},
|
||||
{
|
||||
"id": "time",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "wireless",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "schedule",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "countdown",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "antitheft",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "account",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "synchronize",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "sunrise_sunset",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "led",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "cloud_connect",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "iot_cloud",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "device_local_time",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "default_states",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "control_child",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "child_device",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "brightness",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "preset",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "on_off_gradually",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "dimmer_calibration",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "fan_control",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "homekit",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "overheat_protection",
|
||||
"ver_code": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"discovery_result": {
|
||||
"device_id": "00000000000000000000000000000000",
|
||||
"device_model": "KS240(US)",
|
||||
"device_type": "SMART.KASASWITCH",
|
||||
"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_auto_update_info": {
|
||||
"enable": false,
|
||||
"random_range": 120,
|
||||
"time": 180
|
||||
},
|
||||
"get_child_device_component_list": {
|
||||
"child_component_list": [
|
||||
{
|
||||
"component_list": [
|
||||
{
|
||||
"id": "device",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "firmware",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "quick_setup",
|
||||
"ver_code": 3
|
||||
},
|
||||
{
|
||||
"id": "time",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "schedule",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "countdown",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "antitheft",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"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": "device_local_time",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "default_states",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "brightness",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "preset",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "on_off_gradually",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "dimmer_calibration",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "overheat_protection",
|
||||
"ver_code": 1
|
||||
}
|
||||
],
|
||||
"device_id": "000000000000000000000000000000000000000001"
|
||||
},
|
||||
{
|
||||
"component_list": [
|
||||
{
|
||||
"id": "device",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "firmware",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "quick_setup",
|
||||
"ver_code": 3
|
||||
},
|
||||
{
|
||||
"id": "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": "device_local_time",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "fan_control",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "overheat_protection",
|
||||
"ver_code": 1
|
||||
}
|
||||
],
|
||||
"device_id": "000000000000000000000000000000000000000000"
|
||||
}
|
||||
],
|
||||
"start_index": 0,
|
||||
"sum": 2
|
||||
},
|
||||
"get_child_device_list": {
|
||||
"child_device_list": [
|
||||
{
|
||||
"avatar": "switch_ks240",
|
||||
"bind_count": 1,
|
||||
"category": "kasa.switch.outlet.sub-fan",
|
||||
"device_id": "000000000000000000000000000000000000000000",
|
||||
"device_on": true,
|
||||
"fan_sleep_mode_on": false,
|
||||
"fan_speed_level": 1,
|
||||
"fw_id": "00000000000000000000000000000000",
|
||||
"fw_ver": "1.0.5 Build 231204 Rel.172150",
|
||||
"gc": 1,
|
||||
"has_set_location_info": false,
|
||||
"hw_id": "00000000000000000000000000000000",
|
||||
"hw_ver": "1.0",
|
||||
"la": 0,
|
||||
"lang": "",
|
||||
"lo": 0,
|
||||
"mac": "F0A731000000",
|
||||
"model": "KS240",
|
||||
"nickname": "I01BU0tFRF9OQU1FIw==",
|
||||
"oem_id": "00000000000000000000000000000000",
|
||||
"original_device_id": "0000000000000000000000000000000000000000",
|
||||
"overheat_status": "normal",
|
||||
"region": "America/New_York",
|
||||
"specs": "",
|
||||
"status_follow_edge": true,
|
||||
"type": "SMART.KASASWITCH"
|
||||
},
|
||||
{
|
||||
"avatar": "switch_ks240",
|
||||
"bind_count": 1,
|
||||
"brightness": 100,
|
||||
"category": "kasa.switch.outlet.sub-dimmer",
|
||||
"default_states": {
|
||||
"re_power_type": "always_off",
|
||||
"re_power_type_capability": [
|
||||
"last_states",
|
||||
"always_on",
|
||||
"always_off"
|
||||
],
|
||||
"type": "last_states"
|
||||
},
|
||||
"device_id": "000000000000000000000000000000000000000001",
|
||||
"device_on": false,
|
||||
"fade_off_time": 1,
|
||||
"fade_on_time": 1,
|
||||
"fw_id": "00000000000000000000000000000000",
|
||||
"fw_ver": "1.0.5 Build 231204 Rel.172150",
|
||||
"gc": 1,
|
||||
"gradually_off_mode": 1,
|
||||
"gradually_on_mode": 1,
|
||||
"has_set_location_info": false,
|
||||
"hw_id": "00000000000000000000000000000000",
|
||||
"hw_ver": "1.0",
|
||||
"la": 0,
|
||||
"lang": "",
|
||||
"led_off": 0,
|
||||
"lo": 0,
|
||||
"mac": "F0A731000000",
|
||||
"max_fade_off_time": 60,
|
||||
"max_fade_on_time": 60,
|
||||
"model": "KS240",
|
||||
"nickname": "I01BU0tFRF9OQU1FIw==",
|
||||
"oem_id": "00000000000000000000000000000000",
|
||||
"on_off": 0,
|
||||
"on_time": 0,
|
||||
"original_device_id": "0000000000000000000000000000000000000000",
|
||||
"overheat_status": "normal",
|
||||
"preset_state": [
|
||||
{
|
||||
"brightness": 100
|
||||
},
|
||||
{
|
||||
"brightness": 75
|
||||
},
|
||||
{
|
||||
"brightness": 50
|
||||
},
|
||||
{
|
||||
"brightness": 25
|
||||
},
|
||||
{
|
||||
"brightness": 1
|
||||
}
|
||||
],
|
||||
"region": "America/New_York",
|
||||
"specs": "",
|
||||
"status_follow_edge": true,
|
||||
"type": "SMART.KASASWITCH"
|
||||
}
|
||||
],
|
||||
"start_index": 0,
|
||||
"sum": 2
|
||||
},
|
||||
"get_connect_cloud_state": {
|
||||
"status": 0
|
||||
},
|
||||
"get_device_info": {
|
||||
"avatar": "",
|
||||
"device_id": "0000000000000000000000000000000000000000",
|
||||
"fw_id": "00000000000000000000000000000000",
|
||||
"fw_ver": "1.0.5 Build 231204 Rel.172150",
|
||||
"has_set_location_info": true,
|
||||
"hw_id": "00000000000000000000000000000000",
|
||||
"hw_ver": "1.0",
|
||||
"ip": "127.0.0.123",
|
||||
"lang": "",
|
||||
"latitude": 0,
|
||||
"longitude": 0,
|
||||
"mac": "F0-A7-31-00-00-00",
|
||||
"model": "KS240",
|
||||
"nickname": "I01BU0tFRF9OQU1FIw==",
|
||||
"oem_id": "00000000000000000000000000000000",
|
||||
"region": "America/New_York",
|
||||
"rssi": -46,
|
||||
"signal_level": 3,
|
||||
"specs": "",
|
||||
"ssid": "I01BU0tFRF9TU0lEIw==",
|
||||
"time_diff": -300,
|
||||
"type": "SMART.KASASWITCH"
|
||||
},
|
||||
"get_device_time": {
|
||||
"region": "America/New_York",
|
||||
"time_diff": -300,
|
||||
"timestamp": 1707863232
|
||||
},
|
||||
"get_fw_download_state": {
|
||||
"auto_upgrade": false,
|
||||
"download_progress": 0,
|
||||
"reboot_time": 5,
|
||||
"status": 0,
|
||||
"upgrade_time": 5
|
||||
},
|
||||
"get_latest_fw": {
|
||||
"fw_size": 0,
|
||||
"fw_ver": "1.0.5 Build 231204 Rel.172150",
|
||||
"hw_id": "",
|
||||
"need_to_upgrade": false,
|
||||
"oem_id": "",
|
||||
"release_date": "",
|
||||
"release_note": "",
|
||||
"type": 0
|
||||
},
|
||||
"get_led_info": {
|
||||
"bri_config": {
|
||||
"bri_type": "overall",
|
||||
"overall_bri": 50
|
||||
},
|
||||
"led_rule": "auto",
|
||||
"led_status": true,
|
||||
"night_mode": {
|
||||
"end_time": 420,
|
||||
"night_mode_type": "custom",
|
||||
"start_time": 1320
|
||||
}
|
||||
},
|
||||
"get_wireless_scan_info": {
|
||||
"ap_list": [],
|
||||
"wep_supported": false
|
||||
},
|
||||
"qs_component_nego": {
|
||||
"component_list": [
|
||||
{
|
||||
"id": "quick_setup",
|
||||
"ver_code": 3
|
||||
},
|
||||
{
|
||||
"id": "sunrise_sunset",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "ble_whole_setup",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "iot_cloud",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "inherit",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "firmware",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "control_child",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "child_device",
|
||||
"ver_code": 2
|
||||
}
|
||||
],
|
||||
"extra_info": {
|
||||
"device_model": "KS240",
|
||||
"device_type": "SMART.KASASWITCH",
|
||||
"is_klap": false
|
||||
}
|
||||
}
|
||||
}
|
@@ -10,11 +10,13 @@ brightness = parametrize("brightness smart", component_filter="brightness")
|
||||
@brightness
|
||||
async def test_brightness_component(dev: SmartDevice):
|
||||
"""Test brightness feature."""
|
||||
brightness = dev.modules.get("Brightness")
|
||||
assert brightness
|
||||
assert isinstance(dev, SmartDevice)
|
||||
assert "brightness" in dev._components
|
||||
|
||||
# Test getting the value
|
||||
feature = dev.features["brightness"]
|
||||
feature = brightness._module_features["brightness"]
|
||||
assert isinstance(feature.value, int)
|
||||
assert feature.value > 1 and feature.value <= 100
|
||||
|
||||
|
@@ -1,18 +1,17 @@
|
||||
from pytest_mock import MockerFixture
|
||||
|
||||
from kasa import SmartDevice
|
||||
from kasa.smart.modules import FanModule
|
||||
from kasa.tests.device_fixtures import parametrize
|
||||
|
||||
fan = parametrize(
|
||||
"has fan", component_filter="fan_control", protocol_filter={"SMART.CHILD"}
|
||||
)
|
||||
fan = parametrize("has fan", component_filter="fan_control", protocol_filter={"SMART"})
|
||||
|
||||
|
||||
@fan
|
||||
async def test_fan_speed(dev: SmartDevice, mocker: MockerFixture):
|
||||
"""Test fan speed feature."""
|
||||
fan: FanModule = dev.modules["FanModule"]
|
||||
fan = dev.modules.get("FanModule")
|
||||
assert fan
|
||||
|
||||
level_feature = fan._module_features["fan_speed_level"]
|
||||
assert (
|
||||
level_feature.minimum_value
|
||||
@@ -22,7 +21,7 @@ async def test_fan_speed(dev: SmartDevice, mocker: MockerFixture):
|
||||
|
||||
call = mocker.spy(fan, "call")
|
||||
await fan.set_fan_speed_level(3)
|
||||
call.assert_called_with("set_device_info", {"fan_sleep_level": 3})
|
||||
call.assert_called_with("set_device_info", {"fan_speed_level": 3})
|
||||
|
||||
await dev.update()
|
||||
|
||||
@@ -33,7 +32,8 @@ async def test_fan_speed(dev: SmartDevice, mocker: MockerFixture):
|
||||
@fan
|
||||
async def test_sleep_mode(dev: SmartDevice, mocker: MockerFixture):
|
||||
"""Test sleep mode feature."""
|
||||
fan: FanModule = dev.modules["FanModule"]
|
||||
fan = dev.modules.get("FanModule")
|
||||
assert fan
|
||||
sleep_feature = fan._module_features["fan_sleep_mode"]
|
||||
assert isinstance(sleep_feature.value, bool)
|
||||
|
||||
|
@@ -96,23 +96,29 @@ async def test_negotiate(dev: SmartDevice, mocker: MockerFixture):
|
||||
"get_child_device_list": None,
|
||||
}
|
||||
)
|
||||
assert len(dev.children) == dev.internal_state["get_child_device_list"]["sum"]
|
||||
assert len(dev._children) == dev.internal_state["get_child_device_list"]["sum"]
|
||||
|
||||
|
||||
@device_smart
|
||||
async def test_update_module_queries(dev: SmartDevice, mocker: MockerFixture):
|
||||
"""Test that the regular update uses queries from all supported modules."""
|
||||
query = mocker.spy(dev.protocol, "query")
|
||||
|
||||
# We need to have some modules initialized by now
|
||||
assert dev.modules
|
||||
|
||||
await dev.update()
|
||||
full_query: dict[str, Any] = {}
|
||||
device_queries: dict[SmartDevice, dict[str, Any]] = {}
|
||||
for mod in dev.modules.values():
|
||||
full_query = {**full_query, **mod.query()}
|
||||
device_queries.setdefault(mod._device, {}).update(mod.query())
|
||||
|
||||
query.assert_called_with(full_query)
|
||||
spies = {}
|
||||
for dev in device_queries:
|
||||
spies[dev] = mocker.spy(dev.protocol, "query")
|
||||
|
||||
await dev.update()
|
||||
for dev in device_queries:
|
||||
if device_queries[dev]:
|
||||
spies[dev].assert_called_with(device_queries[dev])
|
||||
else:
|
||||
spies[dev].assert_not_called()
|
||||
|
||||
|
||||
@bulb_smart
|
||||
@@ -187,10 +193,19 @@ async def test_smartdevice_cloud_connection(dev: SmartDevice, mocker: MockerFixt
|
||||
"get_child_device_component_list"
|
||||
]
|
||||
new_dev = SmartDevice("127.0.0.1", protocol=dev.protocol)
|
||||
|
||||
first_call = True
|
||||
|
||||
def side_effect_func(*_, **__):
|
||||
nonlocal first_call
|
||||
resp = initial_response if first_call else last_update
|
||||
first_call = False
|
||||
return resp
|
||||
|
||||
with patch.object(
|
||||
new_dev.protocol,
|
||||
"query",
|
||||
side_effect=[initial_response, last_update, last_update],
|
||||
side_effect=side_effect_func,
|
||||
):
|
||||
await new_dev.update()
|
||||
assert new_dev.is_cloud_connected is False
|
||||
|
Reference in New Issue
Block a user