4949
5050PARALLEL_UPDATES = 0
5151
52+ CHARGE_ENERGY_RESET_KEYS = frozenset (
53+ {"charge_state_charge_energy_added" , "dc_charging_energy_in" }
54+ )
55+ CHARGE_ENERGY_RESET_THRESHOLD = 1.0 # kWh
56+
5257BMS_STATES = {
5358 "Standby" : "standby" ,
5459 "Drive" : "drive" ,
@@ -238,7 +243,7 @@ class TeslemetryVehicleSensorEntityDescription(SensorEntityDescription):
238243 streaming_listener = lambda vehicle , callback : vehicle .listen_ACChargingEnergyIn (
239244 callback
240245 ),
241- state_class = SensorStateClass .TOTAL_INCREASING ,
246+ state_class = SensorStateClass .TOTAL ,
242247 native_unit_of_measurement = UnitOfEnergy .KILO_WATT_HOUR ,
243248 device_class = SensorDeviceClass .ENERGY ,
244249 suggested_display_precision = 1 ,
@@ -612,7 +617,7 @@ class TeslemetryVehicleSensorEntityDescription(SensorEntityDescription):
612617 streaming_listener = lambda vehicle , callback : vehicle .listen_DCChargingEnergyIn (
613618 callback
614619 ),
615- state_class = SensorStateClass .TOTAL_INCREASING ,
620+ state_class = SensorStateClass .TOTAL ,
616621 native_unit_of_measurement = UnitOfEnergy .KILO_WATT_HOUR ,
617622 device_class = SensorDeviceClass .ENERGY ,
618623 entity_category = EntityCategory .DIAGNOSTIC ,
@@ -1564,7 +1569,7 @@ class TeslemetrySensorEntityDescription(SensorEntityDescription):
15641569 native_unit_of_measurement = UnitOfEnergy .WATT_HOUR ,
15651570 suggested_unit_of_measurement = UnitOfEnergy .KILO_WATT_HOUR ,
15661571 suggested_display_precision = 2 ,
1567- state_class = SensorStateClass .TOTAL_INCREASING ,
1572+ state_class = SensorStateClass .TOTAL ,
15681573 entity_registry_enabled_default = (
15691574 key .startswith ("total" ) or key == "grid_energy_imported"
15701575 ),
@@ -1650,6 +1655,7 @@ class TeslemetryStreamSensorEntity(TeslemetryVehicleStreamEntity, RestoreSensor)
16501655 """Base class for Teslemetry vehicle streaming sensors."""
16511656
16521657 entity_description : TeslemetryVehicleSensorEntityDescription
1658+ _previous_value : float | None = None
16531659
16541660 def __init__ (
16551661 self ,
@@ -1666,6 +1672,15 @@ async def async_added_to_hass(self) -> None:
16661672
16671673 if (sensor_data := await self .async_get_last_sensor_data ()) is not None :
16681674 self ._attr_native_value = sensor_data .native_value
1675+ if isinstance (sensor_data .native_value , float | int ):
1676+ self ._previous_value = float (sensor_data .native_value )
1677+
1678+ if (
1679+ self .entity_description .key in CHARGE_ENERGY_RESET_KEYS
1680+ and (last_state := await self .async_get_last_state ()) is not None
1681+ and (last_reset := last_state .attributes .get ("last_reset" )) is not None
1682+ ):
1683+ self ._attr_last_reset = dt_util .parse_datetime (str (last_reset ))
16691684
16701685 if self .entity_description .streaming_listener is not None :
16711686 self .async_on_remove (
@@ -1676,6 +1691,15 @@ async def async_added_to_hass(self) -> None:
16761691
16771692 def _async_value_from_stream (self , value : StateType ) -> None :
16781693 """Update the value of the entity."""
1694+ if self .entity_description .key in CHARGE_ENERGY_RESET_KEYS and isinstance (
1695+ value , float | int
1696+ ):
1697+ if self ._previous_value is not None and (
1698+ value == 0
1699+ or value < self ._previous_value - CHARGE_ENERGY_RESET_THRESHOLD
1700+ ):
1701+ self ._attr_last_reset = dt_util .utcnow ()
1702+ self ._previous_value = float (value )
16791703 self ._attr_native_value = value
16801704 self .async_write_ha_state ()
16811705
@@ -1684,6 +1708,7 @@ class TeslemetryVehicleSensorEntity(TeslemetryVehiclePollingEntity, SensorEntity
16841708 """Base class for Teslemetry vehicle metric sensors."""
16851709
16861710 entity_description : TeslemetryVehicleSensorEntityDescription
1711+ _previous_value : float | None = None
16871712
16881713 def __init__ (
16891714 self ,
@@ -1698,9 +1723,17 @@ def _async_update_attrs(self) -> None:
16981723 """Update the attributes of the sensor."""
16991724 if self .entity_description .nullable or self ._value is not None :
17001725 self ._attr_available = True
1701- self ._attr_native_value = self .entity_description .polling_value_fn (
1702- self ._value
1703- )
1726+ new_value = self .entity_description .polling_value_fn (self ._value )
1727+ if self .entity_description .key in CHARGE_ENERGY_RESET_KEYS and isinstance (
1728+ new_value , float | int
1729+ ):
1730+ if self ._previous_value is not None and (
1731+ new_value == 0
1732+ or new_value < self ._previous_value - CHARGE_ENERGY_RESET_THRESHOLD
1733+ ):
1734+ self ._attr_last_reset = dt_util .utcnow ()
1735+ self ._previous_value = float (new_value )
1736+ self ._attr_native_value = new_value
17041737 else :
17051738 self ._attr_available = False
17061739 self ._attr_native_value = None
@@ -1852,6 +1885,7 @@ def __init__(
18521885 def _async_update_attrs (self ) -> None :
18531886 """Update the attributes of the sensor."""
18541887 self ._attr_native_value = self ._value
1888+ self ._attr_last_reset = self .coordinator .data .get ("_period_start" )
18551889
18561890
18571891class TeslemetryCreditBalanceSensor (RestoreSensor ):
0 commit comments