Add heat meter to Powerfox integration (#134799)
parent
67e2379d2b
commit
99d7f462a0
|
@ -5,7 +5,7 @@ from __future__ import annotations
|
|||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
from powerfox import PowerMeter, WaterMeter
|
||||
from powerfox import HeatMeter, PowerMeter, WaterMeter
|
||||
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
|
@ -52,6 +52,22 @@ async def async_get_config_entry_diagnostics(
|
|||
if isinstance(coordinator.data, WaterMeter)
|
||||
else {}
|
||||
),
|
||||
**(
|
||||
{
|
||||
"heat_meter": {
|
||||
"outdated": coordinator.data.outdated,
|
||||
"timestamp": datetime.strftime(
|
||||
coordinator.data.timestamp, "%Y-%m-%d %H:%M:%S"
|
||||
),
|
||||
"total_energy": coordinator.data.total_energy,
|
||||
"delta_energy": coordinator.data.delta_energy,
|
||||
"total_volume": coordinator.data.total_volume,
|
||||
"delta_volume": coordinator.data.delta_volume,
|
||||
}
|
||||
}
|
||||
if isinstance(coordinator.data, HeatMeter)
|
||||
else {}
|
||||
),
|
||||
}
|
||||
for coordinator in powerfox_data
|
||||
],
|
||||
|
|
|
@ -5,7 +5,7 @@ from __future__ import annotations
|
|||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
|
||||
from powerfox import Device, PowerMeter, WaterMeter
|
||||
from powerfox import Device, HeatMeter, PowerMeter, WaterMeter
|
||||
|
||||
from homeassistant.components.sensor import (
|
||||
SensorDeviceClass,
|
||||
|
@ -23,7 +23,7 @@ from .entity import PowerfoxEntity
|
|||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
class PowerfoxSensorEntityDescription[T: (PowerMeter, WaterMeter)](
|
||||
class PowerfoxSensorEntityDescription[T: (PowerMeter, WaterMeter, HeatMeter)](
|
||||
SensorEntityDescription
|
||||
):
|
||||
"""Describes Poweropti sensor entity."""
|
||||
|
@ -93,6 +93,40 @@ SENSORS_WATER: tuple[PowerfoxSensorEntityDescription[WaterMeter], ...] = (
|
|||
),
|
||||
)
|
||||
|
||||
SENSORS_HEAT: tuple[PowerfoxSensorEntityDescription[HeatMeter], ...] = (
|
||||
PowerfoxSensorEntityDescription[HeatMeter](
|
||||
key="heat_total_energy",
|
||||
translation_key="heat_total_energy",
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||
value_fn=lambda meter: meter.total_energy,
|
||||
),
|
||||
PowerfoxSensorEntityDescription[HeatMeter](
|
||||
key="heat_delta_energy",
|
||||
translation_key="heat_delta_energy",
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
value_fn=lambda meter: meter.delta_energy,
|
||||
),
|
||||
PowerfoxSensorEntityDescription[HeatMeter](
|
||||
key="heat_total_volume",
|
||||
translation_key="heat_total_volume",
|
||||
native_unit_of_measurement=UnitOfVolume.CUBIC_METERS,
|
||||
device_class=SensorDeviceClass.WATER,
|
||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||
value_fn=lambda meter: meter.total_volume,
|
||||
),
|
||||
PowerfoxSensorEntityDescription[HeatMeter](
|
||||
key="heat_delta_volume",
|
||||
translation_key="heat_delta_volume",
|
||||
suggested_display_precision=2,
|
||||
native_unit_of_measurement=UnitOfVolume.CUBIC_METERS,
|
||||
device_class=SensorDeviceClass.WATER,
|
||||
value_fn=lambda meter: meter.delta_volume,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
|
@ -121,6 +155,15 @@ async def async_setup_entry(
|
|||
)
|
||||
for description in SENSORS_WATER
|
||||
)
|
||||
if isinstance(coordinator.data, HeatMeter):
|
||||
entities.extend(
|
||||
PowerfoxSensorEntity(
|
||||
coordinator=coordinator,
|
||||
description=description,
|
||||
device=coordinator.device,
|
||||
)
|
||||
for description in SENSORS_HEAT
|
||||
)
|
||||
async_add_entities(entities)
|
||||
|
||||
|
||||
|
|
|
@ -64,6 +64,18 @@
|
|||
},
|
||||
"warm_water": {
|
||||
"name": "Warm water"
|
||||
},
|
||||
"heat_total_energy": {
|
||||
"name": "Total energy"
|
||||
},
|
||||
"heat_delta_energy": {
|
||||
"name": "Delta energy"
|
||||
},
|
||||
"heat_total_volume": {
|
||||
"name": "Total volume"
|
||||
},
|
||||
"heat_delta_volume": {
|
||||
"name": "Delta volume"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ from collections.abc import Generator
|
|||
from datetime import UTC, datetime
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
from powerfox import Device, DeviceType, PowerMeter, WaterMeter
|
||||
from powerfox import Device, DeviceType, HeatMeter, PowerMeter, WaterMeter
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.powerfox.const import DOMAIN
|
||||
|
@ -53,6 +53,14 @@ def mock_powerfox_client() -> Generator[AsyncMock]:
|
|||
type=DeviceType.COLD_WATER_METER,
|
||||
name="Wateropti",
|
||||
),
|
||||
Device(
|
||||
id="9x9x1f12xx5x",
|
||||
date_added=datetime(2024, 11, 26, 9, 22, 35, tzinfo=UTC),
|
||||
main_device=False,
|
||||
bidirectional=False,
|
||||
type=DeviceType.HEAT_METER,
|
||||
name="Heatopti",
|
||||
),
|
||||
]
|
||||
client.device.side_effect = [
|
||||
PowerMeter(
|
||||
|
@ -70,6 +78,14 @@ def mock_powerfox_client() -> Generator[AsyncMock]:
|
|||
cold_water=1111.111,
|
||||
warm_water=0.0,
|
||||
),
|
||||
HeatMeter(
|
||||
outdated=False,
|
||||
timestamp=datetime(2024, 11, 26, 10, 48, 51, tzinfo=UTC),
|
||||
total_energy=1111.111,
|
||||
delta_energy=111,
|
||||
total_volume=1111.111,
|
||||
delta_volume=0.111,
|
||||
),
|
||||
]
|
||||
yield client
|
||||
|
||||
|
|
|
@ -21,6 +21,16 @@
|
|||
'warm_water': 0.0,
|
||||
}),
|
||||
}),
|
||||
dict({
|
||||
'heat_meter': dict({
|
||||
'delta_energy': 111,
|
||||
'delta_volume': 0.111,
|
||||
'outdated': False,
|
||||
'timestamp': '2024-11-26 10:48:51',
|
||||
'total_energy': 1111.111,
|
||||
'total_volume': 1111.111,
|
||||
}),
|
||||
}),
|
||||
]),
|
||||
})
|
||||
# ---
|
||||
|
|
|
@ -1,4 +1,205 @@
|
|||
# serializer version: 1
|
||||
# name: test_all_sensors[sensor.heatopti_delta_energy-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.heatopti_delta_energy',
|
||||
'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': 'Delta energy',
|
||||
'platform': 'powerfox',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'heat_delta_energy',
|
||||
'unique_id': '9x9x1f12xx5x_heat_delta_energy',
|
||||
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_sensors[sensor.heatopti_delta_energy-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'energy',
|
||||
'friendly_name': 'Heatopti Delta energy',
|
||||
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.heatopti_delta_energy',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '111',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_sensors[sensor.heatopti_delta_volume-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.heatopti_delta_volume',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
'sensor': dict({
|
||||
'suggested_display_precision': 2,
|
||||
}),
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.WATER: 'water'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Delta volume',
|
||||
'platform': 'powerfox',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'heat_delta_volume',
|
||||
'unique_id': '9x9x1f12xx5x_heat_delta_volume',
|
||||
'unit_of_measurement': <UnitOfVolume.CUBIC_METERS: 'm³'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_sensors[sensor.heatopti_delta_volume-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'water',
|
||||
'friendly_name': 'Heatopti Delta volume',
|
||||
'unit_of_measurement': <UnitOfVolume.CUBIC_METERS: 'm³'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.heatopti_delta_volume',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '0.111',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_sensors[sensor.heatopti_total_energy-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.heatopti_total_energy',
|
||||
'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': 'Total energy',
|
||||
'platform': 'powerfox',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'heat_total_energy',
|
||||
'unique_id': '9x9x1f12xx5x_heat_total_energy',
|
||||
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_sensors[sensor.heatopti_total_energy-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'energy',
|
||||
'friendly_name': 'Heatopti Total energy',
|
||||
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
||||
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.heatopti_total_energy',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '1111.111',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_sensors[sensor.heatopti_total_volume-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.heatopti_total_volume',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.WATER: 'water'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Total volume',
|
||||
'platform': 'powerfox',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'heat_total_volume',
|
||||
'unique_id': '9x9x1f12xx5x_heat_total_volume',
|
||||
'unit_of_measurement': <UnitOfVolume.CUBIC_METERS: 'm³'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_sensors[sensor.heatopti_total_volume-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'water',
|
||||
'friendly_name': 'Heatopti Total volume',
|
||||
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
||||
'unit_of_measurement': <UnitOfVolume.CUBIC_METERS: 'm³'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.heatopti_total_volume',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '1111.111',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_sensors[sensor.poweropti_energy_return-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
|
|
Loading…
Reference in New Issue