Remove last_reset attribute and set state class to total_increasing for Shelly energy sensors (#54800)

This commit is contained in:
Erik Montnemery 2021-08-18 13:13:35 +02:00 committed by GitHub
parent 1280a38e0f
commit dcb2a211e5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 7 additions and 55 deletions

View file

@ -109,6 +109,3 @@ KELVIN_MIN_VALUE_WHITE: Final = 2700
KELVIN_MIN_VALUE_COLOR: Final = 3000 KELVIN_MIN_VALUE_COLOR: Final = 3000
UPTIME_DEVIATION: Final = 5 UPTIME_DEVIATION: Final = 5
LAST_RESET_UPTIME: Final = "uptime"
LAST_RESET_NEVER: Final = "never"

View file

@ -179,7 +179,6 @@ class BlockAttributeDescription:
# Callable (settings, block), return true if entity should be removed # Callable (settings, block), return true if entity should be removed
removal_condition: Callable[[dict, aioshelly.Block], bool] | None = None removal_condition: Callable[[dict, aioshelly.Block], bool] | None = None
extra_state_attributes: Callable[[aioshelly.Block], dict | None] | None = None extra_state_attributes: Callable[[aioshelly.Block], dict | None] | None = None
last_reset: str | None = None
@dataclass @dataclass

View file

@ -1,12 +1,8 @@
"""Sensor for Shelly.""" """Sensor for Shelly."""
from __future__ import annotations from __future__ import annotations
from datetime import timedelta
import logging
from typing import Final, cast from typing import Final, cast
import aioshelly
from homeassistant.components import sensor from homeassistant.components import sensor
from homeassistant.components.sensor import SensorEntity from homeassistant.components.sensor import SensorEntity
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
@ -24,10 +20,8 @@ from homeassistant.const import (
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType from homeassistant.helpers.typing import StateType
from homeassistant.util import dt
from . import ShellyDeviceWrapper from .const import SHAIR_MAX_WORK_HOURS
from .const import LAST_RESET_NEVER, LAST_RESET_UPTIME, SHAIR_MAX_WORK_HOURS
from .entity import ( from .entity import (
BlockAttributeDescription, BlockAttributeDescription,
RestAttributeDescription, RestAttributeDescription,
@ -39,8 +33,6 @@ from .entity import (
) )
from .utils import get_device_uptime, temperature_unit from .utils import get_device_uptime, temperature_unit
_LOGGER: Final = logging.getLogger(__name__)
SENSORS: Final = { SENSORS: Final = {
("device", "battery"): BlockAttributeDescription( ("device", "battery"): BlockAttributeDescription(
name="Battery", name="Battery",
@ -119,49 +111,43 @@ SENSORS: Final = {
unit=ENERGY_KILO_WATT_HOUR, unit=ENERGY_KILO_WATT_HOUR,
value=lambda value: round(value / 60 / 1000, 2), value=lambda value: round(value / 60 / 1000, 2),
device_class=sensor.DEVICE_CLASS_ENERGY, device_class=sensor.DEVICE_CLASS_ENERGY,
state_class=sensor.STATE_CLASS_MEASUREMENT, state_class=sensor.STATE_CLASS_TOTAL_INCREASING,
last_reset=LAST_RESET_UPTIME,
), ),
("emeter", "energy"): BlockAttributeDescription( ("emeter", "energy"): BlockAttributeDescription(
name="Energy", name="Energy",
unit=ENERGY_KILO_WATT_HOUR, unit=ENERGY_KILO_WATT_HOUR,
value=lambda value: round(value / 1000, 2), value=lambda value: round(value / 1000, 2),
device_class=sensor.DEVICE_CLASS_ENERGY, device_class=sensor.DEVICE_CLASS_ENERGY,
state_class=sensor.STATE_CLASS_MEASUREMENT, state_class=sensor.STATE_CLASS_TOTAL_INCREASING,
last_reset=LAST_RESET_NEVER,
), ),
("emeter", "energyReturned"): BlockAttributeDescription( ("emeter", "energyReturned"): BlockAttributeDescription(
name="Energy Returned", name="Energy Returned",
unit=ENERGY_KILO_WATT_HOUR, unit=ENERGY_KILO_WATT_HOUR,
value=lambda value: round(value / 1000, 2), value=lambda value: round(value / 1000, 2),
device_class=sensor.DEVICE_CLASS_ENERGY, device_class=sensor.DEVICE_CLASS_ENERGY,
state_class=sensor.STATE_CLASS_MEASUREMENT, state_class=sensor.STATE_CLASS_TOTAL_INCREASING,
last_reset=LAST_RESET_NEVER,
), ),
("light", "energy"): BlockAttributeDescription( ("light", "energy"): BlockAttributeDescription(
name="Energy", name="Energy",
unit=ENERGY_KILO_WATT_HOUR, unit=ENERGY_KILO_WATT_HOUR,
value=lambda value: round(value / 60 / 1000, 2), value=lambda value: round(value / 60 / 1000, 2),
device_class=sensor.DEVICE_CLASS_ENERGY, device_class=sensor.DEVICE_CLASS_ENERGY,
state_class=sensor.STATE_CLASS_MEASUREMENT, state_class=sensor.STATE_CLASS_TOTAL_INCREASING,
default_enabled=False, default_enabled=False,
last_reset=LAST_RESET_UPTIME,
), ),
("relay", "energy"): BlockAttributeDescription( ("relay", "energy"): BlockAttributeDescription(
name="Energy", name="Energy",
unit=ENERGY_KILO_WATT_HOUR, unit=ENERGY_KILO_WATT_HOUR,
value=lambda value: round(value / 60 / 1000, 2), value=lambda value: round(value / 60 / 1000, 2),
device_class=sensor.DEVICE_CLASS_ENERGY, device_class=sensor.DEVICE_CLASS_ENERGY,
state_class=sensor.STATE_CLASS_MEASUREMENT, state_class=sensor.STATE_CLASS_TOTAL_INCREASING,
last_reset=LAST_RESET_UPTIME,
), ),
("roller", "rollerEnergy"): BlockAttributeDescription( ("roller", "rollerEnergy"): BlockAttributeDescription(
name="Energy", name="Energy",
unit=ENERGY_KILO_WATT_HOUR, unit=ENERGY_KILO_WATT_HOUR,
value=lambda value: round(value / 60 / 1000, 2), value=lambda value: round(value / 60 / 1000, 2),
device_class=sensor.DEVICE_CLASS_ENERGY, device_class=sensor.DEVICE_CLASS_ENERGY,
state_class=sensor.STATE_CLASS_MEASUREMENT, state_class=sensor.STATE_CLASS_TOTAL_INCREASING,
last_reset=LAST_RESET_UPTIME,
), ),
("sensor", "concentration"): BlockAttributeDescription( ("sensor", "concentration"): BlockAttributeDescription(
name="Gas Concentration", name="Gas Concentration",
@ -261,39 +247,9 @@ async def async_setup_entry(
class ShellySensor(ShellyBlockAttributeEntity, SensorEntity): class ShellySensor(ShellyBlockAttributeEntity, SensorEntity):
"""Represent a shelly sensor.""" """Represent a shelly sensor."""
def __init__(
self,
wrapper: ShellyDeviceWrapper,
block: aioshelly.Block,
attribute: str,
description: BlockAttributeDescription,
) -> None:
"""Initialize sensor."""
super().__init__(wrapper, block, attribute, description)
self._last_value: float | None = None
if description.last_reset == LAST_RESET_NEVER:
self._attr_last_reset = dt.utc_from_timestamp(0)
elif description.last_reset == LAST_RESET_UPTIME:
self._attr_last_reset = (
dt.utcnow() - timedelta(seconds=wrapper.device.status["uptime"])
).replace(second=0, microsecond=0)
@property @property
def native_value(self) -> StateType: def native_value(self) -> StateType:
"""Return value of sensor.""" """Return value of sensor."""
if (
self.description.last_reset == LAST_RESET_UPTIME
and self.attribute_value is not None
):
value = cast(float, self.attribute_value)
if self._last_value and self._last_value > value:
self._attr_last_reset = dt.utcnow().replace(second=0, microsecond=0)
_LOGGER.info("Energy reset detected for entity %s", self.name)
self._last_value = value
return self.attribute_value return self.attribute_value
@property @property