Vedeneb / HA-SmartThings-Find

Home Assisstant custom integration to provide data from Samsung SmartThings Find, such as SmartTag locations
MIT License
28 stars 0 forks source link

Stopped working, i get "Unavailable" #18

Open zivgin opened 2 months ago

zivgin commented 2 months ago

I had this appear for all my devices: "This entity is no longer being provided by the smartthings_find integration. If the entity is no longer in use, delete it in settings."

Except for my galaxy s6 watch (which is not exactly smartthing item)

Anyone else had encounter that?

stuartdenne commented 1 month ago

Yes, same behaviour for me since about 5 days ago. Nothing in the logs but I haven't tried enabling the debug level. Presumably due to an API change, but if the maintainer needs any further information I'm happy to help.

Vedeneb commented 1 month ago

This is actually a problem with the SmartThings website itself. Whenever I had this problem in the HA integration, the devices were missing from the website aswell. Only phones and tablets were still shown on the website. Logging out and back in fixed the problem.

I need to find a way to detect this scenario and trigger the reauth flow.

While I probably won't be able to fix this the next two weeks, in the meantime you could simply remove and readd the integration. This should fix it at least temporarily.

You also could manually edit the JSESSIONID in .storage/core.config_entries to any invalid value and after a restart of HA you should be prompted to login again.

zivgin commented 1 month ago

Yeah i re-auth and that worked. thank you!

zivgin commented 1 month ago

after i did the re-auth, it worked, but now it keeps asking me to re-auth all the time. image

it even shows my to update the integration twice! image

Vedeneb commented 1 month ago

Are you sure you're on the latest version of this integration? Also, how did you reauthenticate - did you remove the integration or manually edit the .storage-file?

Make sure to always restart HA when doing changes like that!

zivgin commented 1 month ago

Yeah restart probobly solve it

wriel1989 commented 1 month ago

Had the same, Is it not possible that we can automate the steps we do to ready it. That we can see if all sensorsystemen go to unavailable. It ready them all. After that step it all works indeed.

Atleast will make automation that it send notification to me. Then I know to fix it. That will be the first step for me

zivgin commented 1 month ago

Thanks, make sense. Just very annoying, where is this problem coming from?

Vedeneb commented 1 month ago

Sorry for my late response. I was really busy with other stuff the last few weeks (and still am...)

Can't tell exactly, where the problem is coming from. It seems like the (unofficial) API only responds with a few devices after some time.

Currently, the integration works like this:

  1. On HA start, get a list of all available devices from SmartThings
  2. Fetch the data for each of these devices at a specific interval (unless the device is disabled by the user)

Both have their own API endpoint. Now for some reason, the first endpoint only responds with a subset of devices after a few days/weeks. For me it were mainly the SmartTags that were missing while phones/tablets were still available.

So it's not exactly the integrations fault, but we definitely need to find a workaround. Currently I can think of two solutions:

  1. Somehow "detect" that some devices are missing and in that case raise the reauth flow. In this case you have to log in again but after that everything should be working again.
  2. Don't rely on the device-list from the API after initial setup. This would require to store the device list somewhere in HA (which would not be a big problem). The integration could now still feth the data-endpoint even if the device is not available in the device-list-endpoint anymore. However it might very well be that the data endpoint does not work anymore aswell, as soon as the session is in that "corrupted" state. In that case, this solution would not work.

It's also pretty hard to test because I have to wait for the session to get into this state, which sometimes happens after a few hours, sometimes after a few weeks...

zivgin commented 1 month ago

I'm sure you tested it but that's what the gpt told me:

Descriptions of Errors or Bugs and Possible Solutions

  1. Error Handling:

    • Bug: Insufficient error handling in API requests may lead to unhandled exceptions and integration failures.
    • Solution: Implement comprehensive error handling to catch and log exceptions, ensuring the integration can recover or inform the user appropriately.
      def fetch_data(self):
       try:
           response = requests.get(API_URL, headers=self.headers)
           response.raise_for_status()
           return response.json()
       except requests.exceptions.HTTPError as http_err:
           self.logger.error(f"HTTP error occurred: {http_err}")
       except Exception as err:
           self.logger.error(f"An error occurred: {err}")
       return None
  2. Session Management:

    • Bug: The integration might not handle session expiration correctly, causing loss of device data retrieval.
    • Solution: Add logic to check for session expiry and re-authenticate automatically.

      def get_session(self):
       if self.session_expired():
           self.reauthenticate()
       return self.session
      
      def session_expired(self):
       # Logic to check if session is expired
       return self.session_expiry_time < datetime.now()
      
      def reauthenticate(self):
       # Logic to reauthenticate and get new session
       self.session = requests.Session()
       self.session_expiry_time = datetime.now() + timedelta(hours=1)  # Example expiry time
  3. API Rate Limits:

    • Bug: Frequent API requests might hit rate limits, causing incomplete data retrieval.
    • Solution: Implement rate limit handling to pause and retry after hitting limits.
      def fetch_data(self):
       response = requests.get(API_URL, headers=self.headers)
       if response.status_code == 429:  # Too Many Requests
           self.logger.warning("Rate limit hit, sleeping for a while")
           time.sleep(60)  # Sleep for 1 minute
           response = requests.get(API_URL, headers=self.headers)
       return response.json()
  4. Polling Interval Configuration:

    • Bug: Fixed polling intervals may not suit all user needs, leading to inefficiencies or excessive battery drain.
    • Solution: Allow users to configure polling intervals via the configuration flow.
      class SmartThingsFindConfigFlow(ConfigFlow, domain=DOMAIN):
       async def async_step_user(self, user_input=None):
           if user_input is not None:
               return self.async_create_entry(title="SmartThings Find", data=user_input)
           return self.async_show_form(step_id="user", data_schema=vol.Schema({
               vol.Required("polling_interval", default=120): int,
           }))
  5. Polling Impact:

    • Bug: Frequent polling might cause battery drain on connected devices like watches and phones.
    • Solution: Allow disabling polling for specific devices and provide options to adjust the polling frequency.

      def schedule_polling(self, interval):
       self.hass.helpers.event.track_time_interval(self.update_devices, timedelta(seconds=interval))
      
      async def update_devices(self, now):
       # Fetch and update device data
       pass
      
      class SmartThingsFind(Entity):
       def __init__(self, hass, interval=120):
           self.hass = hass
           self.schedule_polling(interval)

By addressing these bugs and implementing the suggested solutions, the HA-SmartThings-Find integration can become more robust, user-friendly, and efficient.