diff --git a/homeassistant/components/tag/__init__.py b/homeassistant/components/tag/__init__.py index 01b283bb778..43dc8ce5db7 100644 --- a/homeassistant/components/tag/__init__.py +++ b/homeassistant/components/tag/__init__.py @@ -13,15 +13,13 @@ from homeassistant.helpers.storage import Store from homeassistant.loader import bind_hass import homeassistant.util.dt as dt_util -from .const import DOMAIN +from .const import DEVICE_ID, DOMAIN, EVENT_TAG_SCANNED, TAG_ID _LOGGER = logging.getLogger(__name__) -DEVICE_ID = "device_id" -EVENT_TAG_SCANNED = "tag_scanned" + LAST_SCANNED = "last_scanned" STORAGE_KEY = DOMAIN STORAGE_VERSION = 1 -TAG_ID = "tag_id" TAGS = "tags" CREATE_FIELDS = { diff --git a/homeassistant/components/tag/const.py b/homeassistant/components/tag/const.py index 60f6e05c27e..ed74a1f0549 100644 --- a/homeassistant/components/tag/const.py +++ b/homeassistant/components/tag/const.py @@ -1,3 +1,6 @@ """Constants for the Tag integration.""" +DEVICE_ID = "device_id" DOMAIN = "tag" +EVENT_TAG_SCANNED = "tag_scanned" +TAG_ID = "tag_id" diff --git a/homeassistant/components/tag/trigger.py b/homeassistant/components/tag/trigger.py new file mode 100644 index 00000000000..8da9baa5aaa --- /dev/null +++ b/homeassistant/components/tag/trigger.py @@ -0,0 +1,37 @@ +"""Support for tag triggers.""" +import voluptuous as vol + +from homeassistant.components.homeassistant.triggers import event as event_trigger +from homeassistant.const import CONF_PLATFORM +from homeassistant.helpers import config_validation as cv + +from .const import DEVICE_ID, DOMAIN, EVENT_TAG_SCANNED, TAG_ID + +TRIGGER_SCHEMA = vol.Schema( + { + vol.Required(CONF_PLATFORM): DOMAIN, + vol.Required(TAG_ID): cv.string, + vol.Optional(DEVICE_ID): cv.string, + } +) + + +async def async_attach_trigger(hass, config, action, automation_info): + """Listen for tag_scanned events based on configuration.""" + tag_id = config.get(TAG_ID) + device_id = config.get(DEVICE_ID) + event_data = {TAG_ID: tag_id} + + if device_id: + event_data[DEVICE_ID] = device_id + + event_config = { + event_trigger.CONF_PLATFORM: "event", + event_trigger.CONF_EVENT_TYPE: EVENT_TAG_SCANNED, + event_trigger.CONF_EVENT_DATA: event_data, + } + event_config = event_trigger.TRIGGER_SCHEMA(event_config) + + return await event_trigger.async_attach_trigger( + hass, event_config, action, automation_info, platform_type=DOMAIN + ) diff --git a/tests/components/tag/test_trigger.py b/tests/components/tag/test_trigger.py new file mode 100644 index 00000000000..0249acaf29b --- /dev/null +++ b/tests/components/tag/test_trigger.py @@ -0,0 +1,85 @@ +"""Tests for tag triggers.""" + +import pytest + +import homeassistant.components.automation as automation +from homeassistant.components.tag import async_scan_tag +from homeassistant.components.tag.const import DOMAIN, TAG_ID +from homeassistant.setup import async_setup_component + +from tests.common import async_mock_service + + +@pytest.fixture +def tag_setup(hass, hass_storage): + """Tag setup.""" + + async def _storage(items=None): + if items is None: + hass_storage[DOMAIN] = { + "key": DOMAIN, + "version": 1, + "data": {"items": [{"id": "test tag"}]}, + } + else: + hass_storage[DOMAIN] = items + config = {DOMAIN: {}} + return await async_setup_component(hass, DOMAIN, config) + + return _storage + + +@pytest.fixture +def calls(hass): + """Track calls to a mock service.""" + return async_mock_service(hass, "test", "automation") + + +async def test_triggers(hass, tag_setup, calls): + """Test tag triggers.""" + assert await tag_setup() + assert await async_setup_component( + hass, + automation.DOMAIN, + { + automation.DOMAIN: [ + { + "trigger": {"platform": DOMAIN, TAG_ID: "abc123"}, + "action": { + "service": "test.automation", + "data": {"message": "service called"}, + }, + } + ] + }, + ) + + await hass.async_block_till_done() + + await async_scan_tag(hass, "abc123", None) + await hass.async_block_till_done() + + assert len(calls) == 1 + assert calls[0].data["message"] == "service called" + + +async def test_exception_bad_trigger(hass, calls, caplog): + """Test for exception on event triggers firing.""" + + await async_setup_component( + hass, + automation.DOMAIN, + { + automation.DOMAIN: [ + { + "trigger": {"trigger": {"platform": DOMAIN, "oops": "abc123"}}, + "action": { + "service": "test.automation", + "data": {"message": "service called"}, + }, + } + ] + }, + ) + await hass.async_block_till_done() + assert "Invalid config for [automation]" in caplog.text