126 lines
4.6 KiB
Python
126 lines
4.6 KiB
Python
"""Services for the Blink integration."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import voluptuous as vol
|
|
|
|
from homeassistant.config_entries import ConfigEntry, ConfigEntryState
|
|
from homeassistant.const import ATTR_DEVICE_ID, CONF_PIN
|
|
from homeassistant.core import HomeAssistant, ServiceCall
|
|
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
|
|
from homeassistant.helpers import (
|
|
config_validation as cv,
|
|
device_registry as dr,
|
|
issue_registry as ir,
|
|
)
|
|
|
|
from .const import ATTR_CONFIG_ENTRY_ID, DOMAIN, SERVICE_REFRESH, SERVICE_SEND_PIN
|
|
from .coordinator import BlinkUpdateCoordinator
|
|
|
|
SERVICE_UPDATE_SCHEMA = vol.Schema(
|
|
{
|
|
vol.Required(ATTR_DEVICE_ID): vol.All(cv.ensure_list, [cv.string]),
|
|
}
|
|
)
|
|
SERVICE_SEND_PIN_SCHEMA = vol.Schema(
|
|
{
|
|
vol.Required(ATTR_CONFIG_ENTRY_ID): vol.All(cv.ensure_list, [cv.string]),
|
|
vol.Optional(CONF_PIN): cv.string,
|
|
}
|
|
)
|
|
|
|
|
|
def setup_services(hass: HomeAssistant) -> None:
|
|
"""Set up the services for the Blink integration."""
|
|
|
|
def collect_coordinators(
|
|
device_ids: list[str],
|
|
) -> list[BlinkUpdateCoordinator]:
|
|
config_entries: list[ConfigEntry] = []
|
|
registry = dr.async_get(hass)
|
|
for target in device_ids:
|
|
device = registry.async_get(target)
|
|
if device:
|
|
device_entries: list[ConfigEntry] = []
|
|
for entry_id in device.config_entries:
|
|
entry = hass.config_entries.async_get_entry(entry_id)
|
|
if entry and entry.domain == DOMAIN:
|
|
device_entries.append(entry)
|
|
if not device_entries:
|
|
raise ServiceValidationError(
|
|
translation_domain=DOMAIN,
|
|
translation_key="invalid_device",
|
|
translation_placeholders={"target": target, "domain": DOMAIN},
|
|
)
|
|
config_entries.extend(device_entries)
|
|
else:
|
|
raise HomeAssistantError(
|
|
translation_domain=DOMAIN,
|
|
translation_key="device_not_found",
|
|
translation_placeholders={"target": target},
|
|
)
|
|
|
|
coordinators: list[BlinkUpdateCoordinator] = []
|
|
for config_entry in config_entries:
|
|
if config_entry.state != ConfigEntryState.LOADED:
|
|
raise HomeAssistantError(
|
|
translation_domain=DOMAIN,
|
|
translation_key="not_loaded",
|
|
translation_placeholders={"target": config_entry.title},
|
|
)
|
|
|
|
coordinators.append(hass.data[DOMAIN][config_entry.entry_id])
|
|
return coordinators
|
|
|
|
async def send_pin(call: ServiceCall):
|
|
"""Call blink to send new pin."""
|
|
for entry_id in call.data[ATTR_CONFIG_ENTRY_ID]:
|
|
if not (config_entry := hass.config_entries.async_get_entry(entry_id)):
|
|
raise ServiceValidationError(
|
|
translation_domain=DOMAIN,
|
|
translation_key="integration_not_found",
|
|
translation_placeholders={"target": DOMAIN},
|
|
)
|
|
if config_entry.state != ConfigEntryState.LOADED:
|
|
raise HomeAssistantError(
|
|
translation_domain=DOMAIN,
|
|
translation_key="not_loaded",
|
|
translation_placeholders={"target": config_entry.title},
|
|
)
|
|
coordinator = hass.data[DOMAIN][entry_id]
|
|
await coordinator.api.auth.send_auth_key(
|
|
coordinator.api,
|
|
call.data[CONF_PIN],
|
|
)
|
|
|
|
async def blink_refresh(call: ServiceCall):
|
|
"""Call blink to refresh info."""
|
|
ir.async_create_issue(
|
|
hass,
|
|
DOMAIN,
|
|
"service_deprecation",
|
|
breaks_in_ha_version="2024.7.0",
|
|
is_fixable=True,
|
|
is_persistent=True,
|
|
severity=ir.IssueSeverity.WARNING,
|
|
translation_key="service_deprecation",
|
|
)
|
|
|
|
for coordinator in collect_coordinators(call.data[ATTR_DEVICE_ID]):
|
|
await coordinator.api.refresh(force_cache=True)
|
|
|
|
# Register all the above services
|
|
# Refresh service is deprecated and will be removed in 7/2024
|
|
service_mapping = [
|
|
(blink_refresh, SERVICE_REFRESH, SERVICE_UPDATE_SCHEMA),
|
|
(send_pin, SERVICE_SEND_PIN, SERVICE_SEND_PIN_SCHEMA),
|
|
]
|
|
|
|
for service_handler, service_name, schema in service_mapping:
|
|
hass.services.async_register(
|
|
DOMAIN,
|
|
service_name,
|
|
service_handler,
|
|
schema=schema,
|
|
)
|