Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add weekly & yearly summaries #265

Merged
merged 161 commits into from
Jan 2, 2024
Merged
Show file tree
Hide file tree
Changes from 159 commits
Commits
Show all changes
161 commits
Select commit Hold shift + click to select a range
6e7051f
Basics working.
Nov 17, 2023
6d25366
Moved all calls to the Vehicle class.
Nov 18, 2023
c03b794
Got a "setter" working. Alias can now be set.
Nov 20, 2023
b2b6070
Update dependencies
Nov 20, 2023
fadb8ea
Added /v1/global/remote/status which brings the door/window sensors (…
Nov 20, 2023
91dec31
Added basic trips endpoint using pydantic models. Needs reviewing for…
Nov 22, 2023
898c977
Used python 3.9 compatible Optional[x] instead of 'x | None'
joro75 Nov 25, 2023
afc95a1
fix type hints in logs utils
CM000n Nov 27, 2023
e7a2c16
Run poetry update
CM000n Nov 27, 2023
07be5f9
Merge branch 'master' into master
CM000n Nov 27, 2023
55e72ff
emoves redundancy by combining censor_dict and censor_all into a sing…
CM000n Nov 27, 2023
4139cf5
Merge branch 'master' of github.com:GitOldGrumpy/mytoyota
CM000n Nov 27, 2023
14254c7
emoves redundancy by combining censor_dict and censor_all into a sing…
CM000n Nov 27, 2023
1487d7e
fix type hint
CM000n Nov 27, 2023
7f5283e
fix type hint
CM000n Nov 27, 2023
eeb906e
Fix type hints in api.py
CM000n Nov 27, 2023
3023210
use inline variable that is imidiatley returned with awared timezone …
CM000n Nov 27, 2023
342658c
lift code into else after jump into control flow
CM000n Nov 27, 2023
263af21
adjsut more type hints
CM000n Nov 27, 2023
d5eb289
fiy pylint errors
CM000n Nov 27, 2023
19c0989
add docstrings
CM000n Nov 27, 2023
a79e042
censor also link with vin from output and dump all by default
CM000n Nov 27, 2023
74553e2
adjust models and print trips in _dump_all()
CM000n Nov 27, 2023
5eddd88
add healt_status model
CM000n Nov 27, 2023
7e7384c
cencor vin in HealtStatusModel
CM000n Nov 27, 2023
5730069
use more generic string cencoring
CM000n Nov 27, 2023
830c01c
add location model
CM000n Nov 27, 2023
18d980e
Fix typing for 3.8. Added Account Model.
Nov 27, 2023
5f85029
Merge branch 'master' into master
CM000n Nov 27, 2023
31a0844
Further Updates!
Nov 27, 2023
ff382ae
Merge branch 'master' of github.com:GitOldGrumpy/mytoyota
Nov 27, 2023
4476e6b
Fix typo
Nov 27, 2023
45eff5b
add vscode to gitignore
CM000n Nov 27, 2023
1c0e946
Added/Updated the following endpoints, with basic tests:
Nov 27, 2023
0bfefe7
Merge branch 'master' of github.com:GitOldGrumpy/mytoyota
Nov 27, 2023
6f66503
Merge branch 'master' into master
CM000n Nov 27, 2023
0795c71
WIP. _STILL BROKEN_
Nov 28, 2023
75bd062
fix trips model and adjust payload unpacking
CM000n Nov 28, 2023
982afae
Fix alias names and data types
CM000n Nov 28, 2023
72e3e5e
Adjust StatusModel to inherit from it
CM000n Nov 28, 2023
556a164
Merge remote-tracking branch 'refs/remotes/origin/master'
Nov 28, 2023
da3b1ff
Use car_ prefix to avoid pydantic namespace error
CM000n Nov 28, 2023
26801c4
adjust request type for vehicles endpoint
CM000n Nov 28, 2023
93c87be
adjust request type for notification endpoint
CM000n Nov 28, 2023
d214b36
replace append loop with list extend
CM000n Nov 28, 2023
6672bb0
Adjust how information is received from VehicleGuidModel in Vehicle c…
CM000n Nov 28, 2023
6db3125
Comment out non supported feature from now in simple_client_test.py
CM000n Nov 28, 2023
4f13c6d
fix notifications endpoint model
CM000n Nov 28, 2023
3781f8d
add RemoteStatusResponseModel
CM000n Nov 28, 2023
ad1eb53
add RemoteStatusResponseModel
CM000n Nov 28, 2023
590a582
add telemtry model
CM000n Nov 28, 2023
bc7415f
adjust return type
CM000n Nov 28, 2023
4e5d4b0
Set payload on all Endpoint models to Optional with None as default
CM000n Nov 28, 2023
8f37341
Use UnitValueModel for common Models
CM000n Nov 28, 2023
9e1c269
Update mytoyota/models/endpoints/vehicle_guid.py
CM000n Nov 28, 2023
d0da6a9
add basic test for notification model
CM000n Nov 28, 2023
ae05882
add basic test for telemetry model
CM000n Nov 28, 2023
76319e1
run pre-commit on all files
CM000n Nov 28, 2023
b8ae73b
HDC needs to be optional for fuel only cars. Range not always reporte…
Nov 28, 2023
cac42a7
Add electric status endpoint
Nov 28, 2023
df3c2e2
Model Trips.Route
Nov 28, 2023
1c8cea6
Adjust Notification model name and fix import in tests
CM000n Nov 28, 2023
e65a0eb
adjust request type
CM000n Nov 28, 2023
873365d
remove unused import and use absolute imports
CM000n Nov 28, 2023
84dc2a8
Updated controller.py
Nov 28, 2023
2538f87
Run pre-commit
Nov 29, 2023
9efffcf
Merge branch 'master' of github.com:GitOldGrumpy/mytoyota
Nov 29, 2023
10f2a33
fix str-bytes-safe error
CM000n Nov 29, 2023
b999fc1
add names, phone_numer and email to censor data
CM000n Nov 29, 2023
7bf613d
replace censor_vin with censor_string
CM000n Nov 29, 2023
e90c596
Incompatible types in assignment literal incompatible with URL
CM000n Nov 29, 2023
0630b80
uuid defined outside init
CM000n Nov 29, 2023
c148dd7
Route endpoint no longer always get route. Changed endpoints to take …
Nov 29, 2023
50a75f3
move conftest file to tests folder
CM000n Nov 29, 2023
622da7e
run pre-commit
CM000n Nov 29, 2023
d89c4e3
run pre-commit
CM000n Nov 29, 2023
67e98dd
remove unused retry arguments
CM000n Nov 29, 2023
c8f7c94
abstracting requesting and parsing into own function
CM000n Nov 29, 2023
79dba7f
run pre-commit
CM000n Nov 29, 2023
9d2c408
better error handling in client
CM000n Nov 29, 2023
feace03
replace isort and flake8 with ruff
CM000n Nov 29, 2023
1e8be42
adjust black line-length to ruff and pylint
CM000n Nov 29, 2023
727a7fe
improve readability for endpoint gathering in vehicle model
CM000n Nov 29, 2023
1c33a4e
Add some documentation. Alter defaults on trip endpoint.
Nov 29, 2023
edc4b85
Update trips.py to to make summary optional, it might not be requested.
Nov 29, 2023
f1c172e
Black issues
Nov 29, 2023
fb1c05f
fix katashiki_code obscuring
CM000n Nov 30, 2023
4abb099
increase line-length to 120
CM000n Nov 30, 2023
d9481f5
deactivate pylint TODO warnings
CM000n Nov 30, 2023
9831729
added some docstrings and fix pylint R1705
CM000n Nov 30, 2023
b6a857e
Added some docstrings
CM000n Nov 30, 2023
9080b32
add test_api.py
CM000n Nov 30, 2023
cff061d
replace test_endpoints with test_api
CM000n Nov 30, 2023
c2b170a
Move endpoints to const
CM000n Nov 30, 2023
55f7788
move controller urls to const
CM000n Nov 30, 2023
37b40e4
seperate testing from linting
CM000n Nov 30, 2023
1f2707b
seperate testing from linting
CM000n Nov 30, 2023
ebd30ad
seperate testing from linting
CM000n Nov 30, 2023
9083321
rename simple_client_test file to exclude it from pytest
CM000n Nov 30, 2023
a20dcac
rename simple_client_test file to exclude it from pytest
CM000n Nov 30, 2023
0d56420
fix svar type for status in notifications model
CM000n Nov 30, 2023
ef80f85
adjust linting workflow
CM000n Nov 30, 2023
d23c5e7
adjust linting workflow
CM000n Nov 30, 2023
426a72a
Replace pylint and black with ruff
CM000n Nov 30, 2023
99c9417
use pytest-pretty
CM000n Nov 30, 2023
621b096
ignore error in test
CM000n Nov 30, 2023
e18cf72
If a notification has not be read it doesn't have a notification read…
Nov 30, 2023
50515e7
Added basic Vehicle API for discussion. Updated endpoint models for d…
Dec 1, 2023
392e1a4
enforce more docstring rules
CM000n Dec 1, 2023
d799155
add rule for unused arguments
CM000n Dec 1, 2023
fbaf64f
implement ruff specific rules
CM000n Dec 1, 2023
0a5ff2b
add ruff_cache to gitignore
CM000n Dec 1, 2023
995b22f
install without dev dependencies in build pipeline
CM000n Dec 1, 2023
a5e5c51
Fix small review issues
Dec 1, 2023
b664326
mark old tests as legacy and add some new tests for utils
CM000n Dec 1, 2023
3f589ee
mark old tests as legacy and add some new tests for utils
CM000n Dec 1, 2023
e7ac49f
run coverage only against source files
CM000n Dec 1, 2023
84c2492
run coverage only against source files
CM000n Dec 1, 2023
abb23f8
add simple test for https response formatting
CM000n Dec 3, 2023
6120f3b
Add notifiations to the Client API
Dec 3, 2023
facae29
Merge branch 'master' of github.com:GitOldGrumpy/mytoyota
Dec 3, 2023
36db649
use pprint in example.py
CM000n Dec 4, 2023
611c514
get initial lock status working
CM000n Dec 4, 2023
51cdf9e
fix misbehaviour in bool conversion
CM000n Dec 4, 2023
450503a
poetry update
CM000n Dec 4, 2023
592581d
fix deprecation warning in httpx formatting test
CM000n Dec 4, 2023
0057405
djust use of pytest.param
CM000n Dec 4, 2023
0230e29
Merge branch 'master' into master
CM000n Dec 4, 2023
2118700
recreate lock file
CM000n Dec 4, 2023
1ef3917
add tests for lock_status model
CM000n Dec 4, 2023
89b349c
use caching client
CM000n Dec 7, 2023
3e2056a
replace unsafe characters, according to RFC specification, in AUTHORI…
CM000n Dec 7, 2023
cb84040
If a refresh token exists this will be tried before attempting userna…
Dec 7, 2023
fd2d699
Add username to cache for people who are testing with multiple accounts
Dec 7, 2023
267a0ed
don't use CacheClient on request_raw
CM000n Dec 8, 2023
a835eb3
bump version and update readme
CM000n Dec 11, 2023
34a9e8f
change badge styling
CM000n Dec 11, 2023
fd22353
add coverage badge
CM000n Dec 11, 2023
97ebe31
Added supported for summaries
Dec 12, 2023
5caaf34
Merge branch 'master' of github.com:GitOldGrumpy/mytoyota
Dec 12, 2023
1441380
Fix possible missing Scores
Dec 12, 2023
6b55ddf
Merge branch 'master' into master
CM000n Dec 15, 2023
669fd16
Add Trips
Dec 15, 2023
0e01c54
Merge branch 'master' of github.com:GitOldGrumpy/mytoyota
Dec 15, 2023
48650c2
lint only on pr
CM000n Dec 17, 2023
2e1ff4d
prevent commit to master
CM000n Dec 17, 2023
3369a62
set preferred default to false
CM000n Dec 18, 2023
8583df2
make preferred optional
CM000n Dec 18, 2023
df5e64d
make can_set_next_charging_event optional
CM000n Dec 19, 2023
69e21a3
revert formatting changes
CM000n Dec 20, 2023
9164494
revert workflow changes
CM000n Dec 20, 2023
aca119e
add whitespaces
CM000n Dec 20, 2023
d9eb91d
Merge branch 'DurgNomis-drol:master' into master
GitOldGrumpy Dec 23, 2023
c4dcd80
Weekly added
Dec 23, 2023
d62ee54
Implement Weekly and Yearly summaries
Dec 27, 2023
9c9a3e7
Merge branch 'master' into add_weekly_yearly_summaries
CM000n Dec 29, 2023
2ed8342
run pre-commit on all files
CM000n Dec 29, 2023
dcaa8a7
Update get_summary with some simplifications and more comments
Dec 30, 2023
87ef363
Break out the summary calculations into there own functions
Dec 31, 2023
c2f0df5
Updated with @CM000n suggestions
Jan 2, 2024
b4eee5c
Remove left over comment.
Jan 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions mytoyota/models/endpoints/trips.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
"""Toyota Connected Services API - Trips Models."""
from __future__ import annotations

from datetime import date, datetime
from typing import Any, List, Optional
from uuid import UUID

from pydantic import BaseModel, Field

from mytoyota.models.endpoints.common import StatusModel
from mytoyota.utils.helpers import add_with_none


class _SummaryBaseModel(BaseModel):
Expand All @@ -23,6 +26,30 @@
alias="fuelConsumption", default=None
) # Electric cars might not use fuel. Milliliters.

