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 __future__ import annotations
from collections.abc import Callable from collections.abc import Callable
from dataclasses import dataclass, replace from dataclasses import dataclass
import logging import logging
from typing import Any, cast from typing import Any, cast
@@ -47,7 +47,6 @@ _LOGGER = logging.getLogger(__name__)
class VolvoSensorDescription(VolvoEntityDescription, SensorEntityDescription): class VolvoSensorDescription(VolvoEntityDescription, SensorEntityDescription):
"""Describes a Volvo sensor entity.""" """Describes a Volvo sensor entity."""
source_fields: list[str] | None = None
value_fn: Callable[[VolvoCarsValue], Any] | None = None value_fn: Callable[[VolvoCarsValue], Any] | None = None
@@ -240,11 +239,15 @@ _DESCRIPTIONS: tuple[VolvoSensorDescription, ...] = (
"none", "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( VolvoSensorDescription(
key="distance_to_empty_battery", key="distance_to_empty_battery",
api_field="", api_field="distanceToEmptyBattery",
source_fields=["distanceToEmptyBattery", "electricRange"],
native_unit_of_measurement=UnitOfLength.KILOMETERS, native_unit_of_measurement=UnitOfLength.KILOMETERS,
device_class=SensorDeviceClass.DISTANCE, device_class=SensorDeviceClass.DISTANCE,
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
@@ -362,12 +365,7 @@ async def async_setup_entry(
if description.key in added_keys: if description.key in added_keys:
continue continue
if description.source_fields: if description.api_field in coordinator.data:
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:
_add_entity(coordinator, description) _add_entity(coordinator, description)
async_add_entities(entities) async_add_entities(entities)

View File

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

View File

@@ -585,7 +585,7 @@
'last_changed': <ANY>, 'last_changed': <ANY>,
'last_reported': <ANY>, 'last_reported': <ANY>,
'last_updated': <ANY>, 'last_updated': <ANY>,
'state': '327', 'state': '250',
}) })
# --- # ---
# name: test_sensor[ex30_2024][sensor.volvo_ex30_distance_to_service-entry] # name: test_sensor[ex30_2024][sensor.volvo_ex30_distance_to_service-entry]
@@ -2514,7 +2514,7 @@
'last_changed': <ANY>, 'last_changed': <ANY>,
'last_reported': <ANY>, 'last_reported': <ANY>,
'last_updated': <ANY>, 'last_updated': <ANY>,
'state': '220', 'state': '250',
}) })
# --- # ---
# name: test_sensor[xc40_electric_2024][sensor.volvo_xc40_distance_to_service-entry] # 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() assert await setup_integration()
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id) 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"