mirror of
https://github.com/home-assistant/core.git
synced 2025-08-31 02:11:32 +02:00
Volvo: Skip unsupported API fields (#150285)
This commit is contained in:
@@ -15,6 +15,7 @@ from volvocarsapi.models import (
|
||||
VolvoAuthException,
|
||||
VolvoCarsApiBaseModel,
|
||||
VolvoCarsValue,
|
||||
VolvoCarsValueStatusField,
|
||||
VolvoCarsVehicle,
|
||||
)
|
||||
|
||||
@@ -36,6 +37,16 @@ type VolvoConfigEntry = ConfigEntry[tuple[VolvoBaseCoordinator, ...]]
|
||||
type CoordinatorData = dict[str, VolvoCarsApiBaseModel | None]
|
||||
|
||||
|
||||
def _is_invalid_api_field(field: VolvoCarsApiBaseModel | None) -> bool:
|
||||
if not field:
|
||||
return True
|
||||
|
||||
if isinstance(field, VolvoCarsValueStatusField) and field.status == "ERROR":
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
class VolvoBaseCoordinator(DataUpdateCoordinator[CoordinatorData]):
|
||||
"""Volvo base coordinator."""
|
||||
|
||||
@@ -121,7 +132,13 @@ class VolvoBaseCoordinator(DataUpdateCoordinator[CoordinatorData]):
|
||||
translation_key="update_failed",
|
||||
) from result
|
||||
|
||||
data |= cast(CoordinatorData, result)
|
||||
api_data = cast(CoordinatorData, result)
|
||||
data |= {
|
||||
key: field
|
||||
for key, field in api_data.items()
|
||||
if not _is_invalid_api_field(field)
|
||||
}
|
||||
|
||||
valid = True
|
||||
|
||||
# Raise an error if not a single API call succeeded
|
||||
|
@@ -20,6 +20,12 @@ _MODEL_SPECIFIC_RESPONSES = {
|
||||
"statistics",
|
||||
"vehicle",
|
||||
],
|
||||
"xc60_phev_2020": [
|
||||
"energy_capabilities",
|
||||
"energy_state",
|
||||
"statistics",
|
||||
"vehicle",
|
||||
],
|
||||
"xc90_petrol_2019": ["commands", "statistics", "vehicle"],
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"isSupported": true,
|
||||
"batteryChargeLevel": {
|
||||
"isSupported": false
|
||||
},
|
||||
"electricRange": {
|
||||
"isSupported": false
|
||||
},
|
||||
"chargerConnectionStatus": {
|
||||
"isSupported": true
|
||||
},
|
||||
"chargingSystemStatus": {
|
||||
"isSupported": true
|
||||
},
|
||||
"chargingType": {
|
||||
"isSupported": false
|
||||
},
|
||||
"chargerPowerStatus": {
|
||||
"isSupported": false
|
||||
},
|
||||
"estimatedChargingTimeToTargetBatteryChargeLevel": {
|
||||
"isSupported": false
|
||||
},
|
||||
"targetBatteryChargeLevel": {
|
||||
"isSupported": true
|
||||
},
|
||||
"chargingCurrentLimit": {
|
||||
"isSupported": false
|
||||
},
|
||||
"chargingPower": {
|
||||
"isSupported": false
|
||||
}
|
||||
}
|
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"batteryChargeLevel": {
|
||||
"status": "ERROR",
|
||||
"code": "NOT_SUPPORTED",
|
||||
"message": "Resource is not supported for this vehicle"
|
||||
},
|
||||
"electricRange": {
|
||||
"status": "ERROR",
|
||||
"code": "NOT_SUPPORTED",
|
||||
"message": "Resource is not supported for this vehicle"
|
||||
},
|
||||
"chargerConnectionStatus": {
|
||||
"status": "OK",
|
||||
"value": "DISCONNECTED",
|
||||
"updatedAt": "2025-08-07T20:29:18Z"
|
||||
},
|
||||
"chargingStatus": {
|
||||
"status": "OK",
|
||||
"value": "IDLE",
|
||||
"updatedAt": "2025-08-07T20:29:18Z"
|
||||
},
|
||||
"chargingType": {
|
||||
"status": "ERROR",
|
||||
"code": "NOT_SUPPORTED",
|
||||
"message": "Resource is not supported for this vehicle"
|
||||
},
|
||||
"chargerPowerStatus": {
|
||||
"status": "ERROR",
|
||||
"code": "NOT_SUPPORTED",
|
||||
"message": "Resource is not supported for this vehicle"
|
||||
},
|
||||
"estimatedChargingTimeToTargetBatteryChargeLevel": {
|
||||
"status": "ERROR",
|
||||
"code": "NOT_SUPPORTED",
|
||||
"message": "Resource is not supported for this vehicle"
|
||||
},
|
||||
"chargingCurrentLimit": {
|
||||
"status": "ERROR",
|
||||
"code": "NOT_SUPPORTED",
|
||||
"message": "Resource is not supported for this vehicle"
|
||||
},
|
||||
"targetBatteryChargeLevel": {
|
||||
"status": "ERROR",
|
||||
"code": "NOT_SUPPORTED",
|
||||
"message": "Resource is not supported for this vehicle"
|
||||
},
|
||||
"chargingPower": {
|
||||
"status": "ERROR",
|
||||
"code": "NOT_SUPPORTED",
|
||||
"message": "Resource is not supported for this vehicle"
|
||||
}
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"averageFuelConsumption": {
|
||||
"value": 4.0,
|
||||
"unit": "l/100km",
|
||||
"timestamp": "2025-08-07T20:29:18.343Z"
|
||||
},
|
||||
"averageSpeed": {
|
||||
"value": 65,
|
||||
"unit": "km/h",
|
||||
"timestamp": "2025-08-07T20:29:18.343Z"
|
||||
},
|
||||
"tripMeterManual": {
|
||||
"value": 219.7,
|
||||
"unit": "km",
|
||||
"timestamp": "2025-08-07T20:29:18.343Z"
|
||||
},
|
||||
"tripMeterAutomatic": {
|
||||
"value": 0.0,
|
||||
"unit": "km",
|
||||
"timestamp": "2025-08-07T20:29:18.343Z"
|
||||
},
|
||||
"distanceToEmptyTank": {
|
||||
"value": 920,
|
||||
"unit": "km",
|
||||
"timestamp": "2025-08-07T20:29:18.343Z"
|
||||
},
|
||||
"distanceToEmptyBattery": {
|
||||
"value": 29,
|
||||
"unit": "km",
|
||||
"timestamp": "2025-08-07T20:29:18.343Z"
|
||||
}
|
||||
}
|
17
tests/components/volvo/fixtures/xc60_phev_2020/vehicle.json
Normal file
17
tests/components/volvo/fixtures/xc60_phev_2020/vehicle.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"vin": "YV1ABCDEFG1234567",
|
||||
"modelYear": 2020,
|
||||
"gearbox": "AUTOMATIC",
|
||||
"fuelType": "PETROL/ELECTRIC",
|
||||
"externalColour": "Bright Silver",
|
||||
"batteryCapacityKWH": 11.832,
|
||||
"images": {
|
||||
"exteriorImageUrl": "https://cas.volvocars.com/image/dynamic/MY20_0000/123/exterior-v1/_/default.png?market=se&client=public-api-engineering&angle=1&bg=00000000&w=1920",
|
||||
"internalImageUrl": "https://cas.volvocars.com/image/dynamic/MY20_0000/123/interior-v1/_/default.jpg?market=se&client=public-api-engineering&angle=0&w=1920"
|
||||
},
|
||||
"descriptions": {
|
||||
"model": "XC60",
|
||||
"upholstery": "CHARCOAL/LEABR3/CHARC/SPO",
|
||||
"steering": "LEFT"
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -15,7 +15,13 @@ from tests.common import MockConfigEntry, snapshot_platform
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"full_model",
|
||||
["ex30_2024", "s90_diesel_2018", "xc40_electric_2024", "xc90_petrol_2019"],
|
||||
[
|
||||
"ex30_2024",
|
||||
"s90_diesel_2018",
|
||||
"xc40_electric_2024",
|
||||
"xc60_phev_2020",
|
||||
"xc90_petrol_2019",
|
||||
],
|
||||
)
|
||||
async def test_sensor(
|
||||
hass: HomeAssistant,
|
||||
@@ -46,3 +52,20 @@ async def test_distance_to_empty_battery(
|
||||
assert await setup_integration()
|
||||
|
||||
assert hass.states.get("sensor.volvo_xc40_distance_to_empty_battery").state == "250"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("full_model", "short_model"),
|
||||
[("ex30_2024", "ex30"), ("xc60_phev_2020", "xc60")],
|
||||
)
|
||||
async def test_skip_invalid_api_fields(
|
||||
hass: HomeAssistant,
|
||||
setup_integration: Callable[[], Awaitable[bool]],
|
||||
short_model: str,
|
||||
) -> None:
|
||||
"""Test if invalid values are not creating a sensor."""
|
||||
|
||||
with patch("homeassistant.components.volvo.PLATFORMS", [Platform.SENSOR]):
|
||||
assert await setup_integration()
|
||||
|
||||
assert not hass.states.get(f"sensor.volvo_{short_model}_charging_power")
|
||||
|
Reference in New Issue
Block a user