From 5f88354cb329836c03ba6ed0460462e1ce47d04b Mon Sep 17 00:00:00 2001 From: Dan Raper Date: Wed, 5 Mar 2025 09:59:47 +0000 Subject: [PATCH] Add vehicle select to Ohme (#139795) * Add vehicle select to Ohme * mypy fixes * Update homeassistant/components/ohme/select.py Co-authored-by: Josef Zweck --------- Co-authored-by: Josef Zweck --- homeassistant/components/ohme/icons.json | 3 + homeassistant/components/ohme/select.py | 30 +++++++++- homeassistant/components/ohme/strings.json | 3 + tests/components/ohme/conftest.py | 2 + .../ohme/snapshots/test_select.ambr | 56 +++++++++++++++++++ 5 files changed, 91 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/ohme/icons.json b/homeassistant/components/ohme/icons.json index 9771b0bf5c2..0e4d58a5294 100644 --- a/homeassistant/components/ohme/icons.json +++ b/homeassistant/components/ohme/icons.json @@ -16,6 +16,9 @@ "select": { "charge_mode": { "default": "mdi:play-box" + }, + "vehicle": { + "default": "mdi:car" } }, "sensor": { diff --git a/homeassistant/components/ohme/select.py b/homeassistant/components/ohme/select.py index 17cc7c67e9a..f065afeb176 100644 --- a/homeassistant/components/ohme/select.py +++ b/homeassistant/components/ohme/select.py @@ -25,10 +25,12 @@ class OhmeSelectDescription(OhmeEntityDescription, SelectEntityDescription): """Class to describe an Ohme select entity.""" select_fn: Callable[[OhmeApiClient, Any], Awaitable[None]] + options: list[str] | None = None + options_fn: Callable[[OhmeApiClient], list[str]] | None = None current_option_fn: Callable[[OhmeApiClient], str | None] -SELECT_DESCRIPTION: Final[OhmeSelectDescription] = OhmeSelectDescription( +MODE_SELECT_DESCRIPTION: Final[OhmeSelectDescription] = OhmeSelectDescription( key="charge_mode", translation_key="charge_mode", select_fn=lambda client, mode: client.async_set_mode(mode), @@ -37,6 +39,14 @@ SELECT_DESCRIPTION: Final[OhmeSelectDescription] = OhmeSelectDescription( available_fn=lambda client: client.mode is not None, ) +VEHICLE_SELECT_DESCRIPTION: Final[OhmeSelectDescription] = OhmeSelectDescription( + key="vehicle", + translation_key="vehicle", + select_fn=lambda client, selection: client.async_set_vehicle(selection), + options_fn=lambda client: client.vehicles, + current_option_fn=lambda client: client.current_vehicle or None, +) + async def async_setup_entry( hass: HomeAssistant, @@ -44,9 +54,15 @@ async def async_setup_entry( async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Ohme selects.""" - coordinator = config_entry.runtime_data.charge_session_coordinator + charge_sessions_coordinator = config_entry.runtime_data.charge_session_coordinator + device_info_coordinator = config_entry.runtime_data.device_info_coordinator - async_add_entities([OhmeSelect(coordinator, SELECT_DESCRIPTION)]) + async_add_entities( + [ + OhmeSelect(charge_sessions_coordinator, MODE_SELECT_DESCRIPTION), + OhmeSelect(device_info_coordinator, VEHICLE_SELECT_DESCRIPTION), + ] + ) class OhmeSelect(OhmeEntity, SelectEntity): @@ -64,6 +80,14 @@ class OhmeSelect(OhmeEntity, SelectEntity): ) from e await self.coordinator.async_request_refresh() + @property + def options(self) -> list[str]: + """Return a set of selectable options.""" + if self.entity_description.options_fn: + return self.entity_description.options_fn(self.coordinator.client) + assert self.entity_description.options + return self.entity_description.options + @property def current_option(self) -> str | None: """Return the current selected option.""" diff --git a/homeassistant/components/ohme/strings.json b/homeassistant/components/ohme/strings.json index 4c845daa8f0..187e825c159 100644 --- a/homeassistant/components/ohme/strings.json +++ b/homeassistant/components/ohme/strings.json @@ -66,6 +66,9 @@ "max_charge": "Max charge", "paused": "Paused" } + }, + "vehicle": { + "name": "Vehicle" } }, "sensor": { diff --git a/tests/components/ohme/conftest.py b/tests/components/ohme/conftest.py index 01cc668ae32..d05e34d1ed2 100644 --- a/tests/components/ohme/conftest.py +++ b/tests/components/ohme/conftest.py @@ -66,4 +66,6 @@ def mock_client(): "model": "Home Pro", "sw_version": "v2.65", } + client.vehicles = ["Nissan Leaf", "Tesla Model 3"] + client.current_vehicle = "Nissan Leaf" yield client diff --git a/tests/components/ohme/snapshots/test_select.ambr b/tests/components/ohme/snapshots/test_select.ambr index 8eec0556889..063a9616588 100644 --- a/tests/components/ohme/snapshots/test_select.ambr +++ b/tests/components/ohme/snapshots/test_select.ambr @@ -57,3 +57,59 @@ 'state': 'unknown', }) # --- +# name: test_selects[select.ohme_home_pro_vehicle-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'options': list([ + 'Nissan Leaf', + 'Tesla Model 3', + ]), + }), + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'select', + 'entity_category': None, + 'entity_id': 'select.ohme_home_pro_vehicle', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Vehicle', + 'platform': 'ohme', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'vehicle', + 'unique_id': 'chargerid_vehicle', + 'unit_of_measurement': None, + }) +# --- +# name: test_selects[select.ohme_home_pro_vehicle-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Ohme Home Pro Vehicle', + 'options': list([ + 'Nissan Leaf', + 'Tesla Model 3', + ]), + }), + 'context': , + 'entity_id': 'select.ohme_home_pro_vehicle', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'Nissan Leaf', + }) +# ---