mirror of
https://github.com/Akkudoktor-EOS/EOS.git
synced 2026-04-11 16:26:20 +00:00
Adds inverter AC/DC efficiency and break-even penalty (#888)
Some checks failed
Bump Version / Bump Version Workflow (push) Has been cancelled
docker-build / platform-excludes (push) Has been cancelled
docker-build / build (push) Has been cancelled
docker-build / merge (push) Has been cancelled
pre-commit / pre-commit (push) Has been cancelled
Run Pytest on Pull Request / test (push) Has been cancelled
Some checks failed
Bump Version / Bump Version Workflow (push) Has been cancelled
docker-build / platform-excludes (push) Has been cancelled
docker-build / build (push) Has been cancelled
docker-build / merge (push) Has been cancelled
pre-commit / pre-commit (push) Has been cancelled
Run Pytest on Pull Request / test (push) Has been cancelled
* feat: add inverter AC/DC efficiency and break-even penalty * test: update tests/test_geneticoptimize.py with new ac_charge_break_even parameter * docs: update documentation * chore: update version numbers in configuration files to v0.2.0.dev2602272006923535
This commit is contained in:
committed by
GitHub
parent
04420e66ab
commit
3ccc25d731
@@ -193,6 +193,44 @@ class InverterCommonSettings(DevicesBaseSettings):
|
||||
},
|
||||
)
|
||||
|
||||
ac_to_dc_efficiency: float = Field(
|
||||
default=1.0,
|
||||
ge=0,
|
||||
le=1,
|
||||
json_schema_extra={
|
||||
"description": (
|
||||
"Efficiency of AC to DC conversion for grid-to-battery AC charging (0-1). "
|
||||
"Set to 0 to disable AC charging. Default 1.0 (no additional inverter loss)."
|
||||
),
|
||||
"examples": [0.95, 1.0, 0.0],
|
||||
},
|
||||
)
|
||||
|
||||
dc_to_ac_efficiency: float = Field(
|
||||
default=1.0,
|
||||
gt=0,
|
||||
le=1,
|
||||
json_schema_extra={
|
||||
"description": (
|
||||
"Efficiency of DC to AC conversion for battery discharging to AC load/grid (0-1). "
|
||||
"Default 1.0 (no additional inverter loss)."
|
||||
),
|
||||
"examples": [0.95, 1.0],
|
||||
},
|
||||
)
|
||||
|
||||
max_ac_charge_power_w: Optional[float] = Field(
|
||||
default=None,
|
||||
ge=0,
|
||||
json_schema_extra={
|
||||
"description": (
|
||||
"Maximum AC charging power in watts. "
|
||||
"null means no additional limit. Set to 0 to disable AC charging."
|
||||
),
|
||||
"examples": [None, 0, 5000],
|
||||
},
|
||||
)
|
||||
|
||||
@computed_field # type: ignore[prop-decorator]
|
||||
@property
|
||||
def measurement_keys(self) -> Optional[list[str]]:
|
||||
|
||||
@@ -26,6 +26,9 @@ class Inverter:
|
||||
self.max_power_wh = (
|
||||
self.parameters.max_power_wh
|
||||
) # Maximum power that the inverter can handle
|
||||
self.dc_to_ac_efficiency = self.parameters.dc_to_ac_efficiency
|
||||
self.ac_to_dc_efficiency = self.parameters.ac_to_dc_efficiency
|
||||
self.max_ac_charge_power_w = self.parameters.max_ac_charge_power_w
|
||||
|
||||
def process_energy(
|
||||
self, generation: float, consumption: float, hour: int
|
||||
@@ -35,6 +38,9 @@ class Inverter:
|
||||
grid_import = 0.0
|
||||
self_consumption = 0.0
|
||||
|
||||
# Cache inverter DC→AC efficiency for discharge path
|
||||
dc_to_ac_eff = self.dc_to_ac_efficiency
|
||||
|
||||
if generation >= consumption:
|
||||
if consumption > self.max_power_wh:
|
||||
# If consumption exceeds maximum inverter power
|
||||
@@ -56,21 +62,29 @@ class Inverter:
|
||||
if remaining_load_evq > 0:
|
||||
# Akku muss den Restverbrauch decken
|
||||
if self.battery:
|
||||
from_battery, discharge_losses = self.battery.discharge_energy(
|
||||
remaining_load_evq, hour
|
||||
# Request more DC from battery to account for DC→AC conversion loss
|
||||
dc_request = remaining_load_evq / dc_to_ac_eff
|
||||
from_battery_dc, discharge_losses = self.battery.discharge_energy(
|
||||
dc_request, hour
|
||||
)
|
||||
remaining_load_evq -= from_battery # Restverbrauch nach Akkuentladung
|
||||
losses += discharge_losses
|
||||
# Convert DC output to AC
|
||||
from_battery_ac = from_battery_dc * dc_to_ac_eff
|
||||
inverter_discharge_losses = from_battery_dc - from_battery_ac
|
||||
remaining_load_evq -= from_battery_ac
|
||||
losses += discharge_losses + inverter_discharge_losses
|
||||
else:
|
||||
from_battery_ac = 0.0
|
||||
|
||||
# Wenn der Akku den Restverbrauch nicht vollständig decken kann, wird der Rest ins Netz gezogen
|
||||
if remaining_load_evq > 0:
|
||||
grid_import += remaining_load_evq
|
||||
remaining_load_evq = 0
|
||||
else:
|
||||
from_battery = 0.0
|
||||
from_battery_ac = 0.0
|
||||
|
||||
if remaining_power > 0:
|
||||
# Load battery with excess energy
|
||||
# Load battery with excess energy (DC path, no inverter conversion needed)
|
||||
charge_losses = 0.0
|
||||
if self.battery:
|
||||
charged_energie, charge_losses = self.battery.charge_energy(
|
||||
remaining_power, hour
|
||||
@@ -88,7 +102,7 @@ class Inverter:
|
||||
|
||||
losses += charge_losses
|
||||
self_consumption = (
|
||||
consumption + from_battery
|
||||
consumption + from_battery_ac
|
||||
) # Self-consumption is equal to the load
|
||||
|
||||
else:
|
||||
@@ -98,15 +112,21 @@ class Inverter:
|
||||
|
||||
# Discharge battery to cover shortfall, if possible
|
||||
if self.battery:
|
||||
battery_discharge, discharge_losses = self.battery.discharge_energy(
|
||||
min(shortfall, available_ac_power), hour
|
||||
# Need shortfall in AC, request more DC from battery for DC→AC conversion
|
||||
ac_needed = min(shortfall, available_ac_power)
|
||||
dc_request = ac_needed / dc_to_ac_eff
|
||||
battery_discharge_dc, discharge_losses = self.battery.discharge_energy(
|
||||
dc_request, hour
|
||||
)
|
||||
losses += discharge_losses
|
||||
# Convert DC output to AC
|
||||
battery_discharge_ac = battery_discharge_dc * dc_to_ac_eff
|
||||
inverter_discharge_losses = battery_discharge_dc - battery_discharge_ac
|
||||
losses += discharge_losses + inverter_discharge_losses
|
||||
else:
|
||||
battery_discharge = 0
|
||||
battery_discharge_ac = 0
|
||||
|
||||
# Draw remaining required power from the grid (discharge_losses are already substraved in the battery)
|
||||
grid_import = shortfall - battery_discharge
|
||||
self_consumption = generation + battery_discharge
|
||||
# Draw remaining required power from the grid (discharge_losses are already subtracted in the battery)
|
||||
grid_import = shortfall - battery_discharge_ac
|
||||
self_consumption = generation + battery_discharge_ac
|
||||
|
||||
return grid_export, grid_import, losses, self_consumption
|
||||
|
||||
Reference in New Issue
Block a user