def __add__(self, other: _SummaryBaseModel):
CM000n marked this conversation as resolved.
Show resolved Hide resolved
"""Add together two SummaryBaseModel's.

Handles Min/Max/Average fields correctly.

Args:
----
other: _SummaryBaseModel: to be added
"""
if other is not None:
self.length += other.length
CM000n marked this conversation as resolved.
Show resolved Hide resolved
self.duration += other.duration
self.duration_idle += other.duration_idle
self.countries.extend(x for x in other.countries if x not in self.countries)
self.max_speed = max(self.max_speed, other.max_speed)
self.average_speed = (self.average_speed + other.average_speed) / 2.0
self.length_overspeed += other.length_overspeed
self.duration_overspeed += other.duration_overspeed
self.length_highway += other.length_highway
self.duration_highway += other.duration_highway
self.fuel_consumption = add_with_none(self.fuel_consumption, other.fuel_consumption)

Check warning on line 49 in mytoyota/models/endpoints/trips.py

View check run for this annotation

Codecov / codecov/patch

mytoyota/models/endpoints/trips.py#L38-L49

Added lines #L38 - L49 were not covered by tests

return self

Check warning on line 51 in mytoyota/models/endpoints/trips.py

View check run for this annotation

Codecov / codecov/patch

mytoyota/models/endpoints/trips.py#L51

Added line #L51 was not covered by tests


class _SummaryModel(_SummaryBaseModel):
start_lat: float = Field(alias="startLat")
Expand Down Expand Up @@ -66,6 +93,27 @@
power_time: Optional[int] = Field(alias="powerTime", default=None)
power_dist: Optional[int] = Field(alias="powerDist", default=None)

def __add__(self, other: _HDCModel):
CM000n marked this conversation as resolved.
Show resolved Hide resolved
"""Add together two HDCModel's.

Handles Min/Max/Average fields correctly.

Args:
----
other: _SummaryBaseModel: to be added
"""
if other is not None:
self.ev_time = add_with_none(self.ev_time, other.ev_time)
self.ev_distance = add_with_none(self.ev_distance, other.ev_distance)
self.charge_time = add_with_none(self.charge_time, other.charge_time)
self.charge_dist = add_with_none(self.charge_dist, other.charge_dist)
self.eco_time = add_with_none(self.eco_time, other.eco_time)
self.eco_dist = add_with_none(self.eco_dist, other.eco_dist)
self.power_time = add_with_none(self.power_time, other.power_time)
self.power_dist = add_with_none(self.power_dist, other.power_dist)

Check warning on line 113 in mytoyota/models/endpoints/trips.py

View check run for this annotation

