Skip to content

Commit

Permalink
Updates
Browse files Browse the repository at this point in the history
  • Loading branch information
epenet committed Dec 11, 2020
1 parent 4433928 commit 1a8402a
Show file tree
Hide file tree
Showing 11 changed files with 40 additions and 41 deletions.
37 changes: 16 additions & 21 deletions src/renault_api/cli/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@
from typing import Callable
from typing import Optional
from typing import Tuple
from tzlocal import get_localzone

import aiohttp
import click
import dateparser
import dateutil
import tzlocal

from renault_api.exceptions import RenaultException

Expand Down Expand Up @@ -103,34 +102,31 @@ def parse_dates(start: str, end: str) -> Tuple[datetime, datetime]:
parsed_start = dateparser.parse(start)
parsed_end = dateparser.parse(end)

if not parsed_start:
if not parsed_start: # pragma: no cover
raise ValueError(f"Unable to parse `{start}` into start datetime.")
if not parsed_end:
if not parsed_end: # pragma: no cover
raise ValueError(f"Unable to parse `{end}` into end datetime.")

return (parsed_start, parsed_end)


def _timezone_offset():
offset = get_localzone().utcoffset(datetime.now()).total_seconds() / 60
return offset / 60, offset % 60
def _timezone_offset() -> int:
"""Return UTC offset in minutes."""
utcoffset = tzlocal.get_localzone().utcoffset(datetime.now())
if utcoffset:
return int(utcoffset.total_seconds() / 60)
return 0 # pragma: no cover


def _format_tzdatetime(datetime: str) -> str:
return (
dateutil.parser.parse(datetime)
.astimezone(dateutil.tz.tzlocal())
.strftime(_DATETIME_FORMAT)
)
def _format_tzdatetime(date_string: str) -> str:
date = datetime.fromisoformat(date_string.replace("Z", "+00:00"))
return str(date.astimezone(tzlocal.get_localzone()).strftime(_DATETIME_FORMAT))


def _format_tztime(time: str) -> str:
offset_hours, offset_minutes = _timezone_offset()
raw_hours = int(time[1:3])
raw_minutes = int(time[4:6])
return "{:02g}:{:02g}".format(
(raw_hours + offset_hours) % 24, raw_minutes + offset_minutes
)
total_minutes = int(time[1:3]) * 60 + int(time[4:6]) + _timezone_offset()
hours, minutes = divmod(total_minutes, 60)
return "{:02g}:{:02g}".format(hours, minutes)


def _format_minutes(mins: float) -> str:
Expand All @@ -141,10 +137,9 @@ def _format_minutes(mins: float) -> str:
def get_display_value(
value: Optional[Any] = None,
unit: Optional[str] = None,
round: Optional[int] = None,
) -> str:
"""Get a display for value."""
if value is None:
if value is None: # pragma: no cover
return ""
if unit is None:
return str(value)
Expand Down
1 change: 0 additions & 1 deletion src/renault_api/cli/renault_vehicle.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

import aiohttp
import click
import dateutil.parser
from tabulate import tabulate

from . import helpers
Expand Down
18 changes: 8 additions & 10 deletions src/renault_api/cli/renault_vehicle_charge.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@

import aiohttp
import click
from click.core import Option
from tabulate import tabulate

from renault_api.kamereon.models import ChargeDaySchedule, ChargeSchedule

from . import helpers
from . import renault_vehicle
from renault_api.kamereon.enums import ChargeMode
from renault_api.kamereon.models import ChargeDaySchedule
from renault_api.kamereon.models import ChargeSchedule


