palazzem / ha-econnect-alarm

Home Assistant integration that provides a full-fledged Alarm Panel to control your Elmo/IESS alarm systems.
BSD 3-Clause "New" or "Revised" License
10 stars 5 forks source link

Unable to arm/disarm when scan interval is used #117

Closed palazzem closed 1 month ago

palazzem commented 6 months ago

Describe the bug When "Scan Interval" is set to a certain value (user reported 120s), the integration doesn't have a valid access token anymore, resulting in a 401 error.

Error message

Logger: custom_components.econnect_metronet.devices
Source: custom_components/econnect_metronet/devices.py:284
Integration: e-Connect/Metronet Alarm (documentation, issues)
First occurred: 18:16:42 (1 occurrences)
Last logged: 18:16:42

Device | Error while arming the system: "User not authenticated"
Errore 2:
Logger: homeassistant.components.websocket_api.http.connection
Source: custom_components/econnect_metronet/devices.py:280
Integration: Home Assistant WebSocket API (documentation, issues)
First occurred: 18:16:42 (1 occurrences)
Last logged: 18:16:42

[547777283008] 401 Client Error: Unauthorized for url: https://connect.elmospa.com/api/panel/syncLogin
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 226, in handle_call_service
    await hass.services.async_call(
  File "/usr/src/homeassistant/homeassistant/core.py", line 1974, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2011, in _execute_service
    return await target(service_call)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 235, in handle_service
    return await service.entity_service_call(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 870, in entity_service_call
    response_data = await _handle_entity_call(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 942, in _handle_entity_call
    result = await task
             ^^^^^^^^^^
File "/config/custom_components/econnect_metronet/decorators.py", line 26, in func_wrapper
  File "/config/custom_components/econnect_metronet/alarm_control_panel.py", line 121, in async_alarm_arm_night
  File "/usr/local/lib/python3.11/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/econnect_metronet/devices.py", line 285, in arm
  File "/config/custom_components/econnect_metronet/devices.py", line 280, in arm
  File "/usr/local/lib/python3.11/contextlib.py", line 137, in enter
    return next(self.gen)
           ^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/elmo/api/client.py", line 179, in lock
    raise err
  File "/usr/local/lib/python3.11/site-packages/elmo/api/client.py", line 173, in lock
    response.raise_for_status()
  File "/usr/local/lib/python3.11/site-packages/requests/models.py", line 1021, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 401 Client Error: Unauthorized for url: https://connect.elmospa.com/api/panel/syncLogin

Expected behavior Even if the access token is expired, it should be renewed so that the API call results in a proper 401 if and only if the actual authentication is not correct.

Additional context This happens only if scan interval is set to a reasonable long period.

To Reproduce

Environment

palazzem commented 4 months ago

Putting this on-hold as we wait for user's feedback.

andr3a88 commented 3 months ago

I think I encountered the same problem:

To Reproduce

IMG_0237

Logs:

2024-03-08 20:30:57.196 ERROR (MainThread) [homeassistant.core] Error executing service: <ServiceCall alarm_control_panel.alarm_arm_home
Traceback (most recent call last):
  File "/usr/local/lib/python3.12/site-packages/elmo/api/client.py", line 183, in lock
    response.raise_for_status()
  File "/usr/local/lib/python3.12/site-packages/requests/models.py", line 1021, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 401 Client Error: Unauthorized for url: https://metronet.iessonline.com/api/panel/syncLogin

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/core.py", line 2335, in _run_service_call_catch_exceptions
    await coro_or_task
  File "/usr/src/homeassistant/homeassistant/core.py", line 2356, in _execute_service
    return await target(service_call)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 905, in entity_service_call
    single_response = await _handle_entity_call(
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 975, in _handle_entity_call
    result = await task
             ^^^^^^^^^^
  File "/config/custom_components/econnect_metronet/decorators.py", line 27, in func_wrapper
    result = await func(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/econnect_metronet/alarm_control_panel.py", line 110, in async_alarm_arm_home
    await self.hass.async_add_executor_job(self._device.arm, code, self._device._sectors_home)
  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/econnect_metronet/devices.py", line 348, in arm
    with self._connection.lock(code, user_id=user_id):
  File "/usr/local/lib/python3.12/contextlib.py", line 137, in __enter__
    return next(self.gen)
           ^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/elmo/api/client.py", line 190, in lock
    raise InvalidToken
elmo.api.exceptions.InvalidToken: Used token is not valid. You must authenticate again.
palazzem commented 1 month ago

In the HA integration, there is a retry logic that re-authenticates the client to refresh the access token if an update fails due to an InvalidToken exception. However, this logic currently applies only during updates and not for actions such as arm, disarm, etc.

I am updating the underlying library so that the ElmoClient used in the AlarmDevice instance automatically handles errors and token expiration. For more details, see: https://github.com/palazzem/econnect-python/issues/152.