Optimizer: add battery grid charging (#27696)
This commit is contained in:
parent
a418b8472b
commit
3626b7f658
1 changed files with 33 additions and 2 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue