mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 04:37:06 +00:00
Add data/data_template/title to alert component (#17616)
* Add data/data_template/title to alert component * Fix line length * Fix tests * Fix lint * fix line length * Fix tests, make title templatable * Fix test * Fix test * Optimize data, make title templated * Fix line length * Add title template * typo * Fix tests
This commit is contained in:
parent
3484e506e8
commit
db277ad023
@ -5,19 +5,19 @@ For more details about this component, please refer to the documentation at
|
||||
https://home-assistant.io/components/alert/
|
||||
"""
|
||||
import asyncio
|
||||
from datetime import datetime, timedelta
|
||||
import logging
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.components.notify import (
|
||||
ATTR_MESSAGE, DOMAIN as DOMAIN_NOTIFY)
|
||||
ATTR_MESSAGE, ATTR_TITLE, ATTR_DATA, DOMAIN as DOMAIN_NOTIFY)
|
||||
from homeassistant.const import (
|
||||
CONF_ENTITY_ID, STATE_IDLE, CONF_NAME, CONF_STATE, STATE_ON, STATE_OFF,
|
||||
SERVICE_TURN_ON, SERVICE_TURN_OFF, SERVICE_TOGGLE, ATTR_ENTITY_ID)
|
||||
from homeassistant.helpers.entity import ToggleEntity
|
||||
from homeassistant.helpers import service, event
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.entity import ToggleEntity
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@ -30,6 +30,8 @@ CONF_REPEAT = 'repeat'
|
||||
CONF_SKIP_FIRST = 'skip_first'
|
||||
CONF_ALERT_MESSAGE = 'message'
|
||||
CONF_DONE_MESSAGE = 'done_message'
|
||||
CONF_TITLE = 'title'
|
||||
CONF_DATA = 'data'
|
||||
|
||||
DEFAULT_CAN_ACK = True
|
||||
DEFAULT_SKIP_FIRST = False
|
||||
@ -43,13 +45,14 @@ ALERT_SCHEMA = vol.Schema({
|
||||
vol.Required(CONF_SKIP_FIRST, default=DEFAULT_SKIP_FIRST): cv.boolean,
|
||||
vol.Optional(CONF_ALERT_MESSAGE): cv.template,
|
||||
vol.Optional(CONF_DONE_MESSAGE): cv.template,
|
||||
vol.Optional(CONF_TITLE): cv.template,
|
||||
vol.Optional(CONF_DATA): dict,
|
||||
vol.Required(CONF_NOTIFIERS): cv.ensure_list})
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema({
|
||||
DOMAIN: cv.schema_with_slug_keys(ALERT_SCHEMA),
|
||||
}, extra=vol.ALLOW_EXTRA)
|
||||
|
||||
|
||||
ALERT_SERVICE_SCHEMA = vol.Schema({
|
||||
vol.Required(ATTR_ENTITY_ID): cv.entity_ids,
|
||||
})
|
||||
@ -77,12 +80,14 @@ async def async_setup(hass, config):
|
||||
done_message_template = cfg.get(CONF_DONE_MESSAGE)
|
||||
notifiers = cfg.get(CONF_NOTIFIERS)
|
||||
can_ack = cfg.get(CONF_CAN_ACK)
|
||||
title_template = cfg.get(CONF_TITLE)
|
||||
data = cfg.get(CONF_DATA)
|
||||
|
||||
entities.append(Alert(hass, object_id, name,
|
||||
watched_entity_id, alert_state, repeat,
|
||||
skip_first, message_template,
|
||||
done_message_template, notifiers,
|
||||
can_ack))
|
||||
can_ack, title_template, data))
|
||||
|
||||
if not entities:
|
||||
return False
|
||||
@ -127,12 +132,14 @@ class Alert(ToggleEntity):
|
||||
|
||||
def __init__(self, hass, entity_id, name, watched_entity_id,
|
||||
state, repeat, skip_first, message_template,
|
||||
done_message_template, notifiers, can_ack):
|
||||
done_message_template, notifiers, can_ack, title_template,
|
||||
data):
|
||||
"""Initialize the alert."""
|
||||
self.hass = hass
|
||||
self._name = name
|
||||
self._alert_state = state
|
||||
self._skip_first = skip_first
|
||||
self._data = data
|
||||
|
||||
self._message_template = message_template
|
||||
if self._message_template is not None:
|
||||
@ -142,6 +149,10 @@ class Alert(ToggleEntity):
|
||||
if self._done_message_template is not None:
|
||||
self._done_message_template.hass = hass
|
||||
|
||||
self._title_template = title_template
|
||||
if self._title_template is not None:
|
||||
self._title_template.hass = hass
|
||||
|
||||
self._notifiers = notifiers
|
||||
self._can_ack = can_ack
|
||||
|
||||
@ -251,9 +262,20 @@ class Alert(ToggleEntity):
|
||||
await self._send_notification_message(message)
|
||||
|
||||
async def _send_notification_message(self, message):
|
||||
|
||||
msg_payload = {ATTR_MESSAGE: message}
|
||||
|
||||
if self._title_template is not None:
|
||||
title = self._title_template.async_render()
|
||||
msg_payload.update({ATTR_TITLE: title})
|
||||
if self._data:
|
||||
msg_payload.update({ATTR_DATA: self._data})
|
||||
|
||||
_LOGGER.debug(msg_payload)
|
||||
|
||||
for target in self._notifiers:
|
||||
await self.hass.services.async_call(
|
||||
DOMAIN_NOTIFY, target, {ATTR_MESSAGE: message})
|
||||
DOMAIN_NOTIFY, target, msg_payload)
|
||||
|
||||
async def async_turn_on(self, **kwargs):
|
||||
"""Async Unacknowledge alert."""
|
||||
|
@ -1,17 +1,16 @@
|
||||
"""The tests for the Alert component."""
|
||||
import unittest
|
||||
# pylint: disable=protected-access
|
||||
from copy import deepcopy
|
||||
import unittest
|
||||
|
||||
from homeassistant.setup import setup_component
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.components.alert import DOMAIN
|
||||
import homeassistant.components.alert as alert
|
||||
import homeassistant.components.notify as notify
|
||||
from homeassistant.components.alert import DOMAIN
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID, CONF_ENTITY_ID, STATE_IDLE, CONF_NAME, CONF_STATE,
|
||||
SERVICE_TOGGLE, SERVICE_TURN_OFF, SERVICE_TURN_ON, STATE_ON, STATE_OFF)
|
||||
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.setup import setup_component
|
||||
from tests.common import get_test_home_assistant
|
||||
|
||||
NAME = "alert_test"
|
||||
@ -19,6 +18,13 @@ DONE_MESSAGE = "alert_gone"
|
||||
NOTIFIER = 'test'
|
||||
TEMPLATE = "{{ states.sensor.test.entity_id }}"
|
||||
TEST_ENTITY = "sensor.test"
|
||||
TITLE = "{{ states.sensor.test.entity_id }}"
|
||||
TEST_TITLE = "sensor.test"
|
||||
TEST_DATA = {
|
||||
'data': {
|
||||
'inline_keyboard': ['Close garage:/close_garage']
|
||||
}
|
||||
}
|
||||
TEST_CONFIG = \
|
||||
{alert.DOMAIN: {
|
||||
NAME: {
|
||||
@ -28,10 +34,13 @@ TEST_CONFIG = \
|
||||
CONF_STATE: STATE_ON,
|
||||
alert.CONF_REPEAT: 30,
|
||||
alert.CONF_SKIP_FIRST: False,
|
||||
alert.CONF_NOTIFIERS: [NOTIFIER]}
|
||||
alert.CONF_NOTIFIERS: [NOTIFIER],
|
||||
alert.CONF_TITLE: TITLE,
|
||||
alert.CONF_DATA: {}
|
||||
}
|
||||
}}
|
||||
TEST_NOACK = [NAME, NAME, "sensor.test",
|
||||
STATE_ON, [30], False, None, None, NOTIFIER, False]
|
||||
STATE_ON, [30], False, None, None, NOTIFIER, False, None, None]
|
||||
ENTITY_ID = alert.ENTITY_ID_FORMAT.format(NAME)
|
||||
|
||||
|
||||
@ -200,7 +209,7 @@ class TestAlert(unittest.TestCase):
|
||||
"""Test notifications."""
|
||||
events = []
|
||||
config = deepcopy(TEST_CONFIG)
|
||||
del(config[alert.DOMAIN][NAME][alert.CONF_DONE_MESSAGE])
|
||||
del (config[alert.DOMAIN][NAME][alert.CONF_DONE_MESSAGE])
|
||||
|
||||
@callback
|
||||
def record_event(event):
|
||||
@ -286,6 +295,34 @@ class TestAlert(unittest.TestCase):
|
||||
last_event = events[-1]
|
||||
self.assertEqual(last_event.data[notify.ATTR_MESSAGE], TEST_ENTITY)
|
||||
|
||||
def test_sending_titled_notification(self):
|
||||
"""Test notifications."""
|
||||
events = self._setup_notify()
|
||||
|
||||
config = deepcopy(TEST_CONFIG)
|
||||
config[alert.DOMAIN][NAME][alert.CONF_TITLE] = TITLE
|
||||
assert setup_component(self.hass, alert.DOMAIN, config)
|
||||
|
||||
self.hass.states.set(TEST_ENTITY, STATE_ON)
|
||||
self.hass.block_till_done()
|
||||
self.assertEqual(1, len(events))
|
||||
last_event = events[-1]
|
||||
self.assertEqual(last_event.data[notify.ATTR_TITLE], TEST_TITLE)
|
||||
|
||||
def test_sending_data_notification(self):
|
||||
"""Test notifications."""
|
||||
events = self._setup_notify()
|
||||
|
||||
config = deepcopy(TEST_CONFIG)
|
||||
config[alert.DOMAIN][NAME][alert.CONF_DATA] = TEST_DATA
|
||||
assert setup_component(self.hass, alert.DOMAIN, config)
|
||||
|
||||
self.hass.states.set(TEST_ENTITY, STATE_ON)
|
||||
self.hass.block_till_done()
|
||||
self.assertEqual(1, len(events))
|
||||
last_event = events[-1]
|
||||
self.assertEqual(last_event.data[notify.ATTR_DATA], TEST_DATA)
|
||||
|
||||
def test_skipfirst(self):
|
||||
"""Test skipping first notification."""
|
||||
config = deepcopy(TEST_CONFIG)
|
||||
|
Loading…
x
Reference in New Issue
Block a user