mirror of
https://github.com/home-assistant/core.git
synced 2025-04-24 09:17:53 +00:00
Re-add state_class total to sensor (#55103)
* Re-add state_class total to sensor * Make energy cost sensor enforce state_class total_increasing * Bump deprecation of last_reset for state_class measurement * Correct rebase mistakes
This commit is contained in:
parent
2634949999
commit
b99a22cd4d
@ -96,11 +96,14 @@ DEVICE_CLASSES_SCHEMA: Final = vol.All(vol.Lower, vol.In(DEVICE_CLASSES))
|
||||
|
||||
# The state represents a measurement in present time
|
||||
STATE_CLASS_MEASUREMENT: Final = "measurement"
|
||||
# The state represents a total amount, e.g. net energy consumption
|
||||
STATE_CLASS_TOTAL: Final = "total"
|
||||
# The state represents a monotonically increasing total, e.g. an amount of consumed gas
|
||||
STATE_CLASS_TOTAL_INCREASING: Final = "total_increasing"
|
||||
|
||||
STATE_CLASSES: Final[list[str]] = [
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
STATE_CLASS_TOTAL,
|
||||
STATE_CLASS_TOTAL_INCREASING,
|
||||
]
|
||||
|
||||
@ -214,9 +217,10 @@ class SensorEntity(Entity):
|
||||
report_issue = self._suggest_report_issue()
|
||||
_LOGGER.warning(
|
||||
"Entity %s (%s) with state_class %s has set last_reset. Setting "
|
||||
"last_reset is deprecated and will be unsupported from Home "
|
||||
"Assistant Core 2021.11. Please update your configuration if "
|
||||
"state_class is manually configured, otherwise %s",
|
||||
"last_reset for entities with state_class other than 'total' is "
|
||||
"deprecated and will be removed from Home Assistant Core 2021.11. "
|
||||
"Please update your configuration if state_class is manually "
|
||||
"configured, otherwise %s",
|
||||
self.entity_id,
|
||||
type(self),
|
||||
self.state_class,
|
||||
|
@ -15,6 +15,7 @@ from homeassistant.components.sensor import (
|
||||
DEVICE_CLASS_PRESSURE,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
STATE_CLASS_TOTAL,
|
||||
STATE_CLASS_TOTAL_INCREASING,
|
||||
STATE_CLASSES,
|
||||
)
|
||||
@ -56,10 +57,12 @@ DEVICE_CLASS_STATISTICS: dict[str, dict[str, set[str]]] = {
|
||||
DEVICE_CLASS_GAS: {"sum"},
|
||||
DEVICE_CLASS_MONETARY: {"sum"},
|
||||
},
|
||||
STATE_CLASS_TOTAL: {},
|
||||
STATE_CLASS_TOTAL_INCREASING: {},
|
||||
}
|
||||
DEFAULT_STATISTICS = {
|
||||
STATE_CLASS_MEASUREMENT: {"mean", "min", "max"},
|
||||
STATE_CLASS_TOTAL: {"sum"},
|
||||
STATE_CLASS_TOTAL_INCREASING: {"sum"},
|
||||
}
|
||||
|
||||
@ -389,7 +392,7 @@ def compile_statistics( # noqa: C901
|
||||
|
||||
for fstate, state in fstates:
|
||||
|
||||
# Deprecated, will be removed in Home Assistant 2021.10
|
||||
# Deprecated, will be removed in Home Assistant 2021.11
|
||||
if (
|
||||
"last_reset" not in state.attributes
|
||||
and state_class == STATE_CLASS_MEASUREMENT
|
||||
|
@ -8,6 +8,7 @@ import pytest
|
||||
from homeassistant.components.energy import data
|
||||
from homeassistant.components.sensor import (
|
||||
ATTR_STATE_CLASS,
|
||||
STATE_CLASS_TOTAL,
|
||||
STATE_CLASS_TOTAL_INCREASING,
|
||||
)
|
||||
from homeassistant.components.sensor.recorder import compile_statistics
|
||||
@ -357,7 +358,7 @@ async def test_cost_sensor_handle_gas(hass, hass_storage) -> None:
|
||||
assert state.state == "50.0"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("state_class", [None])
|
||||
@pytest.mark.parametrize("state_class", [None, STATE_CLASS_TOTAL])
|
||||
async def test_cost_sensor_wrong_state_class(
|
||||
hass, hass_storage, caplog, state_class
|
||||
) -> None:
|
||||
|
@ -45,10 +45,11 @@ async def test_deprecated_last_reset(hass, caplog, enable_custom_integrations):
|
||||
|
||||
assert (
|
||||
"Entity sensor.test (<class 'custom_components.test.sensor.MockSensor'>) "
|
||||
"with state_class measurement has set last_reset. Setting last_reset is "
|
||||
"deprecated and will be unsupported from Home Assistant Core 2021.11. Please "
|
||||
"update your configuration if state_class is manually configured, otherwise "
|
||||
"report it to the custom component author."
|
||||
"with state_class measurement has set last_reset. Setting last_reset for "
|
||||
"entities with state_class other than 'total' is deprecated and will be "
|
||||
"removed from Home Assistant Core 2021.11. Please update your configuration if "
|
||||
"state_class is manually configured, otherwise report it to the custom "
|
||||
"component author."
|
||||
) in caplog.text
|
||||
|
||||
|
||||
|
@ -191,7 +191,7 @@ def test_compile_hourly_statistics_unsupported(hass_recorder, caplog, attributes
|
||||
assert "Error while processing event StatisticsTask" not in caplog.text
|
||||
|
||||
|
||||
@pytest.mark.parametrize("state_class", ["measurement"])
|
||||
@pytest.mark.parametrize("state_class", ["measurement", "total"])
|
||||
@pytest.mark.parametrize(
|
||||
"device_class,unit,native_unit,factor",
|
||||
[
|
||||
@ -349,6 +349,88 @@ def test_compile_hourly_sum_statistics_amount_reset_every_state_change(
|
||||
assert "Error while processing event StatisticsTask" not in caplog.text
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"device_class,unit,native_unit,factor",
|
||||
[
|
||||
("energy", "kWh", "kWh", 1),
|
||||
("energy", "Wh", "kWh", 1 / 1000),
|
||||
("monetary", "EUR", "EUR", 1),
|
||||
("monetary", "SEK", "SEK", 1),
|
||||
("gas", "m³", "m³", 1),
|
||||
("gas", "ft³", "m³", 0.0283168466),
|
||||
],
|
||||
)
|
||||
def test_compile_hourly_sum_statistics_total_no_reset(
|
||||
hass_recorder, caplog, device_class, unit, native_unit, factor
|
||||
):
|
||||
"""Test compiling hourly statistics."""
|
||||
zero = dt_util.utcnow()
|
||||
hass = hass_recorder()
|
||||
recorder = hass.data[DATA_INSTANCE]
|
||||
setup_component(hass, "sensor", {})
|
||||
attributes = {
|
||||
"device_class": device_class,
|
||||
"state_class": "total",
|
||||
"unit_of_measurement": unit,
|
||||
}
|
||||
seq = [10, 15, 20, 10, 30, 40, 50, 60, 70]
|
||||
|
||||
four, eight, states = record_meter_states(
|
||||
hass, zero, "sensor.test1", attributes, seq
|
||||
)
|
||||
hist = history.get_significant_states(
|
||||
hass, zero - timedelta.resolution, eight + timedelta.resolution
|
||||
)
|
||||
assert dict(states)["sensor.test1"] == dict(hist)["sensor.test1"]
|
||||
|
||||
recorder.do_adhoc_statistics(period="hourly", start=zero)
|
||||
wait_recording_done(hass)
|
||||
recorder.do_adhoc_statistics(period="hourly", start=zero + timedelta(hours=1))
|
||||
wait_recording_done(hass)
|
||||
recorder.do_adhoc_statistics(period="hourly", start=zero + timedelta(hours=2))
|
||||
wait_recording_done(hass)
|
||||
statistic_ids = list_statistic_ids(hass)
|
||||
assert statistic_ids == [
|
||||
{"statistic_id": "sensor.test1", "unit_of_measurement": native_unit}
|
||||
]
|
||||
stats = statistics_during_period(hass, zero)
|
||||
assert stats == {
|
||||
"sensor.test1": [
|
||||
{
|
||||
"statistic_id": "sensor.test1",
|
||||
"start": process_timestamp_to_utc_isoformat(zero),
|
||||
"max": None,
|
||||
"mean": None,
|
||||
"min": None,
|
||||
"last_reset": None,
|
||||
"state": approx(factor * seq[2]),
|
||||
"sum": approx(factor * 10.0),
|
||||
},
|
||||
{
|
||||
"statistic_id": "sensor.test1",
|
||||
"start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)),
|
||||
"max": None,
|
||||
"mean": None,
|
||||
"min": None,
|
||||
"last_reset": None,
|
||||
"state": approx(factor * seq[5]),
|
||||
"sum": approx(factor * 30.0),
|
||||
},
|
||||
{
|
||||
"statistic_id": "sensor.test1",
|
||||
"start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=2)),
|
||||
"max": None,
|
||||
"mean": None,
|
||||
"min": None,
|
||||
"last_reset": None,
|
||||
"state": approx(factor * seq[8]),
|
||||
"sum": approx(factor * 60.0),
|
||||
},
|
||||
]
|
||||
}
|
||||
assert "Error while processing event StatisticsTask" not in caplog.text
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"device_class,unit,native_unit,factor",
|
||||
[
|
||||
|
Loading…
x
Reference in New Issue
Block a user