core/homeassistant/components/group/notify.py

84 lines
2.5 KiB
Python
Raw Normal View History

"""Group platform for notify component."""
2022-09-14 09:36:28 +00:00
from __future__ import annotations
import asyncio
2022-09-14 09:36:28 +00:00
from collections.abc import Coroutine, Mapping
2016-11-04 05:56:55 +00:00
from copy import deepcopy
2022-09-14 09:36:28 +00:00
from typing import Any
import voluptuous as vol
from homeassistant.components.notify import (
2019-07-31 19:25:30 +00:00
ATTR_DATA,
ATTR_MESSAGE,
DOMAIN,
PLATFORM_SCHEMA,
BaseNotificationService,
)
from homeassistant.const import ATTR_SERVICE
2022-09-14 09:36:28 +00:00
from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv
2022-09-14 09:36:28 +00:00
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
2019-07-31 19:25:30 +00:00
CONF_SERVICES = "services"
2019-07-31 19:25:30 +00:00
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
{
vol.Required(CONF_SERVICES): vol.All(
cv.ensure_list,
[{vol.Required(ATTR_SERVICE): cv.slug, vol.Optional(ATTR_DATA): dict}],
)
}
)
2022-09-14 09:36:28 +00:00
def update(input_dict: dict[str, Any], update_source: dict[str, Any]) -> dict[str, Any]:
"""Deep update a dictionary.
Async friendly.
"""
for key, val in update_source.items():
if isinstance(val, Mapping):
2022-09-14 09:36:28 +00:00
recurse = update(input_dict.get(key, {}), val) # type: ignore[arg-type]
input_dict[key] = recurse
else:
input_dict[key] = update_source[key]
return input_dict
2022-09-14 09:36:28 +00:00
async def async_get_service(
hass: HomeAssistant,
config: ConfigType,
discovery_info: DiscoveryInfoType | None = None,
) -> GroupNotifyPlatform:
"""Get the Group notification service."""
2022-09-14 09:36:28 +00:00
return GroupNotifyPlatform(hass, config[CONF_SERVICES])
class GroupNotifyPlatform(BaseNotificationService):
"""Implement the notification service for the group notify platform."""
2022-09-14 09:36:28 +00:00
def __init__(self, hass: HomeAssistant, entities: list[dict[str, Any]]) -> None:
"""Initialize the service."""
self.hass = hass
self.entities = entities
2022-09-14 09:36:28 +00:00
async def async_send_message(self, message: str = "", **kwargs: Any) -> None:
"""Send message to all entities in the group."""
2022-09-14 09:36:28 +00:00
payload: dict[str, Any] = {ATTR_MESSAGE: message}
payload.update({key: val for key, val in kwargs.items() if val})
2022-09-14 09:36:28 +00:00
tasks: list[Coroutine[Any, Any, bool | None]] = []
for entity in self.entities:
2016-11-04 05:56:55 +00:00
sending_payload = deepcopy(payload.copy())
2022-09-14 09:36:28 +00:00
if (data := entity.get(ATTR_DATA)) is not None:
update(sending_payload, data)
2019-07-31 19:25:30 +00:00
tasks.append(
self.hass.services.async_call(
2022-09-14 09:36:28 +00:00
DOMAIN, entity[ATTR_SERVICE], sending_payload
2019-07-31 19:25:30 +00:00
)
)
if tasks:
await asyncio.wait(tasks)