Add API documentation generation and use Markdown (#160)

* Add package API documentation generation

Add generation of the API documentation for akkudoktoreos
and akkudoktoreosserver packages.

The API documentation is generated by the Sphinx autosummary extension.

Signed-off-by: Bobby Noelte <b0661n0e17e@gmail.com>

* Enable Google style source commenting and documentation generation.

Enable automatic documentation generation from Google style docstrings in the source.

Signed-off-by: Bobby Noelte <b0661n0e17e@gmail.com>

* Check Google style source commenting.

Check Google style commenting by the appropriate ruff rules.

Commenting is _NOT_ enforced. Missing docstrings are ignored.

Minor commenting quirks of the code base are adapted.

Signed-off-by: Bobby Noelte <b0661n0e17e@gmail.com>

* Improve Markdown handling and switch to Markdown documentation.

Switch to Markdown for the documentation files to improve the user and developer experience (see issue #181).

Keep files with special directives for automatic API documentation in RST format. The
directives expect RST.

Also add dummy handling for openai/ swagger server documentation. The openai interface definition is
for now taken from the fastapi PR as EOS will switch to fastAPI.

Signed-off-by: Bobby Noelte <b0661n0e17e@gmail.com>

---------

Signed-off-by: Bobby Noelte <b0661n0e17e@gmail.com>
Co-authored-by: Normann <github@koldrack.com>
This commit is contained in:
Bobby Noelte
2024-11-10 23:27:52 +01:00
committed by GitHub
parent 3652298134
commit 94467e1a69
28 changed files with 1287 additions and 158 deletions

View File

@@ -149,8 +149,8 @@ class PVAkku:
return geladene_menge, verluste_wh
def aktueller_energieinhalt(self):
"""
This method returns the current remaining energy considering efficiency.
"""This method returns the current remaining energy considering efficiency.
It accounts for both charging and discharging efficiency.
"""
# Calculate remaining energy considering discharge efficiency

View File

@@ -54,12 +54,11 @@ class EnergieManagementSystem:
return self.simuliere(start_stunde)
def simuliere(self, start_stunde: int) -> dict:
"""
hour:
akku_soc_pro_stunde begin of the hour, initial hour state!
last_wh_pro_stunde integral of last hour (end state)
"""
"""hour.
akku_soc_pro_stunde begin of the hour, initial hour state!
last_wh_pro_stunde integral of last hour (end state)
"""
lastkurve_wh = self.gesamtlast
assert (
len(lastkurve_wh) == len(self.pv_prognose_wh) == len(self.strompreis_euro_pro_wh)

View File

@@ -9,8 +9,8 @@ class Haushaltsgeraet:
self.lastkurve = np.zeros(self.hours) # Initialize the load curve with zeros
def set_startzeitpunkt(self, start_hour, global_start_hour=0):
"""
Sets the start time of the device and generates the corresponding load curve.
"""Sets the start time of the device and generates the corresponding load curve.
:param start_hour: The hour at which the device should start.
"""
self.reset()
@@ -27,20 +27,16 @@ class Haushaltsgeraet:
self.lastkurve[start_hour : start_hour + self.dauer_h] = leistung_pro_stunde
def reset(self):
"""
Resets the load curve.
"""
"""Resets the load curve."""
self.lastkurve = np.zeros(self.hours)
def get_lastkurve(self):
"""
Returns the current load curve.
"""
"""Returns the current load curve."""
return self.lastkurve
def get_last_fuer_stunde(self, hour):
"""
Returns the load for a specific hour.
"""Returns the load for a specific hour.
:param hour: The hour for which the load is queried.
:return: The load in watts for the specified hour.
"""
@@ -50,7 +46,5 @@ class Haushaltsgeraet:
return self.lastkurve[hour]
def spaetestmoeglicher_startzeitpunkt(self):
"""
Returns the latest possible start time at which the device can still run completely.
"""
"""Returns the latest possible start time at which the device can still run completely."""
return self.hours - self.dauer_h

View File

@@ -14,8 +14,7 @@ class LoadForecast:
self.load_data()
def get_daily_stats(self, date_str):
"""
Returns the 24-hour profile with mean and standard deviation for a given date.
"""Returns the 24-hour profile with mean and standard deviation for a given date.
:param date_str: Date as a string in the format "YYYY-MM-DD"
:return: An array with shape (2, 24), contains means and standard deviations
@@ -31,8 +30,7 @@ class LoadForecast:
return daily_stats
def get_hourly_stats(self, date_str, hour):
"""
Returns the mean and standard deviation for a specific hour of a given date.
"""Returns the mean and standard deviation for a specific hour of a given date.
:param date_str: Date as a string in the format "YYYY-MM-DD"
:param hour: Specific hour (0 to 23)
@@ -50,8 +48,7 @@ class LoadForecast:
return hourly_stats
def get_stats_for_date_range(self, start_date_str, end_date_str):
"""
Returns the means and standard deviations for a date range.
"""Returns the means and standard deviations for a date range.
:param start_date_str: Start date as a string in the format "YYYY-MM-DD"
:param end_date_str: End date as a string in the format "YYYY-MM-DD"

View File

@@ -7,8 +7,7 @@ class Gesamtlast:
self.prediction_hours = prediction_hours
def hinzufuegen(self, name, last_array):
"""
Adds an array of loads for a specific source.
"""Adds an array of loads for a specific source.
:param name: Name of the load source (e.g., "Household", "Heat Pump")
:param last_array: Array of loads, where each entry corresponds to an hour
@@ -18,8 +17,7 @@ class Gesamtlast:
self.lasten[name] = last_array
def gesamtlast_berechnen(self):
"""
Calculates the total load for each hour and returns an array of total loads.
"""Calculates the total load for each hour and returns an array of total loads.
:return: Array of total loads, where each entry corresponds to an hour
"""

View File

@@ -13,8 +13,7 @@ class NumpyEncoder(json.JSONEncoder):
@staticmethod
def dumps(data):
"""
Static method to serialize a Python object into a JSON string using NumpyEncoder.
"""Static method to serialize a Python object into a JSON string using NumpyEncoder.
Args:
data: The Python object to serialize.

View File

@@ -39,8 +39,8 @@ class optimization_problem:
def decode_charge_discharge(
self, discharge_hours_bin: np.ndarray
) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
"""
Decode the input array `discharge_hours_bin` into three separate arrays for AC charging, DC charging, and discharge.
"""Decode the input array `discharge_hours_bin` into three separate arrays for AC charging, DC charging, and discharge.
The function maps AC and DC charging values to relative power levels (0 to 1), while the discharge remains binary (0 or 1).
Parameters:
@@ -81,8 +81,9 @@ class optimization_problem:
# Custom mutation function that applies type-specific mutations
def mutate(self, individual):
"""
Custom mutation function for the individual. This function mutates different parts of the individual:
"""Custom mutation function for the individual.
This function mutates different parts of the individual:
- Mutates the discharge and charge states (AC, DC, idle) using the split_charge_discharge method.
- Mutates the EV charging schedule if EV optimization is enabled.
- Mutates appliance start times if household appliances are part of the optimization.
@@ -93,7 +94,6 @@ class optimization_problem:
Returns:
- (tuple): The mutated individual as a tuple (required by DEAP).
"""
# Step 1: Mutate the charge/discharge states (idle, discharge, AC charge, DC charge)
# Extract the relevant part of the individual for prediction hours, which represents the charge/discharge behavior.
charge_discharge_part = individual[: self.prediction_hours]
@@ -167,13 +167,13 @@ class optimization_problem:
def split_individual(
self, individual: List[float]
) -> Tuple[List[int], List[float], Optional[int]]:
"""
Split the individual solution into its components:
1. Discharge hours (-1 (Charge),0 (Nothing),1 (Discharge)),
2. Electric vehicle charge hours (possible_charge_values),
"""Split the individual solution into its components.
Components:
1. Discharge hours (binary),
2. Electric vehicle charge hours (float),
3. Dishwasher start time (integer if applicable).
"""
discharge_hours_bin = individual[: self.prediction_hours]
eautocharge_hours_float = (
individual[self.prediction_hours : self.prediction_hours * 2]
@@ -189,9 +189,7 @@ class optimization_problem:
return discharge_hours_bin, eautocharge_hours_float, spuelstart_int
def setup_deap_environment(self, opti_param: Dict[str, Any], start_hour: int) -> None:
"""
Set up the DEAP environment with fitness and individual creation rules.
"""
"""Set up the DEAP environment with fitness and individual creation rules."""
self.opti_param = opti_param
# Remove existing FitnessMin and Individual classes from creator if present
@@ -252,9 +250,9 @@ class optimization_problem:
def evaluate_inner(
self, individual: List[float], ems: EnergieManagementSystem, start_hour: int
) -> Dict[str, Any]:
"""
Internal evaluation function that simulates the energy management system (EMS)
using the provided individual solution.
"""Simulates the energy management system (EMS) using the provided individual solution.
This is an internal function.
"""
ems.reset()
discharge_hours_bin, eautocharge_hours_index, spuelstart_int = self.split_individual(
@@ -288,9 +286,7 @@ class optimization_problem:
start_hour: int,
worst_case: bool,
) -> Tuple[float]:
"""
Evaluate the fitness of an individual solution based on the simulation results.
"""
"""Evaluate the fitness of an individual solution based on the simulation results."""
try:
o = self.evaluate_inner(individual, ems, start_hour)
except Exception as e:
@@ -381,9 +377,7 @@ class optimization_problem:
*,
ngen: int = 600,
) -> Dict[str, Any]:
"""
Perform EMS (Energy Management System) optimization and visualize results.
"""
"""Perform EMS (Energy Management System) optimization and visualize results."""
einspeiseverguetung_euro_pro_wh = np.full(
self.prediction_hours, parameter["einspeiseverguetung_euro_pro_wh"]
)

View File

@@ -35,8 +35,9 @@ class Heatpump:
return temp_celsius > -100 and temp_celsius < 100
def calculate_cop(self, outside_temperature_celsius: float) -> float:
"""Calculate the coefficient of performance (COP) based on outside temperature. Supported
temperate range -100 degree Celsius to 100 degree Celsius.
"""Calculate the coefficient of performance (COP) based on outside temperature.
Supported temperate range -100 degree Celsius to 100 degree Celsius.
Args:
outside_temperature_celsius: Outside temperature in degree Celsius
@@ -59,6 +60,7 @@ class Heatpump:
def calculate_heating_output(self, outside_temperature_celsius: float) -> float:
"""Calculate the heating output in Watts based on outside temperature in degree Celsius.
Temperature range must be between -100 and 100 degree Celsius.
Args: