Move alert constants into const module (#80170)

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
pull/80185/head
Franck Nijhof 2022-10-12 17:17:48 +02:00 committed by GitHub
parent 690556a5f1
commit ad6c3d1cde
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 80 additions and 57 deletions

View File

@ -3,7 +3,6 @@ from __future__ import annotations
from collections.abc import Callable from collections.abc import Callable
from datetime import timedelta from datetime import timedelta
import logging
from typing import Any, final from typing import Any, final
import voluptuous as vol import voluptuous as vol
@ -39,20 +38,19 @@ from homeassistant.helpers.template import Template
from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.typing import ConfigType
from homeassistant.util.dt import now from homeassistant.util.dt import now
_LOGGER = logging.getLogger(__name__) from .const import (
CONF_ALERT_MESSAGE,
DOMAIN = "alert" CONF_CAN_ACK,
CONF_DATA,
CONF_CAN_ACK = "can_acknowledge" CONF_DONE_MESSAGE,
CONF_NOTIFIERS = "notifiers" CONF_NOTIFIERS,
CONF_SKIP_FIRST = "skip_first" CONF_SKIP_FIRST,
CONF_ALERT_MESSAGE = "message" CONF_TITLE,
CONF_DONE_MESSAGE = "done_message" DEFAULT_CAN_ACK,
CONF_TITLE = "title" DEFAULT_SKIP_FIRST,
CONF_DATA = "data" DOMAIN,
LOGGER,
DEFAULT_CAN_ACK = True )
DEFAULT_SKIP_FIRST = False
ALERT_SCHEMA = vol.Schema( ALERT_SCHEMA = vol.Schema(
{ {
@ -242,7 +240,7 @@ class Alert(ToggleEntity):
"""Determine if the alert should start or stop.""" """Determine if the alert should start or stop."""
if (to_state := event.data.get("new_state")) is None: if (to_state := event.data.get("new_state")) is None:
return return
_LOGGER.debug("Watched entity (%s) has changed", event.data.get("entity_id")) LOGGER.debug("Watched entity (%s) has changed", event.data.get("entity_id"))
if to_state.state == self._alert_state and not self._firing: if to_state.state == self._alert_state and not self._firing:
await self.begin_alerting() await self.begin_alerting()
if to_state.state != self._alert_state and self._firing: if to_state.state != self._alert_state and self._firing:
@ -250,7 +248,7 @@ class Alert(ToggleEntity):
async def begin_alerting(self) -> None: async def begin_alerting(self) -> None:
"""Begin the alert procedures.""" """Begin the alert procedures."""
_LOGGER.debug("Beginning Alert: %s", self._attr_name) LOGGER.debug("Beginning Alert: %s", self._attr_name)
self._ack = False self._ack = False
self._firing = True self._firing = True
self._next_delay = 0 self._next_delay = 0
@ -264,7 +262,7 @@ class Alert(ToggleEntity):
async def end_alerting(self) -> None: async def end_alerting(self) -> None:
"""End the alert procedures.""" """End the alert procedures."""
_LOGGER.debug("Ending Alert: %s", self._attr_name) LOGGER.debug("Ending Alert: %s", self._attr_name)
if self._cancel is not None: if self._cancel is not None:
self._cancel() self._cancel()
self._cancel = None self._cancel = None
@ -288,7 +286,7 @@ class Alert(ToggleEntity):
return return
if not self._ack: if not self._ack:
_LOGGER.info("Alerting: %s", self._attr_name) LOGGER.info("Alerting: %s", self._attr_name)
self._send_done_message = True self._send_done_message = True
if self._message_template is not None: if self._message_template is not None:
@ -301,7 +299,7 @@ class Alert(ToggleEntity):
async def _notify_done_message(self) -> None: async def _notify_done_message(self) -> None:
"""Send notification of complete alert.""" """Send notification of complete alert."""
_LOGGER.info("Alerting: %s", self._done_message_template) LOGGER.info("Alerting: %s", self._done_message_template)
self._send_done_message = False self._send_done_message = False
if self._done_message_template is None: if self._done_message_template is None:
@ -321,7 +319,7 @@ class Alert(ToggleEntity):
if self._data: if self._data:
msg_payload[ATTR_DATA] = self._data msg_payload[ATTR_DATA] = self._data
_LOGGER.debug(msg_payload) LOGGER.debug(msg_payload)
for target in self._notifiers: for target in self._notifiers:
await self.hass.services.async_call( await self.hass.services.async_call(
@ -330,13 +328,13 @@ class Alert(ToggleEntity):
async def async_turn_on(self, **kwargs: Any) -> None: async def async_turn_on(self, **kwargs: Any) -> None:
"""Async Unacknowledge alert.""" """Async Unacknowledge alert."""
_LOGGER.debug("Reset Alert: %s", self._attr_name) LOGGER.debug("Reset Alert: %s", self._attr_name)
self._ack = False self._ack = False
self.async_write_ha_state() self.async_write_ha_state()
async def async_turn_off(self, **kwargs: Any) -> None: async def async_turn_off(self, **kwargs: Any) -> None:
"""Async Acknowledge alert.""" """Async Acknowledge alert."""
_LOGGER.debug("Acknowledged Alert: %s", self._attr_name) LOGGER.debug("Acknowledged Alert: %s", self._attr_name)
self._ack = True self._ack = True
self.async_write_ha_state() self.async_write_ha_state()

View File

@ -0,0 +1,19 @@
"""Constants for the Alert integration."""
import logging
from typing import Final
DOMAIN: Final = "alert"
LOGGER = logging.getLogger(__package__)
CONF_CAN_ACK = "can_acknowledge"
CONF_NOTIFIERS = "notifiers"
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

View File

@ -3,7 +3,6 @@ from __future__ import annotations
import asyncio import asyncio
from collections.abc import Iterable from collections.abc import Iterable
import logging
from typing import Any from typing import Any
from homeassistant.const import ( from homeassistant.const import (
@ -15,9 +14,7 @@ from homeassistant.const import (
) )
from homeassistant.core import Context, HomeAssistant, State from homeassistant.core import Context, HomeAssistant, State
from . import DOMAIN from .const import DOMAIN, LOGGER
_LOGGER = logging.getLogger(__name__)
VALID_STATES = {STATE_ON, STATE_OFF} VALID_STATES = {STATE_ON, STATE_OFF}
@ -31,11 +28,11 @@ async def _async_reproduce_state(
) -> None: ) -> None:
"""Reproduce a single state.""" """Reproduce a single state."""
if (cur_state := hass.states.get(state.entity_id)) is None: if (cur_state := hass.states.get(state.entity_id)) is None:
_LOGGER.warning("Unable to find entity %s", state.entity_id) LOGGER.warning("Unable to find entity %s", state.entity_id)
return return
if state.state not in VALID_STATES: if state.state not in VALID_STATES:
_LOGGER.warning( LOGGER.warning(
"Invalid state specified for %s: %s", state.entity_id, state.state "Invalid state specified for %s: %s", state.entity_id, state.state
) )
return return

View File

@ -5,12 +5,21 @@ from copy import deepcopy
import pytest import pytest
import homeassistant.components.alert as alert import homeassistant.components.alert as alert
from homeassistant.components.alert import DOMAIN from homeassistant.components.alert.const import (
CONF_ALERT_MESSAGE,
CONF_DATA,
CONF_DONE_MESSAGE,
CONF_NOTIFIERS,
CONF_SKIP_FIRST,
CONF_TITLE,
DOMAIN,
)
import homeassistant.components.notify as notify import homeassistant.components.notify as notify
from homeassistant.const import ( from homeassistant.const import (
ATTR_ENTITY_ID, ATTR_ENTITY_ID,
CONF_ENTITY_ID, CONF_ENTITY_ID,
CONF_NAME, CONF_NAME,
CONF_REPEAT,
CONF_STATE, CONF_STATE,
SERVICE_TOGGLE, SERVICE_TOGGLE,
SERVICE_TURN_OFF, SERVICE_TURN_OFF,
@ -31,17 +40,17 @@ TITLE = "{{ states.sensor.test.entity_id }}"
TEST_TITLE = "sensor.test" TEST_TITLE = "sensor.test"
TEST_DATA = {"data": {"inline_keyboard": ["Close garage:/close_garage"]}} TEST_DATA = {"data": {"inline_keyboard": ["Close garage:/close_garage"]}}
TEST_CONFIG = { TEST_CONFIG = {
alert.DOMAIN: { DOMAIN: {
NAME: { NAME: {
CONF_NAME: NAME, CONF_NAME: NAME,
alert.CONF_DONE_MESSAGE: DONE_MESSAGE, CONF_DONE_MESSAGE: DONE_MESSAGE,
CONF_ENTITY_ID: TEST_ENTITY, CONF_ENTITY_ID: TEST_ENTITY,
CONF_STATE: STATE_ON, CONF_STATE: STATE_ON,
alert.CONF_REPEAT: 30, CONF_REPEAT: 30,
alert.CONF_SKIP_FIRST: False, CONF_SKIP_FIRST: False,
alert.CONF_NOTIFIERS: [NOTIFIER], CONF_NOTIFIERS: [NOTIFIER],
alert.CONF_TITLE: TITLE, CONF_TITLE: TITLE,
alert.CONF_DATA: {}, CONF_DATA: {},
} }
} }
} }
@ -59,7 +68,7 @@ TEST_NOACK = [
None, None,
None, None,
] ]
ENTITY_ID = f"{alert.DOMAIN}.{NAME}" ENTITY_ID = f"{DOMAIN}.{NAME}"
@callback @callback
@ -119,13 +128,13 @@ async def test_is_on(hass):
async def test_setup(hass): async def test_setup(hass):
"""Test setup method.""" """Test setup method."""
assert await async_setup_component(hass, alert.DOMAIN, TEST_CONFIG) assert await async_setup_component(hass, DOMAIN, TEST_CONFIG)
assert hass.states.get(ENTITY_ID).state == STATE_IDLE assert hass.states.get(ENTITY_ID).state == STATE_IDLE
async def test_fire(hass, mock_notifier): async def test_fire(hass, mock_notifier):
"""Test the alert firing.""" """Test the alert firing."""
assert await async_setup_component(hass, alert.DOMAIN, TEST_CONFIG) assert await async_setup_component(hass, DOMAIN, TEST_CONFIG)
hass.states.async_set("sensor.test", STATE_ON) hass.states.async_set("sensor.test", STATE_ON)
await hass.async_block_till_done() await hass.async_block_till_done()
assert hass.states.get(ENTITY_ID).state == STATE_ON assert hass.states.get(ENTITY_ID).state == STATE_ON
@ -133,7 +142,7 @@ async def test_fire(hass, mock_notifier):
async def test_silence(hass, mock_notifier): async def test_silence(hass, mock_notifier):
"""Test silencing the alert.""" """Test silencing the alert."""
assert await async_setup_component(hass, alert.DOMAIN, TEST_CONFIG) assert await async_setup_component(hass, DOMAIN, TEST_CONFIG)
hass.states.async_set("sensor.test", STATE_ON) hass.states.async_set("sensor.test", STATE_ON)
await hass.async_block_till_done() await hass.async_block_till_done()
async_turn_off(hass, ENTITY_ID) async_turn_off(hass, ENTITY_ID)
@ -151,7 +160,7 @@ async def test_silence(hass, mock_notifier):
async def test_reset(hass, mock_notifier): async def test_reset(hass, mock_notifier):
"""Test resetting the alert.""" """Test resetting the alert."""
assert await async_setup_component(hass, alert.DOMAIN, TEST_CONFIG) assert await async_setup_component(hass, DOMAIN, TEST_CONFIG)
hass.states.async_set("sensor.test", STATE_ON) hass.states.async_set("sensor.test", STATE_ON)
await hass.async_block_till_done() await hass.async_block_till_done()
async_turn_off(hass, ENTITY_ID) async_turn_off(hass, ENTITY_ID)
@ -164,7 +173,7 @@ async def test_reset(hass, mock_notifier):
async def test_toggle(hass, mock_notifier): async def test_toggle(hass, mock_notifier):
"""Test toggling alert.""" """Test toggling alert."""
assert await async_setup_component(hass, alert.DOMAIN, TEST_CONFIG) assert await async_setup_component(hass, DOMAIN, TEST_CONFIG)
hass.states.async_set("sensor.test", STATE_ON) hass.states.async_set("sensor.test", STATE_ON)
await hass.async_block_till_done() await hass.async_block_till_done()
assert hass.states.get(ENTITY_ID).state == STATE_ON assert hass.states.get(ENTITY_ID).state == STATE_ON
@ -180,7 +189,7 @@ async def test_notification_no_done_message(hass):
"""Test notifications.""" """Test notifications."""
events = [] events = []
config = deepcopy(TEST_CONFIG) config = deepcopy(TEST_CONFIG)
del config[alert.DOMAIN][NAME][alert.CONF_DONE_MESSAGE] del config[DOMAIN][NAME][CONF_DONE_MESSAGE]
@callback @callback
def record_event(event): def record_event(event):
@ -189,7 +198,7 @@ async def test_notification_no_done_message(hass):
hass.services.async_register(notify.DOMAIN, NOTIFIER, record_event) hass.services.async_register(notify.DOMAIN, NOTIFIER, record_event)
assert await async_setup_component(hass, alert.DOMAIN, config) assert await async_setup_component(hass, DOMAIN, config)
assert len(events) == 0 assert len(events) == 0
hass.states.async_set("sensor.test", STATE_ON) hass.states.async_set("sensor.test", STATE_ON)
@ -212,7 +221,7 @@ async def test_notification(hass):
hass.services.async_register(notify.DOMAIN, NOTIFIER, record_event) hass.services.async_register(notify.DOMAIN, NOTIFIER, record_event)
assert await async_setup_component(hass, alert.DOMAIN, TEST_CONFIG) assert await async_setup_component(hass, DOMAIN, TEST_CONFIG)
assert len(events) == 0 assert len(events) == 0
hass.states.async_set("sensor.test", STATE_ON) hass.states.async_set("sensor.test", STATE_ON)
@ -226,7 +235,7 @@ async def test_notification(hass):
async def test_sending_non_templated_notification(hass, mock_notifier): async def test_sending_non_templated_notification(hass, mock_notifier):
"""Test notifications.""" """Test notifications."""
assert await async_setup_component(hass, alert.DOMAIN, TEST_CONFIG) assert await async_setup_component(hass, DOMAIN, TEST_CONFIG)
hass.states.async_set(TEST_ENTITY, STATE_ON) hass.states.async_set(TEST_ENTITY, STATE_ON)
await hass.async_block_till_done() await hass.async_block_till_done()
@ -238,8 +247,8 @@ async def test_sending_non_templated_notification(hass, mock_notifier):
async def test_sending_templated_notification(hass, mock_notifier): async def test_sending_templated_notification(hass, mock_notifier):
"""Test templated notification.""" """Test templated notification."""
config = deepcopy(TEST_CONFIG) config = deepcopy(TEST_CONFIG)
config[alert.DOMAIN][NAME][alert.CONF_ALERT_MESSAGE] = TEMPLATE config[DOMAIN][NAME][CONF_ALERT_MESSAGE] = TEMPLATE
assert await async_setup_component(hass, alert.DOMAIN, config) assert await async_setup_component(hass, DOMAIN, config)
hass.states.async_set(TEST_ENTITY, STATE_ON) hass.states.async_set(TEST_ENTITY, STATE_ON)
await hass.async_block_till_done() await hass.async_block_till_done()
@ -251,8 +260,8 @@ async def test_sending_templated_notification(hass, mock_notifier):
async def test_sending_templated_done_notification(hass, mock_notifier): async def test_sending_templated_done_notification(hass, mock_notifier):
"""Test templated notification.""" """Test templated notification."""
config = deepcopy(TEST_CONFIG) config = deepcopy(TEST_CONFIG)
config[alert.DOMAIN][NAME][alert.CONF_DONE_MESSAGE] = TEMPLATE config[DOMAIN][NAME][CONF_DONE_MESSAGE] = TEMPLATE
assert await async_setup_component(hass, alert.DOMAIN, config) assert await async_setup_component(hass, DOMAIN, config)
hass.states.async_set(TEST_ENTITY, STATE_ON) hass.states.async_set(TEST_ENTITY, STATE_ON)
await hass.async_block_till_done() await hass.async_block_till_done()
@ -266,8 +275,8 @@ async def test_sending_templated_done_notification(hass, mock_notifier):
async def test_sending_titled_notification(hass, mock_notifier): async def test_sending_titled_notification(hass, mock_notifier):
"""Test notifications.""" """Test notifications."""
config = deepcopy(TEST_CONFIG) config = deepcopy(TEST_CONFIG)
config[alert.DOMAIN][NAME][alert.CONF_TITLE] = TITLE config[DOMAIN][NAME][CONF_TITLE] = TITLE
assert await async_setup_component(hass, alert.DOMAIN, config) assert await async_setup_component(hass, DOMAIN, config)
hass.states.async_set(TEST_ENTITY, STATE_ON) hass.states.async_set(TEST_ENTITY, STATE_ON)
await hass.async_block_till_done() await hass.async_block_till_done()
@ -279,8 +288,8 @@ async def test_sending_titled_notification(hass, mock_notifier):
async def test_sending_data_notification(hass, mock_notifier): async def test_sending_data_notification(hass, mock_notifier):
"""Test notifications.""" """Test notifications."""
config = deepcopy(TEST_CONFIG) config = deepcopy(TEST_CONFIG)
config[alert.DOMAIN][NAME][alert.CONF_DATA] = TEST_DATA config[DOMAIN][NAME][CONF_DATA] = TEST_DATA
assert await async_setup_component(hass, alert.DOMAIN, config) assert await async_setup_component(hass, DOMAIN, config)
hass.states.async_set(TEST_ENTITY, STATE_ON) hass.states.async_set(TEST_ENTITY, STATE_ON)
await hass.async_block_till_done() await hass.async_block_till_done()
@ -292,7 +301,7 @@ async def test_sending_data_notification(hass, mock_notifier):
async def test_skipfirst(hass): async def test_skipfirst(hass):
"""Test skipping first notification.""" """Test skipping first notification."""
config = deepcopy(TEST_CONFIG) config = deepcopy(TEST_CONFIG)
config[alert.DOMAIN][NAME][alert.CONF_SKIP_FIRST] = True config[DOMAIN][NAME][CONF_SKIP_FIRST] = True
events = [] events = []
@callback @callback
@ -302,7 +311,7 @@ async def test_skipfirst(hass):
hass.services.async_register(notify.DOMAIN, NOTIFIER, record_event) hass.services.async_register(notify.DOMAIN, NOTIFIER, record_event)
assert await async_setup_component(hass, alert.DOMAIN, config) assert await async_setup_component(hass, DOMAIN, config)
assert len(events) == 0 assert len(events) == 0
hass.states.async_set("sensor.test", STATE_ON) hass.states.async_set("sensor.test", STATE_ON)