Volvo: fix distance to empty battery (#150278)

This commit is contained in:
Thomas D
2025-08-08 21:28:29 +02:00
committed by Franck Nijhof
parent 0c31ec9bb6
commit a1731cd210
4 changed files with 29 additions and 15 deletions

View File

@@ -3,7 +3,7 @@
from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass, replace
from dataclasses import dataclass
import logging
from typing import Any, cast
@@ -47,7 +47,6 @@ _LOGGER = logging.getLogger(__name__)
class VolvoSensorDescription(VolvoEntityDescription, SensorEntityDescription):
"""Describes a Volvo sensor entity."""
source_fields: list[str] | None = None
value_fn: Callable[[VolvoCarsValue], Any] | None = None
@@ -240,11 +239,15 @@ _DESCRIPTIONS: tuple[VolvoSensorDescription, ...] = (
"none",
],
),
# statistics & energy state endpoint
# statistics endpoint
# We're not using `electricRange` from the energy state endpoint because
# the official app seems to use `distanceToEmptyBattery`.
# In issue #150213, a user described to behavior as follows:
# - For a `distanceToEmptyBattery` of 250km, the `electricRange` was 150mi
# - For a `distanceToEmptyBattery` of 260km, the `electricRange` was 160mi
VolvoSensorDescription(
key="distance_to_empty_battery",
api_field="",
source_fields=["distanceToEmptyBattery", "electricRange"],
api_field="distanceToEmptyBattery",
native_unit_of_measurement=UnitOfLength.KILOMETERS,
device_class=SensorDeviceClass.DISTANCE,
state_class=SensorStateClass.MEASUREMENT,
@@ -362,12 +365,7 @@ async def async_setup_entry(
if description.key in added_keys:
continue
if description.source_fields:
for field in description.source_fields:
if field in coordinator.data:
description = replace(description, api_field=field)
_add_entity(coordinator, description)
elif description.api_field in coordinator.data:
if description.api_field in coordinator.data:
_add_entity(coordinator, description)
async_add_entities(entities)

View File

@@ -7,8 +7,8 @@
},
"electricRange": {
"status": "OK",
"value": 220,
"unit": "km",
"value": 150,
"unit": "mi",
"updatedAt": "2025-07-02T08:51:23Z"
},
"chargerConnectionStatus": {

View File

@@ -585,7 +585,7 @@
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '327',
'state': '250',
})
# ---
# name: test_sensor[ex30_2024][sensor.volvo_ex30_distance_to_service-entry]
@@ -2514,7 +2514,7 @@
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '220',
'state': '250',
})
# ---
# name: test_sensor[xc40_electric_2024][sensor.volvo_xc40_distance_to_service-entry]

View File

@@ -30,3 +30,19 @@ async def test_sensor(
assert await setup_integration()
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
@pytest.mark.parametrize(
"full_model",
["xc40_electric_2024"],
)
async def test_distance_to_empty_battery(
hass: HomeAssistant,
setup_integration: Callable[[], Awaitable[bool]],
) -> None:
"""Test using `distanceToEmptyBattery` instead of `electricRange`."""
with patch("homeassistant.components.volvo.PLATFORMS", [Platform.SENSOR]):
assert await setup_integration()
assert hass.states.get("sensor.volvo_xc40_distance_to_empty_battery").state == "250"