diff --git a/homeassistant/components/alarm_control_panel/device_action.py b/homeassistant/components/alarm_control_panel/device_action.py index c37bddafcd3..2680b033b03 100644 --- a/homeassistant/components/alarm_control_panel/device_action.py +++ b/homeassistant/components/alarm_control_panel/device_action.py @@ -67,7 +67,7 @@ async def async_get_actions( supported_features = get_supported_features(hass, entry.entity_id) - base_action = { + base_action: dict = { CONF_DEVICE_ID: device_id, CONF_DOMAIN: DOMAIN, CONF_ENTITY_ID: entry.entity_id, diff --git a/homeassistant/components/device_automation/__init__.py b/homeassistant/components/device_automation/__init__.py index 46a3bf6815d..563b13824b3 100644 --- a/homeassistant/components/device_automation/__init__.py +++ b/homeassistant/components/device_automation/__init__.py @@ -13,8 +13,13 @@ import voluptuous as vol import voluptuous_serialize from homeassistant.components import websocket_api -from homeassistant.const import CONF_DEVICE_ID, CONF_DOMAIN, CONF_PLATFORM -from homeassistant.core import HomeAssistant +from homeassistant.const import ( + ATTR_ENTITY_ID, + CONF_DEVICE_ID, + CONF_DOMAIN, + CONF_PLATFORM, +) +from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import ( config_validation as cv, device_registry as dr, @@ -166,6 +171,24 @@ async def async_get_device_automation_platform( return platform +@callback +def _async_set_entity_device_automation_metadata( + hass: HomeAssistant, automation: dict[str, Any] +) -> None: + """Set device automation metadata based on entity registry entry data.""" + if "metadata" not in automation: + automation["metadata"] = {} + if ATTR_ENTITY_ID not in automation or "secondary" in automation["metadata"]: + return + + entity_registry = er.async_get(hass) + # Guard against the entry being removed before this is called + if not (entry := entity_registry.async_get(automation[ATTR_ENTITY_ID])): + return + + automation["metadata"]["secondary"] = bool(entry.entity_category or entry.hidden_by) + + async def _async_get_device_automations_from_domain( hass, domain, automation_type, device_ids, return_exceptions ): @@ -242,6 +265,8 @@ async def async_get_device_automations( ) continue for automation in device_results: + if automation_type == DeviceAutomationType.ACTION: + _async_set_entity_device_automation_metadata(hass, automation) combined_results[automation["device_id"]].append(automation) return combined_results diff --git a/homeassistant/helpers/config_validation.py b/homeassistant/helpers/config_validation.py index df0afb1e443..342c9867527 100644 --- a/homeassistant/helpers/config_validation.py +++ b/homeassistant/helpers/config_validation.py @@ -1465,6 +1465,7 @@ DEVICE_ACTION_BASE_SCHEMA = vol.Schema( **SCRIPT_ACTION_BASE_SCHEMA, vol.Required(CONF_DEVICE_ID): string, vol.Required(CONF_DOMAIN): str, + vol.Remove("metadata"): dict, } ) diff --git a/script/scaffold/templates/device_action/tests/test_device_action.py b/script/scaffold/templates/device_action/tests/test_device_action.py index f300ae55cf7..d4116cdae84 100644 --- a/script/scaffold/templates/device_action/tests/test_device_action.py +++ b/script/scaffold/templates/device_action/tests/test_device_action.py @@ -6,6 +6,7 @@ from homeassistant.components.NEW_DOMAIN import DOMAIN from homeassistant.components.device_automation import DeviceAutomationType from homeassistant.core import HomeAssistant from homeassistant.helpers import device_registry, entity_registry +from homeassistant.helpers.entity import EntityCategory from homeassistant.setup import async_setup_component from tests.common import ( @@ -46,16 +47,58 @@ async def test_get_actions( expected_actions = [ { "domain": DOMAIN, - "type": "turn_on", + "type": action, "device_id": device_entry.id, - "entity_id": "NEW_DOMAIN.test_5678", - }, + "entity_id": f"{DOMAIN}.test_5678", + } + for action in ["turn_off", "turn_on"] + ] + actions = await async_get_device_automations( + hass, DeviceAutomationType.ACTION, device_entry.id + ) + assert_lists_same(actions, expected_actions) + + +@pytest.mark.parametrize( + "hidden_by,entity_category", + ( + (entity_registry.RegistryEntryHider.INTEGRATION, None), + (entity_registry.RegistryEntryHider.USER, None), + (None, EntityCategory.CONFIG), + (None, EntityCategory.DIAGNOSTIC), + ), +) +async def test_get_actions_hidden_auxiliary( + hass, + device_reg, + entity_reg, + hidden_by, + entity_category, +): + """Test we get the expected actions from a hidden or auxiliary entity.""" + config_entry = MockConfigEntry(domain="test", data={}) + config_entry.add_to_hass(hass) + device_entry = device_reg.async_get_or_create( + config_entry_id=config_entry.entry_id, + connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + ) + entity_reg.async_get_or_create( + DOMAIN, + "test", + "5678", + device_id=device_entry.id, + entity_category=entity_category, + hidden_by=hidden_by, + ) + expected_actions = [ { "domain": DOMAIN, - "type": "turn_off", + "type": action, "device_id": device_entry.id, - "entity_id": "NEW_DOMAIN.test_5678", - }, + "entity_id": f"{DOMAIN}.test_5678", + "metadata": {"secondary": True}, + } + for action in ["turn_off", "turn_on", "toggle"] ] actions = await async_get_device_automations( hass, DeviceAutomationType.ACTION, device_entry.id diff --git a/tests/common.py b/tests/common.py index da1e4acd870..baa8f1c2341 100644 --- a/tests/common.py +++ b/tests/common.py @@ -2,7 +2,6 @@ from __future__ import annotations import asyncio -import collections from collections import OrderedDict from collections.abc import Awaitable, Collection from contextlib import contextmanager @@ -1226,72 +1225,17 @@ def async_mock_signal(hass, signal): return calls -class hashdict(dict): - """ - hashable dict implementation, suitable for use as a key into other dicts. - - >>> h1 = hashdict({"apples": 1, "bananas":2}) - >>> h2 = hashdict({"bananas": 3, "mangoes": 5}) - >>> h1+h2 - hashdict(apples=1, bananas=3, mangoes=5) - >>> d1 = {} - >>> d1[h1] = "salad" - >>> d1[h1] - 'salad' - >>> d1[h2] - Traceback (most recent call last): - ... - KeyError: hashdict(bananas=3, mangoes=5) - - based on answers from - http://stackoverflow.com/questions/1151658/python-hashable-dicts - - """ - - def __key(self): - return tuple(sorted(self.items())) - - def __repr__(self): # noqa: D105 no docstring - return ", ".join(f"{i[0]!s}={i[1]!r}" for i in self.__key()) - - def __hash__(self): # noqa: D105 no docstring - return hash(self.__key()) - - def __setitem__(self, key, value): # noqa: D105 no docstring - raise TypeError(f"{self.__class__.__name__} does not support item assignment") - - def __delitem__(self, key): # noqa: D105 no docstring - raise TypeError(f"{self.__class__.__name__} does not support item assignment") - - def clear(self): # noqa: D102 no docstring - raise TypeError(f"{self.__class__.__name__} does not support item assignment") - - def pop(self, *args, **kwargs): # noqa: D102 no docstring - raise TypeError(f"{self.__class__.__name__} does not support item assignment") - - def popitem(self, *args, **kwargs): # noqa: D102 no docstring - raise TypeError(f"{self.__class__.__name__} does not support item assignment") - - def setdefault(self, *args, **kwargs): # noqa: D102 no docstring - raise TypeError(f"{self.__class__.__name__} does not support item assignment") - - def update(self, *args, **kwargs): # noqa: D102 no docstring - raise TypeError(f"{self.__class__.__name__} does not support item assignment") - - # update is not ok because it mutates the object - # __add__ is ok because it creates a new object - # while the new object is under construction, it's ok to mutate it - def __add__(self, right): # noqa: D105 no docstring - result = hashdict(self) - dict.update(result, right) - return result - - def assert_lists_same(a, b): - """Compare two lists, ignoring order.""" - assert collections.Counter([hashdict(i) for i in a]) == collections.Counter( - [hashdict(i) for i in b] - ) + """Compare two lists, ignoring order. + + Check both that all items in a are in b and that all items in b are in a, + otherwise assert_lists_same(["1", "1"], ["1", "2"]) could be True. + """ + assert len(a) == len(b) + for i in a: + assert i in b + for i in b: + assert i in a def raise_contains_mocks(val): diff --git a/tests/components/alarm_control_panel/test_device_action.py b/tests/components/alarm_control_panel/test_device_action.py index 52e60967131..ae10a199f9e 100644 --- a/tests/components/alarm_control_panel/test_device_action.py +++ b/tests/components/alarm_control_panel/test_device_action.py @@ -15,6 +15,8 @@ from homeassistant.const import ( STATE_UNKNOWN, ) from homeassistant.helpers import device_registry +from homeassistant.helpers.entity import EntityCategory +from homeassistant.helpers.entity_registry import RegistryEntryHider from homeassistant.setup import async_setup_component from tests.common import ( @@ -125,6 +127,7 @@ async def test_get_actions( "type": action, "device_id": device_entry.id, "entity_id": f"{DOMAIN}.test_5678", + "metadata": {"secondary": False}, } for action in expected_action_types ] @@ -134,6 +137,55 @@ async def test_get_actions( assert_lists_same(actions, expected_actions) +@pytest.mark.parametrize( + "hidden_by,entity_category", + ( + (RegistryEntryHider.INTEGRATION, None), + (RegistryEntryHider.USER, None), + (None, EntityCategory.CONFIG), + (None, EntityCategory.DIAGNOSTIC), + ), +) +async def test_get_actions_hidden_auxiliary( + hass, + device_reg, + entity_reg, + hidden_by, + entity_category, +): + """Test we get the expected actions from a hidden or auxiliary entity.""" + config_entry = MockConfigEntry(domain="test", data={}) + config_entry.add_to_hass(hass) + device_entry = device_reg.async_get_or_create( + config_entry_id=config_entry.entry_id, + connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + ) + entity_reg.async_get_or_create( + DOMAIN, + "test", + "5678", + device_id=device_entry.id, + entity_category=entity_category, + hidden_by=hidden_by, + supported_features=const.AlarmControlPanelEntityFeature.ARM_AWAY, + ) + expected_actions = [] + expected_actions += [ + { + "domain": DOMAIN, + "type": action, + "device_id": device_entry.id, + "entity_id": f"{DOMAIN}.test_5678", + "metadata": {"secondary": True}, + } + for action in ["disarm", "arm_away"] + ] + actions = await async_get_device_automations( + hass, DeviceAutomationType.ACTION, device_entry.id + ) + assert_lists_same(actions, expected_actions) + + async def test_get_actions_arm_night_only(hass, device_reg, entity_reg): """Test we get the expected actions from a alarm_control_panel.""" config_entry = MockConfigEntry(domain="test", data={}) @@ -152,12 +204,14 @@ async def test_get_actions_arm_night_only(hass, device_reg, entity_reg): "type": "arm_night", "device_id": device_entry.id, "entity_id": "alarm_control_panel.test_5678", + "metadata": {"secondary": False}, }, { "domain": DOMAIN, "type": "disarm", "device_id": device_entry.id, "entity_id": "alarm_control_panel.test_5678", + "metadata": {"secondary": False}, }, ] actions = await async_get_device_automations( diff --git a/tests/components/button/test_device_action.py b/tests/components/button/test_device_action.py index ab1e145cdb1..c5d9fe967b5 100644 --- a/tests/components/button/test_device_action.py +++ b/tests/components/button/test_device_action.py @@ -6,6 +6,7 @@ from homeassistant.components.button import DOMAIN from homeassistant.components.device_automation import DeviceAutomationType from homeassistant.core import HomeAssistant from homeassistant.helpers import device_registry, entity_registry +from homeassistant.helpers.entity import EntityCategory from homeassistant.setup import async_setup_component from tests.common import ( @@ -49,6 +50,7 @@ async def test_get_actions( "type": "press", "device_id": device_entry.id, "entity_id": "button.test_5678", + "metadata": {"secondary": False}, } ] actions = await async_get_device_automations( @@ -57,6 +59,54 @@ async def test_get_actions( assert_lists_same(actions, expected_actions) +@pytest.mark.parametrize( + "hidden_by,entity_category", + ( + (entity_registry.RegistryEntryHider.INTEGRATION, None), + (entity_registry.RegistryEntryHider.USER, None), + (None, EntityCategory.CONFIG), + (None, EntityCategory.DIAGNOSTIC), + ), +) +async def test_get_actions_hidden_auxiliary( + hass, + device_reg, + entity_reg, + hidden_by, + entity_category, +): + """Test we get the expected actions from a hidden or auxiliary entity.""" + config_entry = MockConfigEntry(domain="test", data={}) + config_entry.add_to_hass(hass) + device_entry = device_reg.async_get_or_create( + config_entry_id=config_entry.entry_id, + connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + ) + entity_reg.async_get_or_create( + DOMAIN, + "test", + "5678", + device_id=device_entry.id, + entity_category=entity_category, + hidden_by=hidden_by, + ) + expected_actions = [] + expected_actions += [ + { + "domain": DOMAIN, + "type": action, + "device_id": device_entry.id, + "entity_id": f"{DOMAIN}.test_5678", + "metadata": {"secondary": True}, + } + for action in ["press"] + ] + actions = await async_get_device_automations( + hass, DeviceAutomationType.ACTION, device_entry.id + ) + assert_lists_same(actions, expected_actions) + + async def test_action(hass: HomeAssistant) -> None: """Test for press action.""" assert await async_setup_component( diff --git a/tests/components/climate/test_device_action.py b/tests/components/climate/test_device_action.py index cd9bc0b1baf..15e06835924 100644 --- a/tests/components/climate/test_device_action.py +++ b/tests/components/climate/test_device_action.py @@ -6,6 +6,8 @@ import homeassistant.components.automation as automation from homeassistant.components.climate import DOMAIN, const, device_action from homeassistant.components.device_automation import DeviceAutomationType from homeassistant.helpers import config_validation as cv, device_registry +from homeassistant.helpers.entity import EntityCategory +from homeassistant.helpers.entity_registry import RegistryEntryHider from homeassistant.setup import async_setup_component from tests.common import ( @@ -86,6 +88,7 @@ async def test_get_actions( "type": action, "device_id": device_entry.id, "entity_id": f"{DOMAIN}.test_5678", + "metadata": {"secondary": False}, } for action in expected_action_types ] @@ -96,6 +99,55 @@ async def test_get_actions( assert_lists_same(actions, expected_actions) +@pytest.mark.parametrize( + "hidden_by,entity_category", + ( + (RegistryEntryHider.INTEGRATION, None), + (RegistryEntryHider.USER, None), + (None, EntityCategory.CONFIG), + (None, EntityCategory.DIAGNOSTIC), + ), +) +async def test_get_actions_hidden_auxiliary( + hass, + device_reg, + entity_reg, + hidden_by, + entity_category, +): + """Test we get the expected actions from a hidden or auxiliary entity.""" + config_entry = MockConfigEntry(domain="test", data={}) + config_entry.add_to_hass(hass) + device_entry = device_reg.async_get_or_create( + config_entry_id=config_entry.entry_id, + connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + ) + entity_reg.async_get_or_create( + DOMAIN, + "test", + "5678", + device_id=device_entry.id, + entity_category=entity_category, + hidden_by=hidden_by, + supported_features=0, + ) + expected_actions = [] + expected_actions += [ + { + "domain": DOMAIN, + "type": action, + "device_id": device_entry.id, + "entity_id": f"{DOMAIN}.test_5678", + "metadata": {"secondary": True}, + } + for action in ["set_hvac_mode"] + ] + actions = await async_get_device_automations( + hass, DeviceAutomationType.ACTION, device_entry.id + ) + assert_lists_same(actions, expected_actions) + + async def test_action(hass): """Test for actions.""" hass.states.async_set( diff --git a/tests/components/cover/test_device_action.py b/tests/components/cover/test_device_action.py index e1595089d2e..d4cf5901bbf 100644 --- a/tests/components/cover/test_device_action.py +++ b/tests/components/cover/test_device_action.py @@ -16,6 +16,8 @@ from homeassistant.components.cover import ( from homeassistant.components.device_automation import DeviceAutomationType from homeassistant.const import CONF_PLATFORM from homeassistant.helpers import device_registry +from homeassistant.helpers.entity import EntityCategory +from homeassistant.helpers.entity_registry import RegistryEntryHider from homeassistant.setup import async_setup_component from tests.common import ( @@ -99,6 +101,7 @@ async def test_get_actions( "type": action, "device_id": device_entry.id, "entity_id": f"{DOMAIN}.test_5678", + "metadata": {"secondary": False}, } for action in expected_action_types ] @@ -108,6 +111,55 @@ async def test_get_actions( assert_lists_same(actions, expected_actions) +@pytest.mark.parametrize( + "hidden_by,entity_category", + ( + (RegistryEntryHider.INTEGRATION, None), + (RegistryEntryHider.USER, None), + (None, EntityCategory.CONFIG), + (None, EntityCategory.DIAGNOSTIC), + ), +) +async def test_get_actions_hidden_auxiliary( + hass, + device_reg, + entity_reg, + hidden_by, + entity_category, +): + """Test we get the expected actions from a hidden or auxiliary entity.""" + config_entry = MockConfigEntry(domain="test", data={}) + config_entry.add_to_hass(hass) + device_entry = device_reg.async_get_or_create( + config_entry_id=config_entry.entry_id, + connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + ) + entity_reg.async_get_or_create( + DOMAIN, + "test", + "5678", + device_id=device_entry.id, + entity_category=entity_category, + hidden_by=hidden_by, + supported_features=SUPPORT_CLOSE, + ) + expected_actions = [] + expected_actions += [ + { + "domain": DOMAIN, + "type": action, + "device_id": device_entry.id, + "entity_id": f"{DOMAIN}.test_5678", + "metadata": {"secondary": True}, + } + for action in ["close"] + ] + actions = await async_get_device_automations( + hass, DeviceAutomationType.ACTION, device_entry.id + ) + assert_lists_same(actions, expected_actions) + + async def test_get_action_capabilities( hass, device_reg, entity_reg, enable_custom_integrations ): diff --git a/tests/components/device_automation/test_init.py b/tests/components/device_automation/test_init.py index ad6a08814ff..e9d97c8a70d 100644 --- a/tests/components/device_automation/test_init.py +++ b/tests/components/device_automation/test_init.py @@ -57,18 +57,21 @@ async def test_websocket_get_actions(hass, hass_ws_client, device_reg, entity_re "type": "turn_off", "device_id": device_entry.id, "entity_id": "light.test_5678", + "metadata": {"secondary": False}, }, { "domain": "light", "type": "turn_on", "device_id": device_entry.id, "entity_id": "light.test_5678", + "metadata": {"secondary": False}, }, { "domain": "light", "type": "toggle", "device_id": device_entry.id, "entity_id": "light.test_5678", + "metadata": {"secondary": False}, }, ] diff --git a/tests/components/fan/test_device_action.py b/tests/components/fan/test_device_action.py index eb31a2ece42..ee300aad39f 100644 --- a/tests/components/fan/test_device_action.py +++ b/tests/components/fan/test_device_action.py @@ -5,6 +5,8 @@ import homeassistant.components.automation as automation from homeassistant.components.device_automation import DeviceAutomationType from homeassistant.components.fan import DOMAIN from homeassistant.helpers import device_registry +from homeassistant.helpers.entity import EntityCategory +from homeassistant.helpers.entity_registry import RegistryEntryHider from homeassistant.setup import async_setup_component from tests.common import ( @@ -39,19 +41,64 @@ async def test_get_actions(hass, device_reg, entity_reg): connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, ) entity_reg.async_get_or_create(DOMAIN, "test", "5678", device_id=device_entry.id) - expected_actions = [ + expected_actions = [] + expected_actions += [ { "domain": DOMAIN, - "type": "turn_on", + "type": action, "device_id": device_entry.id, - "entity_id": "fan.test_5678", - }, + "entity_id": f"{DOMAIN}.test_5678", + "metadata": {"secondary": False}, + } + for action in ["turn_on", "turn_off"] + ] + actions = await async_get_device_automations( + hass, DeviceAutomationType.ACTION, device_entry.id + ) + assert_lists_same(actions, expected_actions) + + +@pytest.mark.parametrize( + "hidden_by,entity_category", + ( + (RegistryEntryHider.INTEGRATION, None), + (RegistryEntryHider.USER, None), + (None, EntityCategory.CONFIG), + (None, EntityCategory.DIAGNOSTIC), + ), +) +async def test_get_actions_hidden_auxiliary( + hass, + device_reg, + entity_reg, + hidden_by, + entity_category, +): + """Test we get the expected actions from a hidden or auxiliary entity.""" + config_entry = MockConfigEntry(domain="test", data={}) + config_entry.add_to_hass(hass) + device_entry = device_reg.async_get_or_create( + config_entry_id=config_entry.entry_id, + connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + ) + entity_reg.async_get_or_create( + DOMAIN, + "test", + "5678", + device_id=device_entry.id, + entity_category=entity_category, + hidden_by=hidden_by, + ) + expected_actions = [] + expected_actions += [ { "domain": DOMAIN, - "type": "turn_off", + "type": action, "device_id": device_entry.id, - "entity_id": "fan.test_5678", - }, + "entity_id": f"{DOMAIN}.test_5678", + "metadata": {"secondary": True}, + } + for action in ["turn_on", "turn_off"] ] actions = await async_get_device_automations( hass, DeviceAutomationType.ACTION, device_entry.id diff --git a/tests/components/humidifier/test_device_action.py b/tests/components/humidifier/test_device_action.py index fee8afc7a72..00c45f30885 100644 --- a/tests/components/humidifier/test_device_action.py +++ b/tests/components/humidifier/test_device_action.py @@ -7,6 +7,8 @@ from homeassistant.components.device_automation import DeviceAutomationType from homeassistant.components.humidifier import DOMAIN, const, device_action from homeassistant.const import STATE_ON from homeassistant.helpers import config_validation as cv, device_registry +from homeassistant.helpers.entity import EntityCategory +from homeassistant.helpers.entity_registry import RegistryEntryHider from homeassistant.setup import async_setup_component from tests.common import ( @@ -76,6 +78,7 @@ async def test_get_actions( "type": action, "device_id": device_entry.id, "entity_id": f"{DOMAIN}.test_5678", + "metadata": {"secondary": False}, } for action in basic_action_types ] @@ -85,6 +88,7 @@ async def test_get_actions( "type": action, "device_id": device_entry.id, "entity_id": f"{DOMAIN}.test_5678", + "metadata": {"secondary": False}, } for action in expected_action_types ] @@ -94,6 +98,55 @@ async def test_get_actions( assert_lists_same(actions, expected_actions) +@pytest.mark.parametrize( + "hidden_by,entity_category", + ( + (RegistryEntryHider.INTEGRATION, None), + (RegistryEntryHider.USER, None), + (None, EntityCategory.CONFIG), + (None, EntityCategory.DIAGNOSTIC), + ), +) +async def test_get_actions_hidden_auxiliary( + hass, + device_reg, + entity_reg, + hidden_by, + entity_category, +): + """Test we get the expected actions from a hidden or auxiliary entity.""" + config_entry = MockConfigEntry(domain="test", data={}) + config_entry.add_to_hass(hass) + device_entry = device_reg.async_get_or_create( + config_entry_id=config_entry.entry_id, + connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + ) + entity_reg.async_get_or_create( + DOMAIN, + "test", + "5678", + device_id=device_entry.id, + entity_category=entity_category, + hidden_by=hidden_by, + supported_features=0, + ) + expected_actions = [] + expected_actions += [ + { + "domain": DOMAIN, + "type": action, + "device_id": device_entry.id, + "entity_id": f"{DOMAIN}.test_5678", + "metadata": {"secondary": True}, + } + for action in ["turn_on", "turn_off", "toggle", "set_humidity"] + ] + actions = await async_get_device_automations( + hass, DeviceAutomationType.ACTION, device_entry.id + ) + assert_lists_same(actions, expected_actions) + + async def test_action(hass): """Test for actions.""" hass.states.async_set( diff --git a/tests/components/light/test_device_action.py b/tests/components/light/test_device_action.py index 7234bd57af4..fc330048dc4 100644 --- a/tests/components/light/test_device_action.py +++ b/tests/components/light/test_device_action.py @@ -13,10 +13,13 @@ from homeassistant.components.light import ( ) from homeassistant.const import CONF_PLATFORM, STATE_OFF, STATE_ON from homeassistant.helpers import device_registry +from homeassistant.helpers.entity import EntityCategory +from homeassistant.helpers.entity_registry import RegistryEntryHider from homeassistant.setup import async_setup_component from tests.common import ( MockConfigEntry, + assert_lists_same, async_get_device_automation_capabilities, async_get_device_automations, async_mock_service, @@ -60,48 +63,78 @@ async def test_get_actions(hass, device_reg, entity_reg): supported_features=LightEntityFeature.FLASH, capabilities={"supported_color_modes": ["brightness"]}, ) - expected_actions = [ + expected_actions = [] + expected_actions += [ { "domain": DOMAIN, - "type": "turn_off", + "type": action, "device_id": device_entry.id, "entity_id": f"{DOMAIN}.test_5678", - }, - { - "domain": DOMAIN, - "type": "turn_on", - "device_id": device_entry.id, - "entity_id": f"{DOMAIN}.test_5678", - }, - { - "domain": DOMAIN, - "type": "toggle", - "device_id": device_entry.id, - "entity_id": f"{DOMAIN}.test_5678", - }, - { - "domain": DOMAIN, - "type": "brightness_increase", - "device_id": device_entry.id, - "entity_id": f"{DOMAIN}.test_5678", - }, - { - "domain": DOMAIN, - "type": "brightness_decrease", - "device_id": device_entry.id, - "entity_id": f"{DOMAIN}.test_5678", - }, - { - "domain": DOMAIN, - "type": "flash", - "device_id": device_entry.id, - "entity_id": f"{DOMAIN}.test_5678", - }, + "metadata": {"secondary": False}, + } + for action in [ + "turn_off", + "turn_on", + "toggle", + "brightness_decrease", + "brightness_increase", + "flash", + ] ] actions = await async_get_device_automations( hass, DeviceAutomationType.ACTION, device_entry.id ) - assert actions == expected_actions + assert_lists_same(actions, expected_actions) + + +@pytest.mark.parametrize( + "hidden_by,entity_category", + ( + (RegistryEntryHider.INTEGRATION, None), + (RegistryEntryHider.USER, None), + (None, EntityCategory.CONFIG), + (None, EntityCategory.DIAGNOSTIC), + ), +) +async def test_get_actions_hidden_auxiliary( + hass, + device_reg, + entity_reg, + hidden_by, + entity_category, +): + """Test we get the expected actions from a hidden or auxiliary entity.""" + config_entry = MockConfigEntry(domain="test", data={}) + config_entry.add_to_hass(hass) + device_entry = device_reg.async_get_or_create( + config_entry_id=config_entry.entry_id, + connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + ) + entity_reg.async_get_or_create( + DOMAIN, + "test", + "5678", + device_id=device_entry.id, + entity_category=entity_category, + hidden_by=hidden_by, + supported_features=0, + capabilities={"supported_color_modes": ["onoff"]}, + ) + expected_actions = [] + expected_actions += [ + { + "domain": DOMAIN, + "type": action, + "device_id": device_entry.id, + "entity_id": f"{DOMAIN}.test_5678", + "metadata": {"secondary": True}, + } + for action in ["turn_on", "turn_off", "toggle"] + ] + actions = await async_get_device_automations( + hass, DeviceAutomationType.ACTION, device_entry.id + ) + assert_lists_same(actions, expected_actions) async def test_get_action_capabilities(hass, device_reg, entity_reg): diff --git a/tests/components/lock/test_device_action.py b/tests/components/lock/test_device_action.py index 1f533e8d222..d4b37951f10 100644 --- a/tests/components/lock/test_device_action.py +++ b/tests/components/lock/test_device_action.py @@ -5,6 +5,8 @@ import homeassistant.components.automation as automation from homeassistant.components.device_automation import DeviceAutomationType from homeassistant.components.lock import DOMAIN, LockEntityFeature from homeassistant.helpers import device_registry +from homeassistant.helpers.entity import EntityCategory +from homeassistant.helpers.entity_registry import RegistryEntryHider from homeassistant.setup import async_setup_component from tests.common import ( @@ -74,6 +76,7 @@ async def test_get_actions( "type": action, "device_id": device_entry.id, "entity_id": f"{DOMAIN}.test_5678", + "metadata": {"secondary": False}, } for action in basic_action_types ] @@ -83,6 +86,7 @@ async def test_get_actions( "type": action, "device_id": device_entry.id, "entity_id": f"{DOMAIN}.test_5678", + "metadata": {"secondary": False}, } for action in expected_action_types ] @@ -92,6 +96,55 @@ async def test_get_actions( assert_lists_same(actions, expected_actions) +@pytest.mark.parametrize( + "hidden_by,entity_category", + ( + (RegistryEntryHider.INTEGRATION, None), + (RegistryEntryHider.USER, None), + (None, EntityCategory.CONFIG), + (None, EntityCategory.DIAGNOSTIC), + ), +) +async def test_get_actions_hidden_auxiliary( + hass, + device_reg, + entity_reg, + hidden_by, + entity_category, +): + """Test we get the expected actions from a hidden or auxiliary entity.""" + config_entry = MockConfigEntry(domain="test", data={}) + config_entry.add_to_hass(hass) + device_entry = device_reg.async_get_or_create( + config_entry_id=config_entry.entry_id, + connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + ) + entity_reg.async_get_or_create( + DOMAIN, + "test", + "5678", + device_id=device_entry.id, + entity_category=entity_category, + hidden_by=hidden_by, + supported_features=0, + ) + expected_actions = [] + expected_actions += [ + { + "domain": DOMAIN, + "type": action, + "device_id": device_entry.id, + "entity_id": f"{DOMAIN}.test_5678", + "metadata": {"secondary": True}, + } + for action in ["lock", "unlock"] + ] + actions = await async_get_device_automations( + hass, DeviceAutomationType.ACTION, device_entry.id + ) + assert_lists_same(actions, expected_actions) + + async def test_action(hass): """Test for lock actions.""" assert await async_setup_component( diff --git a/tests/components/mobile_app/test_device_action.py b/tests/components/mobile_app/test_device_action.py index dd4d2a55d82..3047c888b16 100644 --- a/tests/components/mobile_app/test_device_action.py +++ b/tests/components/mobile_app/test_device_action.py @@ -13,7 +13,7 @@ async def test_get_actions(hass, push_registration): assert await async_get_device_automations( hass, device_automation.DeviceAutomationType.ACTION, device_id - ) == [{"domain": DOMAIN, "device_id": device_id, "type": "notify"}] + ) == [{"domain": DOMAIN, "device_id": device_id, "metadata": {}, "type": "notify"}] capabilitites = await device_automation._async_get_device_automation_capabilities( hass, diff --git a/tests/components/number/test_device_action.py b/tests/components/number/test_device_action.py index 806bd8771b2..34efd12c120 100644 --- a/tests/components/number/test_device_action.py +++ b/tests/components/number/test_device_action.py @@ -6,6 +6,8 @@ import homeassistant.components.automation as automation from homeassistant.components.device_automation import DeviceAutomationType from homeassistant.components.number import DOMAIN, device_action from homeassistant.helpers import config_validation as cv, device_registry +from homeassistant.helpers.entity import EntityCategory +from homeassistant.helpers.entity_registry import RegistryEntryHider from homeassistant.setup import async_setup_component from tests.common import ( @@ -47,6 +49,7 @@ async def test_get_actions(hass, device_reg, entity_reg): "type": "set_value", "device_id": device_entry.id, "entity_id": "number.test_5678", + "metadata": {"secondary": False}, }, ] actions = await async_get_device_automations( @@ -55,6 +58,54 @@ async def test_get_actions(hass, device_reg, entity_reg): assert_lists_same(actions, expected_actions) +@pytest.mark.parametrize( + "hidden_by,entity_category", + ( + (RegistryEntryHider.INTEGRATION, None), + (RegistryEntryHider.USER, None), + (None, EntityCategory.CONFIG), + (None, EntityCategory.DIAGNOSTIC), + ), +) +async def test_get_actions_hidden_auxiliary( + hass, + device_reg, + entity_reg, + hidden_by, + entity_category, +): + """Test we get the expected actions from a hidden or auxiliary entity.""" + config_entry = MockConfigEntry(domain="test", data={}) + config_entry.add_to_hass(hass) + device_entry = device_reg.async_get_or_create( + config_entry_id=config_entry.entry_id, + connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + ) + entity_reg.async_get_or_create( + DOMAIN, + "test", + "5678", + device_id=device_entry.id, + entity_category=entity_category, + hidden_by=hidden_by, + ) + expected_actions = [] + expected_actions += [ + { + "domain": DOMAIN, + "type": action, + "device_id": device_entry.id, + "entity_id": f"{DOMAIN}.test_5678", + "metadata": {"secondary": True}, + } + for action in ["set_value"] + ] + actions = await async_get_device_automations( + hass, DeviceAutomationType.ACTION, device_entry.id + ) + assert_lists_same(actions, expected_actions) + + async def test_get_action_no_state(hass, device_reg, entity_reg): """Test we get the expected actions for an entity.""" config_entry = MockConfigEntry(domain="test", data={}) @@ -70,6 +121,7 @@ async def test_get_action_no_state(hass, device_reg, entity_reg): "type": "set_value", "device_id": device_entry.id, "entity_id": "number.test_5678", + "metadata": {"secondary": False}, }, ] actions = await async_get_device_automations( diff --git a/tests/components/remote/test_device_action.py b/tests/components/remote/test_device_action.py index 9c113c26578..57cf92d5728 100644 --- a/tests/components/remote/test_device_action.py +++ b/tests/components/remote/test_device_action.py @@ -6,10 +6,13 @@ from homeassistant.components.device_automation import DeviceAutomationType from homeassistant.components.remote import DOMAIN from homeassistant.const import CONF_PLATFORM, STATE_OFF, STATE_ON from homeassistant.helpers import device_registry +from homeassistant.helpers.entity import EntityCategory +from homeassistant.helpers.entity_registry import RegistryEntryHider from homeassistant.setup import async_setup_component from tests.common import ( MockConfigEntry, + assert_lists_same, async_get_device_automations, async_mock_service, mock_device_registry, @@ -48,27 +51,65 @@ async def test_get_actions(hass, device_reg, entity_reg): expected_actions = [ { "domain": DOMAIN, - "type": "turn_off", + "type": action, "device_id": device_entry.id, "entity_id": f"{DOMAIN}.test_5678", - }, - { - "domain": DOMAIN, - "type": "turn_on", - "device_id": device_entry.id, - "entity_id": f"{DOMAIN}.test_5678", - }, - { - "domain": DOMAIN, - "type": "toggle", - "device_id": device_entry.id, - "entity_id": f"{DOMAIN}.test_5678", - }, + "metadata": {"secondary": False}, + } + for action in ["turn_off", "turn_on", "toggle"] ] actions = await async_get_device_automations( hass, DeviceAutomationType.ACTION, device_entry.id ) - assert actions == expected_actions + assert_lists_same(actions, expected_actions) + + +@pytest.mark.parametrize( + "hidden_by,entity_category", + ( + (RegistryEntryHider.INTEGRATION, None), + (RegistryEntryHider.USER, None), + (None, EntityCategory.CONFIG), + (None, EntityCategory.DIAGNOSTIC), + ), +) +async def test_get_actions_hidden_auxiliary( + hass, + device_reg, + entity_reg, + hidden_by, + entity_category, +): + """Test we get the expected actions from a hidden or auxiliary entity.""" + config_entry = MockConfigEntry(domain="test", data={}) + config_entry.add_to_hass(hass) + device_entry = device_reg.async_get_or_create( + config_entry_id=config_entry.entry_id, + connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + ) + entity_reg.async_get_or_create( + DOMAIN, + "test", + "5678", + device_id=device_entry.id, + entity_category=entity_category, + hidden_by=hidden_by, + ) + expected_actions = [] + expected_actions += [ + { + "domain": DOMAIN, + "type": action, + "device_id": device_entry.id, + "entity_id": f"{DOMAIN}.test_5678", + "metadata": {"secondary": True}, + } + for action in ["turn_off", "turn_on", "toggle"] + ] + actions = await async_get_device_automations( + hass, DeviceAutomationType.ACTION, device_entry.id + ) + assert_lists_same(actions, expected_actions) async def test_action(hass, calls, enable_custom_integrations): diff --git a/tests/components/rfxtrx/test_device_action.py b/tests/components/rfxtrx/test_device_action.py index 79211b73513..6b61e166b2a 100644 --- a/tests/components/rfxtrx/test_device_action.py +++ b/tests/components/rfxtrx/test_device_action.py @@ -105,7 +105,7 @@ async def test_get_actions(hass, device_reg: DeviceRegistry, device, expected): actions = [action for action in actions if action["domain"] == DOMAIN] expected_actions = [ - {"domain": DOMAIN, "device_id": device_entry.id, **action_type} + {"domain": DOMAIN, "device_id": device_entry.id, "metadata": {}, **action_type} for action_type in expected ] diff --git a/tests/components/select/test_device_action.py b/tests/components/select/test_device_action.py index 1d6ebe92626..a3d5d1c306d 100644 --- a/tests/components/select/test_device_action.py +++ b/tests/components/select/test_device_action.py @@ -12,6 +12,7 @@ from homeassistant.helpers import ( device_registry, entity_registry, ) +from homeassistant.helpers.entity import EntityCategory from homeassistant.setup import async_setup_component from tests.common import ( @@ -55,6 +56,7 @@ async def test_get_actions( "type": "select_option", "device_id": device_entry.id, "entity_id": "select.test_5678", + "metadata": {"secondary": False}, } ] actions = await async_get_device_automations( @@ -63,6 +65,54 @@ async def test_get_actions( assert_lists_same(actions, expected_actions) +@pytest.mark.parametrize( + "hidden_by,entity_category", + ( + (entity_registry.RegistryEntryHider.INTEGRATION, None), + (entity_registry.RegistryEntryHider.USER, None), + (None, EntityCategory.CONFIG), + (None, EntityCategory.DIAGNOSTIC), + ), +) +async def test_get_actions_hidden_auxiliary( + hass, + device_reg, + entity_reg, + hidden_by, + entity_category, +): + """Test we get the expected actions from a hidden or auxiliary entity.""" + config_entry = MockConfigEntry(domain="test", data={}) + config_entry.add_to_hass(hass) + device_entry = device_reg.async_get_or_create( + config_entry_id=config_entry.entry_id, + connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + ) + entity_reg.async_get_or_create( + DOMAIN, + "test", + "5678", + device_id=device_entry.id, + entity_category=entity_category, + hidden_by=hidden_by, + ) + expected_actions = [] + expected_actions += [ + { + "domain": DOMAIN, + "type": action, + "device_id": device_entry.id, + "entity_id": f"{DOMAIN}.test_5678", + "metadata": {"secondary": True}, + } + for action in ["select_option"] + ] + actions = await async_get_device_automations( + hass, DeviceAutomationType.ACTION, device_entry.id + ) + assert_lists_same(actions, expected_actions) + + async def test_action(hass: HomeAssistant) -> None: """Test for select_option action.""" assert await async_setup_component( diff --git a/tests/components/switch/test_device_action.py b/tests/components/switch/test_device_action.py index bdfaac5d1ef..43eb76f9cc5 100644 --- a/tests/components/switch/test_device_action.py +++ b/tests/components/switch/test_device_action.py @@ -6,10 +6,13 @@ from homeassistant.components.device_automation import DeviceAutomationType from homeassistant.components.switch import DOMAIN from homeassistant.const import CONF_PLATFORM, STATE_OFF, STATE_ON from homeassistant.helpers import device_registry +from homeassistant.helpers.entity import EntityCategory +from homeassistant.helpers.entity_registry import RegistryEntryHider from homeassistant.setup import async_setup_component from tests.common import ( MockConfigEntry, + assert_lists_same, async_get_device_automations, async_mock_service, mock_device_registry, @@ -45,30 +48,69 @@ async def test_get_actions(hass, device_reg, entity_reg): connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, ) entity_reg.async_get_or_create(DOMAIN, "test", "5678", device_id=device_entry.id) - expected_actions = [ + expected_actions = [] + expected_actions += [ { "domain": DOMAIN, - "type": "turn_off", + "type": action, "device_id": device_entry.id, "entity_id": f"{DOMAIN}.test_5678", - }, - { - "domain": DOMAIN, - "type": "turn_on", - "device_id": device_entry.id, - "entity_id": f"{DOMAIN}.test_5678", - }, - { - "domain": DOMAIN, - "type": "toggle", - "device_id": device_entry.id, - "entity_id": f"{DOMAIN}.test_5678", - }, + "metadata": {"secondary": False}, + } + for action in ["turn_off", "turn_on", "toggle"] ] actions = await async_get_device_automations( hass, DeviceAutomationType.ACTION, device_entry.id ) - assert actions == expected_actions + assert_lists_same(actions, expected_actions) + + +@pytest.mark.parametrize( + "hidden_by,entity_category", + ( + (RegistryEntryHider.INTEGRATION, None), + (RegistryEntryHider.USER, None), + (None, EntityCategory.CONFIG), + (None, EntityCategory.DIAGNOSTIC), + ), +) +async def test_get_actions_hidden_auxiliary( + hass, + device_reg, + entity_reg, + hidden_by, + entity_category, +): + """Test we get the expected actions from a hidden or auxiliary entity.""" + config_entry = MockConfigEntry(domain="test", data={}) + config_entry.add_to_hass(hass) + device_entry = device_reg.async_get_or_create( + config_entry_id=config_entry.entry_id, + connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + ) + entity_reg.async_get_or_create( + DOMAIN, + "test", + "5678", + device_id=device_entry.id, + entity_category=entity_category, + hidden_by=hidden_by, + ) + expected_actions = [] + expected_actions += [ + { + "domain": DOMAIN, + "type": action, + "device_id": device_entry.id, + "entity_id": f"{DOMAIN}.test_5678", + "metadata": {"secondary": True}, + } + for action in ["turn_off", "turn_on", "toggle"] + ] + actions = await async_get_device_automations( + hass, DeviceAutomationType.ACTION, device_entry.id + ) + assert_lists_same(actions, expected_actions) async def test_action(hass, calls, enable_custom_integrations): diff --git a/tests/components/vacuum/test_device_action.py b/tests/components/vacuum/test_device_action.py index ce357f3d6ca..482afce7137 100644 --- a/tests/components/vacuum/test_device_action.py +++ b/tests/components/vacuum/test_device_action.py @@ -5,6 +5,8 @@ import homeassistant.components.automation as automation from homeassistant.components.device_automation import DeviceAutomationType from homeassistant.components.vacuum import DOMAIN from homeassistant.helpers import device_registry +from homeassistant.helpers.entity import EntityCategory +from homeassistant.helpers.entity_registry import RegistryEntryHider from homeassistant.setup import async_setup_component from tests.common import ( @@ -39,19 +41,64 @@ async def test_get_actions(hass, device_reg, entity_reg): connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, ) entity_reg.async_get_or_create(DOMAIN, "test", "5678", device_id=device_entry.id) - expected_actions = [ + expected_actions = [] + expected_actions += [ { "domain": DOMAIN, - "type": "clean", + "type": action, "device_id": device_entry.id, "entity_id": "vacuum.test_5678", - }, + "metadata": {"secondary": False}, + } + for action in ["clean", "dock"] + ] + actions = await async_get_device_automations( + hass, DeviceAutomationType.ACTION, device_entry.id + ) + assert_lists_same(actions, expected_actions) + + +@pytest.mark.parametrize( + "hidden_by,entity_category", + ( + (RegistryEntryHider.INTEGRATION, None), + (RegistryEntryHider.USER, None), + (None, EntityCategory.CONFIG), + (None, EntityCategory.DIAGNOSTIC), + ), +) +async def test_get_actions_hidden_auxiliary( + hass, + device_reg, + entity_reg, + hidden_by, + entity_category, +): + """Test we get the expected actions from a hidden or auxiliary entity.""" + config_entry = MockConfigEntry(domain="test", data={}) + config_entry.add_to_hass(hass) + device_entry = device_reg.async_get_or_create( + config_entry_id=config_entry.entry_id, + connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + ) + entity_reg.async_get_or_create( + DOMAIN, + "test", + "5678", + device_id=device_entry.id, + entity_category=entity_category, + hidden_by=hidden_by, + ) + expected_actions = [] + expected_actions += [ { "domain": DOMAIN, - "type": "dock", + "type": action, "device_id": device_entry.id, - "entity_id": "vacuum.test_5678", - }, + "entity_id": f"{DOMAIN}.test_5678", + "metadata": {"secondary": True}, + } + for action in ["clean", "dock"] ] actions = await async_get_device_automations( hass, DeviceAutomationType.ACTION, device_entry.id diff --git a/tests/components/water_heater/test_device_action.py b/tests/components/water_heater/test_device_action.py index 25b79910bdb..9575823eb40 100644 --- a/tests/components/water_heater/test_device_action.py +++ b/tests/components/water_heater/test_device_action.py @@ -5,6 +5,8 @@ import homeassistant.components.automation as automation from homeassistant.components.device_automation import DeviceAutomationType from homeassistant.components.water_heater import DOMAIN from homeassistant.helpers import device_registry +from homeassistant.helpers.entity import EntityCategory +from homeassistant.helpers.entity_registry import RegistryEntryHider from homeassistant.setup import async_setup_component from tests.common import ( @@ -39,19 +41,64 @@ async def test_get_actions(hass, device_reg, entity_reg): connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, ) entity_reg.async_get_or_create(DOMAIN, "test", "5678", device_id=device_entry.id) - expected_actions = [ + expected_actions = [] + expected_actions += [ { "domain": DOMAIN, - "type": "turn_on", + "type": action, "device_id": device_entry.id, - "entity_id": "water_heater.test_5678", - }, + "entity_id": f"{DOMAIN}.test_5678", + "metadata": {"secondary": False}, + } + for action in ["turn_on", "turn_off"] + ] + actions = await async_get_device_automations( + hass, DeviceAutomationType.ACTION, device_entry.id + ) + assert_lists_same(actions, expected_actions) + + +@pytest.mark.parametrize( + "hidden_by,entity_category", + ( + (RegistryEntryHider.INTEGRATION, None), + (RegistryEntryHider.USER, None), + (None, EntityCategory.CONFIG), + (None, EntityCategory.DIAGNOSTIC), + ), +) +async def test_get_actions_hidden_auxiliary( + hass, + device_reg, + entity_reg, + hidden_by, + entity_category, +): + """Test we get the expected actions from a hidden or auxiliary entity.""" + config_entry = MockConfigEntry(domain="test", data={}) + config_entry.add_to_hass(hass) + device_entry = device_reg.async_get_or_create( + config_entry_id=config_entry.entry_id, + connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + ) + entity_reg.async_get_or_create( + DOMAIN, + "test", + "5678", + device_id=device_entry.id, + entity_category=entity_category, + hidden_by=hidden_by, + ) + expected_actions = [] + expected_actions += [ { "domain": DOMAIN, - "type": "turn_off", + "type": action, "device_id": device_entry.id, - "entity_id": "water_heater.test_5678", - }, + "entity_id": f"{DOMAIN}.test_5678", + "metadata": {"secondary": True}, + } + for action in ["turn_on", "turn_off"] ] actions = await async_get_device_automations( hass, DeviceAutomationType.ACTION, device_entry.id diff --git a/tests/components/zha/test_device_action.py b/tests/components/zha/test_device_action.py index e31f6b50fb5..54cc7e9171d 100644 --- a/tests/components/zha/test_device_action.py +++ b/tests/components/zha/test_device_action.py @@ -58,31 +58,40 @@ async def test_get_actions(hass, device_ias): ) expected_actions = [ - {"domain": DOMAIN, "type": "squawk", "device_id": reg_device.id}, - {"domain": DOMAIN, "type": "warn", "device_id": reg_device.id}, + { + "domain": DOMAIN, + "type": "squawk", + "device_id": reg_device.id, + "metadata": {}, + }, + {"domain": DOMAIN, "type": "warn", "device_id": reg_device.id, "metadata": {}}, { "domain": Platform.SELECT, "type": "select_option", "device_id": reg_device.id, "entity_id": "select.fakemanufacturer_fakemodel_e769900a_ias_wd_warningmode", + "metadata": {"secondary": True}, }, { "domain": Platform.SELECT, "type": "select_option", "device_id": reg_device.id, "entity_id": "select.fakemanufacturer_fakemodel_e769900a_ias_wd_sirenlevel", + "metadata": {"secondary": True}, }, { "domain": Platform.SELECT, "type": "select_option", "device_id": reg_device.id, "entity_id": "select.fakemanufacturer_fakemodel_e769900a_ias_wd_strobelevel", + "metadata": {"secondary": True}, }, { "domain": Platform.SELECT, "type": "select_option", "device_id": reg_device.id, "entity_id": "select.fakemanufacturer_fakemodel_e769900a_ias_wd_strobe", + "metadata": {"secondary": True}, }, ] diff --git a/tests/components/zwave_js/test_device_action.py b/tests/components/zwave_js/test_device_action.py index 657540db94d..b8fa43d9cec 100644 --- a/tests/components/zwave_js/test_device_action.py +++ b/tests/components/zwave_js/test_device_action.py @@ -38,28 +38,40 @@ async def test_get_actions( "type": "clear_lock_usercode", "device_id": device.id, "entity_id": "lock.touchscreen_deadbolt", + "metadata": {"secondary": False}, }, { "domain": DOMAIN, "type": "set_lock_usercode", "device_id": device.id, "entity_id": "lock.touchscreen_deadbolt", + "metadata": {"secondary": False}, + }, + { + "domain": DOMAIN, + "type": "refresh_value", + "device_id": device.id, + "entity_id": "binary_sensor.touchscreen_deadbolt_low_battery_level", + "metadata": {"secondary": True}, }, { "domain": DOMAIN, "type": "refresh_value", "device_id": device.id, "entity_id": "lock.touchscreen_deadbolt", + "metadata": {"secondary": False}, }, { "domain": DOMAIN, "type": "set_value", "device_id": device.id, + "metadata": {}, }, { "domain": DOMAIN, "type": "ping", "device_id": device.id, + "metadata": {}, }, { "domain": DOMAIN, @@ -68,6 +80,7 @@ async def test_get_actions( "parameter": 3, "bitmask": None, "subtype": "3 (Beeper)", + "metadata": {}, }, ] actions = await async_get_device_automations(