SMA: add sensor availability and expand tests (#154953)

This commit is contained in:
Erwin Douna
2025-10-22 08:13:46 +02:00
committed by GitHub
parent 11772dbc46
commit 9e9c8f5724
3 changed files with 82 additions and 5 deletions

View File

@@ -873,6 +873,7 @@ class SMAsensor(CoordinatorEntity[SMADataUpdateCoordinator], SensorEntity):
url = f"{protocol}://{entry.data[CONF_HOST]}"
self._sensor = pysma_sensor
self._serial = coordinator.data.sma_device_info["serial"]
assert entry.unique_id
self._attr_device_info = DeviceInfo(
@@ -902,6 +903,14 @@ class SMAsensor(CoordinatorEntity[SMADataUpdateCoordinator], SensorEntity):
return f"{name_prefix} {super().name}"
@property
def available(self) -> bool:
"""Return if the device is available."""
return (
super().available
and self._serial == self.coordinator.data.sma_device_info["serial"]
)
@property
def native_value(self) -> StateType:
"""Return the state of the sensor."""

View File

@@ -1,12 +1,19 @@
"""Test the sma init file."""
from collections.abc import AsyncGenerator
from collections.abc import AsyncGenerator, Generator
from pysma.exceptions import (
SmaAuthenticationException,
SmaConnectionException,
SmaReadException,
)
import pytest
from homeassistant.components.sma.const import DOMAIN
from homeassistant.config_entries import SOURCE_IMPORT
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntryState
from homeassistant.core import HomeAssistant
from . import MOCK_DEVICE, MOCK_USER_INPUT
from . import MOCK_DEVICE, MOCK_USER_INPUT, setup_integration
from tests.common import MockConfigEntry
@@ -30,3 +37,24 @@ async def test_migrate_entry_minor_version_1_2(
assert entry.version == 1
assert entry.minor_version == 2
assert entry.unique_id == str(MOCK_DEVICE["serial"])
@pytest.mark.parametrize(
("exception", "expected_state"),
[
(SmaConnectionException, ConfigEntryState.SETUP_RETRY),
(SmaAuthenticationException, ConfigEntryState.SETUP_ERROR),
(SmaReadException, ConfigEntryState.SETUP_RETRY),
],
)
async def test_setup_exceptions(
hass: HomeAssistant,
mock_sma_client: Generator,
mock_config_entry: MockConfigEntry,
exception: Exception,
expected_state: ConfigEntryState,
) -> None:
"""Test the _async_setup."""
mock_sma_client.device_info.side_effect = exception
await setup_integration(hass, mock_config_entry)
assert mock_config_entry.state == expected_state

View File

@@ -3,16 +3,25 @@
from collections.abc import Generator
from unittest.mock import patch
from freezegun.api import FrozenDateTimeFactory
from pysma.exceptions import (
SmaAuthenticationException,
SmaConnectionException,
SmaReadException,
)
import pytest
from syrupy.assertion import SnapshotAssertion
from homeassistant.const import Platform
from homeassistant.components.sma.const import DEFAULT_SCAN_INTERVAL
from homeassistant.config_entries import ConfigEntryState
from homeassistant.const import STATE_UNAVAILABLE, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from homeassistant.util import dt as dt_util
from . import setup_integration
from tests.common import MockConfigEntry, snapshot_platform
from tests.common import MockConfigEntry, async_fire_time_changed, snapshot_platform
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
@@ -32,3 +41,34 @@ async def test_all_entities(
await snapshot_platform(
hass, entity_registry, snapshot, mock_config_entry.entry_id
)
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
@pytest.mark.parametrize(
("exception"),
[
(SmaConnectionException),
(SmaAuthenticationException),
(SmaReadException),
(Exception),
],
)
async def test_refresh_exceptions(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_sma_client: Generator,
freezer: FrozenDateTimeFactory,
exception: Exception,
) -> None:
"""Test the coordinator refresh exceptions."""
await setup_integration(hass, mock_config_entry)
assert mock_config_entry.state is ConfigEntryState.LOADED
mock_sma_client.read.side_effect = exception
freezer.tick(DEFAULT_SCAN_INTERVAL)
async_fire_time_changed(hass, dt_util.utcnow())
await hass.async_block_till_done()
state = hass.states.get("sensor.sma_device_name_battery_capacity_a")
assert state.state == STATE_UNAVAILABLE