Codecov / codecov/patch

mytoyota/models/endpoints/trips.py#L105-L113

Added lines #L105 - L113 were not covered by tests

return self

Check warning on line 115 in mytoyota/models/endpoints/trips.py

View check run for this annotation

Codecov / codecov/patch

mytoyota/models/endpoints/trips.py#L115

Added line #L115 was not covered by tests


class _RouteModel(BaseModel):
lat: float = Field(repr=False)
Expand Down
173 changes: 135 additions & 38 deletions mytoyota/models/vehicle.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import logging
from datetime import date, timedelta
from functools import partial
from operator import attrgetter
from typing import Any, Dict, List, Optional, Tuple

from mytoyota.api import Api
Expand All @@ -16,6 +17,7 @@
from mytoyota.models.nofication import Notification
from mytoyota.models.summary import Summary, SummaryType
from mytoyota.models.trips import Trip
from mytoyota.utils.helpers import add_with_none
from mytoyota.utils.logs import censor_all

_LOGGER: logging.Logger = logging.getLogger(__package__)
Expand Down Expand Up @@ -232,13 +234,21 @@
to_date: date,
summary_type: SummaryType = SummaryType.MONTHLY,
) -> Optional[List[Summary]]:
"""Return a Daily, Monthly or Yearly summary between the provided dates.
"""Return a Daily, Weekly, Monthly or Yearly summary between the provided dates.

