Extend persistent notification support (#2371)

This commit is contained in:
Paulus Schoutsen 2016-06-25 16:40:33 -07:00 committed by GitHub
parent 21381a95d4
commit 206e7d7a67
4 changed files with 140 additions and 6 deletions

View File

@ -11,7 +11,7 @@ from threading import RLock
import voluptuous as vol import voluptuous as vol
import homeassistant.components as core_components import homeassistant.components as core_components
import homeassistant.components.group as group from homeassistant.components import group, persistent_notification
import homeassistant.config as config_util import homeassistant.config as config_util
import homeassistant.core as core import homeassistant.core as core
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
@ -262,9 +262,10 @@ def from_config_dict(config, hass=None, config_dir=None, enable_log=True,
if not core_components.setup(hass, config): if not core_components.setup(hass, config):
_LOGGER.error('Home Assistant core failed to initialize. ' _LOGGER.error('Home Assistant core failed to initialize. '
'Further initialization aborted.') 'Further initialization aborted.')
return hass return hass
persistent_notification.setup(hass, config)
_LOGGER.info('Home Assistant core initialized') _LOGGER.info('Home Assistant core initialized')
# Give event decorators access to HASS # Give event decorators access to HASS

View File

@ -37,6 +37,7 @@ def setup(hass, config):
"""Setup a demo environment.""" """Setup a demo environment."""
group = loader.get_component('group') group = loader.get_component('group')
configurator = loader.get_component('configurator') configurator = loader.get_component('configurator')
persistent_notification = loader.get_component('persistent_notification')
config.setdefault(ha.DOMAIN, {}) config.setdefault(ha.DOMAIN, {})
config.setdefault(DOMAIN, {}) config.setdefault(DOMAIN, {})
@ -59,6 +60,11 @@ def setup(hass, config):
demo_config[component] = {CONF_PLATFORM: 'demo'} demo_config[component] = {CONF_PLATFORM: 'demo'}
bootstrap.setup_component(hass, component, demo_config) bootstrap.setup_component(hass, component, demo_config)
# Setup example persistent notification
persistent_notification.create(
hass, 'This is an example of a persistent notification.',
title='Example Notification')
# Setup room groups # Setup room groups
lights = sorted(hass.states.entity_ids('light')) lights = sorted(hass.states.entity_ids('light'))
switches = sorted(hass.states.entity_ids('switch')) switches = sorted(hass.states.entity_ids('switch'))

View File

@ -4,15 +4,77 @@ A component which is collecting configuration errors.
For more details about this component, please refer to the documentation at For more details about this component, please refer to the documentation at
https://home-assistant.io/components/persistent_notification/ https://home-assistant.io/components/persistent_notification/
""" """
import logging
DOMAIN = "persistent_notification" import voluptuous as vol
from homeassistant.exceptions import TemplateError
from homeassistant.helpers import template, config_validation as cv
from homeassistant.helpers.entity import generate_entity_id
from homeassistant.util import slugify
DOMAIN = 'persistent_notification'
ENTITY_ID_FORMAT = DOMAIN + '.{}'
SERVICE_CREATE = 'create'
ATTR_TITLE = 'title'
ATTR_MESSAGE = 'message'
ATTR_NOTIFICATION_ID = 'notification_id'
SCHEMA_SERVICE_CREATE = vol.Schema({
vol.Required(ATTR_MESSAGE): cv.template,
vol.Optional(ATTR_TITLE): cv.template,
vol.Optional(ATTR_NOTIFICATION_ID): cv.string,
})
def create(hass, entity, msg): DEFAULT_OBJECT_ID = 'notification'
"""Create a state for an error.""" _LOGGER = logging.getLogger(__name__)
hass.states.set('{}.{}'.format(DOMAIN, entity), msg)
def create(hass, message, title=None, notification_id=None):
"""Turn all or specified light off."""
data = {
key: value for key, value in [
(ATTR_TITLE, title),
(ATTR_MESSAGE, message),
(ATTR_NOTIFICATION_ID, notification_id),
] if value is not None
}
hass.services.call(DOMAIN, SERVICE_CREATE, data)
def setup(hass, config): def setup(hass, config):
"""Setup the persistent notification component.""" """Setup the persistent notification component."""
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 = generate_entity_id(ENTITY_ID_FORMAT, DEFAULT_OBJECT_ID,
hass=hass)
attr = {}
if title is not None:
try:
title = template.render(hass, title)
except TemplateError as ex:
_LOGGER.error('Error rendering title %s: %s', title, ex)
attr[ATTR_TITLE] = title
try:
message = template.render(hass, message)
except TemplateError as ex:
_LOGGER.error('Error rendering message %s: %s', message, ex)
hass.states.set(entity_id, message, attr)
hass.services.register(DOMAIN, SERVICE_CREATE, create_service, {},
SCHEMA_SERVICE_CREATE)
return True return True

View File

@ -0,0 +1,65 @@
"""The tests for the persistent notification component."""
import homeassistant.components.persistent_notification as pn
from tests.common import get_test_home_assistant
class TestPersistentNotification:
"""Test persistent notification component."""
def setup_method(self, method):
"""Setup things to be run when tests are started."""
self.hass = get_test_home_assistant()
pn.setup(self.hass, {})
def teardown_method(self, method):
"""Stop everything that was started."""
self.hass.stop()
def test_create(self):
"""Test creating notification without title or notification id."""
assert len(self.hass.states.entity_ids(pn.DOMAIN)) == 0
pn.create(self.hass, 'Hello World {{ 1 + 1 }}',
title='{{ 1 + 1 }} beers')
self.hass.pool.block_till_done()
entity_ids = self.hass.states.entity_ids(pn.DOMAIN)
assert len(entity_ids) == 1
state = self.hass.states.get(entity_ids[0])
assert state.state == 'Hello World 2'
assert state.attributes.get('title') == '2 beers'
def test_create_notification_id(self):
"""Ensure overwrites existing notification with same id."""
assert len(self.hass.states.entity_ids(pn.DOMAIN)) == 0
pn.create(self.hass, 'test', notification_id='Beer 2')
self.hass.pool.block_till_done()
assert len(self.hass.states.entity_ids()) == 1
state = self.hass.states.get('persistent_notification.beer_2')
assert state.state == 'test'
pn.create(self.hass, 'test 2', notification_id='Beer 2')
self.hass.pool.block_till_done()
# We should have overwritten old one
assert len(self.hass.states.entity_ids()) == 1
state = self.hass.states.get('persistent_notification.beer_2')
assert state.state == 'test 2'
def test_create_template_error(self):
"""Ensure we output templates if contain error."""
assert len(self.hass.states.entity_ids(pn.DOMAIN)) == 0
pn.create(self.hass, '{{ message + 1 }}', '{{ title + 1 }}')
self.hass.pool.block_till_done()
entity_ids = self.hass.states.entity_ids(pn.DOMAIN)
assert len(entity_ids) == 1
state = self.hass.states.get(entity_ids[0])
assert state.state == '{{ message + 1 }}'
assert state.attributes.get('title') == '{{ title + 1 }}'