Skip to content

Commit

Permalink
Rewrite to use models instead (#126)
Browse files Browse the repository at this point in the history
* Rewrite to use models instead

* Add docstrings, fix linting and some other minor tweaks

* Add defaults for some properties

* Minor code improvements

* Removed a type annotation

* Updated example code in README.md to match actual implementation (#128)

Co-authored-by: John de Rooij <joro75@users.noreply.github.com>
  • Loading branch information
DurgNomis-drol and joro75 authored Jan 30, 2022
1 parent b26c6b2 commit f6df7a1
Show file tree
Hide file tree
Showing 26 changed files with 871 additions and 1,256 deletions.
41 changes: 6 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ async def get_information():
# Returns live data from car/last time you used it as an object.
vehicle = await client.get_vehicle_status(car)


# You can either get them all async (Recommended) or sync (Look further down).
data = await asyncio.gather(
*[
Expand All @@ -59,53 +58,25 @@ async def get_information():
]
)

# You can deposit each result into premade object holder for statistics. This will make it easier to use in your code.

vehicle.statistics.daily = data[0]
vehicle.statistics.weekly = data[1]
vehicle.statistics.monthly = data[2]
vehicle.statistics.yearly = data[3]


# You can access odometer data like this:
mileage = vehicle.odometer.mileage
mileage = vehicle.dashboard.odometer
# Or retrieve the energy level (electric or gasoline)
fuel = vehicle.energy.level
fuel = vehicle.dashboard.fuel_level
battery = vehicle.dashboard.batter_level
# Or Parking information:
latitude = vehicle.parking.latitude


# Pretty print the object. This will provide you with all available information.
print(json.dumps(vehicle.as_dict(), indent=3))
latitude = vehicle.parkinglocation.latitude


# -------------------------------
# All data is return in an object.
# -------------------------------

# Returns live data from car/last time you used it.
vehicle = await client.get_vehicle_status(car)
print(vehicle.as_dict())

# Stats returned in a dict
# Daily stats
daily_stats = await client.get_driving_statistics(vehicle.vin, interval="day")
print(daily_stats.as_list())

# Stats returned in json.
weekly_stats = await client.get_driving_statistics(vehicle.vin, interval="isoweek")
print(weekly_stats.as_list())

# ISO 8601 week stats
iso_weekly_stats = await client.get_driving_statistics(vehicle.vin, interval="isoweek")
print(iso_weekly_stats.as_list)

# Monthly stats is returned by default
monthly_stats = await client.get_driving_statistics(vehicle.vin)
print(monthly_stats.as_list())

#Get year to date stats.
# Get year to date stats.
yearly_stats = await client.get_driving_statistics(vehicle.vin, interval="year")
print(yearly_stats.as_list())


loop = asyncio.get_event_loop()
Expand Down
31 changes: 3 additions & 28 deletions mytoyota/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@
ToyotaLocaleNotValid,
ToyotaRegionNotSupported,
)
from .models.vehicle import Vehicle
from .statistics import Statistics
from .utils.locale import is_valid_locale
from .utils.logs import censor, censor_vin
from .vehicle import Vehicle

_LOGGER: logging.Logger = logging.getLogger(__package__)

Expand Down Expand Up @@ -256,39 +256,14 @@ async def get_vehicle_status(self, vehicle: dict) -> Vehicle:

_LOGGER.debug("Presenting information as an object...")

car = Vehicle(
return Vehicle(
vehicle_info=vehicle,
connected_services=data[0],
odometer=data[1],
status=data[2],
remote_control=data[3],
status_legacy=data[3],
)

return car

async def get_vehicle_status_json(self, vehicle: dict) -> str:
"""Returns vehicle status as json string.
Collects and formats different vehicle status endpoints into
a easy accessible vehicle object.
Args:
vehicle (dict): dict for each vehicle returned in get_vehicles().
Returns:
Json string containing odometer information, parking information, fuel and more.
Raises:
ToyotaLoginError: An error returned when updating token or invalid login information.
ToyotaInternalError: An error occurred when making a request.
ToyotaApiError: Toyota's API returned an error.
"""
vehicle = await self.get_vehicle_status(vehicle)

_LOGGER.debug("Returning it as json")
json_string = json.dumps(vehicle.as_dict(), indent=3)
return json_string

async def get_driving_statistics( # pylint: disable=too-many-branches
self, vin: str, interval: str = MONTH, from_date: str = None, unit: str = METRIC
) -> list:
Expand Down
21 changes: 1 addition & 20 deletions mytoyota/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,7 @@
TOKEN = "token"
UUID = "uuid"
CUSTOMERPROFILE = "customerProfile"
FUEL = "fuel"
MILEAGE = "mileage"
TYPE = "type"
VALUE = "value"
UNIT = "unit"
VEHICLE_INFO = "VehicleInfo"
ACQUISITIONDATE = "AcquisitionDatetime"
CHARGE_INFO = "ChargeInfo"
HVAC = "RemoteHvacInfo"

BUCKET = "bucket"
DAYOFYEAR = "dayOfYear"
Expand All @@ -45,25 +37,14 @@
DATA = "data"
SUMMARY = "summary"
HISTOGRAM = "histogram"
UNIT = "unit"

DAY = "day"
WEEK = "week"
ISOWEEK = "isoweek"
MONTH = "month"
YEAR = "year"

HOOD = "hood"
DOORS = "doors"
WINDOWS = "windows"
LIGHTS = "lamps"
KEY = "key"
CLOSED = "closed"
LOCKED = "locked"
WARNING = "warning"
STATE = "state"
OFF = "off"
INCAR = "inCar"

METRIC = "metric"
IMPERIAL = "imperial"
IMPERIAL_LITERS = "imperial_liters"
Expand Down
52 changes: 0 additions & 52 deletions mytoyota/hvac.py

This file was deleted.

24 changes: 0 additions & 24 deletions mytoyota/location.py

This file was deleted.

101 changes: 101 additions & 0 deletions mytoyota/models/dashboard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
"""Models for vehicle sensors."""
from __future__ import annotations

from typing import TYPE_CHECKING

from mytoyota.utils.conversions import convert_to_miles

if TYPE_CHECKING:
from mytoyota.models.vehicle import Vehicle


class Dashboard:
"""Instrumentation data model."""

def __init__(
self,
vehicle: Vehicle,
) -> None:
"""Dashboard."""
self._vehicle = vehicle

vehicle_info = vehicle._status_legacy.get("VehicleInfo", {})
self._chargeinfo = vehicle_info.get("ChargeInfo", {})
self._energy = (
vehicle._status.get("energy", [])[0] if "energy" in vehicle._status else {}
)

@property
def legacy(self) -> bool:
"""If the car uses the legacy endpoints."""
if "Fuel" in self._vehicle.odometer:
return True
return False

@property
def is_metric(self) -> bool:
"""If the car is reporting data in metric."""
return self._vehicle.odometer.get("mileage_unit") == "km"

@property
def odometer(self) -> int | None:
"""Shows the odometer distance."""
return self._vehicle.odometer.get("mileage")

@property
def fuel_level(self) -> float | None:
"""Shows the fuellevel of the vehicle."""
if self.legacy:
return self._vehicle.odometer.get("Fuel")
return self._energy.get("level")

@property
def fuel_range(self) -> float | None:
"""Shows the range if available."""
fuel_range = (
self._chargeinfo.get("GasolineTravelableDistance")
if self.legacy
else self._energy.get("remainingRange", None)
)
return convert_to_miles(fuel_range) if not self.is_metric else fuel_range

@property
def battery_level(self) -> float | None:
"""Shows the battery level if a hybrid."""
if self.legacy:
return self._chargeinfo.get("ChargeRemainingAmount")
return None

@property
def battery_range(self) -> float | None:
"""Shows the battery range if a hybrid."""
if self.legacy:
battery_range = self._chargeinfo.get("EvDistanceInKm")
return (
convert_to_miles(battery_range) if not self.is_metric else battery_range
)
return None

@property
def battery_range_with_aircon(self) -> float | None:
"""Shows the battery range with aircon on, if a hybrid."""
if self.legacy:
battery_range = self._chargeinfo.get("EvDistanceWithAirCoInKm")
return (
convert_to_miles(battery_range) if not self.is_metric else battery_range
)
return None

@property
def charging_status(self) -> str | None:
"""Shows the charging status if a hybrid."""
if self.legacy:
return self._chargeinfo.get("ChargingStatus")
return None

@property
def remaining_charge_time(self) -> int | None:
"""Shows the remaining time to a full charge, if a hybrid."""
if self.legacy:
return self._chargeinfo.get("RemainingChargeTime")
return None
14 changes: 14 additions & 0 deletions mytoyota/models/data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"""Base data model."""
from typing import Any, Dict


class VehicleData:
"""Vehicle data base model."""

def __init__(self, data: dict) -> None:
self._data = data or {}

@property
def raw_json(self) -> Dict[str, Any]:
"""Return the input data."""
return self._data
Loading

0 comments on commit f6df7a1

Please sign in to comment.