FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

support for h500 hub · Issue #1578 · python-kasa/python-kasa · GitHub

Repository navigation

support for h500 hub #1578

Closed as not planned
Closed as not planned

Description

Home assistant is unable to add the Tapo H500 hub, comes up when scanning for device and says device is already configured but doesnt add the hub or any devices connected to the hub to home assistant

Activity

  1. rytilahti commented on Sep 21, 2025

    Member

    Please try it with the CLI tool from this project & post at least the discovery results with --debug enabled, maybe it is also using the new key derivation protocol as discussed in #1574?

  2. w9925 commented on Nov 28, 2025

    @rytilahti Any update ? Do you still need the logs?

  3. rytilahti commented on Nov 28, 2025

    Member

    Hey, so I haven't heard anyone looking actively on this, but a fixture file (https://python-kasa.readthedocs.io/en/stable/contribute.html#contributing-fixture-files) from the device would be a helpful starting point.

  4. w9925 commented on Nov 28, 2025

    @rytilahti I have created the file. Hope this is helpful.

    H500(EU)_1.0_1.3.8.json

  5. rytilahti commented on Nov 28, 2025

    Member

    Thanks @w9925, looks like this is similar to H200, do you have any child devices bound to it? Looks like yours did not respond to getChildDeviceComponentList or getChildDeviceList commands like H200 does, which contain information about the bound devices.

    Also, did you already try and see if you can control the device using kasa command-line tool? If you add --debug you will get lots of debug output when it tries to find the correct connection parameters.

  6. w9925 commented on Nov 28, 2025

    There is a camera connected to the hub. I can access the camera directly using Kasa commands. I cannot use the Kasa commands for the hub because authentication fails.

  7. w9925 commented on Dec 1, 2025

    @rytilahti Is it possible to add support with the provided file or do i need to provide more informations like logs?

  8. svalsemey commented on Jan 5, 2026

    Hello @rytilahti, I have the exact same issue that WillLuminate and w9925: no possibility to add H500 hub to HA and one C260 connected (which is already associated directly to HA and perfectly working). However, H500 hub provides local face recognition that the C260 alone cannot do. Do you need another fixture file to ease troubleshooting, in order to handle the communications and the data provided by the H500?

  9. thezoid commented on Mar 31, 2026

    Hey, running this down from a technical POV. I host my HA in Docker on TrueNAS SCALE, so no Bluetooth or WiFi discovery in the container, so I am adding everything by static IP. Here's what I pieced together from some digging in the shell. All summaries come from probing commands run directly against the device using uvx --from python-kasa kasa --debug.

    Environment

    python-kasa version latest via uvx
    Python version 3.14 (uvx environment)
    Device Tapo H500 HW 1.0
    Device type SMART.TAPOHUB
    Transport SMART.AES.HTTPS → sslaestransport
    Encrypt type ['3']
    HTTPS True, port 443
    Connection Wired, static IP

    Fixture File Status

    I attempted to generate a fixture file via dump_devinfo but it fails at the same auth step described below, whatever is causing the auth failure also blocks dump_devinfo from completing, so I haven't been able to produce one yet. Once a patch lands that fixes the handshake, I'm happy to immediately run dump_devinfo and submit the fixture in a follow-up.

    Observed Failure: auth never completes, possibly related to -40401/-60502 handling in sslaestransport.perform_handshake1()

    The transport correctly identifies the H500 and routes to sslaestransport via SMART.AES.HTTPS. From the debug log, the failure seems to occur inside perform_handshake1(). The maintainers will know this code better than I do, but here is what I observed:

    1. handshake1 sent with provided credentials → device responds error_code: -40401, data.code: -60502
    2. Instead of continuing the challenge-response flow with the provided credentials, the transport falls into the "Trying default credentials" branch
    3. Default-cred handshake1 receives a proper KLAP challenge: error_code: -40413 + RSA pubkey + nonce + device_confirm
    4. Transport logs "Connected to <ip> with default username", which is a bit misleading since the challenge was received, but auth was not actually completed
    5. Challenge-response crypto fails because device_confirm was derived from the real account credentials, not empty ones → mismatch → AuthenticationError at sslaestransport.py:614

    I'm not sure what the -60502 sub-code on the initial -40401 means; it might signal something like "account requires full KLAP challenge" rather than a simple credential rejection, but that's just my read of it. What I can see in the log is that after receiving it, the transport moves to the default-credential path rather than continuing with the provided creds, which seems to be where things go wrong.

    Call Stack

    sslaestransport.perform_handshake()   line 384
      → perform_handshake1()              line 614  ← AuthenticationError raised here
          ← send()                        line 650
              ← _execute_multiple_query() smartprotocol.py:247
                  ← _negotiate()          smartcamdevice.py:212
    

    What I've Ruled Out

    • Credentials are correct, verified against the Tapo app, and the device's owner field in discovery is populated, so the account is bound
    • Device is reachable over HTTPS/443
    • Tried both kasa discover --debug and kasa state --debug with explicit --username/--password, same result either way, so it doesn't seem to be a CLI credential-passing issue

    Debug Log (sanitized)

    DEBUG:kasa.device_factory:Finding transport for SMART.AES.HTTPS
    DEBUG:kasa.transports.sslaestransport:Created AES transport for 192.168.1.x
    DEBUG:kasa.transports.sslaestransport:Sending handshake1...
    DEBUG:kasa.transports.sslaestransport:Device responded with status 200: {'error_code': -40401, 'result': {'data': {'code': -60502}}}
    DEBUG:kasa.transports.sslaestransport:Trying default credentials to 192.168.1.x
    DEBUG:kasa.transports.sslaestransport:Sending handshake1...
    DEBUG:kasa.httpclient:Device 192.168.1.x received an os error: Server disconnected
    DEBUG:kasa.transports.sslaestransport:Device responded with status 200: {'error_code': -40413, 'result': {'data': {'code': -40401, 'encrypt_type': ['3'], 'key': '<RSA_PUBKEY>', 'nonce': '<NONCE>', 'device_confirm': '<CONFIRM>'}}}
    DEBUG:kasa.transports.sslaestransport:Connected to 192.168.1.x with default username
    DEBUG:kasa.transports.sslaestransport:Device response did not match our challenge on ip 192.168.1.x, check that your e-mail and password (both case-sensitive) are correct.
    kasa.exceptions.AuthenticationError: Device response did not match our challenge
    

    Possible Area to Look At

    I might be wrong here, but sslaestransport.perform_handshake1() around the -40401 + -60502 handling seems like a reasonable place to start. My guess is the default-credential fallback path is intended for unclaimed/unprovisioned devices, and an account-bound device returning a challenge-required sub-error might need to go through the full challenge-response flow with the provided creds instead, but you'll know far better than I do whether that makes sense.

    Happy to test any patches against the live device and will generate and submit a fixture file as soon as auth succeeds.

  10. thezoid commented on Apr 1, 2026

    Note: Used agentic AI to help me clean up my notes and make them more readable for people who are not me. @ me and call out what you need if anything is novel or interesting. Thanks! :)

    Update: following up with new debug runs. Auth is now completing successfully, which is progress from the original failure. The crash has moved to a different point in the flow, so documenting the full picture here.

    One of the changes I made before this run was switching to a 32-character alphanumeric password with no special characters for testing purposes. I've also tried with and without @emailprovider.com. Worth noting since this is not an issue with my H100, which handles out-of-range sensors from the H500 fine with the same credentials (or that's the plan). Not sure if special characters in the password were contributing to the earlier auth failure or if something else changed, but flagging it in case it's relevant.

    I also tried the suggestions from these threads before running the new tests, none of which resolved the issue on their own:

    Note on commands: running from inside a Home Assistant Docker container on TrueNAS SCALE. No Bluetooth or WiFi discovery available, adding by static IP. All runs use uvx --from python-kasa kasa.

    Run 1: discover (no --debug, no --port)

    uvx --from python-kasa kasa \
      --username <REDACTED_EMAIL> \
      --password <REDACTED_PASSWORD> \
      --host 192.168.1.x \
      discover
     
    Installed 16 packages in 288ms
    realpath: --: No such file or directory
    Discovering device 192.168.1.x for 10 seconds
    Raised error: coroutine raised StopIteration
    Run with --debug enabled to see stacktrace
    ERROR:asyncio:Unclosed client session
    ERROR:asyncio:Unclosed connector
    

    Run 2: discover with --port 443 --debug

    uvx --from python-kasa kasa \
      --username <REDACTED_EMAIL> \
      --password <REDACTED_PASSWORD> \
      --host 192.168.1.x \
      --port 443 \
      --debug \
      discover
     
    Installed 16 packages in 318ms
    realpath: --: No such file or directory
    Discovering device 192.168.1.x for 10 seconds
    DEBUG:kasa.discover:[DISCOVERY] 192.168.1.x >> {'system': {'get_sysinfo': {}}}
    DEBUG:kasa.discover:Waiting a total of 10 seconds for responses...
    DEBUG:kasa.discover:Decrypted encrypt_info for 192.168.1.x: {'connect_ssid': '#MASKED_SSID#',
     'connect_type': 'wired',
     'device_id': '<REDACTED>',
     'http_port': 443,
     'owner': '<REDACTED>',
     'sd_status': 'offline'}
    DEBUG:kasa.device_factory:Using SmartCamDevice for SMART.TAPOHUB
    DEBUG:kasa.device_factory:Finding protocol for 192.168.1.x
    DEBUG:kasa.device_factory:Finding protocol for DeviceFamily.SmartTapoHub
    DEBUG:kasa.device_factory:Finding transport for SMART.AES.HTTPS
    DEBUG:kasa.transports.sslaestransport:Created AES transport for 192.168.1.x
    DEBUG:kasa.discover:[DISCOVERY] 192.168.1.x << {'error_code': 0,
     'result': {'device_id': '<REDACTED>',
                'device_model': 'H500',
                'device_name': '#MASKED_NAME#',
                'device_type': 'SMART.TAPOHUB',
                'encrypt_info': {'data': '', 'key': '', 'sym_schm': 'AES'},
                'encrypt_type': ['3'],
                'factory_default': False,
                'hardware_version': '1.0',
                'ip': '192.168.1.x',
                'isResetWiFi': False,
                'is_support_iot_cloud': True,
                'mac': '<REDACTED>',
                'mgt_encrypt_schm': {'is_support_https': True},
                'sv': 1}}
    DEBUG:kasa.device:Initializing 192.168.1.x of type <class 'kasa.smartcam.smartcamdevice.SmartCamDevice'>
    DEBUG:kasa.protocols.smartprotocol:192.168.1.x multi-request-batch-1-of-1 >> '{"method":"multipleRequest","params":{"requests":[{"method":"getDeviceInfo","params":{"device_info":{"name":["basic_info","info"]}}},{"method":"getAppComponentList","params":{"app_component":{"name":"app_component_list"}}},{"method":"getConnectionType","params":{"network":{"get_connection_type":{}}}}]}}'
    DEBUG:kasa.transports.sslaestransport:Sending handshake1...
    DEBUG:kasa.httpclient:Posting to https://192.168.1.x
    DEBUG:kasa.transports.sslaestransport:Device responded with status 200: {'error_code': -40401, 'result': {'data': {'code': -60502}}}
    DEBUG:kasa.transports.sslaestransport:Trying default credentials to 192.168.1.x
    DEBUG:kasa.transports.sslaestransport:Sending handshake1...
    DEBUG:kasa.httpclient:Posting to https://192.168.1.x
    DEBUG:kasa.httpclient:Device 192.168.1.x received an os error, enabling sequential request delay: Server disconnected
    DEBUG:kasa.protocols.smartprotocol:Device 192.168.1.x got a connection error, will retry 3 times
    DEBUG:kasa.transports.sslaestransport:Sending handshake1...
    DEBUG:kasa.httpclient:Posting to https://192.168.1.x
    DEBUG:kasa.transports.sslaestransport:Device responded with status 200: {'error_code': -40401, 'result': {'data': {'code': -60502}}}
    DEBUG:kasa.transports.sslaestransport:Trying default credentials to 192.168.1.x
    DEBUG:kasa.transports.sslaestransport:Sending handshake1...
    DEBUG:kasa.httpclient:Posting to https://192.168.1.x
    DEBUG:kasa.transports.sslaestransport:Device responded with status 200: {'error_code': -40413, 'result': {'data': {'code': -40401, 'encrypt_type': ['3'], 'key': '<RSA_PUBKEY>', 'nonce': '<NONCE>', 'device_confirm': '<DEVICE_CONFIRM>'}}}
    DEBUG:kasa.transports.sslaestransport:Connected to 192.168.1.x with default username
    DEBUG:kasa.transports.sslaestransport:Credentials match
    DEBUG:kasa.transports.sslaestransport:Performing handshake2 ...
    DEBUG:kasa.httpclient:Posting to https://192.168.1.x
    DEBUG:kasa.transports.sslaestransport:Handshake2 complete ...
    DEBUG:kasa.transports.sslaestransport:Sending secure passthrough from 192.168.1.x
    DEBUG:kasa.httpclient:Posting to https://192.168.1.x/stok=<REDACTED_STOK>/ds
    DEBUG:kasa.protocols.smartprotocol:192.168.1.x multi-request-batch-1-of-1 << {'error_code': 0,
     'result': {'responses': [
       {'error_code': 0,
        'method': 'getAppComponentList',
        'result': {'app_component': {'app_component_list': [
          {'name': 'setDetailLanguage', 'version': 1},
          {'name': 'dateTime',          'version': 1},
          {'name': 'system',            'version': 4},
          {'name': 'led',               'version': 1},
          {'name': 'firmware',          'version': 2},
          {'name': 'account',           'version': 1},
          {'name': 'quickSetup',        'version': 1},
          {'name': 'hubRecord',         'version': 2},
          {'name': 'deviceShare',       'version': 1},
          {'name': 'siren',             'version': 2},
          {'name': 'childControl',      'version': 1},
          {'name': 'childQuickSetup',   'version': 1},
          {'name': 'childInherit',      'version': 1},
          {'name': 'deviceLoad',        'version': 1},
          {'name': 'subg',              'version': 2},
          {'name': 'iotCloud',          'version': 1},
          {'name': 'diagnose',          'version': 1},
          {'name': 'preWakeUp',         'version': 1},
          {'name': 'supportRE',         'version': 1},
          {'name': 'testSignal',        'version': 1},
          {'name': 'dataDownload',      'version': 1},
          {'name': 'testChildSignal',   'version': 1},
          {'name': 'ringLog',           'version': 1},
          {'name': 'usbsharemanage',    'version': 1},
          {'name': 'hardDisk',          'version': 1},
          {'name': 'playbackDelete',    'version': 1},
          {'name': 'usrDefAudio',       'version': 1},
          {'name': 'audioSourceCapability', 'version': 1},
          {'name': 'mirrorscreen',      'version': 1},
          {'name': 'AIEnhance',         'version': 1},
          {'name': 'faceDetection',     'version': 1},
          {'name': 'snapshot',          'version': 2},
          {'name': 'faceTracking',      'version': 1},
          {'name': 'matter',            'version': 1},
          {'name': 'matterControl',     'version': 1},
          {'name': 'localSmart',        'version': 1},
          {'name': 'generalCameraManage','version': 1},
          {'name': 'multiLensCamMgmt',  'version': 1},
          {'name': 'playback',          'version': 6},
          {'name': 'chime',             'version': 2},
          {'name': 'hubPlayback',       'version': 1},
          {'name': 'migrate',           'version': 1},
          {'name': 'aovStorage',        'version': 1},
          {'name': 'tssDeviceManage',   'version': 1}]}}},
       {'error_code': 0,
        'method': 'getDeviceInfo',
        'result': {'device_info': {'basic_info': {
          'avatar': 'hub_h500',
          'bind_status': True,
          'child_num': 0,
          'dev_id': '<REDACTED>',
          'device_alias': '#MASKED_NAME#',
          'device_info': 'H500 1.0',
          'device_model': 'H500',
          'device_name': '#MASKED_NAME#',
          'device_type': 'SMART.TAPOHUB',
          'hw_id': '<REDACTED>',
          'hw_version': '1.0',
          'local_ip': '192.168.1.x',
          'mac': '<REDACTED>',
          'matter_controller_leader_dev_id': '<REDACTED>',
          'matter_controller_occupation': 'leader',
          'need_sync_sha1_password': 0,
          'oem_id': '<REDACTED>',
          'product_name': 'Smart HomeBase',
          'region': 'US',
          'status': 'configured',
          'subg_phyid': 'f920p9',
          'sw_version': '1.3.12 Build 20260128 rel.51424'}}}},
       {'error_code': 0,
        'method': 'getConnectionType',
        'result': {'link_type': 'wifi', 'rssiValue': -45, 'ssid': '<REDACTED>'}}
     ]}}
    DEBUG:kasa.protocols.smartprotocol:192.168.1.x multi-request-batch-1-of-1 >> '{"method":"multipleRequest","params":{"requests":[{"method":"getChildDeviceList","params":{"childControl":{"start_index":0}}},{"method":"getChildDeviceComponentList","params":{"childControl":{"start_index":0}}}]}}'
    DEBUG:kasa.httpclient:Posting to https://192.168.1.x/stok=<REDACTED_STOK>/ds
    DEBUG:kasa.protocols.smartprotocol:192.168.1.x multi-request-batch-1-of-1 << {'error_code': 0,
     'result': {'responses': [
       {'error_code': 0, 'method': 'getChildDeviceComponentList', 'result': {'start_index': 0, 'sum': 0}},
       {'error_code': 0, 'method': 'getChildDeviceList',          'result': {'start_index': 0, 'sum': 0}}
     ]}}
    Raised error: coroutine raised StopIteration
    Traceback (most recent call last):
      File "smartprotocol.py", line 381, in _handle_response_lists
        response_list_name = next(iter(...))
    StopIteration
     
    The above exception was the direct cause of the following exception:
     
      smartcamdevice.py:148  _initialize_children
        -> smartprotocol.py:300  _execute_multiple_query
            -> _handle_response_lists
    RuntimeError: coroutine raised StopIteration
    

    Run 3: state with --port 443 --debug

    Same auth flow and same crash point as Run 2. Including in full for completeness.

    uvx --from python-kasa kasa \
      --username <REDACTED_EMAIL> \
      --password <REDACTED_PASSWORD> \
      --host 192.168.1.x \
      --port 443 \
      --debug \
      state
     
    Installed 16 packages in 357ms
    realpath: --: No such file or directory
    Discovering device 192.168.1.x for 10 seconds
    DEBUG:kasa.discover:[DISCOVERY] 192.168.1.x >> {'system': {'get_sysinfo': {}}}
    DEBUG:kasa.discover:Waiting a total of 10 seconds for responses...
    DEBUG:kasa.discover:Decrypted encrypt_info for 192.168.1.x: {'connect_ssid': '#MASKED_SSID#',
     'connect_type': 'wired',
     'device_id': '<REDACTED>',
     'http_port': 443,
     'owner': '<REDACTED>',
     'sd_status': 'offline'}
    DEBUG:kasa.device_factory:Using SmartCamDevice for SMART.TAPOHUB
    DEBUG:kasa.device_factory:Finding protocol for DeviceFamily.SmartTapoHub
    DEBUG:kasa.device_factory:Finding transport for SMART.AES.HTTPS
    DEBUG:kasa.transports.sslaestransport:Created AES transport for 192.168.1.x
    DEBUG:kasa.discover:[DISCOVERY] 192.168.1.x << {'error_code': 0,
     'result': {'device_model': 'H500',
                'device_type': 'SMART.TAPOHUB',
                'encrypt_type': ['3'],
                'factory_default': False,
                'hardware_version': '1.0',
                'ip': '192.168.1.x',
                'mac': '<REDACTED>',
                'mgt_encrypt_schm': {'is_support_https': True},
                'sv': 1}}
    DEBUG:kasa.transports.sslaestransport:Sending handshake1...
    DEBUG:kasa.httpclient:Posting to https://192.168.1.x
    DEBUG:kasa.transports.sslaestransport:Device responded with status 200: {'error_code': -40401, 'result': {'data': {'code': -60502}}}
    DEBUG:kasa.transports.sslaestransport:Trying default credentials to 192.168.1.x
    DEBUG:kasa.transports.sslaestransport:Sending handshake1...
    DEBUG:kasa.httpclient:Posting to https://192.168.1.x
    DEBUG:kasa.httpclient:Device 192.168.1.x received an os error, enabling sequential request delay: Server disconnected
    DEBUG:kasa.protocols.smartprotocol:Device 192.168.1.x got a connection error, will retry 3 times
    DEBUG:kasa.transports.sslaestransport:Sending handshake1...
    DEBUG:kasa.transports.sslaestransport:Device responded with status 200: {'error_code': -40401, 'result': {'data': {'code': -60502}}}
    DEBUG:kasa.transports.sslaestransport:Trying default credentials to 192.168.1.x
    DEBUG:kasa.transports.sslaestransport:Sending handshake1...
    DEBUG:kasa.transports.sslaestransport:Device responded with status 200: {'error_code': -40413, 'result': {'data': {'code': -40401, 'encrypt_type': ['3'], 'key': '<RSA_PUBKEY>', 'nonce': '<NONCE>', 'device_confirm': '<DEVICE_CONFIRM>'}}}
    DEBUG:kasa.transports.sslaestransport:Connected to 192.168.1.x with default username
    DEBUG:kasa.transports.sslaestransport:Credentials match
    DEBUG:kasa.transports.sslaestransport:Performing handshake2 ...
    DEBUG:kasa.httpclient:Posting to https://192.168.1.x
    DEBUG:kasa.transports.sslaestransport:Handshake2 complete ...
    DEBUG:kasa.transports.sslaestransport:Sending secure passthrough from 192.168.1.x
    DEBUG:kasa.httpclient:Posting to https://192.168.1.x/stok=<REDACTED_STOK>/ds
    DEBUG:kasa.protocols.smartprotocol:192.168.1.x multi-request-batch-1-of-1 << {'error_code': 0,
     'result': {'responses': [
       {'error_code': 0,
        'method': 'getAppComponentList',
        'result': {'app_component': {'app_component_list': [
          {'name': 'setDetailLanguage', 'version': 1},
          {'name': 'dateTime',          'version': 1},
          {'name': 'system',            'version': 4},
          {'name': 'led',               'version': 1},
          {'name': 'firmware',          'version': 2},
          {'name': 'account',           'version': 1},
          {'name': 'quickSetup',        'version': 1},
          {'name': 'hubRecord',         'version': 2},
          {'name': 'deviceShare',       'version': 1},
          {'name': 'siren',             'version': 2},
          {'name': 'childControl',      'version': 1},
          {'name': 'childQuickSetup',   'version': 1},
          {'name': 'childInherit',      'version': 1},
          {'name': 'deviceLoad',        'version': 1},
          {'name': 'subg',              'version': 2},
          {'name': 'iotCloud',          'version': 1},
          {'name': 'diagnose',          'version': 1},
          {'name': 'preWakeUp',         'version': 1},
          {'name': 'supportRE',         'version': 1},
          {'name': 'testSignal',        'version': 1},
          {'name': 'dataDownload',      'version': 1},
          {'name': 'testChildSignal',   'version': 1},
          {'name': 'ringLog',           'version': 1},
          {'name': 'usbsharemanage',    'version': 1},
          {'name': 'hardDisk',          'version': 1},
          {'name': 'playbackDelete',    'version': 1},
          {'name': 'usrDefAudio',       'version': 1},
          {'name': 'audioSourceCapability', 'version': 1},
          {'name': 'mirrorscreen',      'version': 1},
          {'name': 'AIEnhance',         'version': 1},
          {'name': 'faceDetection',     'version': 1},
          {'name': 'snapshot',          'version': 2},
          {'name': 'faceTracking',      'version': 1},
          {'name': 'matter',            'version': 1},
          {'name': 'matterControl',     'version': 1},
          {'name': 'localSmart',        'version': 1},
          {'name': 'generalCameraManage','version': 1},
          {'name': 'multiLensCamMgmt',  'version': 1},
          {'name': 'playback',          'version': 6},
          {'name': 'chime',             'version': 2},
          {'name': 'hubPlayback',       'version': 1},
          {'name': 'migrate',           'version': 1},
          {'name': 'aovStorage',        'version': 1},
          {'name': 'tssDeviceManage',   'version': 1}]}}},
       {'error_code': 0,
        'method': 'getDeviceInfo',
        'result': {'device_info': {'basic_info': {
          'avatar': 'hub_h500',
          'bind_status': True,
          'child_num': 0,
          'dev_id': '<REDACTED>',
          'device_model': 'H500',
          'device_type': 'SMART.TAPOHUB',
          'hw_id': '<REDACTED>',
          'hw_version': '1.0',
          'local_ip': '192.168.1.x',
          'mac': '<REDACTED>',
          'matter_controller_leader_dev_id': '<REDACTED>',
          'matter_controller_occupation': 'leader',
          'need_sync_sha1_password': 0,
          'oem_id': '<REDACTED>',
          'product_name': 'Smart HomeBase',
          'region': 'US',
          'status': 'configured',
          'subg_phyid': 'f920p9',
          'sw_version': '1.3.12 Build 20260128 rel.51424'}}}},
       {'error_code': 0,
        'method': 'getConnectionType',
        'result': {'link_type': 'wifi', 'rssiValue': -45, 'ssid': '<REDACTED>'}}
     ]}}
    DEBUG:kasa.protocols.smartprotocol:192.168.1.x multi-request-batch-1-of-1 >> '{"method":"multipleRequest","params":{"requests":[{"method":"getChildDeviceList","params":{"childControl":{"start_index":0}}},{"method":"getChildDeviceComponentList","params":{"childControl":{"start_index":0}}}]}}'
    DEBUG:kasa.httpclient:Posting to https://192.168.1.x/stok=<REDACTED_STOK>/ds
    DEBUG:kasa.protocols.smartprotocol:192.168.1.x multi-request-batch-1-of-1 << {'error_code': 0,
     'result': {'responses': [
       {'error_code': 0, 'method': 'getChildDeviceList',          'result': {'start_index': 0, 'sum': 0}},
       {'error_code': 0, 'method': 'getChildDeviceComponentList', 'result': {'start_index': 0, 'sum': 0}}
     ]}}
    Raised error: coroutine raised StopIteration
    Traceback (most recent call last):
      File "smartprotocol.py", line 381, in _handle_response_lists
        response_list_name = next(iter(...))
    StopIteration
     
    The above exception was the direct cause of the following exception:
     
      smartcamdevice.py:148  _initialize_children
        -> smartprotocol.py:300  _execute_multiple_query
            -> _handle_response_lists
    RuntimeError: coroutine raised StopIteration
    

    What changed from the original report: auth is now completing (Credentials match, Handshake2 complete), and the device is returning full device info successfully. The crash now happens in _handle_response_lists inside smartprotocol.py:381 when processing the child device query. Both getChildDeviceList and getChildDeviceComponentList return sum: 0 since there are no child devices paired to the hub yet, and the next(iter(...)) call on line 381 doesn't appear to handle that empty case gracefully, causing StopIteration to bubble up into the async context and become a RuntimeError. This looks like it may be related to the same _handle_response_lists issue discussed in #1574. Happy to test anything if it helps.


    Writing this made me think more!

    I noticed while digging into this: my H500 currently has no child devices paired to it in the Tapo app (child_num: 0 in the device info response). I'm wondering if the empty hub is actually the reproduction condition here rather than anything H500-specific. The crash happens when _handle_response_lists calls next(iter(...)) on the getChildDeviceList response, and if sum: 0 means there are no list entries to inspect, that next() call would have nothing to iterate over and raise StopIteration regardless of which hub model triggered it.

    Assumption: If that's the case, any hub with zero paired children would hit this crash, and it may just not have come up before because most people testing hubs have at least one sensor paired.

    Going to try pairing a child device to the H500 first and then re-running the discovery to see if that gets further. Will also try running dump_devinfo against it with a local patch that passes None as a default to next() to see if the fixture can be captured. Will report back either way.

  11. thezoid commented on Apr 2, 2026

    Factory reset the hub and a camera, then paired the child device to the H500 via the Tapo app to test whether an empty hub was the root cause. Device info now correctly shows child_num: 1, but getChildDeviceList still returns sum: 0 and the crash is identical. So the empty hub theory doesn't hold, and the crash happens regardless of whether the hub has children or not.

    This suggests either the H500 handles getChildDeviceList differently from the H100/H200, or there's something about the query format the library is sending that the H500 doesn't respond to the same way. Either way, _handle_response_lists gets an empty result and crashes.

    This is where I have to bow out and let the SWE/SDEs do their magic. Happy to do more IT digging if we have any leads!

    Run 1: discover (no --debug, no --port)

    uvx --from python-kasa kasa \
      --username <REDACTED_EMAIL> \
      --password <REDACTED_PASSWORD> \
      --host 192.168.1.x \
      discover
    
    Installed 16 packages in 7.51s
    realpath: --: No such file or directory
    Discovering device 192.168.1.x for 10 seconds
    Raised error: coroutine raised StopIteration
    Run with --debug enabled to see stacktrace
    ERROR:asyncio:Unclosed client session
    ERROR:asyncio:Unclosed connector

    Run 2: discover with --port 443 --debug

    uvx --from python-kasa kasa \
      --username <REDACTED_EMAIL> \
      --password <REDACTED_PASSWORD> \
      --host 192.168.1.x \
      --port 443 \
      --debug \
      discover
    
    Installed 16 packages in 3.38s
    realpath: --: No such file or directory
    Discovering device 192.168.1.x for 10 seconds
    DEBUG:kasa.discover:[DISCOVERY] 192.168.1.x >> {'system': {'get_sysinfo': {}}}
    DEBUG:kasa.discover:Waiting a total of 10 seconds for responses...
    DEBUG:kasa.discover:Decrypted encrypt_info for 192.168.1.x: {'connect_ssid': '#MASKED_SSID#',
     'connect_type': 'wired',
     'device_id': '<REDACTED>',
     'http_port': 443,
     'owner': '<REDACTED>',
     'sd_status': 'offline'}
    DEBUG:kasa.device_factory:Using SmartCamDevice for SMART.TAPOHUB
    DEBUG:kasa.device_factory:Finding protocol for 192.168.1.x
    DEBUG:kasa.device_factory:Finding protocol for DeviceFamily.SmartTapoHub
    DEBUG:kasa.device_factory:Finding transport for SMART.AES.HTTPS
    DEBUG:kasa.transports.sslaestransport:Created AES transport for 192.168.1.x
    DEBUG:kasa.discover:[DISCOVERY] 192.168.1.x << {'error_code': 0,
     'result': {'device_id': '<REDACTED>',
                'device_model': 'H500',
                'device_name': '#MASKED_NAME#',
                'device_type': 'SMART.TAPOHUB',
                'encrypt_info': {'data': '', 'key': '', 'sym_schm': 'AES'},
                'encrypt_type': ['3'],
                'factory_default': False,
                'hardware_version': '1.0',
                'ip': '192.168.1.x',
                'isResetWiFi': False,
                'is_support_iot_cloud': True,
                'mac': '<REDACTED>',
                'mgt_encrypt_schm': {'is_support_https': True},
                'sv': 1}}
    DEBUG:kasa.device:Initializing 192.168.1.x of type <class 'kasa.smartcam.smartcamdevice.SmartCamDevice'>
    DEBUG:kasa.transports.sslaestransport:Sending handshake1...
    DEBUG:kasa.httpclient:Posting to https://192.168.1.x
    DEBUG:kasa.transports.sslaestransport:Device responded with status 200: {'error_code': -40401, 'result': {'data': {'code': -60502}}}
    DEBUG:kasa.transports.sslaestransport:Trying default credentials to 192.168.1.x
    DEBUG:kasa.transports.sslaestransport:Sending handshake1...
    DEBUG:kasa.httpclient:Posting to https://192.168.1.x
    DEBUG:kasa.httpclient:Device 192.168.1.x received an os error, enabling sequential request delay: Server disconnected
    DEBUG:kasa.protocols.smartprotocol:Device 192.168.1.x got a connection error, will retry 3 times
    DEBUG:kasa.transports.sslaestransport:Sending handshake1...
    DEBUG:kasa.httpclient:Posting to https://192.168.1.x
    DEBUG:kasa.transports.sslaestransport:Device responded with status 200: {'error_code': -40401, 'result': {'data': {'code': -60502}}}
    DEBUG:kasa.transports.sslaestransport:Trying default credentials to 192.168.1.x
    DEBUG:kasa.transports.sslaestransport:Sending handshake1...
    DEBUG:kasa.httpclient:Posting to https://192.168.1.x
    DEBUG:kasa.transports.sslaestransport:Device responded with status 200: {'error_code': -40413, 'result': {'data': {'code': -40401, 'encrypt_type': ['3'], 'key': '<RSA_PUBKEY>', 'nonce': '<NONCE>', 'device_confirm': '<DEVICE_CONFIRM>'}}}
    DEBUG:kasa.transports.sslaestransport:Connected to 192.168.1.x with default username
    DEBUG:kasa.transports.sslaestransport:Credentials match
    DEBUG:kasa.transports.sslaestransport:Performing handshake2 ...
    DEBUG:kasa.httpclient:Posting to https://192.168.1.x
    DEBUG:kasa.transports.sslaestransport:Handshake2 complete ...
    DEBUG:kasa.transports.sslaestransport:Sending secure passthrough from 192.168.1.x
    DEBUG:kasa.httpclient:Posting to https://192.168.1.x/stok=<REDACTED_STOK>/ds
    DEBUG:kasa.protocols.smartprotocol:192.168.1.x multi-request-batch-1-of-1 << {'error_code': 0,
     'result': {'responses': [
       {'error_code': 0,
        'method': 'getAppComponentList',
        'result': {'app_component': {'app_component_list': [
          {'name': 'setDetailLanguage',     'version': 1},
          {'name': 'dateTime',              'version': 1},
          {'name': 'system',                'version': 4},
          {'name': 'led',                   'version': 1},
          {'name': 'firmware',              'version': 2},
          {'name': 'account',               'version': 1},
          {'name': 'quickSetup',            'version': 1},
          {'name': 'hubRecord',             'version': 2},
          {'name': 'deviceShare',           'version': 1},
          {'name': 'siren',                 'version': 2},
          {'name': 'childControl',          'version': 1},
          {'name': 'childQuickSetup',       'version': 1},
          {'name': 'childInherit',          'version': 1},
          {'name': 'deviceLoad',            'version': 1},
          {'name': 'subg',                  'version': 2},
          {'name': 'iotCloud',              'version': 1},
          {'name': 'diagnose',              'version': 1},
          {'name': 'preWakeUp',             'version': 1},
          {'name': 'supportRE',             'version': 1},
          {'name': 'testSignal',            'version': 1},
          {'name': 'dataDownload',          'version': 1},
          {'name': 'testChildSignal',       'version': 1},
          {'name': 'ringLog',               'version': 1},
          {'name': 'usbsharemanage',        'version': 1},
          {'name': 'hardDisk',              'version': 1},
          {'name': 'playbackDelete',        'version': 1},
          {'name': 'usrDefAudio',           'version': 1},
          {'name': 'audioSourceCapability', 'version': 1},
          {'name': 'mirrorscreen',          'version': 1},
          {'name': 'AIEnhance',             'version': 1},
          {'name': 'faceDetection',         'version': 1},
          {'name': 'snapshot',              'version': 2},
          {'name': 'faceTracking',          'version': 1},
          {'name': 'matter',                'version': 1},
          {'name': 'matterControl',         'version': 1},
          {'name': 'localSmart',            'version': 1},
          {'name': 'generalCameraManage',   'version': 1},
          {'name': 'multiLensCamMgmt',      'version': 1},
          {'name': 'playback',              'version': 6},
          {'name': 'chime',                 'version': 2},
          {'name': 'hubPlayback',           'version': 1},
          {'name': 'migrate',               'version': 1},
          {'name': 'aovStorage',            'version': 1},
          {'name': 'tssDeviceManage',       'version': 1}]}}},
       {'error_code': 0,
        'method': 'getDeviceInfo',
        'result': {'device_info': {'basic_info': {
          'avatar': 'hub_h500',
          'bind_status': True,
          'child_num': 1,              # child device is paired
          'dev_id': '<REDACTED>',
          'device_model': 'H500',
          'device_type': 'SMART.TAPOHUB',
          'hw_version': '1.0',
          'local_ip': '192.168.1.x',
          'mac': '<REDACTED>',
          'matter_controller_leader_dev_id': '<REDACTED>',
          'matter_controller_occupation': 'leader',
          'need_sync_sha1_password': 0,
          'product_name': 'Smart HomeBase',
          'region': 'US',
          'status': 'configured',
          'subg_phyid': 'f920p9',
          'sw_version': '1.3.12 Build 20260128 rel.51424'}}}},
       {'error_code': 0,
        'method': 'getConnectionType',
        'result': {'link_type': 'wifi', 'rssiValue': -48, 'ssid': '<REDACTED>'}}
     ]}}
    DEBUG:kasa.protocols.smartprotocol:192.168.1.x multi-request-batch-1-of-1 >> getChildDeviceList + getChildDeviceComponentList
    DEBUG:kasa.httpclient:Posting to https://192.168.1.x/stok=<REDACTED_STOK>/ds
    DEBUG:kasa.protocols.smartprotocol:192.168.1.x multi-request-batch-1-of-1 << {'error_code': 0,
     'result': {'responses': [
       {'error_code': 0, 'method': 'getChildDeviceList',          'result': {'start_index': 0, 'sum': 0}},  # reports 0 despite child_num: 1
       {'error_code': 0, 'method': 'getChildDeviceComponentList', 'result': {'start_index': 0, 'sum': 0}}
     ]}}
    Raised error: coroutine raised StopIteration
    Traceback (most recent call last):
      File "smartprotocol.py", line 381, in _handle_response_lists
        response_list_name = next(iter(...))
    StopIteration
    
    The above exception was the direct cause of the following exception:
    
      smartcamdevice.py:148  _initialize_children
        -> smartprotocol.py:300  _execute_multiple_query
            -> _handle_response_lists
    RuntimeError: coroutine raised StopIteration
    

    Run 3: state with --port 443 --debug

    Auth flow identical to Run 2, same crash at the same point. Omitting repeated output for brevity.

    uvx --from python-kasa kasa \
      --username <REDACTED_EMAIL> \
      --password <REDACTED_PASSWORD> \
      --host 192.168.1.x \
      --port 443 \
      --debug \
      state
    
    [... identical auth flow and getDeviceInfo response with child_num: 1 ...]
    
    DEBUG:kasa.protocols.smartprotocol:192.168.1.x multi-request-batch-1-of-1 << {'error_code': 0,
     'result': {'responses': [
       {'error_code': 0, 'method': 'getChildDeviceComponentList', 'result': {'start_index': 0, 'sum': 0}},
       {'error_code': 0, 'method': 'getChildDeviceList',          'result': {'start_index': 0, 'sum': 0}}
     ]}}
    Raised error: coroutine raised StopIteration
      smartcamdevice.py:148  _initialize_children
        -> smartprotocol.py:300  _execute_multiple_query
            -> _handle_response_lists
    RuntimeError: coroutine raised StopIteration

    Fixture file attached.

    H500(US)_1.0_1.3.12.json

  12. ZeliardM commented on Apr 2, 2026

    Collaborator

    Yes, this most likely means they changed the commands in their API to call the child device lists. Will take further investigation on our end to figure this out and see what we can do to get it resolved. Will keep poking and let you know.

  13. supermimai commented on Jun 13, 2026

    hello, I follow the thread and confirm the child ( like a T100 ) is instable. a lot of deconnection. also, the trick to be forced to use the admin as a login, instead of the email... no way to install a fallback and try admin even when the user entered an email ( which was the most logic information to put ) ?

  14. mrUlrik commented on Jun 25, 2026

    I just want to add interest in this bug and am willing to help to the best of my ability. Currently I am not operating python-kasa directly, but through Home Assistant. That said, I can still provide additional information if needed, though the posts earlier are extremely robust. I am keenly interested in getting a new H500 working. Admittedly, I should have done more research first before buying!

  15. jimboca commented on Jul 8, 2026

    Contributor

    I did not find this issue before submitting my PR: #1718
    which has the fixture for my H500 which lists no children even though when I look at the hub in the Tapo app I see them. But reading this, it looks like I need to factory reset everything and add them to the hub directly instead of just telling the cameras to store their videos on the hub.

  16. jimboca commented on Jul 8, 2026

    Contributor

    Update: H500 FW 1.3.18, child_num=6, LAN child list empty even after fresh hub pairing of a camera by adding it directly to the Hub.

  17. github-actions commented on Oct 7, 2026

    There hasn't been any activity on this issue recently. This issue has been automatically marked as stale because of that. It will be closed if no further activity occurs.
    Please make sure to update to the latest python-kasa version and check if that solves the issue.
    Thank you for your contributions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions


      Back | FazBrowse Home | New Git URL