nkgilley / python-ecobee-api

Python API for controlling Ecobee Thermostats
MIT License
44 stars 40 forks source link

authorize exception - ‘NoneType' object is not subscriptable #61

Closed bjpetit closed 3 years ago

bjpetit commented 3 years ago

I’m still digging in a bit on this. But I’m consistently seeing an exception coming out of the request() call under request_pin. Here’s the logging from the latest Home Assistant (with my client_id removed)

2021-02-28 20:34:35 DEBUG (SyncWorker_0) [pyecobee] Making request to authorize endpoint to request pin: url: https://api.ecobee.com/authorize, headers: {}, params: {'response_type': 'ecobeePin', 'client_id': 'xxxxxxxxxxxx', 'scope': 'smartWrite'}, body: None 2021-02-28 20:34:40 ERROR (SyncWorker_0) [pyecobee] Error connecting to ecobee while attempting to request pin. Possible connectivity outage. 2021-02-28 20:34:40 DEBUG (SyncWorker_0) [pyecobee] Error obtaining PIN code from ecobee: 'NoneType' object is not subscriptable

I set up a dev HA environment to start digging in. But, of course, that environment works fine.

The first thing that pops to mind is the empty header in the request. Non-auth_request calls set the content type in _request(), auth_request calls do not. Might that be causing issues?

Thanks. Brent

marthoc commented 3 years ago

ERROR (SyncWorker_0) [pyecobee] Error connecting to ecobee while attempting to request pin. Possible connectivity outage.

This is the problem we need to resolve. Why is the call to ecobee failing? The subsequent NoneType error happens because the request pin method then tries to get the pin from the empty response (failing gracefully).

Turn on debug logging and we will get a more detailed picture of what’s going on, the response code and more is reported in the debug logs.

bjpetit commented 3 years ago

I've been digging a bit to see what additional logging can be enabled. Unfortunately the request module doesn't appear to have much logging. Here's what I get today with the following logging config.

logger:
  default: debug
  logs:
    pyecobee: debug
    homeassistant.components.ecobee: debug
    urllib3: debug
2021-03-10 10:58:07 DEBUG (SyncWorker_4) [pyecobee] Making request to authorize endpoint to request pin: url: https://api.ecobee.com/authorize, headers: {}, params: {'response_type': 'ecobeePin', 'client_id': 'xxxxxxxxxxx', 'scope': 'smartWrite'}, body: None
2021-03-10 10:58:07 DEBUG (SyncWorker_4) [urllib3.connectionpool] Starting new HTTPS connection (1): api.ecobee.com:443
2021-03-10 10:58:12 ERROR (SyncWorker_4) [pyecobee] Error connecting to ecobee while attempting to request pin. Possible connectivity outage.
2021-03-10 10:58:12 DEBUG (SyncWorker_4) [pyecobee] Error obtaining PIN code from ecobee: 'NoneType' object is not subscriptable

It looks to me as if we're popping an exception out of the request() call, as the log message I'm seeing is associated with this exception handler...

except (RequestException, json.decoder.JSONDecodeError):

So far this only fails on my Home Assistant OS stable install. I've reinstalled that install a couple times and the result is always the same for the ecobee integration. And in my development instance this works just fine. So the Python or request module version may be a factor too.

bjpetit commented 3 years ago

I found it... It was DNS. For some reason api.ecobee.com isn't resolving with my default DNS settings. If I point it at the google DNS server it works fine. Other computers on the network resolve api.ecobee.com just fine with the same DHCP config, and my HA system resolves other DNS names just fine.

marthoc commented 3 years ago

So this problem is solved?

bjpetit commented 3 years ago

Yes. I’ve been observing the ecobee integration since modifying the DNS settings and things appear stable. I have a mystery to solve on why DNS is behaving the way it is, but that’s not an ecobee integration issue.