fishbigger / TapoP100

A module for controlling the TP-Link Tapo P100 Plugs
MIT License
567 stars 139 forks source link

Cant login to P100 #62

Open dawidmosk opened 2 years ago

dawidmosk commented 2 years ago

I cant login into P100 - i did check password to tp-link cloud

any one home some idea?

I got error:

p100 = PyP100.P100("192.168.X.X", "email@email.email", "Password123") p100.handshake() p100.login() Traceback (most recent call last): File "/usr/local/lib/python3.10/dist-packages/PyP100/PyP100.py", line 163, in login self.token = ast.literal_eval(decryptedResponse)["result"]["token"] KeyError: 'result'

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "", line 1, in File "/usr/local/lib/python3.10/dist-packages/PyP100/PyP100.py", line 167, in login raise Exception(f"Error Code: {errorCode}, {errorMessage}") Exception: Error Code: -1501, Invalid Request or Credentials

realzoulou commented 2 years ago

I just updated to Home Assistant Core 2022.4.6 and also updated PyP100 from 0.0.18 to .19 and now run also into an exception 'result' when calling getDeviceName. I then downgraded only PyP100 to 0.0.18 and all was fine again. So, I suspect one of the changes from 0.0.18 to 0.0.19 is not good.

This is the relevant stack backtrace:

File "/srv/homeassistant/lib/python3.9/site-packages/PyP100/PyP100.py", line 261, in getDeviceName self.handshake() File "/srv/homeassistant/lib/python3.9/site-packages/PyP100/PyP100.py", line 124, in handshake encryptedKey = r.json()["result"]["key"] KeyError: 'result'

I suspect https://github.com/fishbigger/TapoP100/pull/52

realzoulou commented 2 years ago

@fishbigger Comparing this issue here https://github.com/fishbigger/TapoP100/issues/62 with https://github.com/fishbigger/TapoP100/issues/50 and https://github.com/fishbigger/TapoP100/issues/54 ... Aren't they all quite similar? After a r = self.session.post(URL, json=Payload, timeout=2) an attempt to access the JSON result key throws an Exception...

fishbigger commented 2 years ago

Yes they are @realzoulou. I definitely think some better error detection should be put around there that can attempt to diagnose the problem. At the moment all we can do is guess at what the issue is. I will try and add this asap so we can diagnose it!

realzoulou commented 2 years ago

I did a comparison of PyP100 0.0.18 vs .19 regarding what bytes are actually going back and forth between my test P110 smart plug and my Home Assistant Core running in my WSL2.

Following is the "Follow TCP stream" of Wireshark with PyP100==0.0.18 (still good for me) when HA executes self.handshake in P100.getDeviceName method:

POST /app HTTP/1.1
Host: 192.168.178.38
User-Agent: python-requests/2.24.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
Content-Length: 356
Content-Type: application/json

{"method": "handshake", "params": {"key": "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCS/+vATlGNVqX6dmpsgkBvZMWH\nOL0N9s7NoY3VvT4PDubGJIY+4Zoo0tPA0UQaxCaWqBmhpFJmUjrQOQ3fTBBkFj/g\nm2Can0ihfMKEPLEVtKBNp1tNxwKY6liBBduioH2p8H+jCIY5lG3MVjam0xSQqxOe\nCvvxMhaoK4o/u9PJWwIDAQAB\n-----END PUBLIC KEY-----", "requestTimeMils": 1650811947720}}HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Set-Cookie: TP_SESSIONID=AF40D4DB73336EFCF7B6F8B7C9C37DFB;TIMEOUT=1440
Server: SHIP 2.0
Content-Length: 208
Connection: keep-alive

{"error_code":0,"result":{"key":"Uy8ZDw4YQBitk7/BufuysAeOA0xZvsxmFJ+5IkH9AQTQoaxmN/9aOeV7WrVCB419+0+ONYbmUzGCpgrtKZf0197OVW5Zvq3HLOkoenENPCrqN04HGaf4kImilnV0mtW6PRzJNSesQN8RbNZc8RUVcWh3Fv25RLgLFLr0ClcWrzI="}}

to compare with PyP100==0.0.19 (bad for me):

