mirror of
https://github.com/home-assistant/core.git
synced 2026-05-08 17:49:37 +01:00
Add flow rate (stat_rate) tracking for gas and water (#163274)
This commit is contained in:
@@ -173,6 +173,9 @@ class GasSourceType(TypedDict):
|
||||
|
||||
stat_energy_from: str
|
||||
|
||||
# Instantaneous flow rate: m³/h, L/min, etc.
|
||||
stat_rate: NotRequired[str]
|
||||
|
||||
# statistic_id of costs ($) incurred from the gas meter
|
||||
# If set to None and entity_energy_price or number_energy_price are configured,
|
||||
# an EnergyCostSensor will be automatically created
|
||||
@@ -190,6 +193,9 @@ class WaterSourceType(TypedDict):
|
||||
|
||||
stat_energy_from: str
|
||||
|
||||
# Instantaneous flow rate: L/min, gal/min, m³/h, etc.
|
||||
stat_rate: NotRequired[str]
|
||||
|
||||
# statistic_id of costs ($) incurred from the water meter
|
||||
# If set to None and entity_energy_price or number_energy_price are configured,
|
||||
# an EnergyCostSensor will be automatically created
|
||||
@@ -440,6 +446,7 @@ GAS_SOURCE_SCHEMA = vol.Schema(
|
||||
{
|
||||
vol.Required("type"): "gas",
|
||||
vol.Required("stat_energy_from"): str,
|
||||
vol.Optional("stat_rate"): str,
|
||||
vol.Optional("stat_cost"): vol.Any(str, None),
|
||||
# entity_energy_from was removed in HA Core 2022.10
|
||||
vol.Remove("entity_energy_from"): vol.Any(str, None),
|
||||
@@ -451,6 +458,7 @@ WATER_SOURCE_SCHEMA = vol.Schema(
|
||||
{
|
||||
vol.Required("type"): "water",
|
||||
vol.Required("stat_energy_from"): str,
|
||||
vol.Optional("stat_rate"): str,
|
||||
vol.Optional("stat_cost"): vol.Any(str, None),
|
||||
vol.Optional("entity_energy_price"): vol.Any(str, None),
|
||||
vol.Optional("number_energy_price"): vol.Any(vol.Coerce(float), None),
|
||||
|
||||
@@ -44,6 +44,10 @@
|
||||
"description": "[%key:component::energy::issues::entity_unexpected_unit_energy_price::description%]",
|
||||
"title": "[%key:component::energy::issues::entity_unexpected_unit_energy::title%]"
|
||||
},
|
||||
"entity_unexpected_unit_volume_flow_rate": {
|
||||
"description": "The following entities do not have an expected unit of measurement (either of {flow_rate_units}):",
|
||||
"title": "[%key:component::energy::issues::entity_unexpected_unit_energy::title%]"
|
||||
},
|
||||
"entity_unexpected_unit_water": {
|
||||
"description": "The following entities do not have the expected unit of measurement (either of {water_units}):",
|
||||
"title": "[%key:component::energy::issues::entity_unexpected_unit_energy::title%]"
|
||||
|
||||
@@ -14,6 +14,7 @@ from homeassistant.const import (
|
||||
UnitOfEnergy,
|
||||
UnitOfPower,
|
||||
UnitOfVolume,
|
||||
UnitOfVolumeFlowRate,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant, callback, valid_entity_id
|
||||
|
||||
@@ -28,6 +29,11 @@ POWER_USAGE_DEVICE_CLASSES = (sensor.SensorDeviceClass.POWER,)
|
||||
POWER_USAGE_UNITS: dict[str, tuple[UnitOfPower, ...]] = {
|
||||
sensor.SensorDeviceClass.POWER: tuple(UnitOfPower)
|
||||
}
|
||||
VOLUME_FLOW_RATE_DEVICE_CLASSES = (sensor.SensorDeviceClass.VOLUME_FLOW_RATE,)
|
||||
VOLUME_FLOW_RATE_UNITS: dict[str, tuple[UnitOfVolumeFlowRate, ...]] = {
|
||||
sensor.SensorDeviceClass.VOLUME_FLOW_RATE: tuple(UnitOfVolumeFlowRate)
|
||||
}
|
||||
VOLUME_FLOW_RATE_UNIT_ERROR = "entity_unexpected_unit_volume_flow_rate"
|
||||
|
||||
ENERGY_PRICE_UNITS = tuple(
|
||||
f"/{unit}" for units in ENERGY_USAGE_UNITS.values() for unit in units
|
||||
@@ -109,6 +115,12 @@ def _get_placeholders(hass: HomeAssistant, issue_type: str) -> dict[str, str] |
|
||||
return {
|
||||
"price_units": ", ".join(f"{currency}{unit}" for unit in WATER_PRICE_UNITS),
|
||||
}
|
||||
if issue_type == VOLUME_FLOW_RATE_UNIT_ERROR:
|
||||
return {
|
||||
"flow_rate_units": ", ".join(
|
||||
VOLUME_FLOW_RATE_UNITS[sensor.SensorDeviceClass.VOLUME_FLOW_RATE]
|
||||
),
|
||||
}
|
||||
return None
|
||||
|
||||
|
||||
@@ -590,6 +602,21 @@ def _validate_gas_source(
|
||||
)
|
||||
)
|
||||
|
||||
if stat_rate := source.get("stat_rate"):
|
||||
wanted_statistics_metadata.add(stat_rate)
|
||||
validate_calls.append(
|
||||
functools.partial(
|
||||
_async_validate_power_stat,
|
||||
hass,
|
||||
statistics_metadata,
|
||||
stat_rate,
|
||||
VOLUME_FLOW_RATE_DEVICE_CLASSES,
|
||||
VOLUME_FLOW_RATE_UNITS,
|
||||
VOLUME_FLOW_RATE_UNIT_ERROR,
|
||||
source_result,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def _validate_water_source(
|
||||
hass: HomeAssistant,
|
||||
@@ -650,6 +677,21 @@ def _validate_water_source(
|
||||
)
|
||||
)
|
||||
|
||||
if stat_rate := source.get("stat_rate"):
|
||||
wanted_statistics_metadata.add(stat_rate)
|
||||
validate_calls.append(
|
||||
functools.partial(
|
||||
_async_validate_power_stat,
|
||||
hass,
|
||||
statistics_metadata,
|
||||
stat_rate,
|
||||
VOLUME_FLOW_RATE_DEVICE_CLASSES,
|
||||
VOLUME_FLOW_RATE_UNITS,
|
||||
VOLUME_FLOW_RATE_UNIT_ERROR,
|
||||
source_result,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
async def async_validate(hass: HomeAssistant) -> EnergyPreferencesValidation:
|
||||
"""Validate the energy configuration."""
|
||||
|
||||
@@ -0,0 +1,617 @@
|
||||
"""Test flow rate (stat_rate) validation for gas and water sources."""
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.energy import validate
|
||||
from homeassistant.components.energy.data import EnergyManager
|
||||
from homeassistant.const import UnitOfVolumeFlowRate
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
FLOW_RATE_UNITS_STRING = ", ".join(tuple(UnitOfVolumeFlowRate))
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
async def setup_energy_for_validation(
|
||||
mock_energy_manager: EnergyManager,
|
||||
) -> EnergyManager:
|
||||
"""Ensure energy manager is set up for validation tests."""
|
||||
return mock_energy_manager
|
||||
|
||||
|
||||
async def test_validation_gas_flow_rate_valid(
|
||||
hass: HomeAssistant, mock_energy_manager, mock_get_metadata
|
||||
) -> None:
|
||||
"""Test validating gas with valid flow rate sensor."""
|
||||
await mock_energy_manager.async_update(
|
||||
{
|
||||
"energy_sources": [
|
||||
{
|
||||
"type": "gas",
|
||||
"stat_energy_from": "sensor.gas_consumption",
|
||||
"stat_rate": "sensor.gas_flow_rate",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
hass.states.async_set(
|
||||
"sensor.gas_consumption",
|
||||
"10.10",
|
||||
{
|
||||
"device_class": "gas",
|
||||
"unit_of_measurement": "m³",
|
||||
"state_class": "total_increasing",
|
||||
},
|
||||
)
|
||||
hass.states.async_set(
|
||||
"sensor.gas_flow_rate",
|
||||
"1.5",
|
||||
{
|
||||
"device_class": "volume_flow_rate",
|
||||
"unit_of_measurement": UnitOfVolumeFlowRate.CUBIC_METERS_PER_HOUR,
|
||||
"state_class": "measurement",
|
||||
},
|
||||
)
|
||||
|
||||
result = await validate.async_validate(hass)
|
||||
assert result.as_dict() == {
|
||||
"energy_sources": [[]],
|
||||
"device_consumption": [],
|
||||
"device_consumption_water": [],
|
||||
}
|
||||
|
||||
|
||||
async def test_validation_gas_flow_rate_wrong_unit(
|
||||
hass: HomeAssistant, mock_energy_manager, mock_get_metadata
|
||||
) -> None:
|
||||
"""Test validating gas with flow rate sensor having wrong unit."""
|
||||
await mock_energy_manager.async_update(
|
||||
{
|
||||
"energy_sources": [
|
||||
{
|
||||
"type": "gas",
|
||||
"stat_energy_from": "sensor.gas_consumption",
|
||||
"stat_rate": "sensor.gas_flow_rate",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
hass.states.async_set(
|
||||
"sensor.gas_consumption",
|
||||
"10.10",
|
||||
{
|
||||
"device_class": "gas",
|
||||
"unit_of_measurement": "m³",
|
||||
"state_class": "total_increasing",
|
||||
},
|
||||
)
|
||||
hass.states.async_set(
|
||||
"sensor.gas_flow_rate",
|
||||
"1.5",
|
||||
{
|
||||
"device_class": "volume_flow_rate",
|
||||
"unit_of_measurement": "beers",
|
||||
"state_class": "measurement",
|
||||
},
|
||||
)
|
||||
|
||||
result = await validate.async_validate(hass)
|
||||
assert result.as_dict() == {
|
||||
"energy_sources": [
|
||||
[
|
||||
{
|
||||
"type": "entity_unexpected_unit_volume_flow_rate",
|
||||
"affected_entities": {("sensor.gas_flow_rate", "beers")},
|
||||
"translation_placeholders": {
|
||||
"flow_rate_units": FLOW_RATE_UNITS_STRING
|
||||
},
|
||||
}
|
||||
]
|
||||
],
|
||||
"device_consumption": [],
|
||||
"device_consumption_water": [],
|
||||
}
|
||||
|
||||
|
||||
async def test_validation_gas_flow_rate_wrong_state_class(
|
||||
hass: HomeAssistant, mock_energy_manager, mock_get_metadata
|
||||
) -> None:
|
||||
"""Test validating gas with flow rate sensor having wrong state class."""
|
||||
await mock_energy_manager.async_update(
|
||||
{
|
||||
"energy_sources": [
|
||||
{
|
||||
"type": "gas",
|
||||
"stat_energy_from": "sensor.gas_consumption",
|
||||
"stat_rate": "sensor.gas_flow_rate",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
hass.states.async_set(
|
||||
"sensor.gas_consumption",
|
||||
"10.10",
|
||||
{
|
||||
"device_class": "gas",
|
||||
"unit_of_measurement": "m³",
|
||||
"state_class": "total_increasing",
|
||||
},
|
||||
)
|
||||
hass.states.async_set(
|
||||
"sensor.gas_flow_rate",
|
||||
"1.5",
|
||||
{
|
||||
"device_class": "volume_flow_rate",
|
||||
"unit_of_measurement": UnitOfVolumeFlowRate.CUBIC_METERS_PER_HOUR,
|
||||
"state_class": "total_increasing",
|
||||
},
|
||||
)
|
||||
|
||||
result = await validate.async_validate(hass)
|
||||
assert result.as_dict() == {
|
||||
"energy_sources": [
|
||||
[
|
||||
{
|
||||
"type": "entity_unexpected_state_class",
|
||||
"affected_entities": {("sensor.gas_flow_rate", "total_increasing")},
|
||||
"translation_placeholders": None,
|
||||
}
|
||||
]
|
||||
],
|
||||
"device_consumption": [],
|
||||
"device_consumption_water": [],
|
||||
}
|
||||
|
||||
|
||||
async def test_validation_gas_flow_rate_entity_missing(
|
||||
hass: HomeAssistant, mock_energy_manager, mock_get_metadata
|
||||
) -> None:
|
||||
"""Test validating gas with missing flow rate sensor."""
|
||||
mock_get_metadata["sensor.missing_flow_rate"] = None
|
||||
await mock_energy_manager.async_update(
|
||||
{
|
||||
"energy_sources": [
|
||||
{
|
||||
"type": "gas",
|
||||
"stat_energy_from": "sensor.gas_consumption",
|
||||
"stat_rate": "sensor.missing_flow_rate",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
hass.states.async_set(
|
||||
"sensor.gas_consumption",
|
||||
"10.10",
|
||||
{
|
||||
"device_class": "gas",
|
||||
"unit_of_measurement": "m³",
|
||||
"state_class": "total_increasing",
|
||||
},
|
||||
)
|
||||
|
||||
result = await validate.async_validate(hass)
|
||||
assert result.as_dict() == {
|
||||
"energy_sources": [
|
||||
[
|
||||
{
|
||||
"type": "statistics_not_defined",
|
||||
"affected_entities": {("sensor.missing_flow_rate", None)},
|
||||
"translation_placeholders": None,
|
||||
},
|
||||
{
|
||||
"type": "entity_not_defined",
|
||||
"affected_entities": {("sensor.missing_flow_rate", None)},
|
||||
"translation_placeholders": None,
|
||||
},
|
||||
]
|
||||
],
|
||||
"device_consumption": [],
|
||||
"device_consumption_water": [],
|
||||
}
|
||||
|
||||
|
||||
async def test_validation_gas_without_flow_rate(
|
||||
hass: HomeAssistant, mock_energy_manager, mock_get_metadata
|
||||
) -> None:
|
||||
"""Test validating gas without flow rate sensor still works."""
|
||||
await mock_energy_manager.async_update(
|
||||
{
|
||||
"energy_sources": [
|
||||
{
|
||||
"type": "gas",
|
||||
"stat_energy_from": "sensor.gas_consumption",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
hass.states.async_set(
|
||||
"sensor.gas_consumption",
|
||||
"10.10",
|
||||
{
|
||||
"device_class": "gas",
|
||||
"unit_of_measurement": "m³",
|
||||
"state_class": "total_increasing",
|
||||
},
|
||||
)
|
||||
|
||||
result = await validate.async_validate(hass)
|
||||
assert result.as_dict() == {
|
||||
"energy_sources": [[]],
|
||||
"device_consumption": [],
|
||||
"device_consumption_water": [],
|
||||
}
|
||||
|
||||
|
||||
async def test_validation_water_flow_rate_valid(
|
||||
hass: HomeAssistant, mock_energy_manager, mock_get_metadata
|
||||
) -> None:
|
||||
"""Test validating water with valid flow rate sensor."""
|
||||
await mock_energy_manager.async_update(
|
||||
{
|
||||
"energy_sources": [
|
||||
{
|
||||
"type": "water",
|
||||
"stat_energy_from": "sensor.water_consumption",
|
||||
"stat_rate": "sensor.water_flow_rate",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
hass.states.async_set(
|
||||
"sensor.water_consumption",
|
||||
"10.10",
|
||||
{
|
||||
"device_class": "water",
|
||||
"unit_of_measurement": "m³",
|
||||
"state_class": "total_increasing",
|
||||
},
|
||||
)
|
||||
hass.states.async_set(
|
||||
"sensor.water_flow_rate",
|
||||
"2.5",
|
||||
{
|
||||
"device_class": "volume_flow_rate",
|
||||
"unit_of_measurement": UnitOfVolumeFlowRate.LITERS_PER_MINUTE,
|
||||
"state_class": "measurement",
|
||||
},
|
||||
)
|
||||
|
||||
result = await validate.async_validate(hass)
|
||||
assert result.as_dict() == {
|
||||
"energy_sources": [[]],
|
||||
"device_consumption": [],
|
||||
"device_consumption_water": [],
|
||||
}
|
||||
|
||||
|
||||
async def test_validation_water_flow_rate_wrong_unit(
|
||||
hass: HomeAssistant, mock_energy_manager, mock_get_metadata
|
||||
) -> None:
|
||||
"""Test validating water with flow rate sensor having wrong unit."""
|
||||
await mock_energy_manager.async_update(
|
||||
{
|
||||
"energy_sources": [
|
||||
{
|
||||
"type": "water",
|
||||
"stat_energy_from": "sensor.water_consumption",
|
||||
"stat_rate": "sensor.water_flow_rate",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
hass.states.async_set(
|
||||
"sensor.water_consumption",
|
||||
"10.10",
|
||||
{
|
||||
"device_class": "water",
|
||||
"unit_of_measurement": "m³",
|
||||
"state_class": "total_increasing",
|
||||
},
|
||||
)
|
||||
hass.states.async_set(
|
||||
"sensor.water_flow_rate",
|
||||
"2.5",
|
||||
{
|
||||
"device_class": "volume_flow_rate",
|
||||
"unit_of_measurement": "beers",
|
||||
"state_class": "measurement",
|
||||
},
|
||||
)
|
||||
|
||||
result = await validate.async_validate(hass)
|
||||
assert result.as_dict() == {
|
||||
"energy_sources": [
|
||||
[
|
||||
{
|
||||
"type": "entity_unexpected_unit_volume_flow_rate",
|
||||
"affected_entities": {("sensor.water_flow_rate", "beers")},
|
||||
"translation_placeholders": {
|
||||
"flow_rate_units": FLOW_RATE_UNITS_STRING
|
||||
},
|
||||
}
|
||||
]
|
||||
],
|
||||
"device_consumption": [],
|
||||
"device_consumption_water": [],
|
||||
}
|
||||
|
||||
|
||||
async def test_validation_water_flow_rate_wrong_state_class(
|
||||
hass: HomeAssistant, mock_energy_manager, mock_get_metadata
|
||||
) -> None:
|
||||
"""Test validating water with flow rate sensor having wrong state class."""
|
||||
await mock_energy_manager.async_update(
|
||||
{
|
||||
"energy_sources": [
|
||||
{
|
||||
"type": "water",
|
||||
"stat_energy_from": "sensor.water_consumption",
|
||||
"stat_rate": "sensor.water_flow_rate",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
hass.states.async_set(
|
||||
"sensor.water_consumption",
|
||||
"10.10",
|
||||
{
|
||||
"device_class": "water",
|
||||
"unit_of_measurement": "m³",
|
||||
"state_class": "total_increasing",
|
||||
},
|
||||
)
|
||||
hass.states.async_set(
|
||||
"sensor.water_flow_rate",
|
||||
"2.5",
|
||||
{
|
||||
"device_class": "volume_flow_rate",
|
||||
"unit_of_measurement": UnitOfVolumeFlowRate.LITERS_PER_MINUTE,
|
||||
"state_class": "total_increasing",
|
||||
},
|
||||
)
|
||||
|
||||
result = await validate.async_validate(hass)
|
||||
assert result.as_dict() == {
|
||||
"energy_sources": [
|
||||
[
|
||||
{
|
||||
"type": "entity_unexpected_state_class",
|
||||
"affected_entities": {
|
||||
("sensor.water_flow_rate", "total_increasing")
|
||||
},
|
||||
"translation_placeholders": None,
|
||||
}
|
||||
]
|
||||
],
|
||||
"device_consumption": [],
|
||||
"device_consumption_water": [],
|
||||
}
|
||||
|
||||
|
||||
async def test_validation_water_flow_rate_entity_missing(
|
||||
hass: HomeAssistant, mock_energy_manager, mock_get_metadata
|
||||
) -> None:
|
||||
"""Test validating water with missing flow rate sensor."""
|
||||
mock_get_metadata["sensor.missing_flow_rate"] = None
|
||||
await mock_energy_manager.async_update(
|
||||
{
|
||||
"energy_sources": [
|
||||
{
|
||||
"type": "water",
|
||||
"stat_energy_from": "sensor.water_consumption",
|
||||
"stat_rate": "sensor.missing_flow_rate",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
hass.states.async_set(
|
||||
"sensor.water_consumption",
|
||||
"10.10",
|
||||
{
|
||||
"device_class": "water",
|
||||
"unit_of_measurement": "m³",
|
||||
"state_class": "total_increasing",
|
||||
},
|
||||
)
|
||||
|
||||
result = await validate.async_validate(hass)
|
||||
assert result.as_dict() == {
|
||||
"energy_sources": [
|
||||
[
|
||||
{
|
||||
"type": "statistics_not_defined",
|
||||
"affected_entities": {("sensor.missing_flow_rate", None)},
|
||||
"translation_placeholders": None,
|
||||
},
|
||||
{
|
||||
"type": "entity_not_defined",
|
||||
"affected_entities": {("sensor.missing_flow_rate", None)},
|
||||
"translation_placeholders": None,
|
||||
},
|
||||
]
|
||||
],
|
||||
"device_consumption": [],
|
||||
"device_consumption_water": [],
|
||||
}
|
||||
|
||||
|
||||
async def test_validation_water_without_flow_rate(
|
||||
hass: HomeAssistant, mock_energy_manager, mock_get_metadata
|
||||
) -> None:
|
||||
"""Test validating water without flow rate sensor still works."""
|
||||
await mock_energy_manager.async_update(
|
||||
{
|
||||
"energy_sources": [
|
||||
{
|
||||
"type": "water",
|
||||
"stat_energy_from": "sensor.water_consumption",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
hass.states.async_set(
|
||||
"sensor.water_consumption",
|
||||
"10.10",
|
||||
{
|
||||
"device_class": "water",
|
||||
"unit_of_measurement": "m³",
|
||||
"state_class": "total_increasing",
|
||||
},
|
||||
)
|
||||
|
||||
result = await validate.async_validate(hass)
|
||||
assert result.as_dict() == {
|
||||
"energy_sources": [[]],
|
||||
"device_consumption": [],
|
||||
"device_consumption_water": [],
|
||||
}
|
||||
|
||||
|
||||
async def test_validation_gas_flow_rate_different_units(
|
||||
hass: HomeAssistant, mock_energy_manager, mock_get_metadata
|
||||
) -> None:
|
||||
"""Test validating gas with flow rate sensors using different valid units."""
|
||||
await mock_energy_manager.async_update(
|
||||
{
|
||||
"energy_sources": [
|
||||
{
|
||||
"type": "gas",
|
||||
"stat_energy_from": "sensor.gas_consumption_1",
|
||||
"stat_rate": "sensor.gas_flow_m3h",
|
||||
},
|
||||
{
|
||||
"type": "gas",
|
||||
"stat_energy_from": "sensor.gas_consumption_2",
|
||||
"stat_rate": "sensor.gas_flow_lmin",
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
hass.states.async_set(
|
||||
"sensor.gas_consumption_1",
|
||||
"10.10",
|
||||
{
|
||||
"device_class": "gas",
|
||||
"unit_of_measurement": "m³",
|
||||
"state_class": "total_increasing",
|
||||
},
|
||||
)
|
||||
hass.states.async_set(
|
||||
"sensor.gas_consumption_2",
|
||||
"20.20",
|
||||
{
|
||||
"device_class": "gas",
|
||||
"unit_of_measurement": "m³",
|
||||
"state_class": "total_increasing",
|
||||
},
|
||||
)
|
||||
hass.states.async_set(
|
||||
"sensor.gas_flow_m3h",
|
||||
"1.5",
|
||||
{
|
||||
"device_class": "volume_flow_rate",
|
||||
"unit_of_measurement": UnitOfVolumeFlowRate.CUBIC_METERS_PER_HOUR,
|
||||
"state_class": "measurement",
|
||||
},
|
||||
)
|
||||
hass.states.async_set(
|
||||
"sensor.gas_flow_lmin",
|
||||
"25.0",
|
||||
{
|
||||
"device_class": "volume_flow_rate",
|
||||
"unit_of_measurement": UnitOfVolumeFlowRate.LITERS_PER_MINUTE,
|
||||
"state_class": "measurement",
|
||||
},
|
||||
)
|
||||
|
||||
result = await validate.async_validate(hass)
|
||||
assert result.as_dict() == {
|
||||
"energy_sources": [[], []],
|
||||
"device_consumption": [],
|
||||
"device_consumption_water": [],
|
||||
}
|
||||
|
||||
|
||||
async def test_validation_gas_flow_rate_recorder_untracked(
|
||||
hass: HomeAssistant, mock_energy_manager, mock_is_entity_recorded, mock_get_metadata
|
||||
) -> None:
|
||||
"""Test validating gas with flow rate sensor not tracked by recorder."""
|
||||
mock_is_entity_recorded["sensor.untracked_flow_rate"] = False
|
||||
|
||||
await mock_energy_manager.async_update(
|
||||
{
|
||||
"energy_sources": [
|
||||
{
|
||||
"type": "gas",
|
||||
"stat_energy_from": "sensor.gas_consumption",
|
||||
"stat_rate": "sensor.untracked_flow_rate",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
hass.states.async_set(
|
||||
"sensor.gas_consumption",
|
||||
"10.10",
|
||||
{
|
||||
"device_class": "gas",
|
||||
"unit_of_measurement": "m³",
|
||||
"state_class": "total_increasing",
|
||||
},
|
||||
)
|
||||
|
||||
result = await validate.async_validate(hass)
|
||||
assert result.as_dict() == {
|
||||
"energy_sources": [
|
||||
[
|
||||
{
|
||||
"type": "recorder_untracked",
|
||||
"affected_entities": {("sensor.untracked_flow_rate", None)},
|
||||
"translation_placeholders": None,
|
||||
}
|
||||
]
|
||||
],
|
||||
"device_consumption": [],
|
||||
"device_consumption_water": [],
|
||||
}
|
||||
|
||||
|
||||
async def test_validation_water_flow_rate_recorder_untracked(
|
||||
hass: HomeAssistant, mock_energy_manager, mock_is_entity_recorded, mock_get_metadata
|
||||
) -> None:
|
||||
"""Test validating water with flow rate sensor not tracked by recorder."""
|
||||
mock_is_entity_recorded["sensor.untracked_flow_rate"] = False
|
||||
|
||||
await mock_energy_manager.async_update(
|
||||
{
|
||||
"energy_sources": [
|
||||
{
|
||||
"type": "water",
|
||||
"stat_energy_from": "sensor.water_consumption",
|
||||
"stat_rate": "sensor.untracked_flow_rate",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
hass.states.async_set(
|
||||
"sensor.water_consumption",
|
||||
"10.10",
|
||||
{
|
||||
"device_class": "water",
|
||||
"unit_of_measurement": "m³",
|
||||
"state_class": "total_increasing",
|
||||
},
|
||||
)
|
||||
|
||||
result = await validate.async_validate(hass)
|
||||
assert result.as_dict() == {
|
||||
"energy_sources": [
|
||||
[
|
||||
{
|
||||
"type": "recorder_untracked",
|
||||
"affected_entities": {("sensor.untracked_flow_rate", None)},
|
||||
"translation_placeholders": None,
|
||||
}
|
||||
]
|
||||
],
|
||||
"device_consumption": [],
|
||||
"device_consumption_water": [],
|
||||
}
|
||||
Reference in New Issue
Block a user