All but Daily can return a partial time range. For example if the summary_type is weekly
and the date ranges selected include partial weeks these partial weeks will be returned.
The dates contained in the summary will indicate the range of dates that made up the
partial week.

Note: Weekly and yearly summaries lose a small amount of accuracy due to rounding issues

Args:
----
from_date (date, required): The inclusive from date to report summaries.
to_date (date, required): The inclusive to date to report summaries.
summary_type (???, optional): Daily, Monthly or Yearly summary. Monthly by default.
summary_type (SummaryType, optional): Daily, Monthly or Yearly summary.
Monthly by default.

Returns:
-------
Expand All @@ -255,47 +265,19 @@
if resp.payload is None:
return None

# Sort payload as code requires data in date order. Sorts the monthly summaries only
GitOldGrumpy marked this conversation as resolved.
Show resolved Hide resolved

# Convert to response
ret: List[Summary] = []
if summary_type == SummaryType.DAILY:
for summary in resp.payload.summary:
for histogram in summary.histograms:
summary_date = date(
day=histogram.day, month=histogram.month, year=histogram.year
)
ret.append(
Summary(
histogram.summary,
self._metric,
summary_date,
summary_date,
summary.hdc,
)
)
return self._daily_summaries(resp.payload.summary)

Check warning on line 272 in mytoyota/models/vehicle.py

View check run for this annotation

Codecov / codecov/patch

mytoyota/models/vehicle.py#L272

Added line #L272 was not covered by tests
elif summary_type == SummaryType.WEEKLY:
raise NotImplementedError
return self._weekly_summaries(resp.payload.summary)

Check warning on line 274 in mytoyota/models/vehicle.py

View check run for this annotation

Codecov / codecov/patch

