petretiandrea / home-assistant-tapo-p100

A custom integration to control Tapo devices from home assistant.
MIT License
818 stars 102 forks source link

cannot connect h200 #578

Closed raoul170 closed 4 months ago

raoul170 commented 1 year ago

Deze fout is ontstaan door een aangepaste integratie.

Logger: custom_components.tapo.config_flow Source: custom_components/tapo/config_flow.py:118 Integration: TP-Link Tapo (documentation, issues) First occurred: 16:39:26 (1 occurrences) Last logged: 16:39:26

Failed to setup cannot connect Traceback (most recent call last): File "/usr/local/lib/python3.11/site-packages/aiohttp/connector.py", line 980, in _wrap_create_connection return await self._loop.create_connection(*args, **kwargs) # type: ignore[return-value] # noqa ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/asyncio/base_events.py", line 1085, in create_connection raise exceptions[0] File "/usr/local/lib/python3.11/asyncio/base_events.py", line 1069, in create_connection sock = await self._connect_sock( ^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/asyncio/base_events.py", line 973, in _connect_sock await self.sock_connect(sock, address) File "/usr/local/lib/python3.11/asyncio/selector_events.py", line 628, in sock_connect return await fut ^^^^^^^^^ File "/usr/local/lib/python3.11/asyncio/selector_events.py", line 668, in _sock_connect_cb raise OSError(err, f'Connect call failed {address}') TimeoutError: [Errno 110] Connect call failed ('193.168.178.241', 80)

The above exception was the direct cause of the following exception:

