diff --git a/homeassistant/components/imou/icons.json b/homeassistant/components/imou/icons.json index 778574ddb2d0..aad37b91a2cd 100644 --- a/homeassistant/components/imou/icons.json +++ b/homeassistant/components/imou/icons.json @@ -15,6 +15,9 @@ } }, "select": { + "collection_point": { + "default": "mdi:crosshairs-gps" + }, "device_volume": { "default": "mdi:volume-high", "state": { diff --git a/homeassistant/components/imou/select.py b/homeassistant/components/imou/select.py index a4be6634e6c1..d15b3d804df4 100644 --- a/homeassistant/components/imou/select.py +++ b/homeassistant/components/imou/select.py @@ -3,6 +3,7 @@ from typing import override from pyimouapi.const import ( + PARAM_COLLECTION_POINT, PARAM_CURRENT_OPTION, PARAM_DEVICE_VOLUME, PARAM_NIGHT_VISION_MODE, @@ -33,6 +34,10 @@ SELECT_TYPES: tuple[SelectEntityDescription, ...] = ( entity_category=EntityCategory.CONFIG, translation_key=PARAM_NIGHT_VISION_MODE, ), + SelectEntityDescription( + key=PARAM_COLLECTION_POINT, + translation_key=PARAM_COLLECTION_POINT, + ), ) diff --git a/homeassistant/components/imou/strings.json b/homeassistant/components/imou/strings.json index 051f0d3a8d2b..66c1928a1c03 100644 --- a/homeassistant/components/imou/strings.json +++ b/homeassistant/components/imou/strings.json @@ -63,6 +63,12 @@ } }, "select": { + "collection_point": { + "name": "Go to collection point", + "state": { + "select_collection_point": "Select a collection point…" + } + }, "device_volume": { "name": "Volume", "state": { diff --git a/tests/components/imou/const.py b/tests/components/imou/const.py index 61ad42ee5b95..d9b27a1d5eba 100644 --- a/tests/components/imou/const.py +++ b/tests/components/imou/const.py @@ -2,6 +2,8 @@ from pyimouapi.const import ( PARAM_BATTERY, + PARAM_COLLECTION_POINT, + PARAM_COLLECTION_POINT_PROMPT, PARAM_CURRENT_OPTION, PARAM_DEVICE_VOLUME, PARAM_MOTION_DETECT, @@ -63,6 +65,14 @@ DEFAULT_SELECTS = { PARAM_CURRENT_OPTION: "medium", PARAM_OPTIONS: ["mute", "low", "medium", "high"], }, + PARAM_COLLECTION_POINT: { + PARAM_CURRENT_OPTION: PARAM_COLLECTION_POINT_PROMPT, + PARAM_OPTIONS: [ + PARAM_COLLECTION_POINT_PROMPT, + "Front door", + "Back yard", + ], + }, } DEFAULT_SWITCHES = { diff --git a/tests/components/imou/snapshots/test_select.ambr b/tests/components/imou/snapshots/test_select.ambr index 2f33b5572814..d547ae59a998 100644 --- a/tests/components/imou/snapshots/test_select.ambr +++ b/tests/components/imou/snapshots/test_select.ambr @@ -1,4 +1,65 @@ # serializer version: 1 +# name: test_select_entities_snapshot[select_mock_devices-platforms0][select.device_1_go_to_collection_point-entry] + EntityRegistryEntrySnapshot({ + 'aliases': list([ + None, + ]), + 'area_id': None, + 'capabilities': dict({ + : list([ + 'select_collection_point', + 'Front door', + 'Back yard', + ]), + }), + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'select', + 'entity_category': None, + 'entity_id': 'select.device_1_go_to_collection_point', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'object_id_base': 'Go to collection point', + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Go to collection point', + 'platform': 'imou', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'collection_point', + 'unique_id': 'd1$collection_point', + 'unit_of_measurement': None, + }) +# --- +# name: test_select_entities_snapshot[select_mock_devices-platforms0][select.device_1_go_to_collection_point-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + : 'Device 1 Go to collection point', + : list([ + 'select_collection_point', + 'Front door', + 'Back yard', + ]), + }), + 'context': , + 'entity_id': 'select.device_1_go_to_collection_point', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'select_collection_point', + }) +# --- # name: test_select_entities_snapshot[select_mock_devices-platforms0][select.device_1_night_vision_mode-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ diff --git a/tests/components/imou/test_select.py b/tests/components/imou/test_select.py index 25cc64c27567..922f5d1008cc 100644 --- a/tests/components/imou/test_select.py +++ b/tests/components/imou/test_select.py @@ -4,6 +4,8 @@ from unittest.mock import MagicMock from freezegun.api import FrozenDateTimeFactory from pyimouapi.const import ( + PARAM_COLLECTION_POINT, + PARAM_COLLECTION_POINT_PROMPT, PARAM_CURRENT_OPTION, PARAM_DEVICE_VOLUME, PARAM_NIGHT_VISION_MODE, @@ -88,40 +90,59 @@ async def test_setup_ignores_unknown_select_types( @pytest.mark.parametrize("platforms", [[Platform.SELECT]], indirect=True) @pytest.mark.parametrize("imou_mock_devices", [select_mock_devices], indirect=True) +@pytest.mark.parametrize( + ("unique_id", "option", "select_type", "expected_state"), + [ + pytest.param( + "d1$device_volume", "high", PARAM_DEVICE_VOLUME, "high", id="volume" + ), + pytest.param( + f"d1${PARAM_COLLECTION_POINT}", + "Front door", + PARAM_COLLECTION_POINT, + PARAM_COLLECTION_POINT_PROMPT, + id="collection_point", + ), + ], +) @pytest.mark.usefixtures("init_integration") async def test_select_option_via_domain_service( hass: HomeAssistant, entity_registry: er.EntityRegistry, mock_config_entry: MockConfigEntry, mock_imou_ha_device_manager: MagicMock, + unique_id: str, + option: str, + select_type: str, + expected_state: str, ) -> None: """Selecting an option calls the vendor library through the coordinator.""" async def _side_effect(device: ImouHaDevice, select_type: str, option: str) -> None: - device.selects[select_type][PARAM_CURRENT_OPTION] = option + device.selects[select_type][PARAM_CURRENT_OPTION] = expected_state mock_imou_ha_device_manager.async_select_option.side_effect = _side_effect - volume_entry = next( + select_entry = next( entry for entry in er.async_entries_for_config_entry( entity_registry, mock_config_entry.entry_id ) - if entry.unique_id == "d1$device_volume" + if entry.unique_id == unique_id ) await hass.services.async_call( SELECT_DOMAIN, SERVICE_SELECT_OPTION, - {ATTR_ENTITY_ID: volume_entry.entity_id, ATTR_OPTION: "high"}, + {ATTR_ENTITY_ID: select_entry.entity_id, ATTR_OPTION: option}, blocking=True, ) mock_imou_ha_device_manager.async_select_option.assert_awaited_once() call = mock_imou_ha_device_manager.async_select_option.await_args assert call is not None - assert call.args[1] == PARAM_DEVICE_VOLUME - assert call.args[2] == "high" - assert hass.states.get(volume_entry.entity_id).state == "high" + assert call.args[1] == select_type + assert call.args[2] == option + assert hass.states.get(select_entry.entity_id).state == expected_state @pytest.mark.parametrize("platforms", [[Platform.SELECT]], indirect=True)