Skip to content

Commit

Permalink
feat(statistics): initial support
Browse files Browse the repository at this point in the history
  • Loading branch information
rokam committed Dec 26, 2023
1 parent 88ea5f2 commit 127437d
Show file tree
Hide file tree
Showing 6 changed files with 491 additions and 4 deletions.
50 changes: 48 additions & 2 deletions sunweg/api.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
"""API Helper."""
import json
from datetime import datetime
from datetime import date, datetime
from typing import Any

from requests import Response, session

from .const import (
SUNWEG_INVERTER_DETAIL_PATH,
SUNWEG_LOGIN_PATH,
SUNWEG_MONTH_STATS_PATH,
SUNWEG_PLANT_DETAIL_PATH,
SUNWEG_PLANT_LIST_PATH,
SUNWEG_URL,
)
from .device import MPPT, Inverter, Phase, String
from .plant import Plant
from .util import Status
from .util import ProductionStats, Status


class SunWegApiError(RuntimeError):
Expand Down Expand Up @@ -270,6 +271,51 @@ def complete_inverter(self, inverter: Inverter, retry=True) -> None:
self.authenticate()
self.complete_inverter(inverter, False)

def month_stats_production(self, year: int, month: int, plant: Plant, inverter: Inverter | None = None, retry: bool = True) -> list[ProductionStats]:
"""
Retrieve month energy production statistics.
:param year: statistics year
:type year: int
:param month: statistics month
:type month: int
:param plant: statistics plant
:type plant: Plant
:param inverter: statistics inverter, None for every inverter
:type inverter: Inverter | None
:param retry: reauthenticate if token expired and retry
:type retry: bool
:return: list of daily energy production statistics
:rtype: list[ProductionStats]
"""
return self.month_stats_production(year, month, plant.id, inverter.id if inverter is not None else None, retry)

def month_stats_production(self, year: int, month: int, plant_id: int, inverter_id: int | None = None, retry: bool = True) -> list[ProductionStats]:
"""
Retrieve month energy production statistics.
:param year: statistics year
:type year: int
:param month: statistics month
:type month: int
:param plant_id: id of statistics plant
:type plant_id: int
:param inverter_id: id of statistics inverter, None for every inverter
:type inverter_id: int | None
:param retry: reauthenticate if token expired and retry
:type retry: bool
:return: list of daily energy production statistics
:rtype: list[ProductionStats]
"""
inverter_str:str = str(inverter_id) if inverter_id is not None else ""
try:
result = self._get(SUNWEG_MONTH_STATS_PATH + f"idusina={plant_id}&idinversor={inverter_str}&date={format(month,'02')}/{year}")
return [ProductionStats(datetime.strptime(item["tempoatual"],"%Y-%m-%d").date(), float(item["energiapordia"]), float(item["prognostico"])) for item in result["graficomes"]]
except LoginError:
if retry:
self.authenticate()
self.month_stats_production(year, month, plant_id, inverter_id, False)

def _populate_MPPT(self, result: dict, inverter: Inverter) -> None:
"""Populate MPPT information inside a inverter."""
for str_mppt in result["stringmppt"]:
Expand Down
2 changes: 2 additions & 0 deletions sunweg/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@
"""SunWEG API plant details path"""
SUNWEG_INVERTER_DETAIL_PATH = "inversores/view?id="
"""SunWEG API inverter details path"""
SUNWEG_MONTH_STATS_PATH = "usinas/getgraficomes?"
"""SunWEG API month history path"""
36 changes: 36 additions & 0 deletions sunweg/util.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Sunweg API util."""
from datetime import date
from enum import Enum


Expand All @@ -8,3 +9,38 @@ class Status(Enum):
OK = 0
WARN = 2
ERROR = 1

class ProductionStats:
"""Energy production statistics"""
def __init__(self, date:date, production:float, prognostic:float) -> None:
"""
Initialize energy production statistics.
:param date: statistics date
:type date: date
:param production: statistics production in kWh
:type production: float
:param prognostic: statistics expected production in kWh
"""
self._date = date
self._production = production
self._prognostic = prognostic

@property
def date(self) -> date:
"""Get date."""
return self._date

@property
def production(self) -> float:
"""Get energy production in kWh."""
return self._production

@property
def prognostic(self) -> float:
"""Get expected energy production in kWh."""
return self._prognostic

def __str__(self) -> str:
"""Cast Phase to str."""
return str(self.__class__) + ": " + str(self.__dict__)
4 changes: 4 additions & 0 deletions tests/responses/month_stats_fail_response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"success": false,
"message": "Error message"
}
Loading

0 comments on commit 127437d

Please sign in to comment.