mirror of
https://github.com/home-assistant/core.git
synced 2026-09-24 23:41:48 -05:00
Add Imou collection point select entity (#181251)
Co-authored-by: Erwin Douna <e.douna@gmail.com>
This commit is contained in:
co-authored by
Erwin Douna
parent
f6fe0d0aaf
commit
da29e2de4a
@@ -15,6 +15,9 @@
|
||||
}
|
||||
},
|
||||
"select": {
|
||||
"collection_point": {
|
||||
"default": "mdi:crosshairs-gps"
|
||||
},
|
||||
"device_volume": {
|
||||
"default": "mdi:volume-high",
|
||||
"state": {
|
||||
|
||||
@@ -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,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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({
|
||||
<SelectEntityCapabilityAttribute.OPTIONS: 'options'>: list([
|
||||
'select_collection_point',
|
||||
'Front door',
|
||||
'Back yard',
|
||||
]),
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'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': <ANY>,
|
||||
'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({
|
||||
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Device 1 Go to collection point',
|
||||
<SelectEntityCapabilityAttribute.OPTIONS: 'options'>: list([
|
||||
'select_collection_point',
|
||||
'Front door',
|
||||
'Back yard',
|
||||
]),
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'select.device_1_go_to_collection_point',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'select_collection_point',
|
||||
})
|
||||
# ---
|
||||
# name: test_select_entities_snapshot[select_mock_devices-platforms0][select.device_1_night_vision_mode-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user