Skip to content

Commit

Permalink
Enable ring event listener to fix missing notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
sdb9696 committed Sep 3, 2024
1 parent e3896d1 commit 77b792c
Show file tree
Hide file tree
Showing 12 changed files with 370 additions and 219 deletions.
53 changes: 42 additions & 11 deletions homeassistant/components/ring/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,23 @@
from dataclasses import dataclass
import logging
from typing import Any, cast
import uuid

from ring_doorbell import Auth, Ring, RingDevices

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import APPLICATION_NAME, CONF_TOKEN, __version__
from homeassistant.const import APPLICATION_NAME, CONF_TOKEN
from homeassistant.core import HomeAssistant, ServiceCall, callback
from homeassistant.helpers import device_registry as dr, entity_registry as er
from homeassistant.helpers import (
device_registry as dr,
entity_registry as er,
instance_id,
)
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue

from .const import DOMAIN, PLATFORMS
from .coordinator import RingDataCoordinator, RingNotificationsCoordinator
from .const import CONF_LISTEN_CREDENTIALS, DOMAIN, PLATFORMS
from .coordinator import RingDataCoordinator, RingListenCoordinator

_LOGGER = logging.getLogger(__name__)

Expand All @@ -28,12 +33,26 @@ class RingData:
api: Ring
devices: RingDevices
devices_coordinator: RingDataCoordinator
notifications_coordinator: RingNotificationsCoordinator
listen_coordinator: RingListenCoordinator


type RingConfigEntry = ConfigEntry[RingData]


async def get_auth_agent_id(hass: HomeAssistant) -> tuple[str, str]:
"""Return user-agent and hardware id for Auth instantiation.
user_agent will be the display name in the ring.com authorised devices.
hardware_id will uniquely describe the authorised HA device.
"""
user_agent = f"{APPLICATION_NAME}/{DOMAIN}-integration"

# Generate a new uuid from the instance_uuid to keep the HA one private
instance_uuid = uuid.UUID(hex=await instance_id.async_get(hass))
hardware_id = str(uuid.uuid5(instance_uuid, user_agent))
return user_agent, hardware_id


async def async_setup_entry(hass: HomeAssistant, entry: RingConfigEntry) -> bool:
"""Set up a config entry."""

Expand All @@ -44,26 +63,39 @@ def token_updater(token: dict[str, Any]) -> None:
data={**entry.data, CONF_TOKEN: token},
)

def listen_credentials_updater(token: dict[str, Any]) -> None:
"""Handle from async context when token is updated."""
hass.config_entries.async_update_entry(
entry,
data={**entry.data, CONF_LISTEN_CREDENTIALS: token},
)

user_agent, hardware_id = await get_auth_agent_id(hass)
client_session = async_get_clientsession(hass)
auth = Auth(
f"{APPLICATION_NAME}/{__version__}",
user_agent,
entry.data[CONF_TOKEN],
token_updater,
http_client_session=async_get_clientsession(hass),
hardware_id=hardware_id,
http_client_session=client_session,
)
ring = Ring(auth)

await _migrate_old_unique_ids(hass, entry.entry_id)

devices_coordinator = RingDataCoordinator(hass, ring)
notifications_coordinator = RingNotificationsCoordinator(hass, ring)
listen_credentials = entry.data.get(CONF_LISTEN_CREDENTIALS)
listen_coordinator = RingListenCoordinator(
hass, ring, listen_credentials, listen_credentials_updater
)

await devices_coordinator.async_config_entry_first_refresh()
await notifications_coordinator.async_config_entry_first_refresh()

entry.runtime_data = RingData(
api=ring,
devices=ring.devices(),
devices_coordinator=devices_coordinator,
notifications_coordinator=notifications_coordinator,
listen_coordinator=listen_coordinator,
)

await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
Expand Down Expand Up @@ -91,7 +123,6 @@ async def async_refresh_all(_: ServiceCall) -> None:
)
for loaded_entry in hass.config_entries.async_loaded_entries(DOMAIN):
await loaded_entry.runtime_data.devices_coordinator.async_refresh()
await loaded_entry.runtime_data.notifications_coordinator.async_refresh()

# register service
hass.services.async_register(DOMAIN, "update", async_refresh_all)
Expand Down
136 changes: 0 additions & 136 deletions homeassistant/components/ring/binary_sensor.py

This file was deleted.

13 changes: 5 additions & 8 deletions homeassistant/components/ring/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,12 @@
import voluptuous as vol

from homeassistant.config_entries import ConfigEntry, ConfigFlow, ConfigFlowResult
from homeassistant.const import (
APPLICATION_NAME,
CONF_PASSWORD,
CONF_TOKEN,
CONF_USERNAME,
__version__ as ha_version,
)
from homeassistant.const import CONF_PASSWORD, CONF_TOKEN, CONF_USERNAME
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.aiohttp_client import async_get_clientsession

from . import get_auth_agent_id
from .const import CONF_2FA, DOMAIN

_LOGGER = logging.getLogger(__name__)
Expand All @@ -32,9 +27,11 @@
async def validate_input(hass: HomeAssistant, data: dict[str, str]) -> dict[str, Any]:
"""Validate the user input allows us to connect."""

user_agent, hardware_id = await get_auth_agent_id(hass)
auth = Auth(
f"{APPLICATION_NAME}/{ha_version}",
user_agent,
http_client_session=async_get_clientsession(hass),
hardware_id=hardware_id,
)

try:
Expand Down
4 changes: 2 additions & 2 deletions homeassistant/components/ring/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
DEFAULT_ENTITY_NAMESPACE = "ring"

PLATFORMS = [
Platform.BINARY_SENSOR,
Platform.BUTTON,
Platform.CAMERA,
Platform.EVENT,
Platform.LIGHT,
Platform.SENSOR,
Platform.SIREN,
Expand All @@ -26,6 +26,6 @@


SCAN_INTERVAL = timedelta(minutes=1)
NOTIFICATIONS_SCAN_INTERVAL = timedelta(seconds=5)

CONF_2FA = "2fa"
CONF_LISTEN_CREDENTIALS = "listen_token"
Loading

0 comments on commit 77b792c

Please sign in to comment.