mirror of
https://github.com/python-kasa/python-kasa.git
synced 2024-12-22 19:23:34 +00:00
Add support for KH100 hub (#847)
Add SMART.KASAHUB to the map of supported devices. This also adds fixture files for KH100, KE100, and T310, and adapts affected modules and their tests accordingly. --------- Co-authored-by: Steven B <51370195+sdb9696@users.noreply.github.com>
This commit is contained in:
parent
e7d6758b8d
commit
0ab7436eef
@ -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<sup>\*</sup>, KS220M, KS225<sup>\*</sup>, KS230
|
- **Wall Switches**: ES20M, HS200, HS210, HS220, KP405, KS200M, KS205<sup>\*</sup>, KS220M, KS225<sup>\*</sup>, KS230
|
||||||
- **Bulbs**: KL110, KL120, KL125, KL130, KL135, KL50, KL60, LB110
|
- **Bulbs**: KL110, KL120, KL125, KL130, KL135, KL50, KL60, LB110
|
||||||
- **Light Strips**: KL400L5, KL420L5, KL430
|
- **Light Strips**: KL400L5, KL420L5, KL430
|
||||||
|
- **Hubs**: KH100<sup>\*</sup>
|
||||||
|
|
||||||
### Supported Tapo<sup>\*</sup> devices
|
### Supported Tapo<sup>\*</sup> devices
|
||||||
|
|
||||||
|
@ -126,6 +126,11 @@ Some newer Kasa devices require authentication. These are marked with <sup>*</su
|
|||||||
- Hardware: 2.0 (US) / Firmware: 1.0.8
|
- Hardware: 2.0 (US) / Firmware: 1.0.8
|
||||||
- Hardware: 2.0 (US) / Firmware: 1.0.9
|
- Hardware: 2.0 (US) / Firmware: 1.0.9
|
||||||
|
|
||||||
|
### Hubs
|
||||||
|
|
||||||
|
- **KH100**
|
||||||
|
- Hardware: 1.0 (UK) / Firmware: 1.5.6<sup>\*</sup>
|
||||||
|
|
||||||
|
|
||||||
## Tapo devices
|
## Tapo devices
|
||||||
|
|
||||||
|
@ -166,6 +166,7 @@ def get_device_class_from_family(device_type: str) -> type[Device] | None:
|
|||||||
"SMART.TAPOSWITCH": SmartBulb,
|
"SMART.TAPOSWITCH": SmartBulb,
|
||||||
"SMART.KASAPLUG": SmartDevice,
|
"SMART.KASAPLUG": SmartDevice,
|
||||||
"SMART.TAPOHUB": SmartDevice,
|
"SMART.TAPOHUB": SmartDevice,
|
||||||
|
"SMART.KASAHUB": SmartDevice,
|
||||||
"SMART.KASASWITCH": SmartBulb,
|
"SMART.KASASWITCH": SmartBulb,
|
||||||
"IOT.SMARTPLUGSWITCH": IotPlug,
|
"IOT.SMARTPLUGSWITCH": IotPlug,
|
||||||
"IOT.SMARTBULB": IotBulb,
|
"IOT.SMARTBULB": IotBulb,
|
||||||
|
@ -39,6 +39,7 @@ class DeviceFamilyType(Enum):
|
|||||||
SmartTapoBulb = "SMART.TAPOBULB"
|
SmartTapoBulb = "SMART.TAPOBULB"
|
||||||
SmartTapoSwitch = "SMART.TAPOSWITCH"
|
SmartTapoSwitch = "SMART.TAPOSWITCH"
|
||||||
SmartTapoHub = "SMART.TAPOHUB"
|
SmartTapoHub = "SMART.TAPOHUB"
|
||||||
|
SmartKasaHub = "SMART.KASAHUB"
|
||||||
|
|
||||||
|
|
||||||
def _dataclass_from_dict(klass, in_val):
|
def _dataclass_from_dict(klass, in_val):
|
||||||
|
@ -28,6 +28,7 @@ class TemperatureSensor(SmartModule):
|
|||||||
icon="mdi:thermometer",
|
icon="mdi:thermometer",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
if "current_temp_exception" in device.sys_info:
|
||||||
self._add_feature(
|
self._add_feature(
|
||||||
Feature(
|
Feature(
|
||||||
device,
|
device,
|
||||||
@ -57,7 +58,7 @@ class TemperatureSensor(SmartModule):
|
|||||||
@property
|
@property
|
||||||
def temperature_warning(self) -> bool:
|
def temperature_warning(self) -> bool:
|
||||||
"""Return True if temperature is outside of the wanted range."""
|
"""Return True if temperature is outside of the wanted range."""
|
||||||
return self._device.sys_info["current_temp_exception"] != 0
|
return self._device.sys_info.get("current_temp_exception", 0) != 0
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def temperature_unit(self):
|
def temperature_unit(self):
|
||||||
|
@ -14,7 +14,7 @@ if TYPE_CHECKING:
|
|||||||
class TemperatureControl(SmartModule):
|
class TemperatureControl(SmartModule):
|
||||||
"""Implementation of temperature module."""
|
"""Implementation of temperature module."""
|
||||||
|
|
||||||
REQUIRED_COMPONENT = "temperature_control"
|
REQUIRED_COMPONENT = "temp_control"
|
||||||
|
|
||||||
def __init__(self, device: SmartDevice, module: str):
|
def __init__(self, device: SmartDevice, module: str):
|
||||||
super().__init__(device, module)
|
super().__init__(device, module)
|
||||||
@ -57,11 +57,11 @@ class TemperatureControl(SmartModule):
|
|||||||
return self._device.sys_info["max_control_temp"]
|
return self._device.sys_info["max_control_temp"]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def target_temperature(self) -> int:
|
def target_temperature(self) -> float:
|
||||||
"""Return target temperature."""
|
"""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."""
|
"""Set target temperature."""
|
||||||
if (
|
if (
|
||||||
target < self.minimum_target_temperature
|
target < self.minimum_target_temperature
|
||||||
|
@ -107,8 +107,9 @@ DIMMERS = {
|
|||||||
*DIMMERS_SMART,
|
*DIMMERS_SMART,
|
||||||
}
|
}
|
||||||
|
|
||||||
HUBS_SMART = {"H100"}
|
HUBS_SMART = {"H100", "KH100"}
|
||||||
SENSORS_SMART = {"T315"}
|
SENSORS_SMART = {"T310", "T315"}
|
||||||
|
THERMOSTATS_SMART = {"KE100"}
|
||||||
|
|
||||||
WITH_EMETER_IOT = {"HS110", "HS300", "KP115", "KP125", *BULBS_IOT}
|
WITH_EMETER_IOT = {"HS110", "HS300", "KP115", "KP125", *BULBS_IOT}
|
||||||
WITH_EMETER_SMART = {"P110", "KP125M", "EP25"}
|
WITH_EMETER_SMART = {"P110", "KP125M", "EP25"}
|
||||||
@ -126,6 +127,7 @@ ALL_DEVICES_SMART = (
|
|||||||
.union(HUBS_SMART)
|
.union(HUBS_SMART)
|
||||||
.union(SENSORS_SMART)
|
.union(SENSORS_SMART)
|
||||||
.union(SWITCHES_SMART)
|
.union(SWITCHES_SMART)
|
||||||
|
.union(THERMOSTATS_SMART)
|
||||||
)
|
)
|
||||||
ALL_DEVICES = ALL_DEVICES_IOT.union(ALL_DEVICES_SMART)
|
ALL_DEVICES = ALL_DEVICES_IOT.union(ALL_DEVICES_SMART)
|
||||||
|
|
||||||
@ -275,6 +277,9 @@ hubs_smart = parametrize(
|
|||||||
sensors_smart = parametrize(
|
sensors_smart = parametrize(
|
||||||
"sensors smart", model_filter=SENSORS_SMART, protocol_filter={"SMART.CHILD"}
|
"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(
|
device_smart = parametrize(
|
||||||
"devices smart", model_filter=ALL_DEVICES_SMART, protocol_filter={"SMART"}
|
"devices smart", model_filter=ALL_DEVICES_SMART, protocol_filter={"SMART"}
|
||||||
)
|
)
|
||||||
@ -296,6 +301,7 @@ def check_categories():
|
|||||||
+ dimmers_smart.args[1]
|
+ dimmers_smart.args[1]
|
||||||
+ hubs_smart.args[1]
|
+ hubs_smart.args[1]
|
||||||
+ sensors_smart.args[1]
|
+ sensors_smart.args[1]
|
||||||
|
+ thermostats_smart.args[1]
|
||||||
)
|
)
|
||||||
diffs: set[FixtureInfo] = set(FIXTURE_DATA) - set(categorized_fixtures)
|
diffs: set[FixtureInfo] = set(FIXTURE_DATA) - set(categorized_fixtures)
|
||||||
if diffs:
|
if diffs:
|
||||||
@ -313,7 +319,12 @@ check_categories()
|
|||||||
def device_for_fixture_name(model, protocol):
|
def device_for_fixture_name(model, protocol):
|
||||||
if "SMART" in protocol:
|
if "SMART" in protocol:
|
||||||
for d in chain(
|
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:
|
if d in model:
|
||||||
return SmartDevice
|
return SmartDevice
|
||||||
|
1557
kasa/tests/fixtures/smart/KH100(UK)_1.0_1.5.6.json
vendored
Normal file
1557
kasa/tests/fixtures/smart/KH100(UK)_1.0_1.5.6.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
171
kasa/tests/fixtures/smart/child/KE100(EU)_1.0_2.8.0.json
vendored
Normal file
171
kasa/tests/fixtures/smart/child/KE100(EU)_1.0_2.8.0.json
vendored
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
{
|
||||||
|
"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
|
||||||
|
},
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
}
|
171
kasa/tests/fixtures/smart/child/KE100(UK)_1.0_2.8.0.json
vendored
Normal file
171
kasa/tests/fixtures/smart/child/KE100(UK)_1.0_2.8.0.json
vendored
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
{
|
||||||
|
"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
|
||||||
|
},
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
}
|
530
kasa/tests/fixtures/smart/child/T310(EU)_1.0_1.5.0.json
vendored
Normal file
530
kasa/tests/fixtures/smart/child/T310(EU)_1.0_1.5.0.json
vendored
Normal file
@ -0,0 +1,530 @@
|
|||||||
|
{
|
||||||
|
"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
|
||||||
|
},
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
}
|
@ -7,13 +7,18 @@ temperature = parametrize(
|
|||||||
"has temperature", component_filter="temperature", protocol_filter={"SMART.CHILD"}
|
"has temperature", component_filter="temperature", protocol_filter={"SMART.CHILD"}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
temperature_warning = parametrize(
|
||||||
|
"has temperature warning",
|
||||||
|
component_filter="comfort_temperature",
|
||||||
|
protocol_filter={"SMART.CHILD"},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@temperature
|
@temperature
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"feature, type",
|
"feature, type",
|
||||||
[
|
[
|
||||||
("temperature", float),
|
("temperature", float),
|
||||||
("temperature_warning", bool),
|
|
||||||
("temperature_unit", str),
|
("temperature_unit", str),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@ -27,3 +32,16 @@ async def test_temperature_features(dev, feature, type):
|
|||||||
feat = temp_module._module_features[feature]
|
feat = temp_module._module_features[feature]
|
||||||
assert feat.value == prop
|
assert feat.value == prop
|
||||||
assert isinstance(feat.value, type)
|
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)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from kasa.smart.modules import TemperatureSensor
|
from kasa.smart.modules import TemperatureSensor
|
||||||
from kasa.tests.device_fixtures import parametrize
|
from kasa.tests.device_fixtures import parametrize, thermostats_smart
|
||||||
|
|
||||||
temperature = parametrize(
|
temperature = parametrize(
|
||||||
"has temperature control",
|
"has temperature control",
|
||||||
@ -10,11 +10,11 @@ temperature = parametrize(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@temperature
|
@thermostats_smart
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"feature, type",
|
"feature, type",
|
||||||
[
|
[
|
||||||
("target_temperature", int),
|
("target_temperature", float),
|
||||||
("temperature_offset", int),
|
("temperature_offset", int),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user