Catch all Ring timeout errors (#30960)
* Catch more Ring errors * Fix comment & Disable wifi entities by defaultpull/30993/head
parent
8fcd0e9a79
commit
ecef0f6e93
|
@ -7,6 +7,7 @@ from pathlib import Path
|
|||
from typing import Optional
|
||||
|
||||
from oauthlib.oauth2 import AccessDeniedError
|
||||
import requests
|
||||
from ring_doorbell import Auth, Ring
|
||||
import voluptuous as vol
|
||||
|
||||
|
@ -95,13 +96,19 @@ async def async_setup_entry(hass, entry):
|
|||
"api": ring,
|
||||
"devices": ring.devices(),
|
||||
"device_data": GlobalDataUpdater(
|
||||
hass, entry.entry_id, ring, "update_devices", timedelta(minutes=1)
|
||||
hass, "device", entry.entry_id, ring, "update_devices", timedelta(minutes=1)
|
||||
),
|
||||
"dings_data": GlobalDataUpdater(
|
||||
hass, entry.entry_id, ring, "update_dings", timedelta(seconds=5)
|
||||
hass,
|
||||
"active dings",
|
||||
entry.entry_id,
|
||||
ring,
|
||||
"update_dings",
|
||||
timedelta(seconds=5),
|
||||
),
|
||||
"history_data": DeviceDataUpdater(
|
||||
hass,
|
||||
"history",
|
||||
entry.entry_id,
|
||||
ring,
|
||||
lambda device: device.history(limit=10),
|
||||
|
@ -109,6 +116,7 @@ async def async_setup_entry(hass, entry):
|
|||
),
|
||||
"health_data": DeviceDataUpdater(
|
||||
hass,
|
||||
"health",
|
||||
entry.entry_id,
|
||||
ring,
|
||||
lambda device: device.update_health_data(),
|
||||
|
@ -168,6 +176,7 @@ class GlobalDataUpdater:
|
|||
def __init__(
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
data_type: str,
|
||||
config_entry_id: str,
|
||||
ring: Ring,
|
||||
update_method: str,
|
||||
|
@ -175,6 +184,7 @@ class GlobalDataUpdater:
|
|||
):
|
||||
"""Initialize global data updater."""
|
||||
self.hass = hass
|
||||
self.data_type = data_type
|
||||
self.config_entry_id = config_entry_id
|
||||
self.ring = ring
|
||||
self.update_method = update_method
|
||||
|
@ -215,6 +225,11 @@ class GlobalDataUpdater:
|
|||
_LOGGER.error("Ring access token is no longer valid. Set up Ring again")
|
||||
await self.hass.config_entries.async_unload(self.config_entry_id)
|
||||
return
|
||||
except requests.Timeout:
|
||||
_LOGGER.warning(
|
||||
"Time out fetching Ring %s data", self.data_type,
|
||||
)
|
||||
return
|
||||
|
||||
for update_callback in self.listeners:
|
||||
update_callback()
|
||||
|
@ -226,12 +241,14 @@ class DeviceDataUpdater:
|
|||
def __init__(
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
data_type: str,
|
||||
config_entry_id: str,
|
||||
ring: Ring,
|
||||
update_method: str,
|
||||
update_interval: timedelta,
|
||||
):
|
||||
"""Initialize device data updater."""
|
||||
self.data_type = data_type
|
||||
self.hass = hass
|
||||
self.config_entry_id = config_entry_id
|
||||
self.ring = ring
|
||||
|
@ -282,7 +299,7 @@ class DeviceDataUpdater:
|
|||
|
||||
def refresh_all(self, _=None):
|
||||
"""Refresh all registered devices."""
|
||||
for info in self.devices.values():
|
||||
for device_id, info in self.devices.items():
|
||||
try:
|
||||
data = info["data"] = self.update_method(info["device"])
|
||||
except AccessDeniedError:
|
||||
|
@ -291,6 +308,13 @@ class DeviceDataUpdater:
|
|||
self.hass.config_entries.async_unload(self.config_entry_id)
|
||||
)
|
||||
return
|
||||
except requests.Timeout:
|
||||
_LOGGER.warning(
|
||||
"Time out fetching Ring %s data for device %s",
|
||||
self.data_type,
|
||||
device_id,
|
||||
)
|
||||
continue
|
||||
|
||||
for update_callback in info["update_callbacks"]:
|
||||
self.hass.loop.call_soon_threadsafe(update_callback, data)
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
from datetime import timedelta
|
||||
import logging
|
||||
|
||||
import requests
|
||||
|
||||
from homeassistant.components.light import Light
|
||||
from homeassistant.core import callback
|
||||
import homeassistant.util.dt as dt_util
|
||||
|
@ -72,7 +74,12 @@ class RingLight(RingEntityMixin, Light):
|
|||
|
||||
def _set_light(self, new_state):
|
||||
"""Update light state, and causes Home Assistant to correctly update."""
|
||||
self._device.lights = new_state
|
||||
try:
|
||||
self._device.lights = new_state
|
||||
except requests.Timeout:
|
||||
_LOGGER.error("Time out setting %s light to %s", self.entity_id, new_state)
|
||||
return
|
||||
|
||||
self._light_on = new_state == ON_STATE
|
||||
self._no_updates_until = dt_util.utcnow() + SKIP_UPDATES_DELAY
|
||||
self.async_schedule_update_ha_state()
|
||||
|
|
|
@ -15,9 +15,6 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
"""Set up a sensor for a Ring device."""
|
||||
devices = hass.data[DOMAIN][config_entry.entry_id]["devices"]
|
||||
|
||||
# Makes a ton of requests. We will make this a config entry option in the future
|
||||
wifi_enabled = False
|
||||
|
||||
sensors = []
|
||||
|
||||
for device_type in ("chimes", "doorbots", "authorized_doorbots", "stickup_cams"):
|
||||
|
@ -25,9 +22,6 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
if device_type not in SENSOR_TYPES[sensor_type][1]:
|
||||
continue
|
||||
|
||||
if not wifi_enabled and sensor_type.startswith("wifi_"):
|
||||
continue
|
||||
|
||||
for device in devices[device_type]:
|
||||
if device_type == "battery" and device.battery_life is None:
|
||||
continue
|
||||
|
@ -124,6 +118,12 @@ class HealthDataRingSensor(RingSensor):
|
|||
"""Call update method."""
|
||||
self.async_write_ha_state()
|
||||
|
||||
@property
|
||||
def entity_registry_enabled_default(self) -> bool:
|
||||
"""Return if the entity should be enabled when first added to the entity registry."""
|
||||
# These sensors are data hungry and not useful. Disable by default.
|
||||
return False
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
"""Return the state of the sensor."""
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
from datetime import timedelta
|
||||
import logging
|
||||
|
||||
import requests
|
||||
|
||||
from homeassistant.components.switch import SwitchDevice
|
||||
from homeassistant.core import callback
|
||||
import homeassistant.util.dt as dt_util
|
||||
|
@ -74,7 +76,12 @@ class SirenSwitch(BaseRingSwitch):
|
|||
|
||||
def _set_switch(self, new_state):
|
||||
"""Update switch state, and causes Home Assistant to correctly update."""
|
||||
self._device.siren = new_state
|
||||
try:
|
||||
self._device.siren = new_state
|
||||
except requests.Timeout:
|
||||
_LOGGER.error("Time out setting %s siren to %s", self.entity_id, new_state)
|
||||
return
|
||||
|
||||
self._siren_on = new_state > 0
|
||||
self._no_updates_until = dt_util.utcnow() + SKIP_UPDATES_DELAY
|
||||
self.schedule_update_ha_state()
|
||||
|
|
Loading…
Reference in New Issue