|
3 | 3 | import numpy as np
|
4 | 4 | from pydantic import BaseModel, Field, field_validator
|
5 | 5 |
|
| 6 | +from akkudoktoreos.devices.devicesabc import DeviceBase |
| 7 | +from akkudoktoreos.utils.logutil import get_logger |
6 | 8 | from akkudoktoreos.utils.utils import NumpyEncoder
|
7 | 9 |
|
| 10 | +logger = get_logger(__name__) |
| 11 | + |
8 | 12 |
|
9 | 13 | def max_ladeleistung_w_field(default: Optional[float] = None) -> Optional[float]:
|
10 | 14 | return Field(
|
@@ -83,31 +87,86 @@ def convert_numpy(cls, field: Any) -> Any:
|
83 | 87 | return NumpyEncoder.convert_numpy(field)[0]
|
84 | 88 |
|
85 | 89 |
|
86 |
| -class PVAkku: |
87 |
| - def __init__(self, parameters: BaseAkkuParameters, hours: int = 24): |
88 |
| - # Battery capacity in Wh |
89 |
| - self.kapazitaet_wh = parameters.kapazitaet_wh |
90 |
| - # Initial state of charge in Wh |
91 |
| - self.start_soc_prozent = parameters.start_soc_prozent |
92 |
| - self.soc_wh = (parameters.start_soc_prozent / 100) * parameters.kapazitaet_wh |
93 |
| - self.hours = hours |
| 90 | +class PVAkku(DeviceBase): |
| 91 | + def __init__( |
| 92 | + self, |
| 93 | + parameters: Optional[BaseAkkuParameters] = None, |
| 94 | + hours: Optional[int] = 24, |
| 95 | + provider_id: Optional[str] = None, |
| 96 | + ): |
| 97 | + # Configuration initialisation |
| 98 | + self.provider_id = provider_id |
| 99 | + self.prefix = "<invalid>" |
| 100 | + if self.provider_id == "GenericBattery": |
| 101 | + self.prefix = "battery" |
| 102 | + elif self.provider_id == "GenericBEV": |
| 103 | + self.prefix = "bev" |
| 104 | + # Parameter initialisiation |
| 105 | + self.parameters = parameters |
| 106 | + if hours is None: |
| 107 | + self.hours = self.total_hours |
| 108 | + else: |
| 109 | + self.hours = hours |
| 110 | + |
| 111 | + self.initialised = False |
| 112 | + # Run setup if parameters are given, otherwise setup() has to be called later when the config is initialised. |
| 113 | + if self.parameters is not None: |
| 114 | + self.setup() |
| 115 | + |
| 116 | + def setup(self) -> None: |
| 117 | + if self.initialised: |
| 118 | + return |
| 119 | + if self.provider_id is not None: |
| 120 | + # Setup by configuration |
| 121 | + # Battery capacity in Wh |
| 122 | + self.kapazitaet_wh = getattr(self.config, f"{self.prefix}_capacity") |
| 123 | + # Initial state of charge in Wh |
| 124 | + self.start_soc_prozent = getattr(self.config, f"{self.prefix}_soc_start") |
| 125 | + self.hours = self.total_hours |
| 126 | + # Charge and discharge efficiency |
| 127 | + self.lade_effizienz = getattr(self.config, f"{self.prefix}_charge_efficiency") |
| 128 | + self.entlade_effizienz = getattr(self.config, f"{self.prefix}_discharge_efficiency") |
| 129 | + self.max_ladeleistung_w = getattr(self.config, f"{self.prefix}_charge_power_max") |
| 130 | + # Only assign for storage battery |
| 131 | + if self.provider_id == "GenericBattery": |
| 132 | + self.min_soc_prozent = getattr(self.config, f"{self.prefix}_soc_mint") |
| 133 | + else: |
| 134 | + self.min_soc_prozent = 0 |
| 135 | + self.max_soc_prozent = getattr(self.config, f"{self.prefix}_soc_mint") |
| 136 | + elif self.parameters is not None: |
| 137 | + # Setup by parameters |
| 138 | + # Battery capacity in Wh |
| 139 | + self.kapazitaet_wh = self.parameters.kapazitaet_wh |
| 140 | + # Initial state of charge in Wh |
| 141 | + self.start_soc_prozent = self.parameters.start_soc_prozent |
| 142 | + # Charge and discharge efficiency |
| 143 | + self.lade_effizienz = self.parameters.lade_effizienz |
| 144 | + self.entlade_effizienz = self.parameters.entlade_effizienz |
| 145 | + self.max_ladeleistung_w = self.parameters.max_ladeleistung_w |
| 146 | + # Only assign for storage battery |
| 147 | + self.min_soc_prozent = ( |
| 148 | + self.parameters.min_soc_prozent |
| 149 | + if isinstance(self.parameters, PVAkkuParameters) |
| 150 | + else 0 |
| 151 | + ) |
| 152 | + self.max_soc_prozent = self.parameters.max_soc_prozent |
| 153 | + else: |
| 154 | + error_msg = "Parameters and provider ID missing. Can't instantiate." |
| 155 | + logger.error(error_msg) |
| 156 | + raise ValueError(error_msg) |
| 157 | + |
| 158 | + # init |
| 159 | + if self.max_ladeleistung_w is None: |
| 160 | + self.max_ladeleistung_w = self.kapazitaet_wh |
94 | 161 | self.discharge_array = np.full(self.hours, 1)
|
95 | 162 | self.charge_array = np.full(self.hours, 1)
|
96 |
| - # Charge and discharge efficiency |
97 |
| - self.lade_effizienz = parameters.lade_effizienz |
98 |
| - self.entlade_effizienz = parameters.entlade_effizienz |
99 |
| - self.max_ladeleistung_w = ( |
100 |
| - parameters.max_ladeleistung_w if parameters.max_ladeleistung_w else self.kapazitaet_wh |
101 |
| - ) |
102 |
| - # Only assign for storage battery |
103 |
| - self.min_soc_prozent = ( |
104 |
| - parameters.min_soc_prozent if isinstance(parameters, PVAkkuParameters) else 0 |
105 |
| - ) |
106 |
| - self.max_soc_prozent = parameters.max_soc_prozent |
107 |
| - # Calculate min and max SoC in Wh |
| 163 | + # Calculate start, min and max SoC in Wh |
| 164 | + self.soc_wh = (self.start_soc_prozent / 100) * self.kapazitaet_wh |
108 | 165 | self.min_soc_wh = (self.min_soc_prozent / 100) * self.kapazitaet_wh
|
109 | 166 | self.max_soc_wh = (self.max_soc_prozent / 100) * self.kapazitaet_wh
|
110 | 167 |
|
| 168 | + self.initialised = True |
| 169 | + |
111 | 170 | def to_dict(self) -> dict[str, Any]:
|
112 | 171 | return {
|
113 | 172 | "kapazitaet_wh": self.kapazitaet_wh,
|
|
0 commit comments