Skip to content

Commit

Permalink
Get next service by distance/time (#713)
Browse files Browse the repository at this point in the history
* Get next service by distance/time

* Fix format
  • Loading branch information
rikroe authored Dec 25, 2024
1 parent 6dca9f8 commit e0e821a
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -251,14 +251,14 @@
"type": "BRAKE_FLUID"
},
{
"dateTime": "2024-12-01T00:00:00.000Z",
"dateTime": "2024-11-01T00:00:00.000Z",
"description": "",
"mileage": 50000,
"status": "OK",
"type": "VEHICLE_TUV"
},
{
"dateTime": "2024-12-01T00:00:00.000Z",
"dateTime": "2024-11-01T00:00:00.000Z",
"description": "",
"mileage": 50000,
"status": "OK",
Expand Down
14 changes: 11 additions & 3 deletions bimmer_connected/tests/test_vehicle_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,10 +210,16 @@ async def test_plugged_in_waiting_for_charge_window(caplog, bmw_fixture: respx.R
@pytest.mark.asyncio
async def test_condition_based_services(caplog, bmw_fixture: respx.Router):
"""Test condition based service messages."""
vehicle = (await prepare_account_with_vehicles()).get_vehicle(VIN_G26)
vehicle = (await prepare_account_with_vehicles()).get_vehicle(VIN_G01)

assert vehicle.condition_based_services.next_service_by_distance.due_distance == (50000, "km")
assert vehicle.condition_based_services.next_service_by_distance.service_type == "BRAKE_FLUID"

assert vehicle.condition_based_services.next_service_by_time.due_date == datetime.datetime(2024, 11, 1, tzinfo=UTC)
assert vehicle.condition_based_services.next_service_by_time.service_type == "VEHICLE_CHECK"

cbs = vehicle.condition_based_services.messages
assert len(cbs) == 5
assert len(cbs) == 4
assert cbs[0].state == ConditionBasedServiceStatus.OK
expected_cbs0 = datetime.datetime(year=2024, month=12, day=1, tzinfo=UTC)
assert expected_cbs0 == cbs[0].due_date
Expand All @@ -225,7 +231,7 @@ async def test_condition_based_services(caplog, bmw_fixture: respx.Router):
assert cbs[1].due_distance == (50000, "km")

assert cbs[2].state == ConditionBasedServiceStatus.OK
expected_cbs2 = datetime.datetime(year=2024, month=12, day=1, tzinfo=UTC)
expected_cbs2 = datetime.datetime(year=2024, month=11, day=1, tzinfo=UTC)
assert expected_cbs2 == cbs[2].due_date
assert cbs[2].due_distance == (50000, "km")

Expand Down Expand Up @@ -367,6 +373,7 @@ async def test_check_control_messages(caplog, bmw_fixture: respx.Router):
"""
vehicle = (await prepare_account_with_vehicles()).get_vehicle(VIN_G01)
assert vehicle.check_control_messages.has_check_control_messages is True
assert vehicle.check_control_messages.urgent_check_control_messages == "ENGINE_OIL"

ccms = vehicle.check_control_messages.messages
assert len(ccms) == 2
Expand All @@ -377,6 +384,7 @@ async def test_check_control_messages(caplog, bmw_fixture: respx.Router):

vehicle = (await prepare_account_with_vehicles()).get_vehicle(VIN_G20)
assert vehicle.check_control_messages.has_check_control_messages is False
assert vehicle.check_control_messages.urgent_check_control_messages is None

ccms = vehicle.check_control_messages.messages
assert len(ccms) == 2
Expand Down
33 changes: 33 additions & 0 deletions bimmer_connected/vehicle/reports.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ class ConditionBasedServiceReport(VehicleDataBase):
is_service_required: bool = False
"""Indicate if a service is required."""

next_service_by_distance: Optional[ConditionBasedService] = None
"""Next service by distance."""

next_service_by_time: Optional[ConditionBasedService] = None
"""Next service by due date."""

@classmethod
def _parse_vehicle_data(cls, vehicle_data: Dict) -> Optional[Dict]:
"""Parse doors and windows."""
Expand All @@ -64,6 +70,26 @@ def _parse_vehicle_data(cls, vehicle_data: Dict) -> Optional[Dict]:
retval["messages"] = [ConditionBasedService.from_api_entry(**m) for m in messages]
retval["is_service_required"] = any((m.state != ConditionBasedServiceStatus.OK) for m in retval["messages"])

retval["next_service_by_distance"] = next(
iter(
sorted(
[m for m in retval["messages"] if m.due_distance.value is not None],
key=lambda x: f"{x.due_distance.value:010}-{x.service_type}",
)
),
None,
)

retval["next_service_by_time"] = next(
iter(
sorted(
[m for m in retval["messages"] if m.due_date is not None],
key=lambda x: f"{x.due_date!s}-{x.service_type}",
)
),
None,
)

return retval


Expand Down Expand Up @@ -108,6 +134,8 @@ class CheckControlMessageReport(VehicleDataBase):
has_check_control_messages: bool = False
"""Indicate if check control messages are present."""

urgent_check_control_messages: Optional[str] = None

@classmethod
def _parse_vehicle_data(cls, vehicle_data: Dict) -> Optional[Dict]:
"""Parse doors and windows."""
Expand All @@ -116,6 +144,11 @@ def _parse_vehicle_data(cls, vehicle_data: Dict) -> Optional[Dict]:
if ATTR_STATE in vehicle_data and (messages := vehicle_data[ATTR_STATE].get("checkControlMessages")):
retval["messages"] = [CheckControlMessage.from_api_entry(**m) for m in messages if m["severity"] != "OK"]
retval["has_check_control_messages"] = len([m for m in retval["messages"] if m.state != "LOW"]) > 0
retval["urgent_check_control_messages"] = (
", ".join([m.description_short for m in retval["messages"] if m.state != "LOW"])
if retval["has_check_control_messages"]
else None
)

return retval

Expand Down

0 comments on commit e0e821a

Please sign in to comment.