_DAYS_OF_WEEK = [
Expand Down Expand Up @@ -84,6 +83,7 @@ async def history(
) -> None:
"""Display charge history."""
parsed_start, parsed_end = helpers.parse_dates(start, end)
period = period or "month"

vehicle = await renault_vehicle.get_vehicle(
websession=websession, ctx_data=ctx_data
Expand Down Expand Up @@ -130,12 +130,11 @@ async def mode(
)
if mode:
charge_mode = ChargeMode(mode)
response = await vehicle.set_charge_mode(charge_mode)
click.echo(response.raw_data)
write_response = await vehicle.set_charge_mode(charge_mode)
click.echo(write_response.raw_data)
else:
response = await vehicle.get_charge_mode()
display_data = [("Charge mode", response.chargeMode)]
click.echo(tabulate(display_data))
read_response = await vehicle.get_charge_mode()
click.echo(f"Charge mode: {read_response.chargeMode}")


async def settings(
Expand All @@ -148,7 +147,6 @@ async def settings(
)
response = await vehicle.get_charging_settings()
# Display mode
display_data = [("Mode", response.mode)]
click.echo(f"Mode: {response.mode}")

if not response.schedules: # pragma: no cover
Expand Down Expand Up @@ -176,7 +174,7 @@ async def settings(

def _format_charge_schedule(schedule: ChargeSchedule, key: str) -> List[str]:
details: Optional[ChargeDaySchedule] = getattr(schedule, key)
if not details:
if not details: # pragma: no cover
return [key, "-", "-", "-"]
return [
key.capitalize(),
Expand Down
2 changes: 1 addition & 1 deletion src/renault_api/kamereon/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ def get_end_time(self) -> Optional[str]:
return None
start_hours = int(self.startTime[1:3])
start_minutes = int(self.startTime[4:6])
end_minutes = start_hours * 60 + start_minutes + self.duration
end_minutes = start_hours * 60 + start_minutes + (self.duration or 0)
end_hours = end_minutes // 60
end_minutes = end_minutes % 60
if end_hours > 24:
Expand Down
2 changes: 1 addition & 1 deletion src/renault_api/renault_vehicle.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ async def get_notification_settings(
)

async def get_charge_history(
self, start: datetime, end: datetime, period: str = "month"
self, start: datetime, end: datetime, period: str
) -> models.KamereonVehicleChargeHistoryData:
"""Get vehicle charge history."""
if not isinstance(start, datetime): # pragma: no cover
Expand Down
2 changes: 1 addition & 1 deletion tests/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
def initialise_credential_store(
include_account_id: Optional[bool] = None,
include_vin: Optional[bool] = None,
):
) -> None:
"""Initialise CLI credential store."""
credential_store = FileCredentialStore(os.path.expanduser(CREDENTIAL_PATH))
credential_store[CONF_LOCALE] = Credential(TEST_LOCALE)
Expand Down
4 changes: 2 additions & 2 deletions tests/cli/test_vehicle.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@
EXPEXTED_BATTERY_STATUS = (
"-------------------- -------------------------\n"
"Battery level 50 %\n"
"Last updated 2020-11-17 09:06:48+01:00\n"
"Last updated 2020-11-17 09:06:48\n"
"Range estimate 128 km\n"
"Plug state PlugState.UNPLUGGED\n"
"Charging state ChargeState.NOT_IN_CHARGE\n"
"Charge mode always\n"
"Total mileage 49114.27 km\n"
"GPS Latitude 48.1234567\n"
"GPS Longitude 11.1234567\n"
"GPS last updated 2020-02-18 16:58:38+00:00\n"
"GPS last updated 2020-02-18 17:58:38\n"
"HVAC status off\n"
"External temperature 8.0 °C\n"
"-------------------- -------------------------\n"
Expand Down
4 changes: 1 addition & 3 deletions tests/cli/test_vehicle_charge.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@
"------- ------------------- --------------------- --------\n"
" 202011 1 7:59:00 0\n"
)
EXPECTED_CHARGE_MODE_GET = (
"----------- ------\n" "Charge mode always\n" "----------- ------\n"
)
EXPECTED_CHARGE_MODE_GET = "Charge mode: always\n"
EXPECTED_CHARGE_MODE_SET = "{'action': 'schedule_mode'}\n"
EXPECTED_CHARGES = (
"Charge start Charge end Duration Power (kW) "
Expand Down
8 changes: 8 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
import asyncio
import functools
import pathlib
from typing import Any
from typing import AsyncGenerator
from typing import Generator

import pytest
import pytz
from _pytest.monkeypatch import MonkeyPatch
from aiohttp.client import ClientSession
from aioresponses import aioresponses
Expand Down Expand Up @@ -39,6 +41,12 @@ def cli_runner(

monkeypatch.setattr("os.path.expanduser", lambda x: x.replace("~", str(tmpdir)))

def get_test_zone() -> Any:
# Get a non UTC zone. Let's use Paris.
return pytz.timezone("Europe/Paris")

monkeypatch.setattr("tzlocal.get_localzone", get_test_zone)

yield runner


Expand Down
2 changes: 1 addition & 1 deletion tests/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ def inject_kamereon_action_charging_start(mocked_responses: aioresponses) -> Non
inject_kamereon_action(
mocked_responses,
urlpath,
f"vehicle_action/charging-start.start.json",
"vehicle_action/charging-start.start.json",
)


Expand Down
1 change: 1 addition & 0 deletions tests/test_renault_vehicle.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ async def test_get_charge_history_month(vehicle: RenaultVehicle) -> None:
assert await vehicle.get_charge_history(
start=datetime(2020, 10, 1),
end=datetime(2020, 11, 15),
period="month",
)


Expand Down

0 comments on commit 1a8402a

Please sign in to comment.