Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions homeassistant/components/utility_meter/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

from homeassistant.components.sensor import (
ATTR_LAST_RESET,
DEVICE_CLASS_STATE_CLASSES,
DEVICE_CLASS_UNITS,
RestoreSensor,
SensorDeviceClass,
Expand Down Expand Up @@ -695,12 +696,18 @@ def device_class(self) -> SensorDeviceClass | None:

@property
def state_class(self) -> SensorStateClass:
"""Return the device class of the sensor."""
return (
SensorStateClass.TOTAL
if self._sensor_net_consumption
else SensorStateClass.TOTAL_INCREASING
)
"""Return the state class of the sensor."""
if self._sensor_net_consumption:
return SensorStateClass.TOTAL
if (
self._input_device_class is not None
and SensorStateClass.TOTAL_INCREASING
not in DEVICE_CLASS_STATE_CLASSES.get(
self._input_device_class, {SensorStateClass.TOTAL_INCREASING}
)
):
return SensorStateClass.TOTAL
return SensorStateClass.TOTAL_INCREASING

@property
def extra_state_attributes(self) -> dict[str, Any]:
Expand Down
34 changes: 34 additions & 0 deletions tests/components/utility_meter/test_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,40 @@ async def test_device_class(
assert state.attributes.get(attr) == value


async def test_state_class_monetary_device_class(hass: HomeAssistant) -> None:
"""Test that monetary device class uses state_class total, not total_increasing."""
assert await async_setup_component(
hass,
DOMAIN,
{
"utility_meter": {
"cost_meter": {
"source": "sensor.energy_cost",
}
}
},
)
await hass.async_block_till_done()

hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED)
await hass.async_block_till_done()

hass.states.async_set(
"sensor.energy_cost",
2,
{
ATTR_DEVICE_CLASS: SensorDeviceClass.MONETARY,
ATTR_UNIT_OF_MEASUREMENT: "EUR",
},
)
await hass.async_block_till_done()

state = hass.states.get("sensor.cost_meter")
assert state is not None
assert state.attributes.get(ATTR_DEVICE_CLASS) == SensorDeviceClass.MONETARY
assert state.attributes.get(ATTR_STATE_CLASS) is SensorStateClass.TOTAL


@pytest.mark.parametrize(
("yaml_config", "config_entry_config"),
[
Expand Down