mytoyota/models/vehicle.py#L274

Added line #L274 was not covered by tests
elif summary_type == SummaryType.MONTHLY:
for summary in resp.payload.summary:
summary_from_date = date(day=1, month=summary.month, year=summary.year)
summary_to_date = date(
day=calendar.monthrange(summary.year, summary.month)[1],
month=summary.month,
year=summary.year,
)

ret.append(
Summary(
summary.summary,
self._metric,
summary_from_date if summary_from_date > from_date else from_date,
summary_to_date if summary_to_date < to_date else to_date,
summary.hdc,
)
)
return self._monthly_summaries(resp.payload.summary, from_date, to_date)

Check warning on line 276 in mytoyota/models/vehicle.py

View check run for this annotation

Codecov / codecov/patch

mytoyota/models/vehicle.py#L276

Added line #L276 was not covered by tests
elif summary_type == SummaryType.YEARLY:
raise NotImplementedError

return ret
return self._yearly_summaries(resp.payload.summary, from_date, to_date)

Check warning on line 278 in mytoyota/models/vehicle.py

View check run for this annotation

Codecov / codecov/patch

mytoyota/models/vehicle.py#L278

Added line #L278 was not covered by tests
else:
raise AssertionError("No such SummaryType")

Check warning on line 280 in mytoyota/models/vehicle.py

View check run for this annotation

Codecov / codecov/patch

mytoyota/models/vehicle.py#L280

Added line #L280 was not covered by tests

