core/homeassistant/components/lametric/notify.py

160 lines
5.2 KiB
Python
Raw Normal View History

"""Support for LaMetric notifications."""
from __future__ import annotations
from typing import Any
from lmnotify import Model, SimpleFrame, Sound
from oauthlib.oauth2 import TokenExpiredError
from requests.exceptions import ConnectionError as RequestsConnectionError
import voluptuous as vol
from homeassistant.components.notify import (
2019-07-31 19:25:30 +00:00
ATTR_DATA,
ATTR_TARGET,
PLATFORM_SCHEMA,
BaseNotificationService,
)
from homeassistant.const import CONF_ICON
from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from . import HassLaMetricManager
from .const import (
AVAILABLE_ICON_TYPES,
AVAILABLE_PRIORITIES,
CONF_CYCLES,
CONF_ICON_TYPE,
CONF_LIFETIME,
CONF_PRIORITY,
DOMAIN,
LOGGER,
)
2019-07-31 19:25:30 +00:00
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
{
vol.Optional(CONF_ICON, default="a7956"): cv.string,
vol.Optional(CONF_LIFETIME, default=10): cv.positive_int,
vol.Optional(CONF_CYCLES, default=1): cv.positive_int,
vol.Optional(CONF_PRIORITY, default="warning"): vol.In(AVAILABLE_PRIORITIES),
vol.Optional(CONF_ICON_TYPE, default="info"): vol.In(AVAILABLE_ICON_TYPES),
2019-07-31 19:25:30 +00:00
}
)
def get_service(
hass: HomeAssistant,
config: ConfigType,
discovery_info: DiscoveryInfoType | None = None,
) -> LaMetricNotificationService:
"""Get the LaMetric notification service."""
return LaMetricNotificationService(
hass.data[DOMAIN],
2019-07-31 19:25:30 +00:00
config[CONF_ICON],
config[CONF_LIFETIME] * 1000,
config[CONF_CYCLES],
config[CONF_PRIORITY],
config[CONF_ICON_TYPE],
2019-07-31 19:25:30 +00:00
)
class LaMetricNotificationService(BaseNotificationService):
"""Implement the notification service for LaMetric."""
def __init__(
self,
hasslametricmanager: HassLaMetricManager,
icon: str,
lifetime: int,
cycles: int,
priority: str,
icon_type: str,
) -> None:
"""Initialize the service."""
self.hasslametricmanager = hasslametricmanager
self._icon = icon
self._lifetime = lifetime
self._cycles = cycles
self._priority = priority
self._icon_type = icon_type
self._devices: list[dict[str, Any]] = []
def send_message(self, message: str = "", **kwargs: Any) -> None:
"""Send a message to some LaMetric device."""
targets = kwargs.get(ATTR_TARGET)
data = kwargs.get(ATTR_DATA)
LOGGER.debug("Targets/Data: %s/%s", targets, data)
icon = self._icon
cycles = self._cycles
sound = None
priority = self._priority
icon_type = self._icon_type
# Additional data?
if data is not None:
if "icon" in data:
icon = data["icon"]
if "sound" in data:
try:
2019-07-31 19:25:30 +00:00
sound = Sound(category="notifications", sound_id=data["sound"])
LOGGER.debug("Adding notification sound %s", data["sound"])
except AssertionError:
LOGGER.error("Sound ID %s unknown, ignoring", data["sound"])
if "cycles" in data:
2019-07-31 19:25:30 +00:00
cycles = int(data["cycles"])
if "icon_type" in data:
if data["icon_type"] in AVAILABLE_ICON_TYPES:
icon_type = data["icon_type"]
else:
LOGGER.warning(
"Priority %s invalid, using default %s",
data["priority"],
priority,
)
if "priority" in data:
2019-07-31 19:25:30 +00:00
if data["priority"] in AVAILABLE_PRIORITIES:
priority = data["priority"]
else:
LOGGER.warning(
2019-07-31 19:25:30 +00:00
"Priority %s invalid, using default %s",
data["priority"],
priority,
)
text_frame = SimpleFrame(icon, message)
LOGGER.debug(
2019-07-31 19:25:30 +00:00
"Icon/Message/Cycles/Lifetime: %s, %s, %d, %d",
icon,
message,
self._cycles,
self._lifetime,
)
frames = [text_frame]
model = Model(frames=frames, cycles=cycles, sound=sound)
lmn = self.hasslametricmanager.manager
try:
self._devices = lmn.get_devices()
except TokenExpiredError:
LOGGER.debug("Token expired, fetching new token")
lmn.get_token()
self._devices = lmn.get_devices()
except RequestsConnectionError:
LOGGER.warning(
"Problem connecting to LaMetric, using cached devices instead"
2019-07-31 19:25:30 +00:00
)
for dev in self._devices:
if targets is None or dev["name"] in targets:
try:
lmn.set_device(dev)
2019-07-31 19:25:30 +00:00
lmn.send_notification(
model,
lifetime=self._lifetime,
priority=priority,
icon_type=icon_type,
2019-07-31 19:25:30 +00:00
)
LOGGER.debug("Sent notification to LaMetric %s", dev["name"])
except OSError:
LOGGER.warning("Cannot connect to LaMetric %s", dev["name"])