bm1549 / home-assistant-frigidaire

Custom component for the Frigidaire integration
MIT License
36 stars 11 forks source link

Too many active logins - not an accurate error message? #59

Closed amaisano closed 4 months ago

amaisano commented 4 months ago

I am not logged in ANYWHERE except Home Assistant, yet I am still getting this error.

This is related to #57 which attempted to clarify the problem, but I think it is being applied too liberally.

Prior to this pull request being merged, the error I actually received was different - something about "reached maximum number of API requests," so this new wrapper error is, I think, too generic.

I've been locked out of seeing my entities in HA now for over 2 hours.

Polling is OFF on the integration, and my automation that polls every X seconds is also disabled. So literally the only thing that's "logged in" is, and has been, Home Assistant.

Not Postman, not my IOS app, not my partner's IOS app, not a web browser. Nothing except HA.

Logger: homeassistant.config_entries
Source: config_entries.py:594
First occurred: 10:43:10 AM (2 occurrences)
Last logged: 12:20:06 PM

Error setting up entry frigidaire for frigidaire
Traceback (most recent call last):
  File "/usr/local/lib/python3.12/site-packages/frigidaire/__init__.py", line 547, in post_request
    return self.parse_response(response)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/frigidaire/__init__.py", line 492, in parse_response
    raise FrigidaireException(f'Request failed with status {response.status_code}: {response.content}')
