Optimizer: add battery grid charging (#27696)

This commit is contained in:
RenatusRo 2026-02-27 08:55:24 +01:00 • committed by GitHub
parent a418b8472b
commit 3626b7f658
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -205,7 +205,7 @@ func (site *Site) optimizerUpdate(battery []types.Measurement) error {
continue
}
add(site.batteryRequest(dev, b))
add(site.batteryRequest(dev, b, grid, minLen, firstSlotDuration))
}
httpClient := request.NewClient(site.log)
@ -398,7 +398,7 @@ func (site *Site) loadpointRequest(lp loadpoint.API, minLen int, firstSlotDurati
return bat, detail
}
func (site *Site) batteryRequest(dev config.Device[api.Meter], b types.Measurement) (evopt.BatteryConfig, batteryDetail) {
func (site *Site) batteryRequest(dev config.Device[api.Meter], b types.Measurement, grid api.Rates, minLen int, firstSlotDuration time.Duration) (evopt.BatteryConfig, batteryDetail) {
bat := evopt.BatteryConfig{
CMax: batteryPower,
DMax: batteryPower,
@ -432,6 +432,13 @@ func (site *Site) batteryRequest(dev config.Device[api.Meter], b types.Measureme
Capacity: *b.Capacity,
}
// tariff forecast-based grid charging demand
if bat.ChargeFromGrid {
if demand := site.applyBatteryGridChargeLimit(bat.CMax, grid, minLen); demand != nil {
bat.PDemand = prorate(demand, firstSlotDuration)
}
}
return bat, detail
}
@ -678,6 +685,30 @@ func applySmartCostLimit(lp loadpoint.API, demand []float32, grid api.Rates, min
return demand
}
func (site *Site) applyBatteryGridChargeLimit(cMax float32, grid api.Rates, minLen int) []float32 {
limit := site.GetBatteryGridChargeLimit()
if limit == nil {
return nil
}
maxLen := min(minLen, len(grid))
if hasAffordableSlots := slices.ContainsFunc(grid[:maxLen], func(r api.Rate) bool {
return r.Value <= *limit
}); !hasAffordableSlots {
return nil
}
demand := make([]float32, minLen)
for i := range maxLen {
if grid[i].Value <= *limit {
demand[i] = float32(float64(cMax) / slotsPerHour)
}
}
return demand
}
// apiError extracts error message from optimizer API response
func apiError(resp *evopt.PostOptimizeChargeScheduleResponse) error {
var errObj *evopt.Error