Additional sensor for Weheat integration (#125524)

* Added additional sensor to Weheat

* Added tests for old and new sensors

* Added energy sensor

* Changed tests to use snapshot

* Removed unused value and regenerated the ambr

* Apply suggestions from code review

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

* changed DHW sensor creation

* Wrapped lambda function

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
This commit is contained in:
jesperraemaekers 2024-09-14 12:01:04 +02:00 committed by GitHub
parent 9eb3d84715
commit e92d9317aa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 974 additions and 12 deletions

View File

@ -23,3 +23,4 @@ LOGGER: Logger = getLogger(__package__)
DISPLAY_PRECISION_WATTS = 0
DISPLAY_PRECISION_COP = 1
DISPLAY_PRECISION_WATER_TEMP = 1

View File

@ -46,27 +46,27 @@ class WeheatDataUpdateCoordinator(DataUpdateCoordinator[HeatPump]):
name=DOMAIN,
update_interval=timedelta(seconds=UPDATE_INTERVAL),
)
self._heat_pump_info = heat_pump
self._heat_pump_data = HeatPump(API_URL, self._heat_pump_info.uuid)
self.heat_pump_info = heat_pump
self._heat_pump_data = HeatPump(API_URL, heat_pump.uuid)
self.session = session
@property
def heatpump_id(self) -> str:
"""Return the heat pump id."""
return self._heat_pump_info.uuid
return self.heat_pump_info.uuid
@property
def readable_name(self) -> str | None:
"""Return the readable name of the heat pump."""
if self._heat_pump_info.name:
return self._heat_pump_info.name
return self._heat_pump_info.model
if self.heat_pump_info.name:
return self.heat_pump_info.name
return self.heat_pump_info.model
@property
def model(self) -> str:
"""Return the model of the heat pump."""
return self._heat_pump_info.model
return self.heat_pump_info.model
def fetch_data(self) -> HeatPump:
"""Get the data from the API."""

View File

@ -9,6 +9,30 @@
},
"cop": {
"default": "mdi:speedometer"
},
"water_inlet_temperature": {
"default": "mdi:thermometer"
},
"water_outlet_temperature": {
"default": "mdi:thermometer"
},
"ch_inlet_temperature": {
"default": "mdi:radiator"
},
"outside_temperature": {
"default": "mdi:home-thermometer-outline"
},
"dhw_top_temperature": {
"default": "mdi:thermometer"
},
"dhw_bottom_temperature": {
"default": "mdi:thermometer"
},
"heat_pump_state": {
"default": "mdi:state-machine"
},
"electricity_used": {
"default": "mdi:flash"
}
}
}

View File

