diff --git a/README.md b/README.md
index c17d80b56..85fc6982b 100644
--- a/README.md
+++ b/README.md
@@ -232,6 +232,7 @@ The following devices have been tested and confirmed as working. If your device
- **Bulbs**: KL110, KL120, KL125, KL130, KL135, KL50, KL60, LB110
- **Light Strips**: KL400L5, KL420L5, KL430
- **Hubs**: KH100\*
+- **Hub-Connected Devices\*\*\***: KE100\*
### Supported Tapo\* devices
@@ -241,10 +242,12 @@ The following devices have been tested and confirmed as working. If your device
- **Bulbs**: L510B, L510E, L530E
- **Light Strips**: L900-10, L900-5, L920-5, L930-5
- **Hubs**: H100
+- **Hub-Connected Devices\*\*\***: T300, T310, T315
-* Model requires authentication
-** Newer versions require authentication
+\* Model requires authentication
+\*\* Newer versions require authentication
+\*\*\* Devices may work across TAPO/KASA branded hubs
See [supported devices in our documentation](SUPPORTED.md) for more detailed information about tested hardware and software versions.
diff --git a/SUPPORTED.md b/SUPPORTED.md
index c4957c651..e52697635 100644
--- a/SUPPORTED.md
+++ b/SUPPORTED.md
@@ -6,7 +6,7 @@ The following devices have been tested and confirmed as working. If your device
## Kasa devices
-Some newer Kasa devices require authentication. These are marked with * in the list below.
+Some newer Kasa devices require authentication. These are marked with * in the list below.
Hub-Connected Devices may work across TAPO/KASA branded hubs even if they don't work across the native apps.
### Plugs
@@ -134,10 +134,16 @@ Some newer Kasa devices require authentication. These are marked with *\*
+### Hub-Connected Devices
+
+- **KE100**
+ - Hardware: 1.0 (EU) / Firmware: 2.8.0\*
+ - Hardware: 1.0 (UK) / Firmware: 2.8.0\*
+
## Tapo devices
-All Tapo devices require authentication.
+All Tapo devices require authentication.
Hub-Connected Devices may work across TAPO/KASA branded hubs even if they don't work across the native apps.
### Plugs
@@ -204,5 +210,14 @@ All Tapo devices require authentication.
- Hardware: 1.0 (EU) / Firmware: 1.2.3
- Hardware: 1.0 (EU) / Firmware: 1.5.5
+### Hub-Connected Devices
+
+- **T300**
+ - Hardware: 1.0 (EU) / Firmware: 1.7.0
+- **T310**
+ - Hardware: 1.0 (EU) / Firmware: 1.5.0
+- **T315**
+ - Hardware: 1.0 (EU) / Firmware: 1.7.0
+
diff --git a/devtools/generate_supported.py b/devtools/generate_supported.py
index fb0ac3cdc..b2909149c 100755
--- a/devtools/generate_supported.py
+++ b/devtools/generate_supported.py
@@ -29,10 +29,12 @@ class SupportedVersion(NamedTuple):
DeviceType.StripSocket: "Power Strips",
DeviceType.Dimmer: "Wall Switches",
DeviceType.WallSwitch: "Wall Switches",
+ DeviceType.Fan: "Wall Switches",
DeviceType.Bulb: "Bulbs",
DeviceType.LightStrip: "Light Strips",
DeviceType.Hub: "Hubs",
- DeviceType.Sensor: "Sensors",
+ DeviceType.Sensor: "Hub-Connected Devices",
+ DeviceType.Thermostat: "Hub-Connected Devices",
}
@@ -106,7 +108,7 @@ def _supported_summary(supported):
return _supported_text(
supported,
"### Supported $brand$auth devices\n\n$types\n",
- "- **$type_**: $models\n",
+ "- **$type_$type_asterix**: $models\n",
)
@@ -136,6 +138,10 @@ def _supported_text(
if brand == "kasa"
else "All Tapo devices require authentication."
)
+ preamble_text += (
+ "
Hub-Connected Devices may work across TAPO/KASA branded "
+ + "hubs even if they don't work across the native apps."
+ )
brand_text = brand.capitalize()
brand_auth = r"\*" if brand == "tapo" else ""
types_text = ""
@@ -177,7 +183,14 @@ def _supported_text(
else:
models_list.append(f"{model}{auth_flag}")
models_text = models_text if models_text else ", ".join(models_list)
- types_text += typest.substitute(type_=supported_type, models=models_text)
+ type_asterix = (
+ r"\*\*\*"
+ if supported_type == "Hub-Connected Devices"
+ else ""
+ )
+ types_text += typest.substitute(
+ type_=supported_type, type_asterix=type_asterix, models=models_text
+ )
brands += brandt.substitute(
brand=brand_text, types=types_text, auth=brand_auth, preamble=preamble_text
)
@@ -185,16 +198,22 @@ def _supported_text(
def _get_smart_supported(supported):
- for file in Path(SMART_FOLDER).glob("*.json"):
+ for file in Path(SMART_FOLDER).glob("**/*.json"):
with file.open() as f:
fixture_data = json.load(f)
- model, _, region = fixture_data["discovery_result"]["device_model"].partition(
- "("
- )
+ if "discovery_result" in fixture_data:
+ model, _, region = fixture_data["discovery_result"][
+ "device_model"
+ ].partition("(")
+ device_type = fixture_data["discovery_result"]["device_type"]
+ else: # child devices of hubs do not have discovery result
+ model = fixture_data["get_device_info"]["model"]
+ region = fixture_data["get_device_info"].get("specs")
+ device_type = fixture_data["get_device_info"]["type"]
# P100 doesn't have region HW
region = region.replace(")", "") if region else ""
- device_type = fixture_data["discovery_result"]["device_type"]
+
_protocol, devicetype = device_type.split(".")
brand = devicetype[:4].lower()
components = [
diff --git a/kasa/smart/smartdevice.py b/kasa/smart/smartdevice.py
index 98c5f7efe..185352a5a 100644
--- a/kasa/smart/smartdevice.py
+++ b/kasa/smart/smartdevice.py
@@ -639,6 +639,10 @@ def _get_device_type_from_components(
return DeviceType.Bulb
if "SWITCH" in device_type:
return DeviceType.WallSwitch
+ if "SENSOR" in device_type:
+ return DeviceType.Sensor
+ if "ENERGY" in device_type:
+ return DeviceType.Thermostat
_LOGGER.warning("Unknown device type, falling back to plug")
return DeviceType.Plug