Handle missing kostal plenticore battery option (#65237)

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
stegm 2022-05-02 11:42:18 +02:00 committed by GitHub
parent 37b59dfcc0
commit 738701a2d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 130 additions and 52 deletions

View File

@ -24,6 +24,8 @@ async def async_setup_entry(
) -> None: ) -> None:
"""Add kostal plenticore Select widget.""" """Add kostal plenticore Select widget."""
plenticore: Plenticore = hass.data[DOMAIN][entry.entry_id] plenticore: Plenticore = hass.data[DOMAIN][entry.entry_id]
available_settings_data = await plenticore.client.get_settings()
select_data_update_coordinator = SelectDataUpdateCoordinator( select_data_update_coordinator = SelectDataUpdateCoordinator(
hass, hass,
_LOGGER, _LOGGER,
@ -32,23 +34,34 @@ async def async_setup_entry(
plenticore, plenticore,
) )
async_add_entities( entities = []
PlenticoreDataSelect( for select in SELECT_SETTINGS_DATA:
select_data_update_coordinator, if select.module_id not in available_settings_data:
entry_id=entry.entry_id, continue
platform_name=entry.title, needed_data_ids = {data_id for data_id in select.options if data_id != "None"}
device_class="kostal_plenticore__battery", available_data_ids = {
module_id=select.module_id, setting.id for setting in available_settings_data[select.module_id]
data_id=select.data_id, }
name=select.name, if not needed_data_ids <= available_data_ids:
current_option="None", continue
options=select.options, entities.append(
is_on=select.is_on, PlenticoreDataSelect(
device_info=plenticore.device_info, select_data_update_coordinator,
unique_id=f"{entry.entry_id}_{select.module_id}", entry_id=entry.entry_id,
platform_name=entry.title,
device_class="kostal_plenticore__battery",
module_id=select.module_id,
data_id=select.data_id,
name=select.name,
current_option="None",
options=select.options,
is_on=select.is_on,
device_info=plenticore.device_info,
unique_id=f"{entry.entry_id}_{select.module_id}",
)
) )
for select in SELECT_SETTINGS_DATA
) async_add_entities(entities)
class PlenticoreDataSelect(CoordinatorEntity, SelectEntity, ABC): class PlenticoreDataSelect(CoordinatorEntity, SelectEntity, ABC):

View File

@ -4,9 +4,10 @@ from __future__ import annotations
from collections.abc import Generator from collections.abc import Generator
from unittest.mock import AsyncMock, MagicMock, patch from unittest.mock import AsyncMock, MagicMock, patch
from kostal.plenticore import MeData, SettingsData, VersionData from kostal.plenticore import MeData, VersionData
import pytest import pytest
from homeassistant.components.kostal_plenticore.helper import Plenticore
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.entity import DeviceInfo
@ -14,10 +15,19 @@ from tests.common import MockConfigEntry
@pytest.fixture @pytest.fixture
async def init_integration( def mock_config_entry() -> MockConfigEntry:
hass: HomeAssistant, """Return a mocked ConfigEntry for testing."""
) -> Generator[None, MockConfigEntry, None]: return MockConfigEntry(
"""Set up Kostal Plenticore integration for testing.""" entry_id="2ab8dd92a62787ddfe213a67e09406bd",
title="scb",
domain="kostal_plenticore",
data={"host": "192.168.1.2", "password": "SecretPassword"},
)
@pytest.fixture
def mock_plenticore() -> Generator[Plenticore, None, None]:
"""Set up a Plenticore mock with some default values."""
with patch( with patch(
"homeassistant.components.kostal_plenticore.Plenticore", autospec=True "homeassistant.components.kostal_plenticore.Plenticore", autospec=True
) as mock_api_class: ) as mock_api_class:
@ -60,37 +70,20 @@ async def init_integration(
) )
plenticore.client.get_process_data = AsyncMock() plenticore.client.get_process_data = AsyncMock()
plenticore.client.get_process_data.return_value = {
"devices:local": ["HomeGrid_P", "HomePv_P"]
}
plenticore.client.get_settings = AsyncMock() plenticore.client.get_settings = AsyncMock()
plenticore.client.get_settings.return_value = {
"devices:local": [
SettingsData(
{
"id": "Battery:MinSoc",
"unit": "%",
"default": "None",
"min": 5,
"max": 100,
"type": "byte",
"access": "readwrite",
}
)
]
}
mock_config_entry = MockConfigEntry( yield plenticore
entry_id="2ab8dd92a62787ddfe213a67e09406bd",
title="scb",
domain="kostal_plenticore",
data={"host": "192.168.1.2", "password": "SecretPassword"},
)
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id) @pytest.fixture
await hass.async_block_till_done() async def init_integration(
hass: HomeAssistant, mock_config_entry: MockConfigEntry
) -> MockConfigEntry:
"""Set up Kostal Plenticore integration for testing."""
yield mock_config_entry mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
return mock_config_entry

