Energy validation: Require last_reset attribute to be set for state_class measurement energy and cost sensors (#56254)

* Require last_reset attribute to be set for measurement state_class

* Tweak

* Improve tests

* Lint

Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
This commit is contained in:
Erik Montnemery 2021-09-23 06:48:37 +02:00 committed by GitHub
parent 974376a8de
commit 83156fb9ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 6 deletions

View File

@ -135,12 +135,20 @@ def _async_validate_usage_stat(
if state_class not in allowed_state_classes:
result.append(
ValidationIssue(
"entity_unexpected_state_class_total_increasing",
"entity_unexpected_state_class",
stat_value,
state_class,
)
)
if (
state_class == sensor.STATE_CLASS_MEASUREMENT
and sensor.ATTR_LAST_RESET not in state.attributes
):
result.append(
ValidationIssue("entity_state_class_measurement_no_last_reset", stat_value)
)
@callback
def _async_validate_price_entity(
@ -212,9 +220,15 @@ def _async_validate_cost_stat(
]
if state_class not in supported_state_classes:
result.append(
ValidationIssue(
"entity_unexpected_state_class_total_increasing", stat_id, state_class
)
ValidationIssue("entity_unexpected_state_class", stat_id, state_class)
)
if (
state_class == sensor.STATE_CLASS_MEASUREMENT
and sensor.ATTR_LAST_RESET not in state.attributes
):
result.append(
ValidationIssue("entity_state_class_measurement_no_last_reset", stat_id)
)

View File

@ -39,7 +39,16 @@ async def test_validation_empty_config(hass):
}
async def test_validation(hass, mock_energy_manager):
@pytest.mark.parametrize(
"state_class, extra",
[
("total_increasing", {}),
("total", {}),
("total", {"last_reset": "abc"}),
("measurement", {"last_reset": "abc"}),
],
)
async def test_validation(hass, mock_energy_manager, state_class, extra):
"""Test validating success."""
for key in ("device_cons", "battery_import", "battery_export", "solar_production"):
hass.states.async_set(
@ -48,7 +57,8 @@ async def test_validation(hass, mock_energy_manager):
{
"device_class": "energy",
"unit_of_measurement": "kWh",
"state_class": "total_increasing",
"state_class": state_class,
**extra,
},
)
@ -190,6 +200,35 @@ async def test_validation_device_consumption_recorder_not_tracked(
}
async def test_validation_device_consumption_no_last_reset(hass, mock_energy_manager):
"""Test validating device based on untracked entity."""
await mock_energy_manager.async_update(
{"device_consumption": [{"stat_consumption": "sensor.no_last_reset"}]}
)
hass.states.async_set(
"sensor.no_last_reset",
"10.10",
{
"device_class": "energy",
"unit_of_measurement": "kWh",
"state_class": "measurement",
},
)
assert (await validate.async_validate(hass)).as_dict() == {
"energy_sources": [],
"device_consumption": [
[
{
"type": "entity_state_class_measurement_no_last_reset",
"identifier": "sensor.no_last_reset",
"value": None,
}
]
],
}
async def test_validation_solar(hass, mock_energy_manager):
"""Test validating missing stat for device."""
await mock_energy_manager.async_update(