Skip to content

Commit

Permalink
Add battery session data and corresponding tests (#189)
Browse files Browse the repository at this point in the history
* Add battery session data and corresponding tests

* Add types

* Add docstring to smart_battery_sessions function
  • Loading branch information
berendhaan authored Jun 9, 2024
1 parent ad5f223 commit 426ed5e
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 0 deletions.
62 changes: 62 additions & 0 deletions python_frank_energie/frank_energie.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
Me,
MonthSummary,
SmartBatteries,
SmartBatterySessions,
)


Expand Down Expand Up @@ -535,6 +536,67 @@ async def smart_batteries(self) -> SmartBatteries:

return SmartBatteries.from_dict(await self._query(query))

async def smart_battery_sessions(
self, device_id: str, start_date: date, end_date: date
) -> SmartBatterySessions:
"""List smart battery sessions for a device.
Returns a list of all smart battery sessions for a device.
Full query:
query SmartBatterySessions($startDate: String!, $endDate: String!, $deviceId: String!) {
smartBatterySessions(
startDate: $startDate
endDate: $endDate
deviceId: $deviceId
) {
deviceId
periodEndDate
periodStartDate
periodTradingResult
sessions {
cumulativeTradingResult
date
tradingResult
}
totalTradingResult
}
}
"""
if self._auth is None:
raise AuthRequiredException

query = {
"query": """
query SmartBatterySessions($startDate: String!, $endDate: String!, $deviceId: String!) {
smartBatterySessions(
startDate: $startDate
endDate: $endDate
deviceId: $deviceId
) {
deviceId
periodEndDate
periodStartDate
periodTradingResult
sessions {
cumulativeTradingResult
date
tradingResult
}
totalTradingResult
}
}
""",
"operationName": "SmartBatterySessions",
"variables": {
"deviceId": device_id,
"startDate": str(start_date),
"endDate": str(end_date),
},
}

return SmartBatterySessions.from_dict(await self._query(query))

@property
def is_authenticated(self) -> bool:
"""Return if client is authenticated.
Expand Down
56 changes: 56 additions & 0 deletions python_frank_energie/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -476,3 +476,59 @@ def from_dict(payload: dict[str, str]) -> SmartBatteries.SmartBattery:
created_at=payload.get("createdAt"),
updated_at=payload.get("updatedAt"),
)


@dataclass
class SmartBatterySessions:
"""Collection of battery sessions, for a given battery."""

deviceId: str
periodEndDate: str
periodStartDate: str
periodTradingResult: float
totalTradingResult: float
sessions: list[Session]

@staticmethod
def from_dict(data: dict[str, str]) -> SmartBatterySessions:
"""Parse the response from the SmartBatterySessions query."""
_LOGGER.debug("SmartBatterySessions %s", data)

if errors := data.get("errors"):
raise RequestException(errors[0]["message"])

payload = data.get("data")
if not payload:
raise RequestException("Unexpected response")

smart_battery_session_data = payload.get("smartBatterySessions")
return SmartBatterySessions(
deviceId=smart_battery_session_data.get("deviceId"),
periodEndDate=smart_battery_session_data.get("periodEndDate"),
periodStartDate=smart_battery_session_data.get("periodStartDate"),
periodTradingResult=smart_battery_session_data.get("periodTradingResult"),
totalTradingResult=smart_battery_session_data.get("totalTradingResult"),
sessions=[
SmartBatterySessions.Session.from_dict(session)
for session in smart_battery_session_data.get("sessions")
],
)

@dataclass
class Session:
"""A battery session."""

date: datetime
tradingResult: float
cumulativeTradingResult: float

@staticmethod
def from_dict(payload: dict[str, str]) -> SmartBatterySessions.Session:
"""Parse the sessions payload from the SmartBatterySessions query result."""
_LOGGER.debug("DeliverySites %s", payload)

return SmartBatterySessions.Session(
date=payload.get("date"),
tradingResult=payload.get("tradingResult"),
cumulativeTradingResult=payload.get("cumulativeTradingResult"),
)
3 changes: 3 additions & 0 deletions tests/__snapshots__/test_smart_batteries.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@
# name: test_smart_batteries
SmartBatteries(smart_batteries=[SmartBatteries.SmartBattery(brand='SESSY', capacity=5.2, external_reference='SESSYREF', id='unique_identifier', max_charge_power=2.2, max_discharge_power=1.7, provider='SESSY', created_at='2024-04-30T13:33:42.776Z', updated_at='2024-05-29T08:55:58.270Z')])
# ---
# name: test_smart_battery_sessions
SmartBatterySessions(deviceId='unique_identifier', periodEndDate='2024-05-29', periodStartDate='2024-05-01', periodTradingResult=26.17683031883334, totalTradingResult=26.10297351000001, sessions=[SmartBatterySessions.Session(date='2024-05-01', tradingResult=1.608739184750002, cumulativeTradingResult=1.608739184750002), SmartBatterySessions.Session(date='2024-05-02', tradingResult=0.3197138107499999, cumulativeTradingResult=1.9284529955000018)])
# ---
23 changes: 23 additions & 0 deletions tests/fixtures/smart_battery_sessions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"data": {
"smartBatterySessions": {
"deviceId": "unique_identifier",
"periodEndDate": "2024-05-29",
"periodStartDate": "2024-05-01",
"periodTradingResult": 26.17683031883334,
"sessions": [
{
"cumulativeTradingResult": 1.608739184750002,
"date": "2024-05-01",
"tradingResult": 1.608739184750002
},
{
"cumulativeTradingResult": 1.9284529955000018,
"date": "2024-05-02",
"tradingResult": 0.3197138107499999
}
],
"totalTradingResult": 26.10297351000001
}
}
}
27 changes: 27 additions & 0 deletions tests/test_smart_batteries.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""Tests for Frank Energie Smart batteries implementation."""

from datetime import datetime, timezone

import aiohttp
import pytest
from syrupy.assertion import SnapshotAssertion
Expand Down Expand Up @@ -32,3 +34,28 @@ async def test_smart_batteries(aresponses, snapshot: SnapshotAssertion):

assert smart_batteries is not None
assert smart_batteries == snapshot


@pytest.mark.asyncio
async def test_smart_battery_sessions(aresponses, snapshot: SnapshotAssertion):
"""Test request with authentication."""
aresponses.add(
SIMPLE_DATA_URL,
"/",
"POST",
aresponses.Response(
text=load_fixtures("smart_battery_sessions.json"),
status=200,
headers={"Content-Type": "application/json"},
),
)

async with aiohttp.ClientSession() as session:
api = FrankEnergie(session, auth_token="a", refresh_token="b") # noqa: S106
sessions = await api.smart_battery_sessions(
"device_id", datetime.now(timezone.utc), datetime.now(timezone.utc)
)
await api.close()

assert sessions is not None
assert sessions == snapshot

0 comments on commit 426ed5e

Please sign in to comment.