Add constants to ring integration (#104134)

This commit is contained in:
sdb9696 2023-11-17 18:17:16 +00:00 committed by GitHub
parent 483e0c9a85
commit 2387e4941b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 120 additions and 66 deletions

View File

@ -11,32 +11,30 @@ from typing import Any
import ring_doorbell
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform, __version__
from homeassistant.const import APPLICATION_NAME, CONF_TOKEN, __version__
from homeassistant.core import HomeAssistant, ServiceCall, callback
from homeassistant.exceptions import ConfigEntryAuthFailed
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.event import async_track_time_interval
from homeassistant.util.async_ import run_callback_threadsafe
from .const import (
DEVICES_SCAN_INTERVAL,
DOMAIN,
HEALTH_SCAN_INTERVAL,
HISTORY_SCAN_INTERVAL,
NOTIFICATIONS_SCAN_INTERVAL,
PLATFORMS,
RING_API,
RING_DEVICES,
RING_DEVICES_COORDINATOR,
RING_HEALTH_COORDINATOR,
RING_HISTORY_COORDINATOR,
RING_NOTIFICATIONS_COORDINATOR,
)
_LOGGER = logging.getLogger(__name__)
ATTRIBUTION = "Data provided by Ring.com"
NOTIFICATION_ID = "ring_notification"
NOTIFICATION_TITLE = "Ring Setup"
DOMAIN = "ring"
DEFAULT_ENTITY_NAMESPACE = "ring"
PLATFORMS = [
Platform.BINARY_SENSOR,
Platform.LIGHT,
Platform.SENSOR,
Platform.SWITCH,
Platform.CAMERA,
Platform.SIREN,
]
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up a config entry."""
@ -48,12 +46,12 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
partial(
hass.config_entries.async_update_entry,
entry,
data={**entry.data, "token": token},
data={**entry.data, CONF_TOKEN: token},
),
).result()
auth = ring_doorbell.Auth(
f"HomeAssistant/{__version__}", entry.data["token"], token_updater
f"{APPLICATION_NAME}/{__version__}", entry.data[CONF_TOKEN], token_updater
)
ring = ring_doorbell.Ring(auth)
@ -64,34 +62,34 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
raise ConfigEntryAuthFailed(err) from err
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = {
"api": ring,
"devices": ring.devices(),
"device_data": GlobalDataUpdater(
hass, "device", entry, ring, "update_devices", timedelta(minutes=1)
RING_API: ring,
RING_DEVICES: ring.devices(),
RING_DEVICES_COORDINATOR: GlobalDataUpdater(
hass, "device", entry, ring, "update_devices", DEVICES_SCAN_INTERVAL
),
"dings_data": GlobalDataUpdater(
RING_NOTIFICATIONS_COORDINATOR: GlobalDataUpdater(
hass,
"active dings",
entry,
ring,
"update_dings",
timedelta(seconds=5),
NOTIFICATIONS_SCAN_INTERVAL,
),
"history_data": DeviceDataUpdater(
RING_HISTORY_COORDINATOR: DeviceDataUpdater(
hass,
"history",
entry,
ring,
lambda device: device.history(limit=10),
timedelta(minutes=1),
HISTORY_SCAN_INTERVAL,
),
"health_data": DeviceDataUpdater(
RING_HEALTH_COORDINATOR: DeviceDataUpdater(
hass,
"health",
entry,
ring,
lambda device: device.update_health_data(),
timedelta(minutes=1),
HEALTH_SCAN_INTERVAL,
),
}

View File

@ -14,7 +14,7 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import DOMAIN
from .const import DOMAIN, RING_API, RING_DEVICES, RING_NOTIFICATIONS_COORDINATOR
from .entity import RingEntityMixin
@ -53,8 +53,8 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the Ring binary sensors from a config entry."""
ring = hass.data[DOMAIN][config_entry.entry_id]["api"]
devices = hass.data[DOMAIN][config_entry.entry_id]["devices"]
ring = hass.data[DOMAIN][config_entry.entry_id][RING_API]
devices = hass.data[DOMAIN][config_entry.entry_id][RING_DEVICES]
entities = [
RingBinarySensor(config_entry.entry_id, ring, device, description)
@ -90,13 +90,15 @@ class RingBinarySensor(RingEntityMixin, BinarySensorEntity):
async def async_added_to_hass(self) -> None:
"""Register callbacks."""
await super().async_added_to_hass()
self.ring_objects["dings_data"].async_add_listener(self._dings_update_callback)
self.ring_objects[RING_NOTIFICATIONS_COORDINATOR].async_add_listener(
self._dings_update_callback
)
self._dings_update_callback()
async def async_will_remove_from_hass(self) -> None:
"""Disconnect callbacks."""
await super().async_will_remove_from_hass()
self.ring_objects["dings_data"].async_remove_listener(
self.ring_objects[RING_NOTIFICATIONS_COORDINATOR].async_remove_listener(
self._dings_update_callback
)

View File

@ -16,7 +16,7 @@ from homeassistant.helpers.aiohttp_client import async_aiohttp_proxy_stream
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.util import dt as dt_util
from . import DOMAIN
from .const import DOMAIN, RING_DEVICES, RING_HISTORY_COORDINATOR
from .entity import RingEntityMixin
FORCE_REFRESH_INTERVAL = timedelta(minutes=3)
@ -30,7 +30,7 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up a Ring Door Bell and StickUp Camera."""
devices = hass.data[DOMAIN][config_entry.entry_id]["devices"]
devices = hass.data[DOMAIN][config_entry.entry_id][RING_DEVICES]
ffmpeg_manager = ffmpeg.get_ffmpeg_manager(hass)
cams = []
@ -66,7 +66,7 @@ class RingCam(RingEntityMixin, Camera):
"""Register callbacks."""
await super().async_added_to_hass()
await self.ring_objects["history_data"].async_track_device(
await self.ring_objects[RING_HISTORY_COORDINATOR].async_track_device(
self._device, self._history_update_callback
)
@ -74,7 +74,7 @@ class RingCam(RingEntityMixin, Camera):
"""Disconnect callbacks."""
await super().async_will_remove_from_hass()
self.ring_objects["history_data"].async_untrack_device(
self.ring_objects[RING_HISTORY_COORDINATOR].async_untrack_device(
self._device, self._history_update_callback
)

View File

@ -8,10 +8,16 @@ import voluptuous as vol
from homeassistant import config_entries, core, exceptions
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, __version__ as ha_version
from homeassistant.const import (
APPLICATION_NAME,
CONF_PASSWORD,
CONF_TOKEN,
CONF_USERNAME,
__version__ as ha_version,
)
from homeassistant.data_entry_flow import FlowResult
from . import DOMAIN
from .const import CONF_2FA, DOMAIN
_LOGGER = logging.getLogger(__name__)
@ -24,14 +30,14 @@ STEP_REAUTH_DATA_SCHEMA = vol.Schema({vol.Required(CONF_PASSWORD): str})
async def validate_input(hass: core.HomeAssistant, data):
"""Validate the user input allows us to connect."""
auth = ring_doorbell.Auth(f"HomeAssistant/{ha_version}")
auth = ring_doorbell.Auth(f"{APPLICATION_NAME}/{ha_version}")
try:
token = await hass.async_add_executor_job(
auth.fetch_token,
data["username"],
data["password"],
data.get("2fa"),
data[CONF_USERNAME],
data[CONF_PASSWORD],
data.get(CONF_2FA),
)
except ring_doorbell.Requires2FAError as err:
raise Require2FA from err
@ -65,10 +71,10 @@ class RingConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
_LOGGER.exception("Unexpected exception")
errors["base"] = "unknown"
else:
await self.async_set_unique_id(user_input["username"])
await self.async_set_unique_id(user_input[CONF_USERNAME])
return self.async_create_entry(
title=user_input["username"],
data={"username": user_input["username"], "token": token},
title=user_input[CONF_USERNAME],
data={CONF_USERNAME: user_input[CONF_USERNAME], CONF_TOKEN: token},
)
return self.async_show_form(
@ -87,7 +93,7 @@ class RingConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
return self.async_show_form(
step_id="2fa",
data_schema=vol.Schema({vol.Required("2fa"): str}),
data_schema=vol.Schema({vol.Required(CONF_2FA): str}),
)
async def async_step_reauth(self, entry_data: Mapping[str, Any]) -> FlowResult:
@ -119,7 +125,7 @@ class RingConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
else:
data = {
CONF_USERNAME: user_input[CONF_USERNAME],
"token": token,
CONF_TOKEN: token,
}
self.hass.config_entries.async_update_entry(
self.reauth_entry, data=data

View File

@ -0,0 +1,39 @@
"""The Ring constants."""
from __future__ import annotations
from datetime import timedelta
from homeassistant.const import Platform
ATTRIBUTION = "Data provided by Ring.com"
NOTIFICATION_ID = "ring_notification"
NOTIFICATION_TITLE = "Ring Setup"
DOMAIN = "ring"
DEFAULT_ENTITY_NAMESPACE = "ring"
PLATFORMS = [
Platform.BINARY_SENSOR,
Platform.LIGHT,
Platform.SENSOR,
Platform.SWITCH,
Platform.CAMERA,
Platform.SIREN,
]
DEVICES_SCAN_INTERVAL = timedelta(minutes=1)
NOTIFICATIONS_SCAN_INTERVAL = timedelta(seconds=5)
HISTORY_SCAN_INTERVAL = timedelta(minutes=1)
HEALTH_SCAN_INTERVAL = timedelta(minutes=1)
RING_API = "api"
RING_DEVICES = "devices"
RING_DEVICES_COORDINATOR = "device_data"
RING_NOTIFICATIONS_COORDINATOR = "dings_data"
RING_HISTORY_COORDINATOR = "history_data"
RING_HEALTH_COORDINATOR = "health_data"
CONF_2FA = "2fa"

View File

@ -9,7 +9,7 @@ from homeassistant.components.diagnostics import async_redact_data
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from . import DOMAIN
from .const import DOMAIN
TO_REDACT = {
"id",

View File

@ -3,7 +3,7 @@ from homeassistant.core import callback
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity import Entity
from . import ATTRIBUTION, DOMAIN
from .const import ATTRIBUTION, DOMAIN, RING_DEVICES_COORDINATOR
class RingEntityMixin(Entity):
@ -28,11 +28,15 @@ class RingEntityMixin(Entity):
async def async_added_to_hass(self) -> None:
"""Register callbacks."""
self.ring_objects["device_data"].async_add_listener(self._update_callback)
self.ring_objects[RING_DEVICES_COORDINATOR].async_add_listener(
self._update_callback
)
async def async_will_remove_from_hass(self) -> None:
"""Disconnect callbacks."""
self.ring_objects["device_data"].async_remove_listener(self._update_callback)
self.ring_objects[RING_DEVICES_COORDINATOR].async_remove_listener(
self._update_callback
)
@callback
def _update_callback(self) -> None:

View File

@ -11,7 +11,7 @@ from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
import homeassistant.util.dt as dt_util
from . import DOMAIN
from .const import DOMAIN, RING_DEVICES
from .entity import RingEntityMixin
_LOGGER = logging.getLogger(__name__)
@ -34,7 +34,7 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Create the lights for the Ring devices."""
devices = hass.data[DOMAIN][config_entry.entry_id]["devices"]
devices = hass.data[DOMAIN][config_entry.entry_id][RING_DEVICES]
lights = []

View File

@ -14,7 +14,12 @@ from homeassistant.const import PERCENTAGE, SIGNAL_STRENGTH_DECIBELS_MILLIWATT
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import DOMAIN
from .const import (
DOMAIN,
RING_DEVICES,
RING_HEALTH_COORDINATOR,
RING_HISTORY_COORDINATOR,
)
from .entity import RingEntityMixin
@ -24,7 +29,7 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up a sensor for a Ring device."""
devices = hass.data[DOMAIN][config_entry.entry_id]["devices"]
devices = hass.data[DOMAIN][config_entry.entry_id][RING_DEVICES]
entities = [
description.cls(config_entry.entry_id, device, description)
@ -75,7 +80,7 @@ class HealthDataRingSensor(RingSensor):
"""Register callbacks."""
await super().async_added_to_hass()
await self.ring_objects["health_data"].async_track_device(
await self.ring_objects[RING_HEALTH_COORDINATOR].async_track_device(
self._device, self._health_update_callback
)
@ -83,7 +88,7 @@ class HealthDataRingSensor(RingSensor):
"""Disconnect callbacks."""
await super().async_will_remove_from_hass()
self.ring_objects["health_data"].async_untrack_device(
self.ring_objects[RING_HEALTH_COORDINATOR].async_untrack_device(
self._device, self._health_update_callback
)
@ -112,7 +117,7 @@ class HistoryRingSensor(RingSensor):
"""Register callbacks."""
await super().async_added_to_hass()
await self.ring_objects["history_data"].async_track_device(
await self.ring_objects[RING_HISTORY_COORDINATOR].async_track_device(
self._device, self._history_update_callback
)
@ -120,7 +125,7 @@ class HistoryRingSensor(RingSensor):
"""Disconnect callbacks."""
await super().async_will_remove_from_hass()
self.ring_objects["history_data"].async_untrack_device(
self.ring_objects[RING_HISTORY_COORDINATOR].async_untrack_device(
self._device, self._history_update_callback
)

View File

@ -9,7 +9,7 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import DOMAIN
from .const import DOMAIN, RING_DEVICES
from .entity import RingEntityMixin
_LOGGER = logging.getLogger(__name__)
@ -21,7 +21,7 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Create the sirens for the Ring devices."""
devices = hass.data[DOMAIN][config_entry.entry_id]["devices"]
devices = hass.data[DOMAIN][config_entry.entry_id][RING_DEVICES]
sirens = []
for device in devices["chimes"]:

View File

@ -11,7 +11,7 @@ from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
import homeassistant.util.dt as dt_util
from . import DOMAIN
from .const import DOMAIN, RING_DEVICES
from .entity import RingEntityMixin
_LOGGER = logging.getLogger(__name__)
@ -33,7 +33,7 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Create the switches for the Ring devices."""
devices = hass.data[DOMAIN][config_entry.entry_id]["devices"]
devices = hass.data[DOMAIN][config_entry.entry_id][RING_DEVICES]
switches = []
for device in devices["stickup_cams"]: