mirror of
https://github.com/home-assistant/core.git
synced 2025-08-05 05:35:11 +02:00
WolfllinkSensorEntityDescriptions and updated tests
This commit is contained in:
@@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Callable
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
from wolf_comm.models import (
|
from wolf_comm.models import (
|
||||||
EnergyParameter,
|
EnergyParameter,
|
||||||
HoursParameter,
|
HoursParameter,
|
||||||
@@ -10,6 +13,7 @@ from wolf_comm.models import (
|
|||||||
PercentageParameter,
|
PercentageParameter,
|
||||||
PowerParameter,
|
PowerParameter,
|
||||||
Pressure,
|
Pressure,
|
||||||
|
SimpleParameter,
|
||||||
Temperature,
|
Temperature,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -55,70 +59,95 @@ async def async_setup_entry(
|
|||||||
async_add_entities(entities, True)
|
async_add_entities(entities, True)
|
||||||
|
|
||||||
|
|
||||||
def get_entity_description(parameter: Parameter) -> SensorEntityDescription:
|
@dataclass(kw_only=True, frozen=True)
|
||||||
"""Return the entity description for a given parameter."""
|
class WolflinkSensorEntityDescription(SensorEntityDescription):
|
||||||
if isinstance(parameter, Temperature):
|
"""Describes Wolflink sensor entity."""
|
||||||
return SensorEntityDescription(
|
|
||||||
key=parameter.parameter_id,
|
supported_fn: Callable[[Parameter], bool]
|
||||||
name=parameter.name,
|
|
||||||
|
|
||||||
|
SENSOR_DESCRIPTIONS = [
|
||||||
|
WolflinkSensorEntityDescription(
|
||||||
|
key="temperature",
|
||||||
device_class=SensorDeviceClass.TEMPERATURE,
|
device_class=SensorDeviceClass.TEMPERATURE,
|
||||||
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||||
)
|
supported_fn=lambda param: isinstance(param, Temperature),
|
||||||
if isinstance(parameter, Pressure):
|
),
|
||||||
return SensorEntityDescription(
|
WolflinkSensorEntityDescription(
|
||||||
key=parameter.parameter_id,
|
key="pressure",
|
||||||
name=parameter.name,
|
|
||||||
device_class=SensorDeviceClass.PRESSURE,
|
device_class=SensorDeviceClass.PRESSURE,
|
||||||
native_unit_of_measurement=UnitOfPressure.BAR,
|
native_unit_of_measurement=UnitOfPressure.BAR,
|
||||||
)
|
supported_fn=lambda param: isinstance(param, Pressure),
|
||||||
if isinstance(parameter, EnergyParameter):
|
),
|
||||||
return SensorEntityDescription(
|
WolflinkSensorEntityDescription(
|
||||||
key=parameter.parameter_id,
|
key="energy",
|
||||||
name=parameter.name,
|
|
||||||
device_class=SensorDeviceClass.ENERGY,
|
device_class=SensorDeviceClass.ENERGY,
|
||||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||||
)
|
supported_fn=lambda param: isinstance(param, EnergyParameter),
|
||||||
if isinstance(parameter, PowerParameter):
|
),
|
||||||
return SensorEntityDescription(
|
WolflinkSensorEntityDescription(
|
||||||
key=parameter.parameter_id,
|
key="power",
|
||||||
name=parameter.name,
|
|
||||||
device_class=SensorDeviceClass.POWER,
|
device_class=SensorDeviceClass.POWER,
|
||||||
native_unit_of_measurement=UnitOfPower.KILO_WATT,
|
native_unit_of_measurement=UnitOfPower.KILO_WATT,
|
||||||
)
|
supported_fn=lambda param: isinstance(param, PowerParameter),
|
||||||
if isinstance(parameter, PercentageParameter):
|
),
|
||||||
return SensorEntityDescription(
|
WolflinkSensorEntityDescription(
|
||||||
key=parameter.parameter_id,
|
key="percentage",
|
||||||
name=parameter.name,
|
|
||||||
native_unit_of_measurement=PERCENTAGE,
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
)
|
supported_fn=lambda param: isinstance(param, PercentageParameter),
|
||||||
if isinstance(parameter, ListItemParameter):
|
),
|
||||||
return SensorEntityDescription(
|
WolflinkSensorEntityDescription(
|
||||||
key=parameter.parameter_id,
|
key="list_item",
|
||||||
name=parameter.name,
|
|
||||||
translation_key="state",
|
translation_key="state",
|
||||||
)
|
supported_fn=lambda param: isinstance(param, ListItemParameter),
|
||||||
if isinstance(parameter, HoursParameter):
|
),
|
||||||
return SensorEntityDescription(
|
WolflinkSensorEntityDescription(
|
||||||
key=parameter.parameter_id,
|
key="hours",
|
||||||
name=parameter.name,
|
|
||||||
icon="mdi:clock",
|
icon="mdi:clock",
|
||||||
native_unit_of_measurement=UnitOfTime.HOURS,
|
native_unit_of_measurement=UnitOfTime.HOURS,
|
||||||
)
|
supported_fn=lambda param: isinstance(param, HoursParameter),
|
||||||
return SensorEntityDescription(
|
),
|
||||||
|
WolflinkSensorEntityDescription(
|
||||||
|
key="default",
|
||||||
|
supported_fn=lambda param: isinstance(param, SimpleParameter),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def get_entity_description(parameter: Parameter) -> WolflinkSensorEntityDescription:
|
||||||
|
"""Return the entity description for a given parameter."""
|
||||||
|
for description in SENSOR_DESCRIPTIONS:
|
||||||
|
if description.supported_fn(parameter):
|
||||||
|
return WolflinkSensorEntityDescription(
|
||||||
key=parameter.parameter_id,
|
key=parameter.parameter_id,
|
||||||
name=parameter.name,
|
name=parameter.name,
|
||||||
|
device_class=description.device_class,
|
||||||
|
native_unit_of_measurement=description.native_unit_of_measurement,
|
||||||
|
icon=description.icon,
|
||||||
|
entity_registry_enabled_default=description.entity_registry_enabled_default,
|
||||||
|
entity_category=description.entity_category,
|
||||||
|
has_entity_name=description.has_entity_name,
|
||||||
|
translation_key=description.translation_key,
|
||||||
|
supported_fn=description.supported_fn,
|
||||||
|
)
|
||||||
|
return WolflinkSensorEntityDescription(
|
||||||
|
key=parameter.parameter_id,
|
||||||
|
name=parameter.name,
|
||||||
|
supported_fn=lambda param: True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class WolfLinkSensor(CoordinatorEntity, SensorEntity):
|
class WolfLinkSensor(CoordinatorEntity, SensorEntity):
|
||||||
"""Base class for all Wolf entities."""
|
"""Base class for all Wolf entities."""
|
||||||
|
|
||||||
|
entity_description: WolflinkSensorEntityDescription
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
coordinator,
|
coordinator,
|
||||||
wolf_object: Parameter,
|
wolf_object: Parameter,
|
||||||
device_id: str,
|
device_id: str,
|
||||||
description: SensorEntityDescription,
|
description: WolflinkSensorEntityDescription,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize."""
|
"""Initialize."""
|
||||||
super().__init__(coordinator)
|
super().__init__(coordinator)
|
||||||
@@ -162,10 +191,3 @@ class WolfLinkSensor(CoordinatorEntity, SensorEntity):
|
|||||||
"value_id": self.wolf_object.value_id,
|
"value_id": self.wolf_object.value_id,
|
||||||
"parent": self.wolf_object.parent,
|
"parent": self.wolf_object.parent,
|
||||||
}
|
}
|
||||||
|
|
||||||
@property
|
|
||||||
def native_unit_of_measurement(self) -> str | None:
|
|
||||||
"""Return the unit the value is expressed in."""
|
|
||||||
if isinstance(self.wolf_object, PercentageParameter):
|
|
||||||
return self.wolf_object.unit
|
|
||||||
return self.entity_description.native_unit_of_measurement
|
|
||||||
|
@@ -1,16 +1,18 @@
|
|||||||
"""Test the Wolf SmartSet Service Sensor platform."""
|
"""Test the Wolf SmartSet Service Sensor platform."""
|
||||||
|
|
||||||
from unittest.mock import MagicMock
|
from unittest.mock import MagicMock, Mock
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from wolf_comm import (
|
from wolf_comm import (
|
||||||
PERCENTAGE,
|
PERCENTAGE,
|
||||||
EnergyParameter,
|
EnergyParameter,
|
||||||
HoursParameter,
|
HoursParameter,
|
||||||
|
ListItemParameter,
|
||||||
Parameter,
|
Parameter,
|
||||||
PercentageParameter,
|
PercentageParameter,
|
||||||
PowerParameter,
|
PowerParameter,
|
||||||
Pressure,
|
Pressure,
|
||||||
|
SimpleParameter,
|
||||||
Temperature,
|
Temperature,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -21,7 +23,11 @@ from homeassistant.components.wolflink.const import (
|
|||||||
MANUFACTURER,
|
MANUFACTURER,
|
||||||
PARAMETERS,
|
PARAMETERS,
|
||||||
)
|
)
|
||||||
from homeassistant.components.wolflink.sensor import WolfLinkSensor, async_setup_entry
|
from homeassistant.components.wolflink.sensor import (
|
||||||
|
WolfLinkSensor,
|
||||||
|
async_setup_entry,
|
||||||
|
get_entity_description,
|
||||||
|
)
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
UnitOfEnergy,
|
UnitOfEnergy,
|
||||||
UnitOfPower,
|
UnitOfPower,
|
||||||
@@ -34,7 +40,7 @@ from homeassistant.helpers import device_registry as dr
|
|||||||
|
|
||||||
from .const import CONFIG
|
from .const import CONFIG
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import Literal, MockConfigEntry
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
@@ -46,6 +52,18 @@ def mock_coordinator(hass: HomeAssistant) -> MagicMock:
|
|||||||
return coordinator
|
return coordinator
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mock_device_id():
|
||||||
|
"""Fixture for a mock device ID."""
|
||||||
|
return "1234"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mock_parameter():
|
||||||
|
"""Fixture for a mock parameter."""
|
||||||
|
return Mock(spec=Parameter)
|
||||||
|
|
||||||
|
|
||||||
async def mock_config_entry(
|
async def mock_config_entry(
|
||||||
hass: HomeAssistant, device_registry: dr.DeviceRegistry
|
hass: HomeAssistant, device_registry: dr.DeviceRegistry
|
||||||
) -> None:
|
) -> None:
|
||||||
@@ -55,13 +73,9 @@ async def mock_config_entry(
|
|||||||
)
|
)
|
||||||
config_entry.add_to_hass(hass)
|
config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
device_id = device_registry.async_get_or_create(
|
device = device_registry.async_get_device({(DOMAIN, CONFIG[DEVICE_ID])})
|
||||||
config_entry_id=config_entry.entry_id,
|
assert device is not None
|
||||||
identifiers={(DOMAIN, CONFIG[DEVICE_ID])},
|
assert device.identifiers == {(DOMAIN, CONFIG[DEVICE_ID])}
|
||||||
configuration_url="https://www.wolf-smartset.com/",
|
|
||||||
manufacturer=MANUFACTURER,
|
|
||||||
).id
|
|
||||||
assert device_registry.async_get(device_id).identifiers == {(DOMAIN, "1234")}
|
|
||||||
|
|
||||||
|
|
||||||
def test_wolflink_sensor_native_value(mock_coordinator: MagicMock) -> None:
|
def test_wolflink_sensor_native_value(mock_coordinator: MagicMock) -> None:
|
||||||
@@ -117,7 +131,7 @@ async def test_async_setup_entry(
|
|||||||
hass.data.setdefault(DOMAIN, {})[config_entry.entry_id] = {
|
hass.data.setdefault(DOMAIN, {})[config_entry.entry_id] = {
|
||||||
PARAMETERS: [parameter],
|
PARAMETERS: [parameter],
|
||||||
COORDINATOR: mock_coordinator,
|
COORDINATOR: mock_coordinator,
|
||||||
DEVICE_ID: "mock_device_id",
|
DEVICE_ID: "1234",
|
||||||
}
|
}
|
||||||
async_add_entities = MagicMock()
|
async_add_entities = MagicMock()
|
||||||
|
|
||||||
@@ -129,3 +143,74 @@ async def test_async_setup_entry(
|
|||||||
entity = entities[0]
|
entity = entities[0]
|
||||||
assert isinstance(entity, expected_class)
|
assert isinstance(entity, expected_class)
|
||||||
assert entity.native_unit_of_measurement == expected_unit
|
assert entity.native_unit_of_measurement == expected_unit
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_entity_description() -> None:
|
||||||
|
"""Test the get_entity_description function."""
|
||||||
|
parameter = Mock(spec=Temperature)
|
||||||
|
description = get_entity_description(parameter)
|
||||||
|
assert description.device_class == "temperature"
|
||||||
|
assert description.native_unit_of_measurement == "°C"
|
||||||
|
|
||||||
|
parameter = Mock(spec=Pressure)
|
||||||
|
description = get_entity_description(parameter)
|
||||||
|
assert description.device_class == "pressure"
|
||||||
|
assert description.native_unit_of_measurement == "bar"
|
||||||
|
|
||||||
|
parameter = Mock(spec=EnergyParameter)
|
||||||
|
description = get_entity_description(parameter)
|
||||||
|
assert description.device_class == "energy"
|
||||||
|
assert description.native_unit_of_measurement == "kWh"
|
||||||
|
|
||||||
|
parameter = Mock(spec=PowerParameter)
|
||||||
|
description = get_entity_description(parameter)
|
||||||
|
assert description.device_class == "power"
|
||||||
|
assert description.native_unit_of_measurement == "kW"
|
||||||
|
|
||||||
|
parameter = Mock(spec=PercentageParameter)
|
||||||
|
description = get_entity_description(parameter)
|
||||||
|
assert description.native_unit_of_measurement == PERCENTAGE
|
||||||
|
|
||||||
|
parameter = Mock(spec=ListItemParameter)
|
||||||
|
description = get_entity_description(parameter)
|
||||||
|
assert description.translation_key == "state"
|
||||||
|
|
||||||
|
parameter = Mock(spec=HoursParameter)
|
||||||
|
description = get_entity_description(parameter)
|
||||||
|
assert description.native_unit_of_measurement == UnitOfTime.HOURS
|
||||||
|
assert description.icon == "mdi:clock"
|
||||||
|
|
||||||
|
parameter = Mock(spec=SimpleParameter)
|
||||||
|
description = get_entity_description(parameter)
|
||||||
|
|
||||||
|
|
||||||
|
def test_wolflink_sensor(
|
||||||
|
mock_coordinator, mock_device_id: Literal["1234"], mock_parameter
|
||||||
|
) -> None:
|
||||||
|
"""Test the WolfLinkSensor class."""
|
||||||
|
description = get_entity_description(mock_parameter)
|
||||||
|
sensor = WolfLinkSensor(
|
||||||
|
mock_coordinator, mock_parameter, mock_device_id, description
|
||||||
|
)
|
||||||
|
|
||||||
|
assert sensor.entity_description == description
|
||||||
|
assert sensor.wolf_object == mock_parameter
|
||||||
|
assert sensor._attr_name == description.name
|
||||||
|
assert sensor._attr_unique_id == f"{mock_device_id}:{mock_parameter.parameter_id}"
|
||||||
|
assert sensor._attr_device_info["identifiers"] == {(DOMAIN, str(mock_device_id))}
|
||||||
|
assert (
|
||||||
|
sensor._attr_device_info["configuration_url"]
|
||||||
|
== "https://www.wolf-smartset.com/"
|
||||||
|
)
|
||||||
|
assert sensor._attr_device_info["manufacturer"] == MANUFACTURER
|
||||||
|
|
||||||
|
# Test native_value property
|
||||||
|
mock_coordinator.data = {mock_parameter.parameter_id: ("value_id", "state")}
|
||||||
|
assert sensor.native_value == "state"
|
||||||
|
|
||||||
|
# Test extra_state_attributes property
|
||||||
|
assert sensor.extra_state_attributes == {
|
||||||
|
"parameter_id": mock_parameter.parameter_id,
|
||||||
|
"value_id": mock_parameter.value_id,
|
||||||
|
"parent": mock_parameter.parent,
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user