Add fixtures for KH100, KE100 and KE110 and simulate TRV states (#1726)

This PR adds fixture files for:

- KH100 (UK), hardware 1.0, firmware 1.7.5
- KE100 (UK), hardware 1.0, firmware 2.15.0
- KE110 (EU), hardware 1.0, firmware 1.4.0

The fixtures were collected from physical devices and anonymized for use
in development and testing.

The KE110 fixture is a new device model and has been added to the
appropriate fixture category.

This also improves test suite by adding TRV state simulation to allow tests pass on fixtures that report a non-heating state.

---------

Co-authored-by: Teemu Rytilahti <tpr@iki.fi>
This commit is contained in:
Krotu
2026-10-04 16:09:21 +01:00
committed by GitHub
parent 99716fc3b9
commit d916a49668
9 changed files with 1730 additions and 8 deletions

View File

@@ -192,7 +192,7 @@ The following devices have been tested and confirmed as working. If your device
- **Bulbs**: KL110, KL110B, KL120, KL125, KL130, KL135, KL50, KL60, LB100, LB110, LB130
- **Light Strips**: KL400L10, KL400L5, KL420L5, KL430
- **Hubs**: KH100[^1]
- **Hub-Connected Devices[^3]**: KE100[^1]
- **Hub-Connected Devices[^3]**: KE100[^1], KE110[^1]
### Supported Tapo[^1] devices

View File

@@ -183,13 +183,17 @@ Some newer Kasa devices require authentication. These are marked with [^1] in th
- Hardware: 1.0 (EU) / Firmware: 1.2.3[^1]
- Hardware: 1.0 (EU) / Firmware: 1.5.12[^1]
- Hardware: 1.0 (UK) / Firmware: 1.5.6[^1]
- Hardware: 1.0 (UK) / Firmware: 1.7.5[^1]
### Hub-Connected Devices
- **KE100**
- Hardware: 1.0 (EU) / Firmware: 2.4.0[^1]
- Hardware: 1.0 (EU) / Firmware: 2.8.0[^1]
- Hardware: 1.0 (UK) / Firmware: 2.15.0[^1]
- Hardware: 1.0 (UK) / Firmware: 2.8.0[^1]
- **KE110**
- Hardware: 1.0 (EU) / Firmware: 1.4.0[^1]
## Tapo devices

View File

@@ -153,7 +153,7 @@ SENSORS_SMART = {
"S220",
"D100C", # needs a home category?
}
THERMOSTATS_SMART = {"KE100"}
THERMOSTATS_SMART = {"KE100", "KE110"}
VACUUMS_SMART = {"RV20"}

View File

@@ -410,6 +410,7 @@ class FakeSmartTransport(BaseTransport):
return {"result": result, "error_code": 0}
elif child_method == "set_device_info":
info.update(child_params)
self._update_trv_states(info)
return {"error_code": 0}
elif child_method == "set_preset_rules":
return self._set_child_preset_rules(info, child_params)
@@ -447,6 +448,24 @@ class FakeSmartTransport(BaseTransport):
raise NotImplementedError(f"Method {child_method} not implemented for children")
def _update_trv_states(self, info: dict) -> None:
"""Simulate TRV heating state after a device info update.
The device heats when frost protection is off and the target temperature
exceeds the current temperature.
"""
if "trv_states" not in info:
return
should_heat = not info.get("frost_protection_on", False) and info.get(
"target_temp", 0
) > info.get("current_temp", 0)
trv_states = set(info["trv_states"])
if should_heat:
trv_states.add("heating")
else:
trv_states.discard("heating")
info["trv_states"] = list(trv_states)
def _get_on_off_gradually_info(self, info: dict, params: dict | None):
if self.components["on_off_gradually"] == 1:
info["get_on_off_gradually_info"] = {"enable": True}
@@ -722,6 +741,10 @@ class FakeSmartTransport(BaseTransport):
"resetConsumablesTime", # vacuum special actions
]:
return {"error_code": 0}
elif method == "set_device_info":
info["get_device_info"].update(params)
self._update_trv_states(info["get_device_info"])
return {"error_code": 0}
elif method[:3] == "set":
target_method = f"get{method[3:]}"
# Some vacuum commands do not have a getter

View File

@@ -0,0 +1,721 @@
{
"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": "support_presence_sensor",
"ver_code": 1
},
{
"id": "localSmart",
"ver_code": 2
},
{
"id": "matter",
"ver_code": 3
},
{
"id": "chime",
"ver_code": 2
},
{
"id": "migrate",
"ver_code": 1
},
{
"id": "tpap",
"ver_code": 1
},
{
"id": "noc",
"ver_code": 1
}
]
},
"discovery_result": {
"error_code": 0,
"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": "0C-EF-15-00-00-00",
"mgt_encrypt_schm": {
"encrypt_type": "KLAP",
"http_port": 80,
"is_support_https": false,
"lv": 2
},
"obd_src": "tplink",
"owner": "00000000000000000000000000000000",
"protocol_version": 1,
"tpap_preferred": false
}
},
"get_alarm_configure": {
"duration": 300,
"type": "Alarm 1",
"volume": "low"
},
"get_auto_update_info": {
"enable": true,
"random_range": 120,
"time": 180
},
"get_child_device_component_list": {
"child_component_list": [
{
"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": "remove_scale",
"ver_code": 1
},
{
"id": "early_start",
"ver_code": 1
},
{
"id": "screen_setting",
"ver_code": 1
},
{
"id": "night_mode",
"ver_code": 1
},
{
"id": "firmware",
"ver_code": 1
},
{
"id": "battery_detect",
"ver_code": 1
},
{
"id": "temp_record",
"ver_code": 1
},
{
"id": "progress_calibration",
"ver_code": 1
},
{
"id": "temperature_correction",
"ver_code": 1
},
{
"id": "window_open_detect",
"ver_code": 4
},
{
"id": "shutdown_mode",
"ver_code": 2
},
{
"id": "trv_multi_mode",
"ver_code": 1
},
{
"id": "smart_control_schedule",
"ver_code": 2
},
{
"id": "temp_control",
"ver_code": 2
}
],
"device_id": "SCRUBBED_CHILD_DEVICE_ID_1"
},
{
"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": "remove_scale",
"ver_code": 1
},
{
"id": "early_start",
"ver_code": 1
},
{
"id": "screen_setting",
"ver_code": 1
},
{
"id": "night_mode",
"ver_code": 1
},
{
"id": "firmware",
"ver_code": 1
},
{
"id": "battery_detect",
"ver_code": 1
},
{
"id": "humidity",
"ver_code": 2
},
{
"id": "temp_humidity_record",
"ver_code": 1
},
{
"id": "comfort_humidity",
"ver_code": 1
},
{
"id": "report_mode",
"ver_code": 1
},
{
"id": "comfort_temperature",
"ver_code": 1
},
{
"id": "boost_mode",
"ver_code": 2
},
{
"id": "holdon_mode",
"ver_code": 2
},
{
"id": "temperature_correction",
"ver_code": 1
},
{
"id": "window_open_detect",
"ver_code": 4
},
{
"id": "shutdown_mode",
"ver_code": 2
},
{
"id": "smart_control_schedule",
"ver_code": 2
},
{
"id": "temp_control",
"ver_code": 2
}
],
"device_id": "SCRUBBED_CHILD_DEVICE_ID_2"
}
],
"start_index": 0,
"sum": 2
},
"get_child_device_list": {
"child_device_list": [
{
"at_low_battery": false,
"avatar": "kasa_trv",
"battery_percentage": 100,
"bind_count": 1,
"category": "subg.trv",
"child_protection": false,
"current_humidity": 0,
"current_temp": 23.3,
"device_id": "SCRUBBED_CHILD_DEVICE_ID_1",
"frost_protection_on": false,
"fw_ver": "2.15.0 Build 260212 Rel.072732",
"hidden": false,
"hw_id": "00000000000000000000000000000000",
"hw_ver": "1.0",
"jamming_rssi": -111,
"jamming_signal_level": 1,
"location": "",
"mac": "0CEF15000000",
"max_control_temp": 30,
"min_control_temp": 5,
"model": "KE100",
"nickname": "I01BU0tFRF9OQU1FIw==",
"oem_id": "00000000000000000000000000000000",
"parent_device_id": "0000000000000000000000000000000000000000",
"region": "Europe/London",
"rssi": -41,
"signal_level": 3,
"specs": "UK",
"status": "online",
"status_follow_edge": false,
"target_temp": 23.0,
"temp_offset": 0,
"temp_unit": "celsius",
"trv_states": [],
"type": "SMART.KASAENERGY"
},
{
"at_low_battery": false,
"avatar": "kasa_trv",
"battery_percentage": 100,
"bind_count": 1,
"boost": false,
"category": "subg.trv",
"child_protection": false,
"current_humidity": 43,
"current_humidity_exception": 0,
"current_temp": 23.3,
"current_temp_exception": 0,
"device_id": "SCRUBBED_CHILD_DEVICE_ID_2",
"frost_protection_on": false,
"fw_ver": "1.4.0 Build 260330 Rel.011701",
"hold_on": false,
"hw_id": "00000000000000000000000000000000",
"hw_ver": "1.0",
"jamming_rssi": -116,
"jamming_signal_level": 1,
"location": "",
"mac": "782051000000",
"max_control_temp": 30,
"min_control_temp": 5,
"model": "KE110",
"nickname": "I01BU0tFRF9OQU1FIw==",
"oem_id": "00000000000000000000000000000000",
"parent_device_id": "0000000000000000000000000000000000000000",
"region": "Europe/London",
"rssi": -41,
"signal_level": 3,
"specs": "EU",
"status": "online",
"status_follow_edge": false,
"target_temp": 23.0,
"temp_humidity_notification": false,
"temp_offset": 0,
"temp_unit": "celsius",
"trv_states": [],
"type": "SMART.KASAENERGY"
}
],
"start_index": 0,
"sum": 2
},
"get_connect_cloud_state": {
"status": 0
},
"get_device_info": {
"avatar": "kasa_hub",
"device_id": "0000000000000000000000000000000000000000",
"fw_id": "00000000000000000000000000000000",
"fw_ver": "1.7.5 Build 260304 Rel.032022",
"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": "0C-EF-15-00-00-00",
"model": "KH100",
"nickname": "I01BU0tFRF9OQU1FIw==",
"oem_id": "00000000000000000000000000000000",
"overheated": false,
"region": "Europe/London",
"rssi": -40,
"signal_level": 3,
"specs": "UK",
"ssid": "I01BU0tFRF9TU0lEIw==",
"subg_phyid": "f863p35",
"time_diff": 0,
"type": "SMART.KASAHUB"
},
"get_device_load_info": {
"cur_load_num": 4,
"load_level": "light",
"max_load_num": 64,
"total_memory": 4352,
"used_memory": 1712
},
"get_device_time": {
"region": "Europe/London",
"time_diff": 0,
"timestamp": 1784360412
},
"get_device_usage": {},
"get_fw_download_state": {
"auto_upgrade": false,
"download_progress": 0,
"reboot_time": 5,
"status": 0,
"upgrade_time": 5
},
"get_inherit_info": {
"inherit_status": false
},
"get_latest_fw": {
"fw_size": 0,
"fw_ver": "1.7.5 Build 260304 Rel.032022",
"hw_id": "",
"need_to_upgrade": false,
"oem_id": "",
"release_date": "",
"release_note": "",
"type": 0
},
"get_led_info": {
"led_rule": "night_mode",
"led_status": true,
"night_mode": {
"end_time": 305,
"night_mode_type": "sunrise_sunset",
"start_time": 1287,
"sunrise_offset": 0,
"sunset_offset": 0
}
},
"get_matter_setup_info": {
"setup_code": "00000000000",
"setup_payload": "00:000000000000.000000"
},
"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": [
{
"bssid": "000000000000",
"channel": 0,
"cipher_type": 2,
"key_type": "wpa2_psk",
"signal_level": 3,
"ssid": "I01BU0tFRF9TU0lEIw=="
},
{
"bssid": "000000000000",
"channel": 0,
"cipher_type": 2,
"key_type": "wpa3_sae",
"signal_level": 3,
"ssid": "I01BU0tFRF9TU0lEIw=="
},
{
"bssid": "000000000000",
"channel": 0,
"cipher_type": 2,
"key_type": "wpa2_psk",
"signal_level": 2,
"ssid": "I01BU0tFRF9TU0lEIw=="
},
{
"bssid": "000000000000",
"channel": 0,
"cipher_type": 2,
"key_type": "wpa2_psk",
"signal_level": 2,
"ssid": "I01BU0tFRF9TU0lEIw=="
},
{
"bssid": "000000000000",
"channel": 0,
"cipher_type": 2,
"key_type": "wpa3_sae",
"signal_level": 2,
"ssid": "I01BU0tFRF9TU0lEIw=="
},
{
"bssid": "000000000000",
"channel": 0,
"cipher_type": 2,
"key_type": "wpa2_psk",
"signal_level": 2,
"ssid": "I01BU0tFRF9TU0lEIw=="
},
{
"bssid": "000000000000",
"channel": 0,
"cipher_type": 2,
"key_type": "wpa2_psk",
"signal_level": 1,
"ssid": "I01BU0tFRF9TU0lEIw=="
},
{
"bssid": "000000000000",
"channel": 0,
"cipher_type": 2,
"key_type": "wpa2_psk",
"signal_level": 1,
"ssid": "I01BU0tFRF9TU0lEIw=="
},
{
"bssid": "000000000000",
"channel": 0,
"cipher_type": 0,
"key_type": "none",
"signal_level": 1,
"ssid": "I01BU0tFRF9TU0lEIw=="
},
{
"bssid": "000000000000",
"channel": 0,
"cipher_type": 2,
"key_type": "wpa2_psk",
"signal_level": 1,
"ssid": "I01BU0tFRF9TU0lEIw=="
}
],
"start_index": 0,
"sum": 10,
"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
},
{
"id": "matter",
"ver_code": 3
}
],
"extra_info": {
"device_model": "KH100",
"device_type": "SMART.KASAHUB",
"is_klap": true
}
}
}