View File

@ -1,7 +1,9 @@
"""Test Kostal Plenticore diagnostics.""" """Test Kostal Plenticore diagnostics."""
from aiohttp import ClientSession from aiohttp import ClientSession
from kostal.plenticore import SettingsData
from homeassistant.components.diagnostics import REDACTED from homeassistant.components.diagnostics import REDACTED
from homeassistant.components.kostal_plenticore.helper import Plenticore
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from tests.common import MockConfigEntry from tests.common import MockConfigEntry
@ -9,9 +11,34 @@ from tests.components.diagnostics import get_diagnostics_for_config_entry
async def test_entry_diagnostics( async def test_entry_diagnostics(
hass: HomeAssistant, hass_client: ClientSession, init_integration: MockConfigEntry hass: HomeAssistant,
): hass_client: ClientSession,
mock_plenticore: Plenticore,
init_integration: MockConfigEntry,
) -> None:
"""Test config entry diagnostics.""" """Test config entry diagnostics."""
# set some test process and settings data for the diagnostics output
mock_plenticore.client.get_process_data.return_value = {
"devices:local": ["HomeGrid_P", "HomePv_P"]
}
mock_plenticore.client.get_settings.return_value = {
"devices:local": [
SettingsData(
{
"id": "Battery:MinSoc",
"unit": "%",
"default": "None",
"min": 5,
"max": 100,
"type": "byte",
"access": "readwrite",
}
)
]
}
assert await get_diagnostics_for_config_entry( assert await get_diagnostics_for_config_entry(
hass, hass_client, init_integration hass, hass_client, init_integration
) == { ) == {

View File

@ -0,0 +1,45 @@
"""Test the Kostal Plenticore Solar Inverter select platform."""
from kostal.plenticore import SettingsData
from homeassistant.components.kostal_plenticore.helper import Plenticore
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry
from tests.common import MockConfigEntry
async def test_select_battery_charging_usage_available(
hass: HomeAssistant, mock_plenticore: Plenticore, mock_config_entry: MockConfigEntry
) -> None:
"""Test that the battery charging usage select entity is added if the settings are available."""
mock_plenticore.client.get_settings.return_value = {
"devices:local": [
SettingsData({"id": "Battery:SmartBatteryControl:Enable"}),
SettingsData({"id": "Battery:TimeControl:Enable"}),
]
}
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
assert entity_registry.async_get(hass).async_is_registered(
"select.battery_charging_usage_mode"
)
async def test_select_battery_charging_usage_not_available(
hass: HomeAssistant, mock_plenticore: Plenticore, mock_config_entry: MockConfigEntry
) -> None:
"""Test that the battery charging usage select entity is not added if the settings are unavailable."""
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
assert not entity_registry.async_get(hass).async_is_registered(
"select.battery_charging_usage_mode"
)