""" A component which is collecting configuration errors. For more details about this component, please refer to the documentation at https://home-assistant.io/components/persistent_notification/ """ import asyncio import os import logging import voluptuous as vol from homeassistant.core import callback from homeassistant.exceptions import TemplateError from homeassistant.loader import bind_hass from homeassistant.helpers import config_validation as cv from homeassistant.helpers.entity import async_generate_entity_id from homeassistant.util import slugify from homeassistant.config import load_yaml_config_file ATTR_MESSAGE = 'message' ATTR_NOTIFICATION_ID = 'notification_id' ATTR_TITLE = 'title' DOMAIN = 'persistent_notification' ENTITY_ID_FORMAT = DOMAIN + '.{}' SERVICE_CREATE = 'create' SERVICE_DISMISS = 'dismiss' SCHEMA_SERVICE_CREATE = vol.Schema({ vol.Required(ATTR_MESSAGE): cv.template, vol.Optional(ATTR_TITLE): cv.template, vol.Optional(ATTR_NOTIFICATION_ID): cv.string, }) SCHEMA_SERVICE_DISMISS = vol.Schema({ vol.Required(ATTR_NOTIFICATION_ID): cv.string, }) DEFAULT_OBJECT_ID = 'notification' _LOGGER = logging.getLogger(__name__) @bind_hass def create(hass, message, title=None, notification_id=None): """Generate a notification.""" hass.add_job(async_create, hass, message, title, notification_id) @bind_hass def dismiss(hass, notification_id): """Remove a notification.""" hass.add_job(async_dismiss, hass, notification_id) @callback @bind_hass def async_create(hass, message, title=None, notification_id=None): """Generate a notification.""" data = { key: value for key, value in [ (ATTR_TITLE, title), (ATTR_MESSAGE, message), (ATTR_NOTIFICATION_ID, notification_id), ] if value is not None } hass.async_add_job(hass.services.async_call(DOMAIN, SERVICE_CREATE, data)) @callback @bind_hass def async_dismiss(hass, notification_id): """Remove a notification.""" data = {ATTR_NOTIFICATION_ID: notification_id} hass.async_add_job(hass.services.async_call(DOMAIN, SERVICE_DISMISS, data)) @asyncio.coroutine def async_setup(hass, config): """Set up the persistent notification component.""" @callback def create_service(call): """Handle a create notification service call.""" title = call.data.get(ATTR_TITLE) message = call.data.get(ATTR_MESSAGE) notification_id = call.data.get(ATTR_NOTIFICATION_ID) if notification_id is not None: entity_id = ENTITY_ID_FORMAT.format(slugify(notification_id)) else: entity_id = async_generate_entity_id( ENTITY_ID_FORMAT, DEFAULT_OBJECT_ID, hass=hass) attr = {} if title is not None: try: title.hass = hass title = title.async_render() except TemplateError as ex: _LOGGER.error('Error rendering title %s: %s', title, ex) title = title.template attr[ATTR_TITLE] = title try: message.hass = hass message = message.async_render() except TemplateError as ex: _LOGGER.error('Error rendering message %s: %s', message, ex) message = message.template hass.states.async_set(entity_id, message, attr) @callback def dismiss_service(call): """Handle the dismiss notification service call.""" notification_id = call.data.get(ATTR_NOTIFICATION_ID) entity_id = ENTITY_ID_FORMAT.format(slugify(notification_id)) hass.states.async_remove(entity_id) descriptions = yield from hass.async_add_job( load_yaml_config_file, os.path.join( os.path.dirname(__file__), 'services.yaml') ) hass.services.async_register(DOMAIN, SERVICE_CREATE, create_service, descriptions[DOMAIN][SERVICE_CREATE], SCHEMA_SERVICE_CREATE) hass.services.async_register(DOMAIN, SERVICE_DISMISS, dismiss_service, descriptions[DOMAIN][SERVICE_DISMISS], SCHEMA_SERVICE_DISMISS) return True