Guard against flaky SimpliSafe API calls (#59175)

This commit is contained in:
Aaron Bach 2021-11-07 16:34:25 -07:00 committed by GitHub
parent 72aaeda8a0
commit 8ebd47b430
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 18 additions and 18 deletions

View File

@ -102,9 +102,11 @@ ATTR_TIMESTAMP = "timestamp"
DEFAULT_ENTITY_MODEL = "alarm_control_panel"
DEFAULT_ENTITY_NAME = "Alarm Control Panel"
DEFAULT_REST_API_ERROR_COUNT = 2
DEFAULT_SCAN_INTERVAL = timedelta(seconds=30)
DEFAULT_SOCKET_MIN_RETRY = 15
DISPATCHER_TOPIC_WEBSOCKET_EVENT = "simplisafe_websocket_event_{0}"
EVENT_SIMPLISAFE_EVENT = "SIMPLISAFE_EVENT"
@ -553,6 +555,8 @@ class SimpliSafeEntity(CoordinatorEntity):
assert simplisafe.coordinator
super().__init__(simplisafe.coordinator)
self._rest_api_errors = 0
if device:
model = device.type.name
device_name = device.name
@ -615,11 +619,24 @@ class SimpliSafeEntity(CoordinatorEntity):
else:
system_offline = False
return super().available and self._online and not system_offline
return (
self._rest_api_errors < DEFAULT_REST_API_ERROR_COUNT
and self._online
and not system_offline
)
@callback
def _handle_coordinator_update(self) -> None:
"""Update the entity with new REST API data."""
# SimpliSafe can incorrectly return an error state when there isn't any
# error. This can lead to the system having an unknown state frequently.
# To protect against that, we measure how many "error states" we receive
# and only alter the state if we detect a few in a row:
if self.coordinator.last_update_success:
self._rest_api_errors = 0
else:
self._rest_api_errors += 1
self.async_update_from_rest_api()
self.async_write_ha_state()

View File

@ -71,8 +71,6 @@ ATTR_RF_JAMMING = "rf_jamming"
ATTR_WALL_POWER_LEVEL = "wall_power_level"
ATTR_WIFI_STRENGTH = "wifi_strength"
DEFAULT_ERRORS_TO_ACCOMMODATE = 2
VOLUME_STRING_MAP = {
VOLUME_HIGH: "high",
VOLUME_LOW: "low",
@ -140,8 +138,6 @@ class SimpliSafeAlarm(SimpliSafeEntity, AlarmControlPanelEntity):
additional_websocket_events=WEBSOCKET_EVENTS_TO_LISTEN_FOR,
)
self._errors = 0
if code := self._simplisafe.entry.options.get(CONF_CODE):
if code.isdigit():
self._attr_code_format = FORMAT_NUMBER
@ -248,19 +244,6 @@ class SimpliSafeAlarm(SimpliSafeEntity, AlarmControlPanelEntity):
}
)
# SimpliSafe can incorrectly return an error state when there isn't any
# error. This can lead to the system having an unknown state frequently.
# To protect against that, we measure how many "error states" we receive
# and only alter the state if we detect a few in a row:
if self._system.state == SystemStates.error:
if self._errors > DEFAULT_ERRORS_TO_ACCOMMODATE:
self._attr_state = None
else:
self._errors += 1
return
self._errors = 0
self._set_state_from_system_data()
@callback