mirror of
				https://github.com/python-kasa/python-kasa.git
				synced 2025-11-04 06:32:07 +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:
		@@ -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
 | 
			
		||||
- **Bulbs**: KL110, KL120, KL125, KL130, KL135, KL50, KL60, LB110
 | 
			
		||||
- **Light Strips**: KL400L5, KL420L5, KL430
 | 
			
		||||
- **Hubs**: KH100<sup>\*</sup>
 | 
			
		||||
 | 
			
		||||
### 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.9
 | 
			
		||||
 | 
			
		||||
### Hubs
 | 
			
		||||
 | 
			
		||||
- **KH100**
 | 
			
		||||
  - Hardware: 1.0 (UK) / Firmware: 1.5.6<sup>\*</sup>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Tapo devices
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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,
 | 
			
		||||
 
 | 
			
		||||
@@ -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):
 | 
			
		||||
 
 | 
			
		||||
@@ -28,16 +28,17 @@ class TemperatureSensor(SmartModule):
 | 
			
		||||
                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,7 @@ class TemperatureSensor(SmartModule):
 | 
			
		||||
    @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
 | 
			
		||||
        return self._device.sys_info.get("current_temp_exception", 0) != 0
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def temperature_unit(self):
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@ if TYPE_CHECKING:
 | 
			
		||||
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 @@ class TemperatureControl(SmartModule):
 | 
			
		||||
        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
 | 
			
		||||
 
 | 
			
		||||
@@ -107,8 +107,9 @@ DIMMERS = {
 | 
			
		||||
    *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 @@ ALL_DEVICES_SMART = (
 | 
			
		||||
    .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 @@ hubs_smart = 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 @@ 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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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"}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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 = parametrize(
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@temperature
 | 
			
		||||
@thermostats_smart
 | 
			
		||||
@pytest.mark.parametrize(
 | 
			
		||||
    "feature, type",
 | 
			
		||||
    [
 | 
			
		||||
        ("target_temperature", int),
 | 
			
		||||
        ("target_temperature", float),
 | 
			
		||||
        ("temperature_offset", int),
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user