@ -11,13 +11,17 @@ from homeassistant.components.sensor import (
SensorEntityDescription,
SensorStateClass,
)
from homeassistant.const import UnitOfPower
from homeassistant.const import UnitOfEnergy, UnitOfPower, UnitOfTemperature
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType
from . import WeheatConfigEntry
from .const import DISPLAY_PRECISION_COP, DISPLAY_PRECISION_WATTS
from .const import (
DISPLAY_PRECISION_COP,
DISPLAY_PRECISION_WATER_TEMP,
DISPLAY_PRECISION_WATTS,
)
from .coordinator import WeheatDataUpdateCoordinator
from .entity import WeheatEntity
@ -55,6 +59,84 @@ SENSORS = [
suggested_display_precision=DISPLAY_PRECISION_COP,
value_fn=lambda status: status.cop,
),
WeHeatSensorEntityDescription(
translation_key="water_inlet_temperature",
key="water_inlet_temperature",
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
device_class=SensorDeviceClass.TEMPERATURE,
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=DISPLAY_PRECISION_WATER_TEMP,
value_fn=lambda status: status.water_inlet_temperature,
),
WeHeatSensorEntityDescription(
translation_key="water_outlet_temperature",
key="water_outlet_temperature",
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
device_class=SensorDeviceClass.TEMPERATURE,
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=DISPLAY_PRECISION_WATER_TEMP,
value_fn=lambda status: status.water_outlet_temperature,
),
WeHeatSensorEntityDescription(
translation_key="ch_inlet_temperature",
key="ch_inlet_temperature",
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
device_class=SensorDeviceClass.TEMPERATURE,
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=DISPLAY_PRECISION_WATER_TEMP,
value_fn=lambda status: status.water_house_in_temperature,
),
WeHeatSensorEntityDescription(
translation_key="outside_temperature",
key="outside_temperature",
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
device_class=SensorDeviceClass.TEMPERATURE,
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=DISPLAY_PRECISION_WATER_TEMP,
value_fn=lambda status: status.air_inlet_temperature,
),
WeHeatSensorEntityDescription(
translation_key="heat_pump_state",
key="heat_pump_state",
name=None,
device_class=SensorDeviceClass.ENUM,
options=[s.name.lower() for s in HeatPump.State],
value_fn=(
lambda status: status.heat_pump_state.name.lower()
if status.heat_pump_state
else None
),
),
WeHeatSensorEntityDescription(
translation_key="electricity_used",
key="electricity_used",
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
device_class=SensorDeviceClass.ENERGY,
state_class=SensorStateClass.TOTAL_INCREASING,
value_fn=lambda status: status.energy_total,
),
]
DHW_SENSORS = [
WeHeatSensorEntityDescription(
translation_key="dhw_top_temperature",
key="dhw_top_temperature",
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
device_class=SensorDeviceClass.TEMPERATURE,
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=DISPLAY_PRECISION_WATER_TEMP,
value_fn=lambda status: status.dhw_top_temperature,
),
WeHeatSensorEntityDescription(
translation_key="dhw_bottom_temperature",
key="dhw_bottom_temperature",
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
device_class=SensorDeviceClass.TEMPERATURE,
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=DISPLAY_PRECISION_WATER_TEMP,
value_fn=lambda status: status.dhw_bottom_temperature,
),
]
@ -64,12 +146,20 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the sensors for weheat heat pump."""
async_add_entities(
entities = [
WeheatHeatPumpSensor(coordinator, entity_description)
for entity_description in SENSORS
for coordinator in entry.runtime_data
]
entities.extend(
WeheatHeatPumpSensor(coordinator, entity_description)
for entity_description in DHW_SENSORS
for coordinator in entry.runtime_data
if coordinator.heat_pump_info.has_dhw
)
async_add_entities(entities)
class WeheatHeatPumpSensor(WeheatEntity, SensorEntity):
"""Defines a Weheat heat pump sensor."""

View File

@ -40,6 +40,40 @@
},
"cop": {
"name": "COP"
},
"water_inlet_temperature": {
"name": "Water inlet temperature"
},
"water_outlet_temperature": {
"name": "Water outlet temperature"
},
"ch_inlet_temperature": {
"name": "Central heating inlet temperature"
},
"outside_temperature": {
"name": "Outside temperature"
},
"dhw_top_temperature": {
"name": "DHW top temperature"
},
"dhw_bottom_temperature": {
"name": "DHW bottom temperature"
},
"heat_pump_state": {
"state": {
"standby": "[%key:common::state::standby%]",
"water_check": "Checking water temperature",
"heating": "Heating",
"cooling": "Cooling",
"dhw": "Heating DHW",
"legionella_prevention": "Legionella prevention",
"defrosting": "Defrosting",
"self_test": "Self test",
"manual_control": "Manual control"
}
},
"electricity_used": {
"name": "Electricity used"
}
}
}

View File

@ -1 +1,13 @@
"""Tests for the Weheat integration."""
from homeassistant.core import HomeAssistant
from tests.common import MockConfigEntry
async def setup_integration(hass: HomeAssistant, config_entry: MockConfigEntry) -> None:
"""Fixture for setting up the component."""
config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()

View File

@ -1,8 +1,12 @@
"""Fixtures for Weheat tests."""
from unittest.mock import patch
from collections.abc import Generator
from time import time
from unittest.mock import AsyncMock, MagicMock, patch
import pytest
from weheat.abstractions.discovery import HeatPumpDiscovery
from weheat.abstractions.heat_pump import HeatPump
from homeassistant.components.application_credentials import (
DOMAIN as APPLICATION_CREDENTIALS,
@ -13,7 +17,9 @@ from homeassistant.components.weheat.const import DOMAIN
from homeassistant.core import HomeAssistant
from homeassistant.setup import async_setup_component
from .const import CLIENT_ID, CLIENT_SECRET
from .const import CLIENT_ID, CLIENT_SECRET, TEST_HP_UUID, TEST_MODEL, TEST_SN
from tests.common import MockConfigEntry
@pytest.fixture(autouse=True)
@ -34,3 +40,77 @@ def mock_setup_entry():
"homeassistant.components.weheat.async_setup_entry", return_value=True
) as mock_setup:
yield mock_setup
@pytest.fixture
def mock_heat_pump_info() -> HeatPumpDiscovery.HeatPumpInfo:
"""Create a HeatPumpInfo with default settings."""
return HeatPumpDiscovery.HeatPumpInfo(TEST_HP_UUID, None, TEST_MODEL, TEST_SN, True)
@pytest.fixture
def mock_config_entry() -> MockConfigEntry:
"""Mock a config entry."""
return MockConfigEntry(
domain=DOMAIN,
title="Weheat",
data={
"id": "12345",
"auth_implementation": DOMAIN,
"token": {
"refresh_token": "mock-refresh-token",
"access_token": "mock-access-token",
"type": "Bearer",
"expires_in": 60,
"expires_at": time() + 60,
},
},
unique_id="123456789",
)
@pytest.fixture
def mock_weheat_discover(mock_heat_pump_info) -> Generator[AsyncMock]:
"""Mock an Weheat discovery."""
with (
patch(
"homeassistant.components.weheat.HeatPumpDiscovery.discover_active",
autospec=True,
) as mock_discover,
):
mock_discover.return_value = [mock_heat_pump_info]
yield mock_discover
@pytest.fixture
def mock_weheat_heat_pump_instance() -> MagicMock:
"""Mock an Weheat heat pump instance with a set of default values."""
mock_heat_pump_instance = MagicMock(spec_set=HeatPump)
mock_heat_pump_instance.water_inlet_temperature = 11
mock_heat_pump_instance.water_outlet_temperature = 22
mock_heat_pump_instance.water_house_in_temperature = 33
mock_heat_pump_instance.air_inlet_temperature = 44
mock_heat_pump_instance.power_input = 55
mock_heat_pump_instance.power_output = 66
mock_heat_pump_instance.dhw_top_temperature = 77
mock_heat_pump_instance.dhw_bottom_temperature = 88
mock_heat_pump_instance.cop = 4.5
mock_heat_pump_instance.heat_pump_state = HeatPump.State.HEATING
mock_heat_pump_instance.energy_total = 12345
return mock_heat_pump_instance
@pytest.fixture
def mock_weheat_heat_pump(mock_weheat_heat_pump_instance) -> Generator[AsyncMock]:
"""Mock the coordinator HeatPump data."""
with (
patch(
"homeassistant.components.weheat.coordinator.HeatPump",
) as mock_heat_pump,
):
mock_heat_pump.return_value = mock_weheat_heat_pump_instance
yield mock_weheat_heat_pump_instance

View File

@ -9,3 +9,8 @@ CONF_REFRESH_TOKEN = "refresh_token"
CONF_AUTH_IMPLEMENTATION = "auth_implementation"
MOCK_REFRESH_TOKEN = "mock_refresh_token"
MOCK_ACCESS_TOKEN = "mock_access_token"
TEST_HP_UUID = "0000-1111-2222-3333"
TEST_NAME = "Test Heat Pump"
TEST_MODEL = "Test Model"
TEST_SN = "SN-Test-This"

View File

@ -0,0 +1,660 @@
# serializer version: 1
# name: test_all_entities[sensor.test_model-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'options': list([
'standby',
'water_check',
'heating',
'cooling',
'dhw',
'legionella_prevention',
'defrosting',
'self_test',
'manual_control',
]),
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.test_model',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.ENUM: 'enum'>,
'original_icon': None,
'original_name': None,
'platform': 'weheat',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'heat_pump_state',
'unique_id': '0000-1111-2222-3333_heat_pump_state',
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[sensor.test_model-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'enum',
'friendly_name': 'Test Model',
'options': list([
'standby',
'water_check',
'heating',
'cooling',
'dhw',
'legionella_prevention',
'defrosting',
'self_test',
'manual_control',
]),
}),
'context': <ANY>,
'entity_id': 'sensor.test_model',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'heating',
})
# ---
# name: test_all_entities[sensor.test_model_central_heating_inlet_temperature-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.test_model_central_heating_inlet_temperature',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
'sensor': dict({
'suggested_display_precision': 1,
}),
}),
'original_device_class': <SensorDeviceClass.TEMPERATURE: 'temperature'>,
'original_icon': None,
'original_name': 'Central heating inlet temperature',
'platform': 'weheat',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'ch_inlet_temperature',
'unique_id': '0000-1111-2222-3333_ch_inlet_temperature',
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
})
# ---
# name: test_all_entities[sensor.test_model_central_heating_inlet_temperature-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'temperature',
'friendly_name': 'Test Model Central heating inlet temperature',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
}),
'context': <ANY>,
'entity_id': 'sensor.test_model_central_heating_inlet_temperature',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '33',
})
# ---
# name: test_all_entities[sensor.test_model_cop-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.test_model_cop',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
'sensor': dict({
'suggested_display_precision': 1,
}),
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'COP',
'platform': 'weheat',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'cop',
'unique_id': '0000-1111-2222-3333_cop',
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[sensor.test_model_cop-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Test Model COP',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'context': <ANY>,
'entity_id': 'sensor.test_model_cop',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '4.5',
})
# ---
# name: test_all_entities[sensor.test_model_dhw_bottom_temperature-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.test_model_dhw_bottom_temperature',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
'sensor': dict({
'suggested_display_precision': 1,
}),
}),
'original_device_class': <SensorDeviceClass.TEMPERATURE: 'temperature'>,
'original_icon': None,
'original_name': 'DHW bottom temperature',
'platform': 'weheat',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'dhw_bottom_temperature',
'unique_id': '0000-1111-2222-3333_dhw_bottom_temperature',
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
})
# ---
# name: test_all_entities[sensor.test_model_dhw_bottom_temperature-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'temperature',
'friendly_name': 'Test Model DHW bottom temperature',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
}),
'context': <ANY>,
'entity_id': 'sensor.test_model_dhw_bottom_temperature',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '88',
})
# ---
# name: test_all_entities[sensor.test_model_dhw_top_temperature-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.test_model_dhw_top_temperature',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
'sensor': dict({
'suggested_display_precision': 1,
}),
}),
'original_device_class': <SensorDeviceClass.TEMPERATURE: 'temperature'>,
'original_icon': None,
'original_name': 'DHW top temperature',
'platform': 'weheat',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'dhw_top_temperature',
'unique_id': '0000-1111-2222-3333_dhw_top_temperature',
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
})
# ---
# name: test_all_entities[sensor.test_model_dhw_top_temperature-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'temperature',
'friendly_name': 'Test Model DHW top temperature',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
}),
'context': <ANY>,
'entity_id': 'sensor.test_model_dhw_top_temperature',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '77',
})
# ---
# name: test_all_entities[sensor.test_model_electricity_used-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.test_model_electricity_used',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.ENERGY: 'energy'>,
'original_icon': None,
'original_name': 'Electricity used',
'platform': 'weheat',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'electricity_used',
'unique_id': '0000-1111-2222-3333_electricity_used',
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
})
# ---
# name: test_all_entities[sensor.test_model_electricity_used-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'energy',
'friendly_name': 'Test Model Electricity used',
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
}),
'context': <ANY>,
'entity_id': 'sensor.test_model_electricity_used',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '12345',
})
# ---
# name: test_all_entities[sensor.test_model_input_power-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.test_model_input_power',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
'sensor': dict({
'suggested_display_precision': 0,
}),
}),
'original_device_class': <SensorDeviceClass.POWER: 'power'>,
'original_icon': None,
'original_name': 'Input power',
'platform': 'weheat',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'power_input',
'unique_id': '0000-1111-2222-3333_power_input',
'unit_of_measurement': <UnitOfPower.WATT: 'W'>,
})
# ---
# name: test_all_entities[sensor.test_model_input_power-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'power',
'friendly_name': 'Test Model Input power',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': <UnitOfPower.WATT: 'W'>,
}),
'context': <ANY>,
'entity_id': 'sensor.test_model_input_power',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '55',
})
# ---
# name: test_all_entities[sensor.test_model_output_power-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.test_model_output_power',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
'sensor': dict({
'suggested_display_precision': 0,
}),
}),
'original_device_class': <SensorDeviceClass.POWER: 'power'>,
'original_icon': None,
'original_name': 'Output power',
'platform': 'weheat',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'power_output',
'unique_id': '0000-1111-2222-3333_power_output',
'unit_of_measurement': <UnitOfPower.WATT: 'W'>,
})
# ---
# name: test_all_entities[sensor.test_model_output_power-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'power',
'friendly_name': 'Test Model Output power',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': <UnitOfPower.WATT: 'W'>,
}),
'context': <ANY>,
'entity_id': 'sensor.test_model_output_power',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '66',
})
# ---
# name: test_all_entities[sensor.test_model_outside_temperature-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.test_model_outside_temperature',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
'sensor': dict({
'suggested_display_precision': 1,
}),
}),
'original_device_class': <SensorDeviceClass.TEMPERATURE: 'temperature'>,
'original_icon': None,
'original_name': 'Outside temperature',
'platform': 'weheat',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'outside_temperature',
'unique_id': '0000-1111-2222-3333_outside_temperature',
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
})
# ---
# name: test_all_entities[sensor.test_model_outside_temperature-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'temperature',
'friendly_name': 'Test Model Outside temperature',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
}),
'context': <ANY>,
'entity_id': 'sensor.test_model_outside_temperature',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '44',
})
# ---
# name: test_all_entities[sensor.test_model_power_output-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.test_model_power_output',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
'sensor': dict({
'suggested_display_precision': 0,
}),
}),
'original_device_class': <SensorDeviceClass.POWER: 'power'>,
'original_icon': None,
'original_name': 'power output',
'platform': 'weheat',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'power_output',
'unique_id': '0000-1111-2222-3333_power_output',
'unit_of_measurement': <UnitOfPower.WATT: 'W'>,
})
# ---
# name: test_all_entities[sensor.test_model_power_output-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'power',
'friendly_name': 'Test Model power output',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': <UnitOfPower.WATT: 'W'>,
}),
'context': <ANY>,
'entity_id': 'sensor.test_model_power_output',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '77',
})
# ---
# name: test_all_entities[sensor.test_model_water_inlet_temperature-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.test_model_water_inlet_temperature',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
'sensor': dict({
'suggested_display_precision': 1,
}),
}),
'original_device_class': <SensorDeviceClass.TEMPERATURE: 'temperature'>,
'original_icon': None,
'original_name': 'Water inlet temperature',
'platform': 'weheat',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'water_inlet_temperature',
'unique_id': '0000-1111-2222-3333_water_inlet_temperature',
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
})
# ---
# name: test_all_entities[sensor.test_model_water_inlet_temperature-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'temperature',
'friendly_name': 'Test Model Water inlet temperature',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
}),
'context': <ANY>,
'entity_id': 'sensor.test_model_water_inlet_temperature',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '11',
})
# ---
# name: test_all_entities[sensor.test_model_water_outlet_temperature-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.test_model_water_outlet_temperature',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
'sensor': dict({
'suggested_display_precision': 1,
}),
}),
'original_device_class': <SensorDeviceClass.TEMPERATURE: 'temperature'>,
'original_icon': None,
'original_name': 'Water outlet temperature',
'platform': 'weheat',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'water_outlet_temperature',
'unique_id': '0000-1111-2222-3333_water_outlet_temperature',
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
})
# ---
# name: test_all_entities[sensor.test_model_water_outlet_temperature-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'temperature',
'friendly_name': 'Test Model Water outlet temperature',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
}),
'context': <ANY>,
'entity_id': 'sensor.test_model_water_outlet_temperature',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '22',
})
# ---

View File

@ -0,0 +1,56 @@
"""Tests for the weheat sensor platform."""
from unittest.mock import AsyncMock, patch
from freezegun.api import FrozenDateTimeFactory
import pytest
from syrupy import SnapshotAssertion
from weheat.abstractions.discovery import HeatPumpDiscovery
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from . import setup_integration
from tests.common import MockConfigEntry, snapshot_platform
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
async def test_all_entities(
hass: HomeAssistant,
snapshot: SnapshotAssertion,
mock_weheat_discover: AsyncMock,
mock_weheat_heat_pump: AsyncMock,
mock_config_entry: MockConfigEntry,
entity_registry: er.EntityRegistry,
) -> None:
"""Test all entities."""
with patch("homeassistant.components.weheat.PLATFORMS", [Platform.SENSOR]):
await setup_integration(hass, mock_config_entry)
await hass.async_block_till_done()
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
@pytest.mark.parametrize(("has_dhw", "nr_of_entities"), [(False, 9), (True, 11)])
async def test_create_entities(
hass: HomeAssistant,
mock_weheat_discover: AsyncMock,
mock_weheat_heat_pump: AsyncMock,
mock_heat_pump_info: HeatPumpDiscovery.HeatPumpInfo,
mock_config_entry: MockConfigEntry,
freezer: FrozenDateTimeFactory,
has_dhw: bool,
nr_of_entities: int,
) -> None:
"""Test creating entities."""
mock_heat_pump_info.has_dhw = has_dhw
mock_weheat_discover.return_value = [mock_heat_pump_info]
with patch("homeassistant.components.weheat.PLATFORMS", [Platform.SENSOR]):
await setup_integration(hass, mock_config_entry)
await hass.async_block_till_done()
assert len(hass.states.async_all()) == nr_of_entities