petretiandrea / plugp100

Work in progress implementation of tapo protocol in python.
GNU General Public License v3.0
72 stars 27 forks source link

Error code 1003 when running `get_device_info()` #116

Closed carbolymer closed 1 year ago

carbolymer commented 1 year ago

I managed to set up my L530 lightbulb with home-assistant successfully, but I forgot to set up static DHCP lease and the IP of the bulb has changed. So I removed the hub and tried to add it again. this time however I'm getting error 1003 instead in HA:

2023-08-25 18:34:40.327 ERROR (MainThread) [custom_components.tapo.config_flow] Failed to setup cannot connect 
Traceback (most recent call last):
  File "/config/custom_components/tapo/config_flow.py", line 182, in _try_setup_api
    .get_or_raise()
     ^^^^^^^^^^^^^^
  File "/config/deps/lib/python3.11/site-packages/plugp100/common/functional/tri.py", line 159, in get_or_raise
    raise self.value
plugp100.responses.tapo_exception.TapoException: Returned unknown error_code: 1003  msg: No message

I tried to use a simple code to connect to L530 to gather more details:

import logging
import asyncio
import os

from plugp100.api.light_effect_preset import LightEffectPreset
from plugp100.api.tapo_client import TapoClient
from plugp100.common.credentials import AuthCredential

logging.basicConfig(level=logging.DEBUG)

async def main():
    # create generic tapo api
    username = os.getenv('USERNAME', 'email@gmail.com')
    password = os.getenv('PASSWORD', 'password')

    client = TapoClient(AuthCredential(username, password), 'lightbulb_ip')

    print(await client.get_device_info())
    await client.close()

if __name__ == "__main__":
    loop = asyncio.new_event_loop()
    loop.run_until_complete(main())
    loop.run_until_complete(asyncio.sleep(0.1))
    loop.close()

But instead I'm getting the same error:

DEBUG:asyncio:Using selector: EpollSelector
DEBUG:plugp100.protocol.securepassthrough_transport:Will perform handshaking...
DEBUG:plugp100.protocol.securepassthrough_transport:Generating keypair
DEBUG:plugp100.protocol.securepassthrough_transport:Handshake params: {"key": "-----BEGIN PUBLIC KEY-----\nMI<cut>AB\n-----END PUBLIC KEY-----\n"}
DEBUG:plugp100.protocol.securepassthrough_transport:Request {'method': 'handshake', 'params': {'key': '-----BEGIN PUBLIC KEY-----\nMI<cut>AB\n-----END PUBLIC KEY-----\n'}}
DEBUG:plugp100.protocol.securepassthrough_transport:Device responded with: {'error_code': 1003}
Failure(Returned unknown error_code: 1003  msg: No message)

Any ideas what this error could mean?

By the way, the code sample in README is outdated.

carbolymer commented 1 year ago

Seems like this is the same issue: https://github.com/petretiandrea/home-assistant-tapo-p100/issues/482

alexgeraldo commented 1 year ago

Seems like this is the same issue: petretiandrea/home-assistant-tapo-p100#482

I was able to replicate your error. What I think happened is that the new TapoCliente object had its old parameters changed, so now, in addition to the credentials, the protocol must also be specified. Below is the code I was able to successfully get a response from:

Note: The default protocol is the previous one.

import logging
import asyncio
import os

from plugp100.api.tapo_client import TapoClient, AuthCredential, TapoProtocolType

logging.basicConfig(level=logging.DEBUG)

async def main():
    # create generic tapo api
    client = TapoClient(AuthCredential('email@gmail.com', 'password'), 'lightbulb_ip', TapoProtocolType.KLAP)

    print(await client.get_device_info())
    await client.close()

if __name__ == "__main__":
    loop = asyncio.new_event_loop()
    loop.run_until_complete(main())
    loop.run_until_complete(asyncio.sleep(0.1))
    loop.close()

Hope I helped you.

carbolymer commented 1 year ago

Nope, it didn't help. There's a new error though:

DEBUG:asyncio:Using selector: EpollSelector
DEBUG:plugp100.protocol.klap_protocol:[KLAP] Starting handshake with lightbulb_ip
DEBUG:plugp100.protocol.klap_protocol:Handshake1 posted at 1693045552.953525.  Host is lightbulb_ip, Session
cookie is 417A<cut>FC06, Response status is 200, Request was dd302becb2<cut>329d9624e
DEBUG:plugp100.protocol.klap_protocol:Server remote_seed is: a45<cut>d07, server hash is: 1cba<cut>49c2
DEBUG:plugp100.protocol.klap_protocol:Expected 1478<cut>dd got 1cba<cut>c2 in handshake1.  Checking if blank auth is a match
DEBUG:plugp100.protocol.klap_protocol:Server response doesn't match our challenge on ip lightbulb_ip
DEBUG:plugp100.protocol.klap_protocol:[KLAP] Handshake with lightbulb_ip complete
Traceback (most recent call last):
  File "/tmp/tapo/./tapo.py", line 23, in <module>
    loop.run_until_complete(main())
  File "/usr/lib/python3.11/asyncio/base_events.py", line 653, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/tmp/tapo/./tapo.py", line 18, in main
    print(await client.get_device_info())
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/tapo/venv/lib/python3.11/site-packages/plugp100/api/tapo_client.py", line 93, in get_device_info
    return (await self._protocol.send_request(get_info_request)).map(
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/tapo/venv/lib/python3.11/site-packages/plugp100/protocol/klap_protocol.py", line 48, in send_request
    response = await self._send_request(request, retry)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/tapo/venv/lib/python3.11/site-packages/plugp100/protocol/klap_protocol.py", line 60, in _send_request
    if not self._klap_session.handshake_complete:
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'handshake_complete'
ERROR:asyncio:Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x7fcd522d2310>
ERROR:asyncio:Unclosed connector
connections: ['[(<aiohttp.client_proto.ResponseHandler object at 0x7fcd51a42190>, 185114.782006612)]']
connector: <aiohttp.connector.TCPConnector object at 0x7fcd510a4150>
petretiandrea commented 1 year ago

I forgot to update readme.md. You must use:

username = os.getenv('USERNAME', '<tapo_email>')
password = os.getenv('PASSWORD', '<tapo_password>')

credential = AuthCredential(username, password)
client = await TapoClient.connect(credential, "<ip_address>")

connect will automatically detect the right protocol

alexgeraldo commented 1 year ago

DEBUG:plugp100.protocol.klap_protocol:Server response doesn't match our challenge on ip lightbulb_ip

This handshake error is most likely caused by wrong credentials. When trying to reproduce the authentication hash locally, it was unable to match it to the server hash. In other words, the credentials used locally (provided by you) are not the same ones used by the light bulb when generating the hash.

Of course there could have been another reason, but I strongly believe this is what is happening. Check if the credentials are correct.

carbolymer commented 1 year ago

No dice - same error. Credentials are 100% correct, because I've just added the bulb in HA using those.

Anyway, my main interest was in adding the lightbulb in HA and that works already so I'm no longer interested in this issue so I'm closing it.

Thanks guys for the hard work!