View File

@@ -0,0 +1,175 @@
{
"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": "remove_scale",
"ver_code": 1
},
{
"id": "early_start",
"ver_code": 1
},
{
"id": "screen_setting",
"ver_code": 1
},
{
"id": "night_mode",
"ver_code": 1
},
{
"id": "firmware",
"ver_code": 1
},
{
"id": "battery_detect",
"ver_code": 1
},
{
"id": "temp_record",
"ver_code": 1
},
{
"id": "progress_calibration",
"ver_code": 1
},
{
"id": "temperature_correction",
"ver_code": 1
},
{
"id": "window_open_detect",
"ver_code": 4
},
{
"id": "shutdown_mode",
"ver_code": 2
},
{
"id": "trv_multi_mode",
"ver_code": 1
},
{
"id": "smart_control_schedule",
"ver_code": 2
},
{
"id": "temp_control",
"ver_code": 2
}
]
},
"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": 23.3,
"device_id": "SCRUBBED_CHILD_DEVICE_ID_1",
"frost_protection_on": false,
"fw_ver": "2.15.0 Build 260212 Rel.072732",
"hidden": false,
"hw_id": "00000000000000000000000000000000",
"hw_ver": "1.0",
"jamming_rssi": -111,
"jamming_signal_level": 1,
"lastOnboardingTimestamp": 1769099784,
"location": "",
"mac": "0CEF15000000",
"max_control_temp": 30,
"min_control_temp": 5,
"model": "KE100",
"next_schedule_time": 0,
"nickname": "I01BU0tFRF9OQU1FIw==",
"oem_id": "00000000000000000000000000000000",
"parent_device_id": "0000000000000000000000000000000000000000",
"region": "Europe/London",
"rssi": -41,
"signal_level": 3,
"specs": "UK",
"status": "online",
"target_temp": 23.0,
"temp_offset": 0,
"temp_unit": "celsius",
"trv_states": [],
"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.15.0 Build 260212 Rel.072732",
"hw_id": "",
"need_to_upgrade": false,
"oem_id": "",
"release_date": "",
"release_note": "",
"type": 0
}
}