Traceback (most recent call last): File "/config/custom_components/tapo/config_flow.py", line 215, in _try_setup_api await client.initialize() File "/usr/local/lib/python3.11/site-packages/plugp100/api/tapo_client.py", line 62, in initialize await self._guess_protocol() File "/usr/local/lib/python3.11/site-packages/plugp100/api/tapo_client.py", line 218, in _guess_protocol response = await self.execute_raw_request( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/plugp100/api/tapo_client.py", line 71, in execute_raw_request return (await self._protocol.send_request(request)).map(lambda x: x.result) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/plugp100/protocol/passthrough_protocol.py", line 42, in send_request response = await self._send_request(request) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/plugp100/protocol/passthrough_protocol.py", line 62, in _send_request await self._login_with_version(self._credential) File "/usr/local/lib/python3.11/site-packages/plugp100/protocol/passthrough_protocol.py", line 81, in _login_with_version session_or_error = await self._passthrough.handshake(self._url) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/plugp100/protocol/securepassthrough_transport.py", line 70, in handshake response = await self._http.async_make_post(url, json=request_body) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/plugp100/common/utils/http_client.py", line 18, in async_make_post async with self.session.post( File "/usr/local/lib/python3.11/site-packages/aiohttp/client.py", line 1141, in aenter self._resp = await self._coro ^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/aiohttp/client.py", line 536, in _request conn = await self._connector.connect( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/aiohttp/connector.py", line 540, in connect proto = await self._create_connection(req, traces, timeout) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/aiohttp/connector.py", line 901, in _createconnection , proto = await self._create_direct_connection(req, traces, timeout) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/aiohttp/connector.py", line 1209, in _create_direct_connection raise last_exc File "/usr/local/lib/python3.11/site-packages/aiohttp/connector.py", line 1178, in _create_direct_connection transp, proto = await self._wrap_create_connection( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/aiohttp/connector.py", line 988, in _wrap_create_connection raise client_error(req.connection_key, exc) from exc aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host 193.168.178.241:80 ssl:default [Connect call failed ('193.168.178.241', 80)]

The above exception was the direct cause of the following exception:

Traceback (most recent call last): File "/config/custom_components/tapo/config_flow.py", line 118, in async_step_user tapo_client = await self._try_setup_api(user_input) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/config/custom_components/tapo/config_flow.py", line 220, in _try_setup_api raise CannotConnect from error custom_components.tapo.errors.CannotConnect

slartibartfast11 commented 11 months ago

I don't know if this helps, or if it's a red herring for debugging but I set up a reverse proxy for the Integration to talk to on port 80 that forwarded everything to my H200 on SSL. This is the error the integration setup displayed.

Failed to setup cannot connect
Traceback (most recent call last):
  File "/config/custom_components/tapo/config_flow.py", line 215, in _try_setup_api
    await client.initialize()
  File "/usr/local/lib/python3.11/site-packages/plugp100/api/tapo_client.py", line 70, in initialize
    await self._guess_protocol()
  File "/usr/local/lib/python3.11/site-packages/plugp100/api/tapo_client.py", line 260, in _guess_protocol
    raise error
plugp100.responses.tapo_exception.TapoException: Returned unknown error_code: -40401  msg: No message

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/tapo/config_flow.py", line 118, in async_step_user
    tapo_client = await self._try_setup_api(user_input)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/tapo/config_flow.py", line 218, in _try_setup_api
    self._raise_from_tapo_exception(error)
  File "/config/custom_components/tapo/config_flow.py", line 227, in _raise_from_tapo_exception
    raise CannotConnect from exception
custom_components.tapo.errors.CannotConnect
tvpetersen commented 10 months ago

I need a volunteer to schedule a remote call or give me access to a device to try it

if you need access to an H200 just drop me a line. But from looking at the code it only tries a HTTP port 80 connections and this is now closed on the H200, it only run HTTPS port 443. So the codes needs to fixed to take that into effect.

HTTPS needs to be only TLS 1.2 connections, this should be ok from Homeassistance, the connection should just trust the certificate, as it looks to be a selfsigned.

###########################################################
    testssl.sh       3.1dev from https://testssl.sh/dev/
    (13f0388 2022-02-02 13:34:23 -- )

      This program is free software. Distribution and
             modification under GPLv2 permitted.
      USAGE w/o ANY WARRANTY. USE IT AT YOUR OWN RISK!

       Please file bugs @ https://testssl.sh/bugs/

###########################################################

 Using "OpenSSL 1.1.1f  31 Mar 2020" [~98 ciphers]
 on Ayumi:/usr/bin/openssl
 (built: "May 24 17:14:51 2023", platform: "debian-amd64")

 Start 2023-12-12 12:24:39        -->> 192.168.0.53:443 (192.168.0.53) <<--

 rDNS (192.168.0.53):    --
 Service detected:       HTTP

 Testing protocols via sockets except NPN+ALPN

 SSLv2      not offered (OK)
 SSLv3      not offered (OK)
 TLS 1      not offered
 TLS 1.1    not offered
 TLS 1.2    offered (OK)
 TLS 1.3    not offered and downgraded to a weaker protocol
 NPN/SPDY   not offered
 ALPN/HTTP2 not offered

 Testing cipher categories

 NULL ciphers (no encryption)                      not offered (OK)
 Anonymous NULL Ciphers (no authentication)        not offered (OK)
 Export ciphers (w/o ADH+NULL)                     not offered (OK)
 LOW: 64 Bit + DES, RC[2,4], MD5 (w/o export)      not offered (OK)
 Triple DES Ciphers / IDEA                         not offered
 Obsoleted CBC ciphers (AES, ARIA etc.)            offered
 Strong encryption (AEAD ciphers) with no FS       offered (OK)
 Forward Secrecy strong encryption (AEAD ciphers)  not offered

 Testing server's cipher preferences

 Has server cipher order?     yes (OK)
 Negotiated protocol          TLSv1.2
 Negotiated cipher            AES256-GCM-SHA384
 Cipher per protocol

Hexcode  Cipher Suite Name (OpenSSL)       KeyExch.   Encryption  Bits     Cipher Suite Name (IANA/RFC)
-----------------------------------------------------------------------------------------------------------------------------
SSLv2
 -
SSLv3
 -
TLSv1
 -
TLSv1.1
 -
TLSv1.2 (server order)
 x9d     AES256-GCM-SHA384                 RSA        AESGCM      256      TLS_RSA_WITH_AES_256_GCM_SHA384
 x3d     AES256-SHA256                     RSA        AES         256      TLS_RSA_WITH_AES_256_CBC_SHA256
 x35     AES256-SHA                        RSA        AES         256      TLS_RSA_WITH_AES_256_CBC_SHA
 x9c     AES128-GCM-SHA256                 RSA        AESGCM      128      TLS_RSA_WITH_AES_128_GCM_SHA256
 x3c     AES128-SHA256                     RSA        AES         128      TLS_RSA_WITH_AES_128_CBC_SHA256
 x2f     AES128-SHA                        RSA        AES         128      TLS_RSA_WITH_AES_128_CBC_SHA
TLSv1.3
 -

 Testing robust forward secrecy (FS) -- omitting Null Authentication/Encryption, 3DES, RC4

 No ciphers supporting Forward Secrecy (FS) offered

 Testing server defaults (Server Hello)

 TLS extensions (standard)    "renegotiation info/#65281" "EC point formats/#11" "max fragment length/#1" "encrypt-then-mac/#22" "extended master secret/#23"
 Session Ticket RFC 5077 hint no -- no lifetime advertised
 SSL Session ID support       yes
 Session Resumption           Tickets no, ID: no
 TLS clock skew               -2 sec from localtime
 Client Authentication        none
 Signature Algorithm          SHA1 with RSA -- besides: users will receive a strong browser WARNING
 Server key size              RSA 1024 bits (exponent is 65537)
 Server key usage             Digital Signature, Non Repudiation, Key Encipherment
 Server extended key usage    --
 Serial                       BC43D87A6D471F3A (OK: length 8)
 Fingerprints                 SHA1 2ADCD3A7C7F039BCCF8175811B790A5795DF65EF
                              SHA256 A68510F07E2D6D60BC5A74125443EBC0C00BDD65BFDE02B06E283E41A344E9C2
 Common Name (CN)             TPRI-DEVICE
 subjectAltName (SAN)         missing (NOT ok) -- Browsers are complaining
 Trust (hostname)             certificate does not match supplied URI
 Chain of trust               NOT ok (chain incomplete)
 EV cert (experimental)       no
 Certificate Validity (UTC)   201 >= 60 days (2014-07-04 05:47 --> 2024-07-01 05:47)
                              >= 10 years is way too long
 ETS/"eTLS", visibility info  not present
 Certificate Revocation List  --
 OCSP URI                     --
                              NOT ok -- neither CRL nor OCSP URI provided
 OCSP stapling                not offered
 OCSP must staple extension   --
 DNS CAA RR (experimental)    not offered
 Certificate Transparency     --
 Certificates provided        1
 Issuer                       TPRI-CA (TPRI from US)
 Intermediate Bad OCSP (exp.) Ok

 Testing HTTP header response @ "/"

 HTTP Status Code             200 OK
 HTTP clock skew              Got no HTTP time, maybe try different URL?
 Strict Transport Security    not offered
 Public Key Pinning           --
 Server banner                (no "Server" line in header, interesting!)
 Application banner           --
 Cookie(s)                    (none issued at "/")
 Security headers             Cache-Control: no-cache
 Reverse Proxy banner         --

 Testing vulnerabilities

 Heartbleed (CVE-2014-0160)                not vulnerable (OK), no heartbeat extension
 CCS (CVE-2014-0224)                       not vulnerable (OK)
 Ticketbleed (CVE-2016-9244), experiment.  not vulnerable (OK), no session ticket extension
 ROBOT                                     not vulnerable (OK)
 Secure Renegotiation (RFC 5746)           supported (OK)
 Secure Client-Initiated Renegotiation     not vulnerable (OK)
 CRIME, TLS (CVE-2012-4929)                not vulnerable (OK)
 BREACH (CVE-2013-3587)                    no gzip/deflate/compress/br HTTP compression (OK)  - only supplied "/" tested
 POODLE, SSL (CVE-2014-3566)               not vulnerable (OK), no SSLv3 support
 TLS_FALLBACK_SCSV (RFC 7507)              No fallback possible (OK), no protocol below TLS 1.2 offered
 SWEET32 (CVE-2016-2183, CVE-2016-6329)    not vulnerable (OK)
 FREAK (CVE-2015-0204)                     not vulnerable (OK)
 DROWN (CVE-2016-0800, CVE-2016-0703)      not vulnerable on this host and port (OK)
                                           make sure you don't use this certificate elsewhere with SSLv2 enabled services
                                           https://censys.io/ipv4?q=A68510F07E2D6D60BC5A74125443EBC0C00BDD65BFDE02B06E283E41A344E9C2 could help you to find out
 LOGJAM (CVE-2015-4000), experimental      not vulnerable (OK): no DH EXPORT ciphers, no DH key detected with <= TLS 1.2
 BEAST (CVE-2011-3389)                     not vulnerable (OK), no SSL3 or TLS1
 LUCKY13 (CVE-2013-0169), experimental     potentially VULNERABLE, uses cipher block chaining (CBC) ciphers with TLS. Check patches
 Winshock (CVE-2014-6321), experimental    not vulnerable (OK) - GCM rollup ciphers found
 RC4 (CVE-2013-2566, CVE-2015-2808)        no RC4 ciphers detected (OK)

 Running client simulations (HTTP) via sockets

 Browser                      Protocol  Cipher Suite Name (OpenSSL)       Forward Secrecy
------------------------------------------------------------------------------------------------
 Android 4.4.2                TLSv1.2   AES256-GCM-SHA384                 No FS
 Android 5.0.0                TLSv1.2   AES256-SHA                        No FS
 Android 6.0                  TLSv1.2   AES256-SHA                        No FS
 Android 7.0 (native)         TLSv1.2   AES256-GCM-SHA384                 No FS
 Android 8.1 (native)         TLSv1.2   AES256-GCM-SHA384                 No FS
 Android 9.0 (native)         TLSv1.2   AES256-GCM-SHA384                 No FS
 Android 10.0 (native)        TLSv1.2   AES256-GCM-SHA384                 No FS
 Chrome 74 (Win 10)           TLSv1.2   AES256-GCM-SHA384                 No FS
 Chrome 79 (Win 10)           TLSv1.2   AES256-GCM-SHA384                 No FS
 Firefox 66 (Win 8.1/10)      TLSv1.2   AES256-SHA                        No FS
 Firefox 71 (Win 10)          TLSv1.2   AES256-SHA                        No FS
 IE 6 XP                      No connection
 IE 8 Win 7                   No connection
 IE 8 XP                      No connection
 IE 11 Win 7                  TLSv1.2   AES256-GCM-SHA384                 No FS
 IE 11 Win 8.1                TLSv1.2   AES256-GCM-SHA384                 No FS
 IE 11 Win Phone 8.1          TLSv1.2   AES256-SHA256                     No FS
 IE 11 Win 10                 TLSv1.2   AES256-GCM-SHA384                 No FS
 Edge 15 Win 10               TLSv1.2   AES256-GCM-SHA384                 No FS
 Edge 17 (Win 10)             TLSv1.2   AES256-GCM-SHA384                 No FS
 Opera 66 (Win 10)            TLSv1.2   AES256-GCM-SHA384                 No FS
 Safari 9 iOS 9               TLSv1.2   AES256-GCM-SHA384                 No FS
 Safari 9 OS X 10.11          TLSv1.2   AES256-GCM-SHA384                 No FS
 Safari 10 OS X 10.12         TLSv1.2   AES256-GCM-SHA384                 No FS
 Safari 12.1 (iOS 12.2)       TLSv1.2   AES256-GCM-SHA384                 No FS
 Safari 13.0 (macOS 10.14.6)  TLSv1.2   AES256-GCM-SHA384                 No FS
 Apple ATS 9 iOS 9            No connection
 Java 6u45                    No connection
 Java 7u25                    No connection
 Java 8u161                   TLSv1.2   AES256-GCM-SHA384                 No FS
 Java 11.0.2 (OpenJDK)        TLSv1.2   AES256-GCM-SHA384                 No FS
 Java 12.0.1 (OpenJDK)        TLSv1.2   AES256-GCM-SHA384                 No FS
 OpenSSL 1.0.2e               TLSv1.2   AES256-GCM-SHA384                 No FS
 OpenSSL 1.1.0l (Debian)      TLSv1.2   AES256-GCM-SHA384                 No FS
 OpenSSL 1.1.1d (Debian)      TLSv1.2   AES256-GCM-SHA384                 No FS
 Thunderbird (68.3)           TLSv1.2   AES256-SHA                        No FS

 Rating (experimental)

 Rating specs (not complete)  SSL Labs's 'SSL Server Rating Guide' (version 2009q from 2020-01-30)
 Specification documentation  https://github.com/ssllabs/research/wiki/SSL-Server-Rating-Guide
 Protocol Support (weighted)  0 (0)
 Key Exchange     (weighted)  0 (0)
 Cipher Strength  (weighted)  0 (0)
 Final Score                  0
 Overall Grade                T
 Grade cap reasons            Grade capped to T. Uses SHA1 algorithm
                              Grade capped to T. Issues with the chain of trust (chain incomplete)
                              Grade capped to M. Domain name mismatch
                              Grade capped to B. Forward Secrecy (FS) is not supported
                              Grade capped to A. HSTS is not offered

 Done 2023-12-12 12:25:50 [  73s] -->> 192.168.0.53:443 (192.168.0.53) <<--
ndricjaho commented 10 months ago

Also, is it safe to assume, that since Tapo has upgraded their connection to the H200 from port 80 to 443 (with certificate), they might just roll that to their other wifi devices (bulbs, plugs, etc.)? In that case maybe the connection should always try :443 first and if that fails to try :80 in order to make the integration future-proof? Or maybe when we are at the configuration of a new device we can choose the protocol if the former method causes delays.

dastardo commented 10 months ago

Hi All,

I'm running HAos on VMware on Windows as my Linux knowledge is non-existent. How can I edit the connection port? I managed to find this list of files, but no connector.py

image

Thanks

boheme61 commented 10 months ago

my Linux knowledge is non-existent.

But you can read English right ? ... Read the "thread" , from top to bottom, then i think/hope you get a picture of where we're "standing" right now.

dastardo commented 10 months ago

my Linux knowledge is non-existent.

But you can read English right ? ... Read the "thread" , from top to bottom, then i think/hope you get a picture of where we're "standing" right now.

I can read English thanks, but I'd like to try changing the port as it seems some people have had some success.

boheme61 commented 10 months ago

changing the port as it seems some people have had some success.

Do you have any references to these "succes" ?

hiltonhowie commented 10 months ago

I too can be free for a remote session to test on my H200

Oalexxx commented 10 months ago

I'm also having trouble integrating the H200 hub. I would like to integrate my window contacts (T110) into HA... Will there be a timely solution to the problem?

petretiandrea commented 10 months ago

I need a volunteer to schedule a remote call or give me access to a device to try it

I volunteer, I have the same problem and the device

Write me by email

boheme61 commented 10 months ago

@ petretiandrea Not sure You are aware of it, or whether you are testing with others above, but this is the latest outcome of " main.py " with the client-changes you provided. Running TapoController v2.12.2 and plugp100 v4.0.1

➜  tapo python main.py
Traceback (most recent call last):
  File "/homeassistant/custom_components/tapo/main.py", line 26, 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 "/homeassistant/custom_components/tapo/main.py", line 17, in main
    await client.initialize()
          ^^^^^^^^^^^^^^^^^
AttributeError: 'TapoClient' object has no attribute 'initialize'
➜  tapo 

Actually been like this the latest couple of updates of both

boheme61 commented 10 months ago

FYI ... H200 just got another "security" Update

And below is the latest exceptions, trying to add the hub ...slightly different ... just thought i wanted to post this, just in casei it's a change/update that affect this issue

File "/usr/local/lib/python3.11/site-packages/aiohttp/connector.py", line 980, in _wrap_create_connection
return await self._loop.create_connection(*args, **kwargs) # type: ignore[return-value] # noqa
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/asyncio/base_events.py", line 1085, in create_connection
raise exceptions[0]
File "/usr/local/lib/python3.11/asyncio/base_events.py", line 1069, in create_connection
sock = await self._connect_sock(
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/asyncio/base_events.py", line 973, in _connect_sock
await self.sock_connect(sock, address)
File "/usr/local/lib/python3.11/asyncio/selector_events.py", line 628, in sock_connect
return await fut
^^^^^^^^^
File "/usr/local/lib/python3.11/asyncio/selector_events.py", line 668, in _sock_connect_cb
raise OSError(err, f'Connect call failed {address}')
TimeoutError: [Errno 110] Connect call failed ('192.168.50.21', 80)
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/config/custom_components/tapo/config_flow.py", line 192, in _get_first_data_from_api
(await tapo_client.get_device_info())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/plugp100/api/tapo_client.py", line 92, in get_device_info
return await self.execute_raw_request(get_info_request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/plugp100/api/tapo_client.py", line 77, in execute_raw_request
await self._initialize_protocol_if_needed()
File "/usr/local/lib/python3.11/site-packages/plugp100/api/tapo_client.py", line 71, in _initialize_protocol_if_needed
await self._guess_protocol()
File "/usr/local/lib/python3.11/site-packages/plugp100/api/tapo_client.py", line 221, in _guess_protocol
response = await self.get_component_negotiation()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/plugp100/api/tapo_client.py", line 81, in get_component_negotiation
return (await self.execute_raw_request(TapoRequest.component_negotiation())).map(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/plugp100/api/tapo_client.py", line 78, in execute_raw_request
return (await self._protocol.send_request(request)).map(lambda x: x.result)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/plugp100/protocol/passthrough_protocol.py", line 41, in send_request
response = await self._send_request(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/plugp100/protocol/passthrough_protocol.py", line 61, in _send_request
await self._login_with_version(self._credential)
File "/usr/local/lib/python3.11/site-packages/plugp100/protocol/passthrough_protocol.py", line 80, in _login_with_version
session_or_error = await self._passthrough.handshake(self._url)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/plugp100/protocol/securepassthrough_transport.py", line 70, in handshake
response = await self._http.async_make_post(url, json=request_body)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/plugp100/common/utils/http_client.py", line 18, in async_make_post
async with self.session.post(
File "/usr/local/lib/python3.11/site-packages/aiohttp/client.py", line 1141, in __aenter__
self._resp = await self._coro
^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/aiohttp/client.py", line 536, in _request
conn = await self._connector.connect(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/aiohttp/connector.py", line 540, in connect
proto = await self._create_connection(req, traces, timeout)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/aiohttp/connector.py", line 901, in _create_connection
_, proto = await self._create_direct_connection(req, traces, timeout)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/aiohttp/connector.py", line 1209, in _create_direct_connection
raise last_exc
File "/usr/local/lib/python3.11/site-packages/aiohttp/connector.py", line 1178, in _create_direct_connection
transp, proto = await self._wrap_create_connection(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/aiohttp/connector.py", line 988, in _wrap_create_connection
raise client_error(req.connection_key, exc) from exc
aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host 192.168.50.21:80 ssl:default [Connect call failed ('192.168.50.21', 80)]
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/config/custom_components/tapo/config_flow.py", line 119, in async_step_user
device_data = await self._get_first_data_from_api(tapo_client)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/config/custom_components/tapo/config_flow.py", line 199, in _get_first_data_from_api
raise CannotConnect from error
custom_components.tapo.errors.CannotConnect

BR

jajera commented 10 months ago

another H200 logs and observation on the current code.

text  error  warn  system  array  login  

                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/tapo/config_flow.py", line 199, in _get_first_data_from_api
    raise CannotConnect from error
custom_components.tapo.errors.CannotConnect
2023-12-26 18:29:42.002 WARNING (MainThread) [plugp100.api.tapo_client] Default protocol not working, fallback to KLAP ;)
2023-12-26 18:30:17.026 WARNING (MainThread) [plugp100.api.tapo_client] Default protocol not working, fallback to KLAP ;)
2023-12-26 18:50:21.248 ERROR (MainThread) [custom_components.tapo.config_flow] Failed to setup cannot connect 
Traceback (most recent call last):
  File "/usr/local/lib/python3.11/site-packages/aiohttp/connector.py", line 992, in _wrap_create_connection
    return await self._loop.create_connection(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/asyncio/base_events.py", line 1085, in create_connection
    raise exceptions[0]
  File "/usr/local/lib/python3.11/asyncio/base_events.py", line 1069, in create_connection
    sock = await self._connect_sock(
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/asyncio/base_events.py", line 973, in _connect_sock
    await self.sock_connect(sock, address)
  File "/usr/local/lib/python3.11/asyncio/selector_events.py", line 628, in sock_connect
    return await fut
           ^^^^^^^^^
  File "/usr/local/lib/python3.11/asyncio/selector_events.py", line 668, in _sock_connect_cb
    raise OSError(err, f'Connect call failed {address}')
TimeoutError: [Errno 110] Connect call failed ('192.168.22.80', 80)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/tapo/config_flow.py", line 192, in _get_first_data_from_api
    (await tapo_client.get_device_info())
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/plugp100/api/tapo_client.py", line 92, in get_device_info
    return await self.execute_raw_request(get_info_request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/plugp100/api/tapo_client.py", line 77, in execute_raw_request
    await self._initialize_protocol_if_needed()
  File "/usr/local/lib/python3.11/site-packages/plugp100/api/tapo_client.py", line 71, in _initialize_protocol_if_needed
    await self._guess_protocol()
  File "/usr/local/lib/python3.11/site-packages/plugp100/api/tapo_client.py", line 221, in _guess_protocol
    response = await self.get_component_negotiation()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/plugp100/api/tapo_client.py", line 81, in get_component_negotiation
    return (await self.execute_raw_request(TapoRequest.component_negotiation())).map(
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/plugp100/api/tapo_client.py", line 78, in execute_raw_request
    return (await self._protocol.send_request(request)).map(lambda x: x.result)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/plugp100/protocol/passthrough_protocol.py", line 41, in send_request
    response = await self._send_request(request)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/plugp100/protocol/passthrough_protocol.py", line 61, in _send_request
    await self._login_with_version(self._credential)
  File "/usr/local/lib/python3.11/site-packages/plugp100/protocol/passthrough_protocol.py", line 80, in _login_with_version
    session_or_error = await self._passthrough.handshake(self._url)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/plugp100/protocol/securepassthrough_transport.py", line 70, in handshake
    response = await self._http.async_make_post(url, json=request_body)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/plugp100/common/utils/http_client.py", line 18, in async_make_post
    async with self.session.post(
  File "/usr/local/lib/python3.11/site-packages/aiohttp/client.py", line 1187, in __aenter__
    self._resp = await self._coro
                 ^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/aiohttp/client.py", line 574, in _request
    conn = await self._connector.connect(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/aiohttp/connector.py", line 544, in connect
    proto = await self._create_connection(req, traces, timeout)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/aiohttp/connector.py", line 911, in _create_connection
    _, proto = await self._create_direct_connection(req, traces, timeout)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/aiohttp/connector.py", line 1235, in _create_direct_connection
    raise last_exc
  File "/usr/local/lib/python3.11/site-packages/aiohttp/connector.py", line 1204, in _create_direct_connection
    transp, proto = await self._wrap_create_connection(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/aiohttp/connector.py", line 1000, in _wrap_create_connection
    raise client_error(req.connection_key, exc) from exc
aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host 192.168.22.80:80 ssl:default [Connect call failed ('192.168.22.80', 80)]

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/tapo/config_flow.py", line 119, in async_step_user
    device_data = await self._get_first_data_from_api(tapo_client)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/tapo/config_flow.py", line 199, in _get_first_data_from_api
    raise CannotConnect from error
custom_components.tapo.errors.CannotConnect

it appears that H200 is just responding via port 443

openssl - https/443

$ openssl.exe s_client -connect 192.168.22.80:443 -tls1_2
CONNECTED(00000160)
Can't use SSL_get_servername
depth=0 C = US, ST = CA, O = TPRI, CN = TPRI-DEVICE
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 C = US, ST = CA, O = TPRI, CN = TPRI-DEVICE
verify error:num=21:unable to verify the first certificate
verify return:1
depth=0 C = US, ST = CA, O = TPRI, CN = TPRI-DEVICE
verify return:1
---
Certificate chain
 0 s:C = US, ST = CA, O = TPRI, CN = TPRI-DEVICE
   i:C = US, ST = CA, O = TPRI, CN = TPRI-CA
---
Server certificate
-----BEGIN CERTIFICATE-----
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-----END CERTIFICATE-----
subject=C = US, ST = CA, O = TPRI, CN = TPRI-DEVICE

issuer=C = US, ST = CA, O = TPRI, CN = TPRI-CA

---
No client certificate CA names sent
---
SSL handshake has read 705 bytes and written 384 bytes
Verification error: unable to verify the first certificate
---
New, TLSv1.2, Cipher is AES256-GCM-SHA384
Server public key is 1024 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : AES256-GCM-SHA384
    Session-ID: 3FD3FFBCA0ED1E334F035FBA47EC381EFECBE149B83DC1F65BF3201FF345F8A1
    Session-ID-ctx:
    Master-Key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1703578175
    Timeout   : 7200 (sec)
    Verify return code: 21 (unable to verify the first certificate)
    Extended master secret: yes
---
HTTP/1.1 200 OK
Connection: keep-alive
Content-Type: application/json
Cache-Control: no-cache
Expires: 0
Transfer-Encoding: chunked

2
{}
0

closed

openssl - http/80

$ openssl.exe s_client -connect 192.168.22.80:80 -tls1_2
20708:error:0200274C:system library:connect:reason(1868):../openssl-1.1.1u/crypto/bio/b_sock2.c:110:
20708:error:2008A067:BIO routines:BIO_connect:connect error:../openssl-1.1.1u/crypto/bio/b_sock2.c:111:
connect:errno=0

curl - https/443

$ curl https://192.168.22.80/api/v1/device
curl: (60) schannel: SEC_E_UNTRUSTED_ROOT (0x80090325) - The certificate chain was issued by an authority that is not trusted.
More details here: https://curl.se/docs/sslcerts.html
$ curl -k https://192.168.22.80/api/v1/device
{}

curl - http/80

$ curl -k http://192.168.22.80/api/v1/device
curl: (28) Failed to connect to 192.168.22.80 port 80 after 21034 ms: Couldn't connect to server

port connectivity test - https/443

PS C:\> Test-NetConnection 192.168.22.80 -Port 443                                                                                                                                                                                                                                                                                                                                                                     
RemoteAddress    : 192.168.22.80                                                                                  
RemotePort       : 443
TcpTestSucceeded : True

port connectivity test - http/80

PS C:\> Test-NetConnection 192.168.22.80 -Port 443                                                                                                                                                                                                                                                                                                                                                                     
RemoteAddress    : 192.168.22.80                                                                                  
RemotePort       : 80
TcpTestSucceeded : False
jajera commented 10 months ago

i would second on what @tvpetersen mentioned about tls1.2.

using this test code, it is does attempt to connect using https but on the older sslv3 protocol.

import asyncio
import os

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

async def main():
    # create generic tapo api
    username = os.getenv("USERNAME", "<email>")
    password = os.getenv("PASSWORD", "<password>")

    credentials = AuthCredential(username, password)
    # client = TapoClient(credentials, "192.168.22.80")
    client = TapoClient.create(credentials, "192.168.22.80", 443, True)

    print(await client.get_device_info())
    # print(await client.get_child_device_list())
    # print(await client.get_child_device_component_list())

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

error:

vscode ➜ /workspaces/home-assistant-tapo-p100 (main) $ python /tmp/main.py 
Traceback (most recent call last):
  File "/home/vscode/.local/lib/python3.11/site-packages/aiohttp/connector.py", line 980, in _wrap_create_connection
    return await self._loop.create_connection(*args, **kwargs)  # type: ignore[return-value]  # noqa
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/asyncio/base_events.py", line 1112, in create_connection
    transport, protocol = await self._create_connection_transport(
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/asyncio/base_events.py", line 1145, in _create_connection_transport
    await waiter
  File "/usr/local/lib/python3.11/asyncio/sslproto.py", line 575, in _on_handshake_complete
    raise handshake_exc
  File "/usr/local/lib/python3.11/asyncio/sslproto.py", line 557, in _do_handshake
    self._sslobj.do_handshake()
  File "/usr/local/lib/python3.11/ssl.py", line 979, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:1006)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/tmp/main.py", line 26, in <module>
    loop.run_until_complete(main())
  File "/usr/local/lib/python3.11/asyncio/base_events.py", line 653, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/tmp/main.py", line 19, in main
    print(await client.get_device_info())
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/vscode/.local/lib/python3.11/site-packages/plugp100/api/tapo_client.py", line 92, in get_device_info
    return await self.execute_raw_request(get_info_request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/vscode/.local/lib/python3.11/site-packages/plugp100/api/tapo_client.py", line 77, in execute_raw_request
    await self._initialize_protocol_if_needed()
  File "/home/vscode/.local/lib/python3.11/site-packages/plugp100/api/tapo_client.py", line 71, in _initialize_protocol_if_needed
    await self._guess_protocol()
  File "/home/vscode/.local/lib/python3.11/site-packages/plugp100/api/tapo_client.py", line 221, in _guess_protocol
    response = await self.get_component_negotiation()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/vscode/.local/lib/python3.11/site-packages/plugp100/api/tapo_client.py", line 81, in get_component_negotiation
    return (await self.execute_raw_request(TapoRequest.component_negotiation())).map(
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/vscode/.local/lib/python3.11/site-packages/plugp100/api/tapo_client.py", line 78, in execute_raw_request
    return (await self._protocol.send_request(request)).map(lambda x: x.result)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/vscode/.local/lib/python3.11/site-packages/plugp100/protocol/passthrough_protocol.py", line 41, in send_request
    response = await self._send_request(request)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/vscode/.local/lib/python3.11/site-packages/plugp100/protocol/passthrough_protocol.py", line 61, in _send_request
    await self._login_with_version(self._credential)
  File "/home/vscode/.local/lib/python3.11/site-packages/plugp100/protocol/passthrough_protocol.py", line 80, in _login_with_version
    session_or_error = await self._passthrough.handshake(self._url)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/vscode/.local/lib/python3.11/site-packages/plugp100/protocol/securepassthrough_transport.py", line 70, in handshake
    response = await self._http.async_make_post(url, json=request_body)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/vscode/.local/lib/python3.11/site-packages/plugp100/common/utils/http_client.py", line 18, in async_make_post
    async with self.session.post(
  File "/home/vscode/.local/lib/python3.11/site-packages/aiohttp/client.py", line 1141, in __aenter__
    self._resp = await self._coro
                 ^^^^^^^^^^^^^^^^
  File "/home/vscode/.local/lib/python3.11/site-packages/aiohttp/client.py", line 536, in _request
    conn = await self._connector.connect(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/vscode/.local/lib/python3.11/site-packages/aiohttp/connector.py", line 540, in connect
    proto = await self._create_connection(req, traces, timeout)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/vscode/.local/lib/python3.11/site-packages/aiohttp/connector.py", line 901, in _create_connection
    _, proto = await self._create_direct_connection(req, traces, timeout)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/vscode/.local/lib/python3.11/site-packages/aiohttp/connector.py", line 1209, in _create_direct_connection
    raise last_exc
  File "/home/vscode/.local/lib/python3.11/site-packages/aiohttp/connector.py", line 1178, in _create_direct_connection
    transp, proto = await self._wrap_create_connection(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/vscode/.local/lib/python3.11/site-packages/aiohttp/connector.py", line 984, in _wrap_create_connection
    raise ClientConnectorSSLError(req.connection_key, exc) from exc
aiohttp.client_exceptions.ClientConnectorSSLError: Cannot connect to host 192.168.22.80:443 ssl:default [[SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:1006)]
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x7f74e519dc10>

i think we just need to update the code to explicitly use tls1.2. i tried but i can't figure out it yet :)

petretiandrea commented 10 months ago

I've updated on this. H200 use a different protocol, the one used for tapo cameras. My library actually doens't support this protocol, but I'm working to add it

coochster commented 10 months ago

Thanks Andrea, I really appreciate your efforts on this 😊

boheme61 commented 10 months ago

Yeah, i did suspect it was a "Major" rewrite/re-thinking task you was facing

Wish You a prosperous New-Year !

jakeycrx commented 10 months ago

You can integrate the H200 into Home Assistant via smartthings

Yury-Zakharov commented 9 months ago

@jakeycrx Could you please elaborate on this?

jakeycrx commented 9 months ago

@Yury-Zakharov Add the H200 devices to smartthings, then integrate them into HA via the smartthings integration

github-actions[bot] commented 8 months ago

This issue is stale because it has been open for 30 days with no activity.

antstyl commented 8 months ago

Kindly asking if there is any progress on this?

g-chap commented 8 months ago

Would definitely still appreciate support for H200.

Yury-Zakharov commented 8 months ago

Release 2.14.0 did not fix the issue.

Yury-Zakharov commented 7 months ago

Release 3.0 did not fix the issue neither.

petretiandrea commented 7 months ago

H200 is still in developmente

f commented 7 months ago

Tapo Camera Control can connect to H200 but shows only the cameras connected to it. I think it can be tweaked to show all the child devices, right?

kaltasGit commented 7 months ago

H200 is still in developmente

Is there already a release date?

geistchevalier commented 7 months ago

Don't know if this will help, but Tapo H200 has a new firmware version (1.30) that adds matter support, I personally don't have a matter dongle/hub to test it with home-assistant though. I'm unsure if this will affect the ssl implementation that you're planning/creating.

github-actions[bot] commented 6 months ago

This issue is stale because it has been open for 30 days with no activity.

AshleyJackson commented 6 months ago

Bump

github-actions[bot] commented 5 months ago

This issue is stale because it has been open for 30 days with no activity.

github-actions[bot] commented 4 months ago

This issue was closed because it has been inactive for 14 days since being marked as stale.

Yury-Zakharov commented 4 months ago

The issue persists.

antstyl commented 4 months ago

Is there any plan to sort out this?