Skip to content

Commit

Permalink
Merge pull request #181 from robinostlund/statistics
Browse files Browse the repository at this point in the history
Enable statistics for HA
  • Loading branch information
milkboy authored Mar 16, 2022
2 parents 5ae609f + e2e1cbd commit c3e2d10
Show file tree
Hide file tree
Showing 8 changed files with 815 additions and 103 deletions.
2 changes: 1 addition & 1 deletion requirements-test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ freezegun>=1.0.0
pre-commit
pytest>=7.0.0
pytest-asyncio
pytest-cov
pytest-cov>=3.0.0
pytest-subtests
setuptools
33 changes: 29 additions & 4 deletions tests/vw_timer_test.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
"""Depature timer tests."""
import datetime
from unittest import TestCase

from volkswagencarnet.vw_timer import TimerData, TimerProfile
from volkswagencarnet.vw_timer import TimerData, TimerProfile, parse_vw_datetime


class TimerTest(TestCase):
Expand All @@ -13,7 +14,7 @@ class TimerTest(TestCase):
"timerProfileList": {
"timerProfile": [
{
"timestamp": "2022-02-22T20:00:22Z",
"timestamp": "2022-02-22T20:00:22+0000",
"profileName": "Profile 1",
"profileID": "1",
"operationCharging": True,
Expand All @@ -30,7 +31,7 @@ class TimerTest(TestCase):
"timerList": {
"timer": [
{
"timestamp": "2022-02-22T20:00:22Z",
"timestamp": "2022-02-22T20:00:22+0000", # actual data probably has "Z", but either works
"timerID": "3",
"profileID": "3",
"timerProgrammedStatus": "notProgrammed",
Expand All @@ -42,7 +43,7 @@ class TimerTest(TestCase):
]
},
"timerBasicSetting": {
"timestamp": "2022-02-22T20:00:22Z",
"timestamp": "2022-02-22T20:00:22+0000",
"chargeMinLimit": 20,
"targetTemperature": 2955,
"heaterSource": None,
Expand Down Expand Up @@ -97,6 +98,7 @@ def test_timer_serialization(self):
"""Test de- and serialization of timers."""
timer = TimerData(**self.data["timer"])
self.assertEqual(self.data, timer.json)
self.assertTrue(timer.valid)
self.assertNotEqual(timer.json, timer.json_updated)

def test_update_serialization(self):
Expand Down Expand Up @@ -133,3 +135,26 @@ def test_update_profile(self):

profile.profileID = 42
self.assertRaises(Exception, timer.update_profile(profile))

def test_parse_datetime(self):
"""Test that we can parse datetimes."""
self.assertEqual(parse_vw_datetime("2021-03-04 05:06:07Z"), None)
self.assertEqual(parse_vw_datetime("2021-03-04T05:06:07"), None)
self.assertEqual(
parse_vw_datetime("2021-03-04T05:06:07Z"),
datetime.datetime(
year=2021, month=3, day=4, hour=5, minute=6, second=7, microsecond=0, tzinfo=datetime.timezone.utc
),
)
self.assertEqual(
parse_vw_datetime("2021-03-04T05:06:07+0000"),
datetime.datetime(
year=2021, month=3, day=4, hour=5, minute=6, second=7, microsecond=0, tzinfo=datetime.timezone.utc
),
)
self.assertEqual(
parse_vw_datetime("2021-03-04T05:06:07+00:00"),
datetime.datetime(
year=2021, month=3, day=4, hour=5, minute=6, second=7, microsecond=0, tzinfo=datetime.timezone.utc
),
)
32 changes: 27 additions & 5 deletions tests/vw_vehicle_test.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"""Vehicle class tests."""
import sys
from datetime import datetime
from datetime import datetime, timezone

import pytest
import sys

from volkswagencarnet.vw_timer import TimerData
from volkswagencarnet.vw_utilities import json_loads
Expand Down Expand Up @@ -194,7 +194,8 @@ async def test_get_schedule2(self):
with patch.dict(vehicle._services, {"timerprogramming_v1": {"active": True}}):
await vehicle.get_timerprogramming()
self.assertFalse(vehicle.is_departure_timer2_supported)
self.assertIsNone(vehicle.departure_timer2)
with self.assertRaises(ValueError):
self.assertIsNone(vehicle.departure_timer2)

async def test_get_schedule1(self):
"""Test that schedule 1 support works."""
Expand All @@ -204,7 +205,8 @@ async def test_get_schedule1(self):
with patch.dict(vehicle._services, {"timerprogramming_v1": {"active": True}}):
await vehicle.get_timerprogramming()
self.assertFalse(vehicle.is_departure_timer1_supported)
self.assertIsNone(vehicle.departure_timer1)
with self.assertRaises(ValueError):
self.assertIsNone(vehicle.departure_timer1)

async def test_get_schedule_not_supported(self):
"""Test that not found schedule is unsupported."""
Expand All @@ -214,7 +216,20 @@ async def test_get_schedule_not_supported(self):
with patch.dict(vehicle._services, {"timerprogramming_v1": {"active": True}}):
await vehicle.get_timerprogramming()
self.assertFalse(vehicle.is_schedule_supported(42))
self.assertIsNone(vehicle.schedule(42))
with self.assertRaises(ValueError):
self.assertIsNone(vehicle.schedule(42))

async def test_get_schedule_last_updated(self):
"""Test that not found schedule is unsupported."""
vehicle = Vehicle(conn=TimersConnection(None), url=MOCK_VIN)
vehicle._discovered = True

with patch.dict(vehicle._services, {"timerprogramming_v1": {"active": True}}):
await vehicle.get_timerprogramming()
dt = datetime.fromisoformat("2022-02-22T20:00:22+00:00").astimezone(timezone.utc)
self.assertEqual(dt, vehicle.schedule_heater_source_last_updated)
self.assertEqual(dt, vehicle.schedule_min_charge_level_last_updated)
self.assertEqual(dt, vehicle.departure_timer3_last_updated)

async def test_last_connected(self):
"""
Expand Down Expand Up @@ -254,6 +269,13 @@ def test_requests_remaining(self):
# attribute should be removed once read
self.assertNotIn("rate_limit_remaining", vehicle.attrs)

@freeze_time("2022-02-02 02:02:02", tz_offset=0)
def test_requests_remaining_last_updated(self):
"""Test requests remaining logic."""
vehicle = Vehicle(conn=None, url="")
vehicle.requests_remaining = 4
self.assertEqual(datetime.fromisoformat("2022-02-02T02:02:02"), vehicle.requests_remaining_last_updated)

async def test_json(self):
"""Test JSON serialization of dict containing datetime."""
vehicle = Vehicle(conn=None, url="dummy34")
Expand Down
9 changes: 9 additions & 0 deletions volkswagencarnet/vw_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,15 @@ async def setChargeMinLevel(self, vin: str, limit: int):
data.timersAndProfiles.timerBasicSetting.set_charge_min_limit(limit)
return await self._setDepartureTimer(vin, data.timersAndProfiles, "setChargeMinLimit")

# Not working :/
# async def setHeaterSource(self, vin: str, source: str):
# """Set heater source for departure timers."""
# data: Optional[TimerData] = await self.getTimers(vin)
# if data is None:
# raise Exception("No existing timer data?")
# data.timersAndProfiles.timerBasicSetting.set_heater_source(source)
# return await self._setDepartureTimer(vin, data.timersAndProfiles, "setHeaterSource")

async def _setDepartureTimer(self, vin, data: TimersAndProfiles, action: str):
"""Set schedules."""
try:
Expand Down
22 changes: 22 additions & 0 deletions volkswagencarnet/vw_const.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,25 @@
"User-Agent": USER_AGENT,
"X-App-Name": XAPPNAME,
}

TEMP_CELSIUS: str = "°C"
TEMP_FAHRENHEIT: str = "°F"


class VWStateClass:
MEASUREMENT = "measurement"
TOTAL = "total"
TOTAL_INCREASING = "total_increasing"


class VWDeviceClass:
BATTERY = "battery"
CONNECTIVITY = "connectivity"
DOOR = "door"
LIGHT = "light"
LOCK = "lock"
MOVING = "moving"
PLUG = "plug"
POWER = "power"
TEMPERATURE = "temperature"
WINDOW = "window"
Loading

0 comments on commit c3e2d10

Please sign in to comment.