View File

@@ -0,0 +1,797 @@
{
"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": "remove_scale",
"ver_code": 1
},
{
"id": "early_start",
"ver_code": 1
},
{
"id": "screen_setting",
"ver_code": 1
},
{
"id": "night_mode",
"ver_code": 1
},
{
"id": "firmware",
"ver_code": 1
},
{
"id": "battery_detect",
"ver_code": 1
},
{
"id": "humidity",
"ver_code": 2
},
{
"id": "temp_humidity_record",
"ver_code": 1
},
{
"id": "comfort_humidity",
"ver_code": 1
},
{
"id": "report_mode",
"ver_code": 1
},
{
"id": "comfort_temperature",
"ver_code": 1
},
{
"id": "boost_mode",
"ver_code": 2
},
{
"id": "holdon_mode",
"ver_code": 2
},
{
"id": "temperature_correction",
"ver_code": 1
},
{
"id": "window_open_detect",
"ver_code": 4
},
{
"id": "shutdown_mode",
"ver_code": 2
},
{
"id": "smart_control_schedule",
"ver_code": 2
},
{
"id": "temp_control",
"ver_code": 2
}
]
},
"get_connect_cloud_state": {
"status": 0
},
"get_device_info": {
"at_low_battery": false,
"avatar": "kasa_trv",
"battery_percentage": 100,
"bind_count": 1,
"boost_remain_time": 1780479977,
"boost_temp": 300,
"boost_time": 1800,
"category": "subg.trv",
"child_protection": false,
"current_humidity": 43,
"current_humidity_exception": 0,
"current_temp": 23.3,
"current_temp_exception": 0,
"default_boost_temp": 300,
"default_boost_time": 1800,
"default_hold_on_time": 0,
"device_id": "SCRUBBED_CHILD_DEVICE_ID_2",
"frost_protection_on": false,
"fw_ver": "1.4.0 Build 260330 Rel.011701",
"hold_on": false,
"hold_on_remain_time": 1780441201,
"hold_on_time": 0,
"humidity_offset": 0,
"hw_id": "00000000000000000000000000000000",
"hw_ver": "1.0",
"jamming_rssi": -116,
"jamming_signal_level": 1,
"lastOnboardingTimestamp": 1769099419,
"location": "",
"mac": "782051000000",
"max_control_temp": 30,
"min_control_temp": 5,
"model": "KE110",
"next_schedule_time": 0,
"nickname": "I01BU0tFRF9OQU1FIw==",
"oem_id": "00000000000000000000000000000000",
"parent_device_id": "0000000000000000000000000000000000000000",
"region": "Europe/London",
"rssi": -41,
"signal_level": 3,
"specs": "EU",
"status": "online",
"target_temp": 23.0,
"temp_humidity_notification": false,
"temp_offset": 0,
"temp_unit": "celsius",
"trv_states": [],
"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": "1.4.0 Build 260330 Rel.011701",
"hw_id": "",
"need_to_upgrade": false,
"oem_id": "",
"release_date": "",
"release_note": "",
"type": 0
},
"get_temp_humidity_records": {
"deviceState": [
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[]
],
"heating_time": 0,
"local_time": 1784360414,
"past24h_humidity": [
57,
57,
58,
57,
58,
53,
47,
47,
49,
50,
50,
51,
51,
45,
45,
45,
45,
44,
42,
43,
41,
41,
41,
42,
42,
42,
42,
43,
43,
44,
44,
44,
45,
46,
45,
46,
47,
46,
45,
44,
43,
41,
40,
40,
42,
43,
45,
46,
41,
40,
40,
41,
42,
43,
43,
44,
44,
44,
45,
45,
45,
40,
40,
40,
41,
42,
42,
43,
44,
44,
45,
46,
47,
48,
48,
49,
50,
51,
51,
52,
52,
52,
53,
53,
54,
55,
56,
56,
55,
56,
57,
58,
58,
54,
45,
43
],
"past24h_humidity_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,
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,
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
],
"past24h_temp": [
281,
281,
280,
280,
280,
280,
267,
274,
279,
283,
286,
289,
290,
282,
282,
283,
283,
283,
277,
278,
269,
260,
255,
254,
249,
245,
243,
263,
267,
269,
271,
273,
274,
275,
277,
278,
279,
281,
278,
283,
280,
269,
264,
271,
274,
282,
285,
285,
275,
262,
270,
276,
280,
284,
286,
289,
291,
291,
292,
293,
292,
275,
265,
251,
265,
269,
271,
272,
273,
273,
273,
273,
273,
273,
273,
273,
273,
273,
273,
273,
273,
273,
272,
272,
272,
272,
271,
271,
271,
271,
271,
271,
271,
270,
257,
245
],
"past24h_temp_exception": [
21,
21,
20,
20,
20,
20,
7,
14,
19,
23,
26,
29,
30,
22,
22,
23,
23,
23,
17,
18,
9,
0,
0,
0,
0,
0,
0,
3,
7,
9,
11,
13,
14,
15,
17,
18,
19,
21,
18,
23,
20,
9,
4,
11,
14,
22,
25,
25,
15,
2,
10,
16,
20,
24,
26,
29,
31,
31,
32,
33,
32,
15,
5,
0,
5,
9,
11,
12,
13,
13,
13,
13,
13,
13,
13,
13,
13,
13,
13,
13,
13,
13,
12,
12,
12,
12,
11,
11,
11,
11,
11,
11,
11,
10,
0,
0
],
"target_temp": [
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230,
230
],
"temp_unit": "celsius"
}
}

