Fix gas validation ()

pull/55951/head
Paulus Schoutsen 2021-09-07 20:53:43 -07:00 committed by GitHub
parent efafe82799
commit ec337101dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 125 additions and 14 deletions
homeassistant/components/energy
tests/components/energy

View File

@ -1,6 +1,7 @@
"""Validate the energy preferences provide valid data."""
from __future__ import annotations
from collections.abc import Sequence
import dataclasses
from typing import Any
@ -10,12 +11,24 @@ from homeassistant.const import (
ENERGY_WATT_HOUR,
STATE_UNAVAILABLE,
STATE_UNKNOWN,
VOLUME_CUBIC_FEET,
VOLUME_CUBIC_METERS,
)
from homeassistant.core import HomeAssistant, callback, valid_entity_id
from . import data
from .const import DOMAIN
ENERGY_USAGE_UNITS = (ENERGY_KILO_WATT_HOUR, ENERGY_WATT_HOUR)
ENERGY_UNIT_ERROR = "entity_unexpected_unit_energy"
GAS_USAGE_UNITS = (
ENERGY_WATT_HOUR,
ENERGY_KILO_WATT_HOUR,
VOLUME_CUBIC_METERS,
VOLUME_CUBIC_FEET,
)
GAS_UNIT_ERROR = "entity_unexpected_unit_gas"
@dataclasses.dataclass
class ValidationIssue:
@ -43,8 +56,12 @@ class EnergyPreferencesValidation:
@callback
def _async_validate_energy_stat(
hass: HomeAssistant, stat_value: str, result: list[ValidationIssue]
def _async_validate_usage_stat(
hass: HomeAssistant,
stat_value: str,
allowed_units: Sequence[str],
unit_error: str,
result: list[ValidationIssue],
) -> None:
"""Validate a statistic."""
has_entity_source = valid_entity_id(stat_value)
@ -91,10 +108,8 @@ def _async_validate_energy_stat(
unit = state.attributes.get("unit_of_measurement")
if unit not in (ENERGY_KILO_WATT_HOUR, ENERGY_WATT_HOUR):
result.append(
ValidationIssue("entity_unexpected_unit_energy", stat_value, unit)
)
if unit not in allowed_units:
result.append(ValidationIssue(unit_error, stat_value, unit))
state_class = state.attributes.get("state_class")
@ -211,8 +226,12 @@ async def async_validate(hass: HomeAssistant) -> EnergyPreferencesValidation:
if source["type"] == "grid":
for flow in source["flow_from"]:
_async_validate_energy_stat(
hass, flow["stat_energy_from"], source_result
_async_validate_usage_stat(
hass,
flow["stat_energy_from"],
ENERGY_USAGE_UNITS,
ENERGY_UNIT_ERROR,
source_result,
)
if flow.get("stat_cost") is not None:
@ -229,7 +248,13 @@ async def async_validate(hass: HomeAssistant) -> EnergyPreferencesValidation:
)
for flow in source["flow_to"]:
_async_validate_energy_stat(hass, flow["stat_energy_to"], source_result)
_async_validate_usage_stat(
hass,
flow["stat_energy_to"],
ENERGY_USAGE_UNITS,
ENERGY_UNIT_ERROR,
source_result,
)
if flow.get("stat_compensation") is not None:
_async_validate_cost_stat(
@ -247,7 +272,13 @@ async def async_validate(hass: HomeAssistant) -> EnergyPreferencesValidation:
)
elif source["type"] == "gas":
_async_validate_energy_stat(hass, source["stat_energy_from"], source_result)
_async_validate_usage_stat(
hass,
source["stat_energy_from"],
GAS_USAGE_UNITS,
GAS_UNIT_ERROR,
source_result,
)
if source.get("stat_cost") is not None:
_async_validate_cost_stat(hass, source["stat_cost"], source_result)
@ -263,15 +294,39 @@ async def async_validate(hass: HomeAssistant) -> EnergyPreferencesValidation:
)
elif source["type"] == "solar":
_async_validate_energy_stat(hass, source["stat_energy_from"], source_result)
_async_validate_usage_stat(
hass,
source["stat_energy_from"],
ENERGY_USAGE_UNITS,
ENERGY_UNIT_ERROR,
source_result,
)
elif source["type"] == "battery":
_async_validate_energy_stat(hass, source["stat_energy_from"], source_result)
_async_validate_energy_stat(hass, source["stat_energy_to"], source_result)
_async_validate_usage_stat(
hass,
source["stat_energy_from"],
ENERGY_USAGE_UNITS,
ENERGY_UNIT_ERROR,
source_result,
)
_async_validate_usage_stat(
hass,
source["stat_energy_to"],
ENERGY_USAGE_UNITS,
ENERGY_UNIT_ERROR,
source_result,
)
for device in manager.data["device_consumption"]:
device_result: list[ValidationIssue] = []
result.device_consumption.append(device_result)
_async_validate_energy_stat(hass, device["stat_consumption"], device_result)
_async_validate_usage_stat(
hass,
device["stat_consumption"],
ENERGY_USAGE_UNITS,
ENERGY_UNIT_ERROR,
device_result,
)
return result

View File

@ -441,3 +441,59 @@ async def test_validation_grid_price_errors(
],
"device_consumption": [],
}
async def test_validation_gas(hass, mock_energy_manager, mock_is_entity_recorded):
"""Test validating gas with sensors for energy and cost/compensation."""
mock_is_entity_recorded["sensor.gas_cost_1"] = False
mock_is_entity_recorded["sensor.gas_compensation_1"] = False
await mock_energy_manager.async_update(
{
"energy_sources": [
{
"type": "gas",
"stat_energy_from": "sensor.gas_consumption_1",
"stat_cost": "sensor.gas_cost_1",
},
{
"type": "gas",
"stat_energy_from": "sensor.gas_consumption_2",
"stat_cost": "sensor.gas_cost_2",
},
]
}
)
hass.states.async_set(
"sensor.gas_consumption_1",
"10.10",
{"unit_of_measurement": "beers", "state_class": "total_increasing"},
)
hass.states.async_set(
"sensor.gas_consumption_2",
"10.10",
{"unit_of_measurement": "kWh", "state_class": "total_increasing"},
)
hass.states.async_set(
"sensor.gas_cost_2",
"10.10",
{"unit_of_measurement": "EUR/kWh", "state_class": "total_increasing"},
)
assert (await validate.async_validate(hass)).as_dict() == {
"energy_sources": [
[
{
"type": "entity_unexpected_unit_gas",
"identifier": "sensor.gas_consumption_1",
"value": "beers",
},
{
"type": "recorder_untracked",
"identifier": "sensor.gas_cost_1",
"value": None,
},
],
[],
],
"device_consumption": [],
}