async def get_trips(
self, from_date: date, to_date: date, full_route: bool = False
Expand Down Expand Up @@ -365,3 +347,118 @@
dump[name] = json.loads(data.model_dump_json())

return censor_all(copy.deepcopy(dump))

def _daily_summaries(self, summary) -> List[Summary]:
GitOldGrumpy marked this conversation as resolved.
Show resolved Hide resolved
GitOldGrumpy marked this conversation as resolved.
Show resolved Hide resolved
summary.sort(key=attrgetter("year", "month"))

Check warning on line 352 in mytoyota/models/vehicle.py

View check run for this annotation

Codecov / codecov/patch

mytoyota/models/vehicle.py#L352

Added line #L352 was not covered by tests

ret: List[Summary] = []
for month in summary: # Loop the months

Check warning on line 355 in mytoyota/models/vehicle.py

View check run for this annotation

Codecov / codecov/patch

mytoyota/models/vehicle.py#L354-L355

Added lines #L354 - L355 were not covered by tests
# Ensure daily data is in date order
for histogram in sorted(month.histograms, key=attrgetter("day")): # Loop the days
summary_date = date(day=histogram.day, month=histogram.month, year=histogram.year)
ret.append(

Check warning on line 359 in mytoyota/models/vehicle.py

View check run for this annotation

Codecov / codecov/patch

mytoyota/models/vehicle.py#L357-L359

Added lines #L357 - L359 were not covered by tests
Summary(
histogram.summary,
self._metric,
summary_date,
summary_date,
histogram.hdc,
)
)

return ret

Check warning on line 369 in mytoyota/models/vehicle.py

View check run for this annotation

Codecov / codecov/patch

mytoyota/models/vehicle.py#L369

Added line #L369 was not covered by tests

def _weekly_summaries(self, summary) -> List[Summary]:
GitOldGrumpy marked this conversation as resolved.
Show resolved Hide resolved
# To build a weekly summary we need to add together all the daily summaries for the
# week. A week starts on a Monday so data is added into build_hdc & build_summary
# until the current day is Sunday(i.e. last day of the week). At this point the
# build_hdc & build_summary are added to the response and we start again.
build_hdc = None
build_summary = None
start_date = None

Check warning on line 378 in mytoyota/models/vehicle.py

View check run for this annotation

Codecov / codecov/patch

mytoyota/models/vehicle.py#L376-L378

Added lines #L376 - L378 were not covered by tests

ret: List[Summary] = []
summary.sort(key=attrgetter("year", "month"))
for month in summary:
month.histograms.sort(key=attrgetter("day")) # Code required days are in date order
for histogram in month.histograms:
histogram_day = date(day=histogram.day, month=histogram.month, year=histogram.year)
if start_date is None:
start_date = histogram_day
build_hdc = copy.copy(histogram.hdc)
build_summary = copy.copy(histogram.summary)

Check warning on line 389 in mytoyota/models/vehicle.py

View check run for this annotation

Codecov / codecov/patch

mytoyota/models/vehicle.py#L380-L389

Added lines #L380 - L389 were not covered by tests
else:
add_with_none(build_hdc, histogram.hdc)
build_summary += histogram.summary

Check warning on line 392 in mytoyota/models/vehicle.py

View check run for this annotation

Codecov / codecov/patch

mytoyota/models/vehicle.py#L391-L392

Added lines #L391 - L392 were not covered by tests

# If current histogram is a Sunday then we have a full week of data so add it
# to our response, also need to add to response if ts the last item in the
# loops(otherwise partial week is lost)
if histogram_day.weekday() == 6 or (

Check warning on line 397 in mytoyota/models/vehicle.py

View check run for this annotation

Codecov / codecov/patch

mytoyota/models/vehicle.py#L397

Added line #L397 was not covered by tests
month == summary[-1] and histogram == month.histograms[-1]
):
ret.append(

Check warning on line 400 in mytoyota/models/vehicle.py

View check run for this annotation

Codecov / codecov/patch

mytoyota/models/vehicle.py#L400

Added line #L400 was not covered by tests
Summary(
build_summary,
self._metric,
start_date,
histogram_day,
build_hdc,
)
)
start_date = None # Reset start date so we can start a new week

Check warning on line 409 in mytoyota/models/vehicle.py

View check run for this annotation

Codecov / codecov/patch

mytoyota/models/vehicle.py#L409

Added line #L409 was not covered by tests

return ret

Check warning on line 411 in mytoyota/models/vehicle.py

View check run for this annotation

Codecov / codecov/patch

mytoyota/models/vehicle.py#L411

Added line #L411 was not covered by tests

def _monthly_summaries(self, summary, from_date: date, to_date: date) -> List[Summary]:
CM000n marked this conversation as resolved.
Show resolved Hide resolved
# Convert all the monthly responses from the payload to a summary response

ret: List[Summary] = []
summary.sort(key=attrgetter("year", "month"))
for month in summary:
month_from_date = date(day=1, month=month.month, year=month.year)
month_to_date = date(

Check warning on line 420 in mytoyota/models/vehicle.py

View check run for this annotation

Codecov / codecov/patch

mytoyota/models/vehicle.py#L416-L420

Added lines #L416 - L420 were not covered by tests
day=calendar.monthrange(month.year, month.month)[1],
month=month.month,
year=month.year,
)

ret.append(

Check warning on line 426 in mytoyota/models/vehicle.py

View check run for this annotation

Codecov / codecov/patch

mytoyota/models/vehicle.py#L426

Added line #L426 was not covered by tests
Summary(
month.summary,
self._metric,
# The data might not include an entire month so update start and end dates
max(month_from_date, from_date),
min(month_to_date, to_date),
month.hdc,
)
)

return ret

Check warning on line 437 in mytoyota/models/vehicle.py

View check run for this annotation

Codecov / codecov/patch

mytoyota/models/vehicle.py#L437

Added line #L437 was not covered by tests

def _yearly_summaries(self, summar, from_date: date, to_date: date) -> List[Summary]:
GitOldGrumpy marked this conversation as resolved.
Show resolved Hide resolved
build_hdc = None
build_summary = None
start_date = None

Check warning on line 442 in mytoyota/models/vehicle.py

View check run for this annotation

Codecov / codecov/patch

mytoyota/models/vehicle.py#L440-L442

Added lines #L440 - L442 were not covered by tests

ret: List[Summary] = []
summar.sort(key=attrgetter("year", "month"))
for month in summar:
summary_month = date(day=1, month=month.month, year=month.year)
if start_date is None or summary_month < from_date:
start_date = summary_month
build_hdc = copy.copy(month.hdc)
build_summary = copy.copy(month.summary)

Check warning on line 451 in mytoyota/models/vehicle.py

View check run for this annotation

Codecov / codecov/patch

mytoyota/models/vehicle.py#L444-L451

Added lines #L444 - L451 were not covered by tests
else:
add_with_none(build_hdc, month.hdc)
build_summary += month.summary

Check warning on line 454 in mytoyota/models/vehicle.py

View check run for this annotation

Codecov / codecov/patch

mytoyota/models/vehicle.py#L453-L454

Added lines #L453 - L454 were not covered by tests

# If "today" is december then we have reached the end of the year so add it the
# response also need to add to response if last item in list to add the last
# partial year
if summary_month.month == 12 or month == summar[-1]:
end_date = min(to_date, date(day=31, month=12, year=summary_month.year))
ret.append(Summary(build_summary, self._metric, start_date, end_date, build_hdc))
start_date = None

Check warning on line 462 in mytoyota/models/vehicle.py

View check run for this annotation

Codecov / codecov/patch

mytoyota/models/vehicle.py#L459-L462

Added lines #L459 - L462 were not covered by tests

return ret

Check warning on line 464 in mytoyota/models/vehicle.py

View check run for this annotation

Codecov / codecov/patch

mytoyota/models/vehicle.py#L464

Added line #L464 was not covered by tests
14 changes: 14 additions & 0 deletions mytoyota/utils/helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"""Helper functions used in multiple places."""


def add_with_none(this, that):
"""Add two items.

First checking if either item is None.
"""
if this is None:
return that
if that is None:
return this

return this + that
12 changes: 11 additions & 1 deletion simple_client_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,22 @@ async def get_information():
# Notifications
pp.pprint(f"Notifications: {[[x] for x in car.notifications]}")
# Summary
# pp.pprint(
# f"Summary: {[[x] for x in await car.get_summary(date.today() - timedelta(days=7), date.today(), summary_type=SummaryType.DAILY)]}" # noqa: E501 # pylint: disable=C0301
# )
# pp.pprint(
# f"Summary: {[[x] for x in await car.get_summary(date.today() - timedelta(days=7 * 4), date.today(), summary_type=SummaryType.WEEKLY)]}" # noqa: E501 # pylint: disable=C0301
# )
pp.pprint(
f"Summary: {[[x] for x in await car.get_summary(date.today() - timedelta(days=6 * 30), date.today(), summary_type=SummaryType.MONTHLY)]}" # noqa: E501
)
# pp.pprint(
# f"Summary: {[[x] for x in await car.get_summary(date.today() - timedelta(days=365), date.today(), summary_type=SummaryType.YEARLY)]}" # noqa: E501 # pylint: disable=C0301
# )

# Trips
pp.pprint(
f"Trips: f{await car.get_trips(date.today() - timedelta(days=2), date.today(), full_route=True)}" # noqa: E501
f"Trips: f{await car.get_trips(date.today() - timedelta(days=7), date.today(), full_route=True)}" # noqa: E501
)

# Dump all the information collected so far:
Expand Down
18 changes: 18 additions & 0 deletions tests/test_utils/test_helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"""Test Helper Utils."""
import pytest

from mytoyota.utils.helpers import add_with_none


# Parametrized test for happy path with various realistic test values
@pytest.mark.parametrize(
"this, that, result",
[
pytest.param(1, None, 1),
pytest.param(None, 1, 1),
pytest.param(1, 1, 2),
pytest.param(None, None, None),
],
)
def test_is_valid_locale_happy_path(this, that, result): # noqa: D103
assert result == add_with_none(this, that)