View File

@@ -52,11 +52,12 @@ async def test_set_temperature_turns_heating_on(dev: SmartDevice) -> None:
assert temp_module.state is False
assert temp_module.mode is ThermostatState.Off
await temp_module.set_target_temperature(10)
max_temp = temp_module.maximum_target_temperature
await temp_module.set_target_temperature(max_temp)
await dev.update()
assert temp_module.state is True
assert temp_module.mode is ThermostatState.Heating
assert temp_module.target_temperature == 10
assert temp_module.target_temperature == max_temp
@thermostats_smart

View File

@@ -404,15 +404,16 @@ async def test_thermostat(dev: Device, mocker: MockerFixture) -> None:
assert therm_mod.state is False
assert therm_mod.mode is ThermostatState.Off
await therm_mod.set_target_temperature(10)
temp_control = dev.modules.get(Module.TemperatureControl)
assert temp_control
max_temp = temp_control.maximum_target_temperature
await therm_mod.set_target_temperature(max_temp)
await dev.update()
assert therm_mod.state is True
assert therm_mod.mode is ThermostatState.Heating
assert therm_mod.target_temperature == 10
assert therm_mod.target_temperature == max_temp
target_temperature_feature = therm_mod.get_feature(therm_mod.set_target_temperature)
temp_control = dev.modules.get(Module.TemperatureControl)
assert temp_control
allowed_range = temp_control.allowed_temperature_range
assert target_temperature_feature.minimum_value == allowed_range[0]
assert target_temperature_feature.maximum_value == allowed_range[1]