| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
Codecov Report❌ Patch coverage is 97.33333% with 2 lines in your changes missing coverage. Please review.
@@ Coverage Diff @@
## master #1580 +/- ##
==========================================
+ Coverage 93.21% 93.40% +0.18%
==========================================
Files 157 157
Lines 9819 9870 +51
Branches 1005 1013 +8
==========================================
+ Hits 9153 9219 +66
+ Misses 472 462 -10
+ Partials 194 189 -5 ☔ View full report in Codecov by Harness.
|
Sorry, something went wrong.
|
@rytilahti I haven't seen this before: 1 high Annotations Code scanning Use of a broken or weak cryptographic hashing algorithm on sensitive data is used in a hashing algorithm (SHA1) that is insecure. Is this because I modified this file and now it's looking at it? You had the code they flag already in your code, but I'm not sure why it's being flagged as a problem now. |
Sorry, something went wrong.
|
Ok, had my user test and the discovery and CLI tests were successful, but we're getting 400 error responses at first with handshake1 one or two times and then it works. Not sure what that's about yet, will keep poking around. |
Sorry, something went wrong.
|
@rytilahti Ok, here's where it gets weird. I found that it actually isn't a new KLAP, it still uses XOR. The issue isn't the actual transport, it's how it's selecting the transport. I will modify things so that in the device factory, it's still forcing XOR if the device has new_klap. It's a much easier fix and has been working consistently on my end. |
Sorry, something went wrong.
There was a problem hiding this comment.
This PR implements KlapTransportV3 for the new_klap protocol by adding support for a new "new_klap" parameter throughout the discovery and device configuration system. The implementation allows devices that support this new KLAP variant to be properly detected and configured to use XorTransport instead of the standard KlapTransport.
Key changes:
Copilot reviewed 14 out of 14 changed files in this pull request and generated no comments.
Show a summary per file| File | Description |
|---|---|
| kasa/deviceconfig.py | Added new_klap field to DeviceConnectionParameters with custom serialization |
| kasa/discover.py | Added new_klap support to discovery protocol with special finalization logic |
| kasa/device_factory.py | Added routing logic to use XorTransport for new_klap devices |
| tests/test_discovery.py | Added comprehensive test for new_klap discovery finalization behavior |
| tests/test_deviceconfig.py | Added test configuration and serialization test for new_klap |
| tests/test_device_factory.py | Added test case for new_klap protocol selection |
| devtools/dump_devinfo.py | Updated device info capture to include new_klap parameter |
tests/test_cli.py:1
import json
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
Sorry, something went wrong.
|
@rytilahti Ok, so you can understand what I did here. I managed to make it where during discovery, it adds a new_klap portion to the management schema if it exists. Then it checks if that exists and if so, it runs the XOR transport on the IOT protocol. Otherwise, it was trying to actually use the KLAP transport which even though it says KLAP it's XOR. This allows the device to initially be discovered, but the problem comes up where the KLAP discovery results don't allow for the segmented device types for IOT. So, I update the device one time, pull the sysinfo, then mutate that back to what a XOR discovery result would be and re-initialize the device from the sysinfo. This seems to be working quite well and reliably for me and the one user who has been testing this with me, @allenrabinovich. Old IOT and new SMART devices are working correctly for me as well. |
Sorry, something went wrong.
There was a problem hiding this comment.
A couple of quick comments, also, please do not forget to change the title of this PR when this is ready for a review :-)
Sorry, something went wrong.
|
@rytilahti Ok, I think I got everything figured out. It is actually KlapTransportV2. I have modified everything to handle this and updated all of the test coverage as well. Everything looks good on my end as well. |
Sorry, something went wrong.
There was a problem hiding this comment.
I cannot test this mysef, but it looks good on surface. I would suggest tidying it up a bit to keep the code more maintainable if and when new authentication methods pop up, but your call!
Sorry, something went wrong.
|
I tested this locally and it's working well so far. Thanks! |
Sorry, something went wrong.
|
Any idea when this might make it to production? I had been using the patch in this post after each HomeAssistant update but after the latest 2026.2.3 the patch doesn't work anymore. |
Sorry, something went wrong.
test logI tested the PR and it's working with HS103 firmware 1.1.3. Reminder: after upgrading the plug to firmware 1.1.3, even correct credentials can trigger an authentication error. The fix was to unregister the plug from the app and reinitialize it. (.venv) user@host:~/kasa$ kasa -v -d --host REDACTED_IP sysinfo
Discovering device REDACTED_IP for 10 seconds
DEBUG:kasa.discover:[DISCOVERY] REDACTED_IP >> {'system': {'get_sysinfo': {}}}
DEBUG:kasa.discover:Waiting a total of 10 seconds for responses...
DEBUG:kasa.device_factory:Finding protocol for REDACTED_IP
DEBUG:kasa.device_factory:Finding protocol for DeviceFamily.IotSmartPlugSwitch
DEBUG:kasa.device_factory:Finding transport for IOT.KLAP.NEW_KLAP
DEBUG:kasa.transports.klaptransport:Created KLAP transport for REDACTED_IP
DEBUG:kasa.protocols.iotprotocol:REDACTED_IP >> {"system":{"get_sysinfo":{}}}
DEBUG:kasa.transports.klaptransport:Starting handshake with REDACTED_IP
DEBUG:kasa.httpclient:Posting to http://REDACTED_IP/app/handshake1
DEBUG:kasa.transports.klaptransport:Handshake1 posted at 2026-04-26 20:39:38.854634. Host is REDACTED_IP, Response status is 200, Request was REDACTED_REQUEST_ID
DEBUG:kasa.transports.klaptransport:Handshake1 success at 2026-04-26 20:39:38.854874. Host is REDACTED_IP, Server remote_seed is: REDACTED_REMOTE_SEED, server hash is: REDACTED_SERVER_HASH
DEBUG:kasa.transports.klaptransport:handshake1 hashes match with expected credentials
DEBUG:kasa.httpclient:Posting to http://REDACTED_IP/app/handshake2
DEBUG:kasa.transports.klaptransport:Handshake2 posted 2026-04-26 20:39:38.860822. Host is REDACTED_IP, Response status is 200, Request was REDACTED_REQUEST_ID_2
DEBUG:kasa.transports.klaptransport:Handshake with REDACTED_IP complete
DEBUG:kasa.httpclient:Posting to http://REDACTED_IP/app/request
DEBUG:kasa.transports.klaptransport:Device REDACTED_IP query posted Host is REDACTED_IP, Sequence is -1639787443, Response status is 200, Request was {"system":{"get_sysinfo":{}}}
DEBUG:kasa.transports.klaptransport:Device REDACTED_IP query response received
DEBUG:kasa.protocols.iotprotocol:REDACTED_IP << {'system': {'get_sysinfo': {'active_mode': 'none',
'alias': '#MASKED_NAME#',
'dev_name': 'Smart Wi-Fi Plug Mini',
'deviceId': 'REDACTED_DEVICE_ID',
'err_code': 0,
'feature': 'TIM',
'hwId': 'REDACTED_HW_ID',
'hw_ver': '5.0',
'icon_hash': '',
'latitude_i': 0,
'led_off': 0,
'lnk_on': 0,
'longitude_i': 0,
'mac': 'REDACTED_MAC',
'mic_type': 'IOT.SMARTPLUGSWITCH',
'model': 'HS103(US)',
'next_action': {'type': -1},
'obd_src': 'tplink',
'oemId': 'REDACTED_OEM_ID',
'on_time': 0,
'relay_state': 0,
'rssi': -26,
'status': 'new',
'sw_ver': '1.1.3 Build 250908 Rel.112508',
'updating': 0}}}
DEBUG:kasa.device:Initializing REDACTED_IP of type <class 'kasa.iot.iotplug.IotPlug'>
DEBUG:kasa.discover:[DISCOVERY] REDACTED_IP << {'error_code': 0,
'result': {'device_id': 'REDACTED_DEVICE_ID',
'device_model': 'HS103(US)',
'device_type': 'IOT.SMARTPLUGSWITCH',
'factory_default': False,
'hw_ver': '5.0',
'ip': 'REDACTED_IP',
'mac': 'REDACTED_MAC',
'mgt_encrypt_schm': {'ANS': False,
'encrypt_type': 'KLAP',
'http_port': 80,
'is_support_https': False,
'lv': 2,
'new_klap': 1},
'obd_src': 'tplink',
'owner': 'REDACTED_OWNER',
'protocol_version': 1}}
DEBUG:kasa.iot.iotdevice:Performing the initial update to obtain sysinfo
DEBUG:kasa.protocols.iotprotocol:REDACTED_IP >> {"system":{"get_sysinfo":{}}}
DEBUG:kasa.httpclient:Posting to http://REDACTED_IP/app/request
DEBUG:kasa.transports.klaptransport:Device REDACTED_IP query posted Host is REDACTED_IP, Sequence is -1639787442, Response status is 200, Request was {"system":{"get_sysinfo":{}}}
DEBUG:kasa.transports.klaptransport:Device REDACTED_IP query response received
DEBUG:kasa.protocols.iotprotocol:REDACTED_IP << {'system': {'get_sysinfo': {'active_mode': 'none',
'alias': '#MASKED_NAME#',
'dev_name': 'Smart Wi-Fi Plug Mini',
'deviceId': 'REDACTED_DEVICE_ID',
'err_code': 0,
'feature': 'TIM',
'hwId': 'REDACTED_HW_ID',
'hw_ver': '5.0',
'icon_hash': '',
'latitude_i': 0,
'led_off': 0,
'lnk_on': 0,
'longitude_i': 0,
'mac': 'REDACTED_MAC',
'mic_type': 'IOT.SMARTPLUGSWITCH',
'model': 'HS103(US)',
'next_action': {'type': -1},
'obd_src': 'tplink',
'oemId': 'REDACTED_OEM_ID',
'on_time': 0,
'relay_state': 0,
'rssi': -26,
'status': 'new',
'sw_ver': '1.1.3 Build 250908 Rel.112508',
'updating': 0}}}
DEBUG:kasa.iot.iotdevice:Adding module <Module HomeKit (smartlife.iot.homekit) for REDACTED_IP>
DEBUG:kasa.iot.iotdevice:Adding module <Module Schedule (schedule) for REDACTED_IP>
DEBUG:kasa.iot.iotdevice:Adding module <Module Usage (schedule) for REDACTED_IP>
DEBUG:kasa.iot.iotdevice:Adding module <Module Antitheft (anti_theft) for REDACTED_IP>
DEBUG:kasa.iot.iotdevice:Adding module <Module Time (time) for REDACTED_IP>
DEBUG:kasa.iot.iotdevice:Adding module <Module Cloud (cnCloud) for REDACTED_IP>
DEBUG:kasa.iot.iotdevice:Adding module <Module Led (system) for REDACTED_IP>
DEBUG:kasa.iot.iotmodule:Initial update, so consider supported: smartlife.iot.homekit
DEBUG:kasa.iot.iotdevice:Adding query for <Module HomeKit (smartlife.iot.homekit) for REDACTED_IP>: {'smartlife.iot.homekit': {'setup_info_get': {}}}
DEBUG:kasa.iot.iotmodule:Initial update, so consider supported: schedule
DEBUG:kasa.iot.iotdevice:Adding query for <Module Schedule (schedule) for REDACTED_IP>: {'schedule': {'get_rules': {}, 'get_next_action': {}}}
DEBUG:kasa.iot.iotmodule:Initial update, so consider supported: schedule
DEBUG:kasa.iot.iotdevice:Adding query for <Module Usage (schedule) for REDACTED_IP>: {'schedule': {'get_realtime': {}, 'get_daystat': {'year': 2026, 'month': 4}, 'get_monthstat': {'year': 2026}}}
DEBUG:kasa.iot.iotmodule:Initial update, so consider supported: anti_theft
DEBUG:kasa.iot.iotdevice:Adding query for <Module Antitheft (anti_theft) for REDACTED_IP>: {'anti_theft': {'get_rules': {}, 'get_next_action': {}}}
DEBUG:kasa.iot.iotmodule:Initial update, so consider supported: time
DEBUG:kasa.iot.iotdevice:Adding query for <Module Time (time) for REDACTED_IP>: {'time': {'get_time': {}, 'get_timezone': {}}}
DEBUG:kasa.iot.iotmodule:Initial update, so consider supported: cnCloud
DEBUG:kasa.iot.iotdevice:Adding query for <Module Cloud (cnCloud) for REDACTED_IP>: {'cnCloud': {'get_info': {}}}
DEBUG:kasa.iot.iotdevice:Adding query for <Module Led (system) for REDACTED_IP>: {}
DEBUG:kasa.protocols.iotprotocol:REDACTED_IP >> {"system":{"get_sysinfo":{}},"smartlife.iot.homekit":{"setup_info_get":{}},"schedule":{"get_rules":{},"get_next_action":{},"get_realtime":{},"get_daystat":{"year":2026,"month":4},"get_monthstat":{"year":2026}},"anti_theft":{"get_rules":{},"get_next_action":{}},"time":{"get_time":{},"get_timezone":{}},"cnCloud":{"get_info":{}}}
DEBUG:kasa.httpclient:Posting to http://REDACTED_IP/app/request
DEBUG:kasa.transports.klaptransport:Device REDACTED_IP query posted Host is REDACTED_IP, Sequence is -1639787441, Response status is 200, Request was {"system":{"get_sysinfo":{}},"smartlife.iot.homekit":{"setup_info_get":{}},"schedule":{"get_rules":{},"get_next_action":{},"get_realtime":{},"get_daystat":{"year":2026,"month":4},"get_monthstat":{"year":2026}},"anti_theft":{"get_rules":{},"get_next_action":{}},"time":{"get_time":{},"get_timezone":{}},"cnCloud":{"get_info":{}}}
DEBUG:kasa.transports.klaptransport:Device REDACTED_IP query response received
DEBUG:kasa.protocols.iotprotocol:REDACTED_IP << {'anti_theft': {'get_next_action': {'err_code': -2,
'err_msg': 'member not support'},
'get_rules': {'enable': 0,
'err_code': 0,
'rule_list': [],
'version': 2}},
'cnCloud': {'get_info': {'binded': 1,
'cld_connection': 1,
'err_code': 0,
'fwDlPage': '',
'fwNotifyType': -1,
'illegalType': 0,
'server': 'n-devs.tplinkcloud.com',
'stopConnect': 0,
'tcspInfo': '',
'tcspStatus': 1,
'username': 'REDACTED_USERNAME'}},
'schedule': {'get_daystat': {'day_list': [{'day': 26,
'month': 4,
'time': 68,
'year': 2026}],
'err_code': 0},
'get_monthstat': {'err_code': 0,
'month_list': [{'month': 4,
'time': 68,
'year': 2026}]},
'get_next_action': {'err_code': 0, 'type': -1},
'get_realtime': {'err_code': -2, 'err_msg': 'member not support'},
'get_rules': {'enable': 1,
'err_code': 0,
'rule_list': [],
'version': 2}},
'smartlife.iot.homekit': {'err_code': -1, 'err_msg': 'module not support'},
'system': {'get_sysinfo': {'active_mode': 'none',
'alias': '#MASKED_NAME#',
'dev_name': 'Smart Wi-Fi Plug Mini',
'deviceId': 'REDACTED_DEVICE_ID',
'err_code': 0,
'feature': 'TIM',
'hwId': 'REDACTED_HW_ID',
'hw_ver': '5.0',
'icon_hash': '',
'latitude_i': 0,
'led_off': 0,
'lnk_on': 0,
'longitude_i': 0,
'mac': 'REDACTED_MAC',
'mic_type': 'IOT.SMARTPLUGSWITCH',
'model': 'HS103(US)',
'next_action': {'type': -1},
'obd_src': 'tplink',
'oemId': 'REDACTED_OEM_ID',
'on_time': 0,
'relay_state': 0,
'rssi': -26,
'status': 'new',
'sw_ver': '1.1.3 Build 250908 Rel.112508',
'updating': 0}},
'time': {'get_time': {'err_code': 0,
'hour': 20,
'mday': 26,
'min': 39,
'month': 4,
'sec': 38,
'year': 2026},
'get_timezone': {'err_code': 0, 'index': 6}}}
== System info ==
{'active_mode': 'none',
'alias': '#MASKED_NAME#',
'dev_name': 'Smart Wi-Fi Plug Mini',
'deviceId': 'REDACTED_DEVICE_ID',
'err_code': 0,
'feature': 'TIM',
'hwId': 'REDACTED_HW_ID',
'hw_ver': '5.0',
'icon_hash': '',
'latitude_i': REDACTED_LATITUDE,
'led_off': 0,
'lnk_on': 0,
'longitude_i': REDACTED_LONGITUDE,
'mac': 'REDACTED_MAC',
'mic_type': 'IOT.SMARTPLUGSWITCH',
'model': 'HS103(US)',
'next_action': {'type': -1},
'obd_src': 'tplink',
'oemId': 'REDACTED_OEM_ID',
'on_time': 0,
'relay_state': 0,
'rssi': -26,
'status': 'new',
'sw_ver': '1.1.3 Build 250908 Rel.112508',
'updating': 0}
|
Sorry, something went wrong.
|
@genzj Thanks for the test and information. There are still some transient issues with Discover and how devices respond that can cause some issues but overall this fix works. I have several other PRs that I'm trying to get all worked on and merged before another release but I'm not sure when that will happen. |
Sorry, something went wrong.
|
any update on the status of this PR? my two HS300s suddenly stopped working with home-assistant today and I think this is why... |
Sorry, something went wrong.
|
Follow-up pass pushed in 71a4147. Covered in this pass:
Local validation:
After the push, GitHub lint and CodeQL were already green; the matrix CI/readthedocs jobs were still running when I checked. |
Sorry, something went wrong.
|
Independent real-device validation of the current head (71a4147984aedc7cfa9ce4613204ecf28b15dac7) against an HS300 that fails with python-kasa 0.10.2 because discovery advertises IOT + KLAP with login version 2 while that release selects the v1 transport. Device details:
Results with this PR:
The same physical device currently requires an application-level workaround that forces KlapTransportV2 when using 0.10.2. This PR makes that workaround unnecessary. Credentials, network addresses, MAC addresses, device IDs, and outlet names were excluded from this report. Independent HS300 validation: works as expected. |
Sorry, something went wrong.
|
hi @ZeliardM - do you know if/when this PR will be merged and a new release created? |
Sorry, something went wrong.
|
This PR also helped me bypass an authentication error. == TP-LINK_Smart Plug_FA58 - HS103 == Hardware: 5.0 (US) Firmware: 1.1.3 Build 250908 Rel.112508 Initially, I connected to SSID of plug (which had previously been connected to cloud), then ran: uv run kasa --debug --username "username@example.com" --password "some&passw123rd!" --host 192.168.0.1 time sync Discovering device 192.168.0.1 for 10 seconds
DEBUG:kasa.discover:[DISCOVERY] 192.168.0.1 >> {'system': {'get_sysinfo': {}}}
DEBUG:kasa.discover:Waiting a total of 10 seconds for responses...
DEBUG:kasa.device_factory:Using IotPlug for IOT.SMARTPLUGSWITCH
DEBUG:kasa.device_factory:Finding protocol for 192.168.0.1
DEBUG:kasa.device_factory:Finding protocol for DeviceFamily.IotSmartPlugSwitch
DEBUG:kasa.device_factory:Finding transport for IOT.KLAP
DEBUG:kasa.transports.klaptransport:Created KLAP transport for 192.168.0.1
DEBUG:kasa.discover:[DISCOVERY] 192.168.0.1 << {'error_code': 0,
'result': {'device_id': 'REDACTED_bb86dbf1b674c79addd0c8b',
'device_model': 'HS103(US)',
'device_type': 'IOT.SMARTPLUGSWITCH',
'factory_default': True,
'hw_ver': '5.0',
'ip': '192.168.0.1',
'mac': '00-5F-67-00-00-00',
'mgt_encrypt_schm': {'ANS': False,
'encrypt_type': 'KLAP',
'http_port': 80,
'is_support_https': False,
'lv': 2,
'new_klap': 1},
'obd_src': 'tplink',
'owner': '',
'protocol_version': 1}}
DEBUG:kasa.device:Initializing 192.168.0.1 of type <class 'kasa.iot.iotplug.IotPlug'>
DEBUG:kasa.iot.iotdevice:Performing the initial update to obtain sysinfo
DEBUG:kasa.protocols.iotprotocol:192.168.0.1 >> {"system":{"get_sysinfo":{}}}
DEBUG:kasa.transports.klaptransport:Starting handshake with 192.168.0.1
DEBUG:kasa.httpclient:Posting to http://192.168.0.1/app/handshake1
DEBUG:kasa.transports.klaptransport:Handshake1 posted at 2026-08-29 11:21:29.686484. Host is 192.168.0.1, Response status is 200, Request was 01eb02fd6c3347ed5495df770f9e90cb
DEBUG:kasa.transports.klaptransport:Handshake1 success at 2026-08-29 11:21:29.686616. Host is 192.168.0.1, Server remote_seed is: 3ec60589e231868b15df048a7b24058b, server hash is: 5234c1ddfd45ae354d03d9f44732f4fde8ba02e8f74cb537b081fb08ca4532a7
DEBUG:kasa.transports.klaptransport:Device response did not match our challenge on ip 192.168.0.1, check that your e-mail and password (both case-sensitive) are correct.
DEBUG:kasa.protocols.iotprotocol:Unable to authenticate with 192.168.0.1, not retrying
Raised error: Device response did not match our challenge on ip 192.168.0.1, check that your e-mail and password (both case-sensitive) are correct.
git fetch origin pull/1580/head:pr-1580-ZeliardM git checkout pr-1580-ZeliardM Discovering device 192.168.0.1 for 10 seconds
DEBUG:kasa.discover:[DISCOVERY] 192.168.0.1 >> {'system': {'get_sysinfo': {}}}
DEBUG:kasa.discover:Waiting a total of 10 seconds for responses...
DEBUG:kasa.device_factory:Finding protocol for 192.168.0.1
DEBUG:kasa.device_factory:Finding protocol for DeviceFamily.IotSmartPlugSwitch
DEBUG:kasa.device_factory:Finding transport for IOT.KLAP.NEW_KLAP
DEBUG:kasa.transports.klaptransport:Created KLAP transport for 192.168.0.1
DEBUG:kasa.protocols.iotprotocol:192.168.0.1 >> {"system":{"get_sysinfo":{}}}
DEBUG:kasa.transports.klaptransport:Starting handshake with 192.168.0.1
DEBUG:kasa.httpclient:Posting to http://192.168.0.1/app/handshake1
DEBUG:kasa.transports.klaptransport:Handshake1 posted at 2026-08-29 11:30:29.847252. Host is 192.168.0.1, Response status is 200, Request was 49f7e64c63a0111ee34dcb3d5112addd
DEBUG:kasa.transports.klaptransport:Handshake1 success at 2026-08-29 11:30:29.847471. Host is 192.168.0.1, Server remote_seed is: c04149b402724bb431134bb5d00a4ab5, server hash is: 6235debdd4ffae301ef0e836087f4ae4cd612285ec74c70b72a31fe78491eef8
DEBUG:kasa.transports.klaptransport:Device response did not match our expected hash on ip 192.168.0.1,but an authentication with KASA default credentials worked
DEBUG:kasa.httpclient:Posting to http://192.168.0.1/app/handshake2
DEBUG:kasa.transports.klaptransport:Handshake2 posted 2026-08-29 11:30:29.852758. Host is 192.168.0.1, Response status is 200, Request was 4b15dd64f589940b3b38315eee0bc77633dac8bd47b1526e7392665ec0ff40ff
DEBUG:kasa.transports.klaptransport:Handshake with 192.168.0.1 complete
DEBUG:kasa.httpclient:Posting to http://192.168.0.1/app/request
DEBUG:kasa.transports.klaptransport:Device 192.168.0.1 query posted Host is 192.168.0.1, Sequence is -534551261, Response status is 200, Request was {"system":{"get_sysinfo":{}}}
DEBUG:kasa.transports.klaptransport:Device 192.168.0.1 query response received
DEBUG:kasa.protocols.iotprotocol:192.168.0.1 << {'system': {'get_sysinfo': {'active_mode': 'none',
'alias': '#MASKED_NAME#',
'dev_name': 'Smart Wi-Fi Plug Mini',
'deviceId': 'REDACTED_2DAB5A958F38BCCFF8352E51E114A5E',
'err_code': 0,
'feature': 'TIM',
'hwId': 'REDACTED_1DD892EA69AB42199F59E41',
'hw_ver': '5.0',
'icon_hash': '',
'latitude_i': 0,
'led_off': 0,
'lnk_on': 0,
'longitude_i': 0,
'mac': '00:5F:67:00:00:00',
'mic_type': 'IOT.SMARTPLUGSWITCH',
'model': 'HS103(US)',
'next_action': {'type': -1},
'obd_src': 'tplink',
'oemId': 'REDACTED_6FA93568D818524FE170CEC',
'on_time': 2393,
'relay_state': 1,
'rssi': -41,
'status': 'new',
'sw_ver': '1.1.3 Build 250908 Rel.112508',
'updating': 0}}}
DEBUG:kasa.device:Initializing 192.168.0.1 of type <class 'kasa.iot.iotplug.IotPlug'>
DEBUG:kasa.discover:[DISCOVERY] 192.168.0.1 << {'error_code': 0,
'result': {'device_id': 'REDACTED_bb86dbf1b674c79addd0c8b',
'device_model': 'HS103(US)',
'device_type': 'IOT.SMARTPLUGSWITCH',
'factory_default': True,
'hw_ver': '5.0',
'ip': '192.168.0.1',
'mac': '00-5F-67-00-00-00',
'mgt_encrypt_schm': {'ANS': False,
'encrypt_type': 'KLAP',
'http_port': 80,
'is_support_https': False,
'lv': 2,
'new_klap': 1},
'obd_src': 'tplink',
'owner': '',
'protocol_version': 1}}
DEBUG:kasa.iot.iotdevice:Performing the initial update to obtain sysinfo
DEBUG:kasa.protocols.iotprotocol:192.168.0.1 >> {"system":{"get_sysinfo":{}}}
DEBUG:kasa.httpclient:Posting to http://192.168.0.1/app/request
DEBUG:kasa.transports.klaptransport:Device 192.168.0.1 query posted Host is 192.168.0.1, Sequence is -534551260, Response status is 200, Request was {"system":{"get_sysinfo":{}}}
DEBUG:kasa.transports.klaptransport:Device 192.168.0.1 query response received
DEBUG:kasa.protocols.iotprotocol:192.168.0.1 << {'system': {'get_sysinfo': {'active_mode': 'none',
'alias': '#MASKED_NAME#',
'dev_name': 'Smart Wi-Fi Plug Mini',
'deviceId': 'REDACTED_2DAB5A958F38BCCFF8352E51E114A5E',
'err_code': 0,
'feature': 'TIM',
'hwId': 'REDACTED_1DD892EA69AB42199F59E41',
'hw_ver': '5.0',
'icon_hash': '',
'latitude_i': 0,
'led_off': 0,
'lnk_on': 0,
'longitude_i': 0,
'mac': '00:5F:67:00:00:00',
'mic_type': 'IOT.SMARTPLUGSWITCH',
'model': 'HS103(US)',
'next_action': {'type': -1},
'obd_src': 'tplink',
'oemId': 'REDACTED_6FA93568D818524FE170CEC',
'on_time': 2393,
'relay_state': 1,
'rssi': -41,
'status': 'new',
'sw_ver': '1.1.3 Build 250908 Rel.112508',
'updating': 0}}}
DEBUG:kasa.iot.iotdevice:Adding module <Module HomeKit (smartlife.iot.homekit) for 192.168.0.1>
DEBUG:kasa.iot.iotdevice:Adding module <Module Schedule (schedule) for 192.168.0.1>
DEBUG:kasa.iot.iotdevice:Adding module <Module Usage (schedule) for 192.168.0.1>
DEBUG:kasa.iot.iotdevice:Adding module <Module Antitheft (anti_theft) for 192.168.0.1>
DEBUG:kasa.iot.iotdevice:Adding module <Module Time (time) for 192.168.0.1>
DEBUG:kasa.iot.iotdevice:Adding module <Module Cloud (cnCloud) for 192.168.0.1>
DEBUG:kasa.iot.iotdevice:Adding module <Module Led (system) for 192.168.0.1>
DEBUG:kasa.iot.iotmodule:Initial update, so consider supported: smartlife.iot.homekit
DEBUG:kasa.iot.iotdevice:Adding query for <Module HomeKit (smartlife.iot.homekit) for 192.168.0.1>: {'smartlife.iot.homekit': {'setup_info_get': {}}}
DEBUG:kasa.iot.iotmodule:Initial update, so consider supported: schedule
DEBUG:kasa.iot.iotdevice:Adding query for <Module Schedule (schedule) for 192.168.0.1>: {'schedule': {'get_rules': {}, 'get_next_action': {}}}
DEBUG:kasa.iot.iotmodule:Initial update, so consider supported: schedule
DEBUG:kasa.iot.iotdevice:Adding query for <Module Usage (schedule) for 192.168.0.1>: {'schedule': {'get_realtime': {}, 'get_daystat': {'year': 2026, 'month': 8}, 'get_monthstat': {'year': 2026}}}
DEBUG:kasa.iot.iotmodule:Initial update, so consider supported: anti_theft
DEBUG:kasa.iot.iotdevice:Adding query for <Module Antitheft (anti_theft) for 192.168.0.1>: {'anti_theft': {'get_rules': {}, 'get_next_action': {}}}
DEBUG:kasa.iot.iotmodule:Initial update, so consider supported: time
DEBUG:kasa.iot.iotdevice:Adding query for <Module Time (time) for 192.168.0.1>: {'time': {'get_time': {}, 'get_timezone': {}}}
DEBUG:kasa.iot.iotmodule:Initial update, so consider supported: cnCloud
DEBUG:kasa.iot.iotdevice:Adding query for <Module Cloud (cnCloud) for 192.168.0.1>: {'cnCloud': {'get_info': {}}}
DEBUG:kasa.iot.iotdevice:Adding query for <Module Led (system) for 192.168.0.1>: {}
DEBUG:kasa.protocols.iotprotocol:192.168.0.1 >> {"system":{"get_sysinfo":{}},"smartlife.iot.homekit":{"setup_info_get":{}},"schedule":{"get_rules":{},"get_next_action":{},"get_realtime":{},"get_daystat":{"year":2026,"month":8},"get_monthstat":{"year":2026}},"anti_theft":{"get_rules":{},"get_next_action":{}},"time":{"get_time":{},"get_timezone":{}},"cnCloud":{"get_info":{}}}
DEBUG:kasa.httpclient:Posting to http://192.168.0.1/app/request
DEBUG:kasa.transports.klaptransport:Device 192.168.0.1 query posted Host is 192.168.0.1, Sequence is -534551259, Response status is 200, Request was {"system":{"get_sysinfo":{}},"smartlife.iot.homekit":{"setup_info_get":{}},"schedule":{"get_rules":{},"get_next_action":{},"get_realtime":{},"get_daystat":{"year":2026,"month":8},"get_monthstat":{"year":2026}},"anti_theft":{"get_rules":{},"get_next_action":{}},"time":{"get_time":{},"get_timezone":{}},"cnCloud":{"get_info":{}}}
DEBUG:kasa.transports.klaptransport:Device 192.168.0.1 query response received
DEBUG:kasa.protocols.iotprotocol:192.168.0.1 << {'anti_theft': {'get_next_action': {'err_code': -2,
'err_msg': 'member not support'},
'get_rules': {'err_code': -11, 'err_msg': 'time not sync'}},
'cnCloud': {'get_info': {'binded': 0,
'cld_connection': 0,
'err_code': 0,
'fwDlPage': '',
'fwNotifyType': -1,
'illegalType': 0,
'server': 'n-devs.tplinkcloud.com',
'stopConnect': 0,
'tcspInfo': '',
'tcspStatus': 0,
'username': ''}},
'schedule': {'get_daystat': {'day_list': [], 'err_code': 0},
'get_monthstat': {'err_code': 0, 'month_list': []},
'get_next_action': {'err_code': 0, 'type': -1},
'get_realtime': {'err_code': -2, 'err_msg': 'member not support'},
'get_rules': {'err_code': -11, 'err_msg': 'time not sync'}},
'smartlife.iot.homekit': {'err_code': -1, 'err_msg': 'module not support'},
'system': {'get_sysinfo': {'active_mode': 'none',
'alias': '#MASKED_NAME#',
'dev_name': 'Smart Wi-Fi Plug Mini',
'deviceId': 'REDACTED_2DAB5A958F38BCCFF8352E51E114A5E',
'err_code': 0,
'feature': 'TIM',
'hwId': 'REDACTED_1DD892EA69AB42199F59E41',
'hw_ver': '5.0',
'icon_hash': '',
'latitude_i': 0,
'led_off': 0,
'lnk_on': 0,
'longitude_i': 0,
'mac': '00:5F:67:00:00:00',
'mic_type': 'IOT.SMARTPLUGSWITCH',
'model': 'HS103(US)',
'next_action': {'type': -1},
'obd_src': 'tplink',
'oemId': 'REDACTED_6FA93568D818524FE170CEC',
'on_time': 2394,
'relay_state': 1,
'rssi': -41,
'status': 'new',
'sw_ver': '1.1.3 Build 250908 Rel.112508',
'updating': 0}},
'time': {'get_time': {'err_code': 0,
'hour': 16,
'mday': 1,
'min': 39,
'month': 1,
'sec': 54,
'year': 2000},
'get_timezone': {'err_code': 0, 'index': 6}}}
Old time: 2000-01-01 16:39:54-08:00 (PST8PDT)
DEBUG:kasa.protocols.iotprotocol:192.168.0.1 >> {"time":{"set_time":{"year":2026,"month":8,"mday":29,"hour":11,"min":30,"sec":30}}}
DEBUG:kasa.httpclient:Posting to http://192.168.0.1/app/request
DEBUG:kasa.transports.klaptransport:Device 192.168.0.1 query posted Host is 192.168.0.1, Sequence is -534551258, Response status is 200, Request was {"time":{"set_time":{"year":2026,"month":8,"mday":29,"hour":11,"min":30,"sec":30}}}
DEBUG:kasa.transports.klaptransport:Device 192.168.0.1 query response received
DEBUG:kasa.protocols.iotprotocol:192.168.0.1 << {'time': {'set_time': {'err_code': 0}}}
DEBUG:kasa.iot.iotdevice:Module <Module HomeKit (smartlife.iot.homekit) for 192.168.0.1> not supported, skipping
DEBUG:kasa.iot.iotdevice:Adding query for <Module Schedule (schedule) for 192.168.0.1>: {'schedule': {'get_rules': {}, 'get_next_action': {}}}
DEBUG:kasa.iot.iotdevice:Adding query for <Module Usage (schedule) for 192.168.0.1>: {'schedule': {'get_realtime': {}, 'get_daystat': {'year': 2026, 'month': 8}, 'get_monthstat': {'year': 2026}}}
DEBUG:kasa.iot.iotdevice:Adding query for <Module Antitheft (anti_theft) for 192.168.0.1>: {'anti_theft': {'get_rules': {}, 'get_next_action': {}}}
DEBUG:kasa.iot.iotdevice:Adding query for <Module Time (time) for 192.168.0.1>: {'time': {'get_time': {}, 'get_timezone': {}}}
DEBUG:kasa.iot.iotdevice:Adding query for <Module Cloud (cnCloud) for 192.168.0.1>: {'cnCloud': {'get_info': {}}}
DEBUG:kasa.iot.iotdevice:Adding query for <Module Led (system) for 192.168.0.1>: {}
DEBUG:kasa.protocols.iotprotocol:192.168.0.1 >> {"system":{"get_sysinfo":{}},"schedule":{"get_rules":{},"get_next_action":{},"get_realtime":{},"get_daystat":{"year":2026,"month":8},"get_monthstat":{"year":2026}},"anti_theft":{"get_rules":{},"get_next_action":{}},"time":{"get_time":{},"get_timezone":{}},"cnCloud":{"get_info":{}}}
DEBUG:kasa.httpclient:Posting to http://192.168.0.1/app/request
DEBUG:kasa.transports.klaptransport:Device 192.168.0.1 query posted Host is 192.168.0.1, Sequence is -534551257, Response status is 200, Request was {"system":{"get_sysinfo":{}},"schedule":{"get_rules":{},"get_next_action":{},"get_realtime":{},"get_daystat":{"year":2026,"month":8},"get_monthstat":{"year":2026}},"anti_theft":{"get_rules":{},"get_next_action":{}},"time":{"get_time":{},"get_timezone":{}},"cnCloud":{"get_info":{}}}
DEBUG:kasa.transports.klaptransport:Device 192.168.0.1 query response received
DEBUG:kasa.protocols.iotprotocol:192.168.0.1 << {'anti_theft': {'get_next_action': {'err_code': -2,
'err_msg': 'member not support'},
'get_rules': {'enable': 0,
'err_code': 0,
'rule_list': [],
'version': 2}},
'cnCloud': {'get_info': {'binded': 0,
'cld_connection': 0,
'err_code': 0,
'fwDlPage': '',
'fwNotifyType': -1,
'illegalType': 0,
'server': 'n-devs.tplinkcloud.com',
'stopConnect': 0,
'tcspInfo': '',
'tcspStatus': 0,
'username': ''}},
'schedule': {'get_daystat': {'day_list': [], 'err_code': 0},
'get_monthstat': {'err_code': 0, 'month_list': []},
'get_next_action': {'err_code': 0, 'type': -1},
'get_realtime': {'err_code': -2, 'err_msg': 'member not support'},
'get_rules': {'enable': 0,
'err_code': 0,
'rule_list': [],
'version': 2}},
'system': {'get_sysinfo': {'active_mode': 'none',
'alias': '#MASKED_NAME#',
'dev_name': 'Smart Wi-Fi Plug Mini',
'deviceId': 'REDACTED_2DAB5A958F38BCCFF8352E51E114A5E',
'err_code': 0,
'feature': 'TIM',
'hwId': 'REDACTED_1DD892EA69AB42199F59E41',
'hw_ver': '5.0',
'icon_hash': '',
'latitude_i': 0,
'led_off': 0,
'lnk_on': 0,
'longitude_i': 0,
'mac': '00:5F:67:00:00:00',
'mic_type': 'IOT.SMARTPLUGSWITCH',
'model': 'HS103(US)',
'next_action': {'type': -1},
'obd_src': 'tplink',
'oemId': 'REDACTED_6FA93568D818524FE170CEC',
'on_time': 2394,
'relay_state': 1,
'rssi': -41,
'status': 'new',
'sw_ver': '1.1.3 Build 250908 Rel.112508',
'updating': 0}},
'time': {'get_time': {'err_code': 0,
'hour': 11,
'mday': 29,
'min': 30,
'month': 8,
'sec': 30,
'year': 2026},
'get_timezone': {'err_code': 0, 'index': 6}}}
New time: 2026-08-29 11:30:30-07:00 (PST8PDT)
|
Sorry, something went wrong.
|
I have two KL125 bulbs that stopped authenticating after a firmware update, with the familiar Device response did not match our challenge. Their discovery response has no new_klap key at all — mgt_encrypt_schm is just {is_support_https: false, encrypt_type: "KLAP", http_port: 80, lv: 2}. I'm not sure #1648 and #1731 will cover this use case as these do not advertise new_klap: 1. It does look like #1731's login_version approach may solve this though. Looking at the current PR, should we also handle the case where the encrypt_type has switched to KLAP but does not provide this field? Potentially reusing what's in #1731 |
Sorry, something went wrong.
|
I have 2 HS200 (US wifi smart switch) that stopped working after I updated their firmware, I can confirm that pulling this change fixed my issues and they are now connected again. |
Sorry, something went wrong.
|
+1, I bought brand new KL125 bulbs (hw 4.0, fw 1.1.1 Build 260710 Rel.082646 (discovery: encrypt_type: KLAP, lv: 2)) and they didn't connect for the reasons above: (AuthenticationError: Device response did not match our challenge) connects as IotBulb over KlapTransportV2, and update() works. fix #1692 and #1731 seemingly also would work for this re: the earlier comment that KL125s don't advertise new_klap: this bulb's port-20002 discovery response does include new_klap: 1 in mgt_encrypt_schm. it seemingly just drops the field when it parses the response, so it doesn't appear in output from master. this PR 1580's detection covers these bulbs, claude wrote me a local patch fix while this is being merged |
Sorry, something went wrong.
|
Tested this branch against real new_klap hardware — works unmodified. Reporting since the PR mentions wanting field testing, and this covers a model and device family that isn't in the fixtures here. Hardware: 2× Kasa KS200M(US) Motion-Sensor Light Switch, hw 1.0, fw 1.1.4 Build 241223 Rel.104700 Result: auto-detection and transport selection both workconnection_type : family=IOT.SMARTPLUGSWITCH enc=KLAP login_version=2 new_klap=True
protocol : IotProtocol / transport=KlapTransportV2 <- selected automatically
auth : OK
class : IotWallSwitch (DeviceType.WallSwitch)
modules : Led, Time, ambient, anti_theft, cloud, motion, schedule, usage
features : state, led, on_since, rssi, cloud_connection, reboot,
pir_enabled, pir_triggered, pir_range, pir_threshold,
pir_value, pir_percent, pir_adc_{min,mid,max,value},
ambient_light, ambient_light_enabled
On 0.10.2 both units fail with AuthenticationError: Device response did not match our challenge, and setting login_version=2 on DeviceConnectionParameters doesn't help because get_protocol() doesn't consult it — so the .NEW_KLAP key is what actually unblocks these. The unconditional sysinfo lookup matters hereWorth calling out that the device_factory change — querying sysinfo for the precise subclass for all IotDevices rather than only on XorTransport — is load-bearing for this device, not just tidy-up. Without it the KS200M resolves from its family string to a generic plug; with it, it comes back as IotWallSwitch and the motion / ambient modules and the whole PIR feature set appear. A KLAP wall switch would otherwise be silently under-featured. Test suite22,543 passed, 852 skipped on the branch. I initially saw 4 failures in tests/iot/test_iottimezone.py and test_device_timezones, but those were ZoneInfoNotFoundError from my container lacking tzdata — installing it gives 14/14 passing. No real failures. The touched test modules (test_device_factory, test_discovery, test_deviceconfig) are 3508 passed. End-to-end in Home AssistantAlso exercised through HA rather than just the library: installed the branch into a Home Assistant 2026.9.2 container (the branch reports 0.10.2, so it satisfies HA's python-kasa[speedups]==0.10.2 pin), added both switches through the normal tplink config flow, and got 14 entities across both devices — main switch, motion-sensor enable, LED, signal strength, on-since, cloud connection, restart. Verified write control by toggling and restoring, and the state read back correctly each time. Happy to run anything else against these two, or to retest after further review changes. |
Sorry, something went wrong.
|
@mitchwebster adding a KL125 data point, plus a separate failure on mine that turns out not to be a transport problem at all. As @LTKMN noted above, mine does advertise the field: port-20002 discovery returns 'mgt_encrypt_schm': {'ANS': False, 'encrypt_type': 'KLAP', 'http_port': 80, 'is_support_https': False, 'lv': 2, 'new_klap': 1} so your bulbs having no new_klap key at all is likely a firmware-revision difference rather than a model one. Hardware: 1× Kasa KL125(US), hw 4.0, fw 1.1.1 Build 260710 Rel.082646 Detection and transport selection are correctdevice_factory : Finding transport for IOT.KLAP.NEW_KLAP class : kasa.iot.iotbulb.IotBulb <- correct, automatically handshake1 : hashes match with expected credentials handshake2 : complete state succeeds about half the time20 consecutive runs of kasa --host <ip> --debug state, 5 s apart: 10 passed, 10 failed (9 × Error trying to decrypt ... not a multiple of the block length, 1 × TimeoutError). Both handshakes and the first two {"system":{"get_sysinfo":{}}} queries always succeed. The failure always lands on the third, larger query on /app/request. The failing response isn't an encrypted payload, it's an HTML pageLogging the response length around KlapEncryptionSession.decrypt shows the same query returning 3264 bytes when it works and 49 bytes when it doesn't. Those 49 bytes are: <html><body><center>200 OK</center></body></html> So the bulb intermittently answers /app/request with a plain HTTP status page instead of a KLAP frame. decrypt() then slices the first 32 bytes off as the signature and tries to AES-decrypt er></body></html>, which is where the block-length error comes from. That's a device-side fault, but it might be worth a cheap guard on our side: the response is only ever valid if len(body) > 32 and (len(body) - 32) % 16 == 0. Checking that before decrypt() and raising a retryable device error would turn a confusing crypto message into a clean retry, and this one is worth retrying, because the bulb recovers on its own. The failures come in blocks rather than at random: run: 1 10 20
F F F F P P P P P F F F F F P P P P P F
Transitions land every ~28–29 s, so the bulb alternates between serving KLAP and serving that HTML page on roughly a 57 s cycle. ControlSame loop, branch and credentials against an HS300 on the same LAN: 20 passed, 0 failed, 9 queries deep each time including all 6 children. Nothing wrong with the branch. None of this should block the PR, detection is doing its job on this bulb. Posting in case the length guard is of interest, and happy to run anything else against it. Debug excerpt from a failing run, and the raw response capture (redacted)DEBUG:kasa.transports.klaptransport:Starting handshake with 10.0.0.247
DEBUG:kasa.httpclient:Posting to http://10.0.0.247/app/handshake1
DEBUG:kasa.transports.klaptransport:Handshake1 posted at 2026-09-17 09:20:14.186369. Host is 10.0.0.247, Response status is 200, Request was ab66ed063f25e5aba85a6353298112f6
DEBUG:kasa.transports.klaptransport:Handshake1 success at 2026-09-17 09:20:14.186415. Host is 10.0.0.247, Server remote_seed is: e3f8ee0f9db96d0edc06ec0fe3a66d0f, server hash is: 9634b77bf570bdb70b669f8f8c5d78b68063530c96d16d1a8ffa36efb5ac997d
DEBUG:kasa.transports.klaptransport:handshake1 hashes match with expected credentials
DEBUG:kasa.httpclient:Posting to http://10.0.0.247/app/handshake2
DEBUG:kasa.transports.klaptransport:Handshake2 posted 2026-09-17 09:20:14.196090. Host is 10.0.0.247, Response status is 200, Request was e7e4bafc3bdda0793bb9167bb4000192486560a6436c12d46da989909186f62b
DEBUG:kasa.transports.klaptransport:Handshake with 10.0.0.247 complete
DEBUG:kasa.httpclient:Posting to http://10.0.0.247/app/request
DEBUG:kasa.transports.klaptransport:Device 10.0.0.247 query posted Host is 10.0.0.247, Sequence is -603044004, Response status is 200, Request was {"system":{"get_sysinfo":{}}}
DEBUG:kasa.transports.klaptransport:Device 10.0.0.247 query response received
... second get_sysinfo query succeeds (seq -603044003) ...
DEBUG:kasa.transports.klaptransport:Device 10.0.0.247 query posted Host is 10.0.0.247, Sequence is -603044002, Response status is 200, Request was {"system":{"get_sysinfo":{}},"smartlife.iot.homekit":{"setup_info_get":{}},"smartlife.iot.common.emeter":{"get_realtime":{},"get_daystat":{"year":2026,"month":9},"get_monthstat":{"year":2026}},"smartlife.iot.common.schedule":{"get_rules":{},"get_next_action":{}}}
DEBUG:kasa.protocols.iotprotocol:Unable to query the device: 10.0.0.247, not retrying: Error trying to decrypt device 10.0.0.247 response: The length of the provided data is not a multiple of the block length.
Raised error: Error trying to decrypt device 10.0.0.247 response: The length of the provided data is not a multiple of the block length.
Instrumented around KlapEncryptionSession.decrypt, verbatim from one run, a failing attempt followed by a passing one: --- attempt 3
[OK ] ciphertext_len=1120
[OK ] ciphertext_len=1120
[BAD] total=49 ciphertext_len=17
raw_full_hex = 3c68746d6c3e3c626f64793e3c63656e7465723e323030204f4b3c2f63656e7465723e3c2f626f64793e3c2f68746d6c3e
body_after_sig = b'er></body></html>'
attempt 3: FAIL KasaException
--- attempt 10
[OK ] ciphertext_len=1120
[OK ] ciphertext_len=1120
[OK ] ciphertext_len=3232
[OK ] ciphertext_len=1520
attempt 10: OK
(raw_full_hex decodes to <html><body><center>200 OK</center></body></html>.) Separately, confirming the rest of my KLAP/lv: 2/new_klap: 1 devices all authenticate on this branch, none of which appear in the fixtures here:
All six fail on 0.10.2 with AuthenticationError: Device response did not match our challenge. Only the KL125 shows the intermittent HTML-response behaviour above; the other five are stable. |
Sorry, something went wrong.
Real-world HS300 / Home Assistant testingI tested this PR against multiple real Kasa HS300(US) HW 2.0 strips, both directly with python-kasa and through Home Assistant. Tested commit: 71a4147984aedc7cfa9ce4613204ecf28b15dac7 Environment:
The affected devices advertise discovery information including: device_type: IOT.SMARTPLUGSWITCH
encrypt_type: KLAP
lv/login_version: 2
new_klap: 1
ResultsWith this PR installed, the HS300s correctly:
For example, direct discovery of one previously unused HS300 produced: Python class : IotStrip Protocol : IotProtocol Transport : KlapTransportV2 Model : HS300 Child count : 6 All six children were present, and a direct relay test successfully toggled an outlet off and restored it. Home Assistant testingI also force-installed this commit over Home Assistant's stock python-kasa==0.10.2 and tested the normal TP-Link integration. Results across several HS300s:
I also ended up factory-resetting and reprovisioning one HS300 while investigating an apparently unrelated intermittent connectivity problem. After the factory reset, Tapo-side configuration/names had been lost. Home Assistant automatically rediscovered the physical strip and reassociated its six outlets with the existing entity-registry entries. The previous Home Assistant entity names returned rather than the new outlet names assigned during Tapo provisioning. So the child/device identity remained sufficiently stable across a factory reset to preserve the existing HA entities in this test. Intermittent timeout investigated separatelyOne HS300 initially appeared to expose another problem: the initial modular update would occasionally time out. I broke the update request apart and verified that every individual query worked, including:
I then tested the complete combined modular request directly, and it also succeeded. Repeated fresh-session testing showed that the device itself was behaving intermittently rather than failing on a particular request. Before factory reset/reprovisioning: Successes : 15/20 Failures : 5/20 Query min : 0.116s Query avg : 0.798s Query max : 3.305s After factory reset/reprovisioning, using the same test and same complete request: Successes : 20/20 Failures : 0/20 Query min : 0.032s Query avg : 0.243s Query max : 0.703s The device was also intermittently unavailable from the Tapo application before being reset. Based on that testing, I do not believe the intermittent timeout was caused by this PR or by the combined modular query. OverallFrom my testing, this PR successfully resolves both issues I was seeing with these newer HS300 HW2 devices:
I've now tested this with multiple HS300 HW2 strips, including direct python-kasa discovery/query/control, existing Home Assistant config entries, Home Assistant reauthentication, and fresh Home Assistant discovery/configuration. Happy to collect additional debug output or generate a device fixture from one of these HS300s if that would be useful. |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
Implementing KlapTranportV2 to handle IoT devices with newer firmware and a new_klap flag and all associated tests hopefully.
With this PR, I will get the user to pull the specific branch for testing on their end, and I will test on my end to make sure that the old stuff still functions as well.