frigidaire.FrigidaireException: Request failed with status 429: b'{"error":"cas_3403","message":"You have exceeded the maximum number of active sessions. Please log out of another device or wait until an existing session expires.","detail":"Too many active login context"}'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/config/custom_components/frigidaire/__init__.py", line 22, in setup
    hass.data[DOMAIN][entry.entry_id] = frigidaire.Frigidaire(
                                        ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/frigidaire/__init__.py", line 247, in __init__
    self.authenticate()
  File "/usr/local/lib/python3.12/site-packages/frigidaire/__init__.py", line 380, in authenticate
    frigidaire_auth_response = self.post_request(self.regional_base_url, '/one-account-authorization/api/v1/token',
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/frigidaire/__init__.py", line 549, in post_request
    self.handle_request_exception(e, "POST", f'{url}{path}', headers, json.dumps(data))
  File "/usr/local/lib/python3.12/site-packages/frigidaire/__init__.py", line 517, in handle_request_exception
    raise FrigidaireException(error_str)
frigidaire.FrigidaireException: Error processing request:
POST https://api.us.ocp.electrolux.one/one-account-authorization/api/v1/token
headers={'x-api-key': 'XXXXXXXXXX', 'Authorization': 'Bearer', 'Accept': 'application/json', 'Accept-Charset': 'UTF-8', 'User-Agent': 'Ktor client', 'Content-Type': 'application/json'}
payload={"grantType": "urn:ietf:params:oauth:grant-type:token-exchange", "clientId": "FrigidaireOneApp", "idToken": "XXXXXXXXXX", "scope": ""}

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

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/config_entries.py", line 594, in async_setup
    result = await component.async_setup_entry(hass, self)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/frigidaire/__init__.py", line 33, in async_setup_entry
    await hass.async_add_executor_job(
  File "/usr/local/lib/python3.12/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/frigidaire/__init__.py", line 30, in setup
    raise data_entry_flow.AbortFlow("You have exceeded Frigidaire's maximum number of active sessions. Please log out of another device or wait until an existing session expires.") from err
homeassistant.data_entry_flow.AbortFlow: Flow aborted: You have exceeded Frigidaire's maximum number of active sessions. Please log out of another device or wait until an existing session expires.

cc @rothn @bm1549

amaisano commented 4 months ago

FYI the lockout/timeout period seems to be exactly 2 hours.

amaisano commented 4 months ago

I got the entities back, they were working, and then after setting Polling back to enabled for the integration, THEY ALL FAILED AGAIN AND ARE DISABLED.

Something smells fishy. I have 3 AC units. Is each of them counting as 1 active login??

rothn commented 4 months ago

Hmm. I think we just create one session in the config flow's validate_input (custom_components/frigidaire/config_flow.py) and one in the module-level init.py (https://github.com/bm1549/home-assistant-frigidaire/blob/main/custom_components/frigidaire/__init__.py).

So, what could be going wrong?

I would start by counting the number of frigidaire.Frigidaire() instances we create, perhaps with some sort of debug print. This would show up in the homeassistant logs. Let us know. I don't have the time to write this for you right now, but it shouldn't be too hard if you can code.

amaisano commented 4 months ago

Ok, I can play with that later this weekend, thanks for the tips.

More anecdotes:

I chose to only enable 1 of 3 AC unit entities when my lockout was released, and it worked fine. I was able to control it, and since polling was back on, the state updated within 30 seconds just fine. I sent further controls, no problem.

I then went to enable 1 of the 2 remaining disabled AC entities, and got the "Home Assistant will enable this in 30 seconds" message. In 30 seconds, all entities went back down again, totally unavailable. I assume what HA did in the background was just reload the whole integration, which probably ignores the fact that I have disabled some of the entities.

Anyway, here's to another 2 hours of waiting for my ACs to come back online.

amaisano commented 4 months ago

@rothn you got any time this weekend? I tried debugging and couldn't get code to output where you suggested.

rothn commented 4 months ago

Sorry-- I'm visiting family and making some repairs on a property last weekend and this next one. One thing I've noticed is that print() doesn't work well. For an example of logging, see custom_components/frigidaire/humidifier.py in this repo:

import logging
...
_LOGGER = logging.getLogger(__name__)
...
_LOGGER.error("Failed to connect to Frigidaire servers")

Does that work for you?

amaisano commented 4 months ago

I added this to the __init_.py file and am only getting output 1x when home assistant restarts and/or when i manually reload my frigidaire config entity.

It does not fire off when command actions are made from HA, nor when it polls every 60 seconds. I will update this when it comes back online after 2 hours because every time I reload the integration now it says I have logged in too many times.

However, I did notice this async_setup_entry method is also present inside the climate.py file. I added a different logging output there, but now I have to wait another 2 hours until I can test it out. Do you think they could by "doubling up?"

UPDATE: Did a restart of HA, it was in a failure state. About 30 minutes later, I ran the homeassistant reload config entity service on frigidaire and it "came back online". Some logs from that period. Note: the 2 occurrences listed for the INIT debug are from very different times today, they aren't back to back (previous restarts, etc).

image

rothn commented 4 months ago

The entry in climate.py should not be an issue since it doesn't perform a login, but rather re-uses an existing Frigidaire object (in theory). It's possible that there's some serialization logic going on that causes unexpected behavior. Can you add a logging message directly into /usr/local/lib/python3.12/site-packages/frigidaire/init.py in class Frigidaire -> def __init__()?

rothn commented 4 months ago

It might also be useful to capture a Wireshark trace from your homeassistant server

amaisano commented 4 months ago

I am putting debugging on hold. I was able to get full functionality back by reverting to this commit: https://github.com/bm1549/home-assistant-frigidaire/tree/d85d58a9222af0fb95814a611126eebdfc669d6f

And including a few Celsius hacks I've written about in other issues. Maybe when you're back we can go back to debugging again, but my family was getting really hot, haha.

karlg100 commented 4 months ago

My plugins has stopped working. Any chance we can roll back the HACS release to this commit?

bm1549 commented 4 months ago

@amaisano / @karlg100 can you try using https://github.com/bm1549/home-assistant-frigidaire/tree/57baf069830a6697fe9c3a25b680cc313a0f6e3a instead? I'd like to isolate the problem to either the changes in the frigidaire module or the changes in this repo

bm1549 commented 4 months ago

Hey folks, I just opened #62 with should help alleviate the problem by reducing the number of times the plugin tries to re-authenticate

Can you try it out for a few days and see if it makes the situation any better?

bm1549 commented 4 months ago

Fixed via #62