[... cut ... the previous TCP session requests/responses ... the last response still kept in here to visualize that we are in an active TCP session ...]
{"error_code":0,"result":{"response":"qkmkrgSdRZBEKnDAW7aYX33bLGZfccziz65r64mXzpS+q5BKbNxOb94lGpAm4rF+2b77I++99jL+eLTlT3rjWf4dvU9doz1hpShfZjGf/EA="}}POST /app HTTP/1.1
Host: 192.168.178.38
User-Agent: python-requests/2.24.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
Cookie: TP_SESSIONID=9CCDAEE756D01B8648D1A02FDD8F397D
Content-Length: 356
Content-Type: application/json

{"method": "handshake", "params": {"key": "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAW+lNMinO5CeVQXkOJUoco/ha\n3VAkdnZQcxd3kF5J5tVhVyFvZJVWZsRW5q55eV/kcP0dU79JSXD8Wf0ma+SY1U8I\nk75ta3nGbyf8LMEUs550jG9eeTa4X9m0csdIEmj6J7p6ZdO5CgoBWJla9w1F+oUl\nHVDsolS3zvdZCiaJGwIDAQAB\n-----END PUBLIC KEY-----", "requestTimeMils": 1650812106567}}HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Server: SHIP 2.0
Content-Length: 19
Connection: keep-alive

{"error_code":9999}

Note: I saw already that I have an "old" requests==2.24.0 and updated to 2.27.1. Did not change anything for good.

realzoulou commented 2 years ago

Did a few experiments and I am now pretty sure that (some or all?) Tapo devices (or firmware versions?) do not allow a 2nd handshake and/or login within the same TCP session. Because P100.getDeviceName repeats self.login and self.handshake even if already logged in and handshaked, my HA Integration runs into this error_code 9999 always. If I omit P100.handshake and .login calls and only do a P100.getDeviceName after the initial creation of the P100 object, I succeed until my Integration again calls P100.getDeviceName on the P100 object.

So my two cents on the alternatives I could image for fixing this issue: a) revert PR #52 (not my favorite) b) delete handshake+login from P100.getDeviceName and leave it up to the users of PyP100 to never attempt to handshake/login a 2nd time (not my favorite either) c) Remember in P100 if handshake+login were done previously and if a new handshake call comes in, reset the self.session attribute to a new Session()

dawidmosk commented 2 years ago

I had this problem even on .18 version. I'm doing something wrong?

Python3 p100 = PyP100.P100("192.168.X.X", "email@email.email", "Password123") p100.handshake() p100.login()

dawidmosk commented 2 years ago

TapoP100 it's working or closed as unsuccessful project? Maybe some day it will work? even one time? I changed password and still getting Invalid "Request or Credentials". DFA disabled. Tested e-mail and login name. Even tested login from tplink camera.

b4ldr commented 1 year ago

i looked into this a bit and im getting the following error

>>> r = self.session.post(URL, json=SecurePassthroughPayload, headers=headers, timeout=2)
>>> r.json()
{'error_code': -20103, 'msg': 'The method does not exist or is not available'}

so wondering if the api has changed (hardware 1.20.0, firmware 1.4.10)

agentgonzo commented 1 year ago

I'm getting the invalid credentials problem on the P105.

Firmware on the plug: 1.3.6

With PyP100 0.0.25, I can operate the plug fine.

With 0.1.0, I get this on p100.login()

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.10/site-packages/PyP100/PyP100.py", line 168, in login
    raise Exception(f"Error Code: {errorCode}, {errorMessage}")
Exception: Error Code: -1501, Invalid Request or Credentials
rhuijben commented 1 year ago

Similar issue here.

print(decryptedResponse) gives me a {"error_code":-1501}

rhuijben commented 1 year ago

Similar issue here.

print(decryptedResponse) gives me a {"error_code":-1501}

Got things working months ago by updating the millisec part of the requests as noted in a different issue/

I think this value is used to deduplicate requests, and therefore just passing 0 all the time won't work.

peterdk commented 1 year ago

Got things working months ago by updating the millisec part of the requests as noted in a different issue/ I think this value is used to deduplicate requests, and therefore just passing 0 all the time won't work.

Could you point me to where that millisec part issue is?