Site: respect minSoc in maxDischargePower calculation (#32664)

This commit is contained in:
mfuchs1984 2026-08-09 13:39:13 +02:00 • committed by GitHub
parent fdea008b0b
commit 9ef7ea748a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 71 additions and 2 deletions

View file

@ -715,8 +715,18 @@ func (site *Site) updateBatteryMeters() {
}
if bpl, ok := api.Cap[api.BatteryPowerLimiter](meter); ok && maxDischargePower >= 0 {
_, discharge := bpl.GetPowerLimits()
maxDischargePower += discharge
var empty bool
if bsl, ok := api.Cap[api.BatterySocLimiter](meter); ok {
minSoc, _ := bsl.GetSocLimits()
if mm[i].Soc != nil && *mm[i].Soc <= minSoc {
empty = true
}
}
if !empty {
_, discharge := bpl.GetPowerLimits()
maxDischargePower += discharge
}
} else {
maxDischargePower = -1 // any battery without a limit disables the cap
}

View file

@ -18,6 +18,10 @@ func (m *mockBatteryPowerLimiter) GetPowerLimits() (float64, float64) {
return m.charge, m.discharge
}
func (m *mockBatteryPowerLimiter) Soc() (float64, error) {
return 50, nil
}
type mockMeter struct {
api.Meter
}
@ -26,6 +30,10 @@ func (m *mockMeter) CurrentPower() (float64, error) {
return 0, nil
}
func (m *mockMeter) Soc() (float64, error) {
return 50, nil
}
func TestBatteryMaxDischargePowerAggregation(t *testing.T) {
site := &Site{
log: util.NewLogger("foo"),
@ -53,3 +61,54 @@ func TestBatteryMaxDischargePowerAggregation(t *testing.T) {
site.updateBatteryMeters()
assert.Equal(t, 5000.0, site.GetBatteryMaxDischargePower())
}
type mockBatterySocLimiter struct {
api.Meter
soc, min, max float64
}
func (m *mockBatterySocLimiter) Soc() (float64, error) {
return m.soc, nil
}
func (m *mockBatterySocLimiter) GetSocLimits() (float64, float64) {
return m.min, m.max
}
type mockLimiter struct {
mockBatterySocLimiter
discharge float64
}
func (m *mockLimiter) GetPowerLimits() (float64, float64) {
return 0, m.discharge
}
func TestBatteryMaxDischargePowerWithMinSoc(t *testing.T) {
site := &Site{
log: util.NewLogger("foo"),
}
// one battery empty (soc <= min), one normal
m1 := &mockLimiter{mockBatterySocLimiter: mockBatterySocLimiter{Meter: &mockMeter{}, soc: 10, min: 20}, discharge: 2000}
m2 := &mockLimiter{mockBatterySocLimiter: mockBatterySocLimiter{Meter: &mockMeter{}, soc: 50, min: 20}, discharge: 3000}
site.batteryMeters = []config.Device[api.Meter]{
config.NewStaticDevice[api.Meter](config.Named{Name: "bat1"}, m1),
config.NewStaticDevice[api.Meter](config.Named{Name: "bat2"}, m2),
}
site.updateBatteryMeters()
// Only m2 should contribute
assert.Equal(t, 3000.0, site.GetBatteryMaxDischargePower())
// Both empty
m3 := &mockLimiter{mockBatterySocLimiter: mockBatterySocLimiter{Meter: &mockMeter{}, soc: 15, min: 20}, discharge: 3000}
site.batteryMeters = []config.Device[api.Meter]{
config.NewStaticDevice[api.Meter](config.Named{Name: "bat1"}, m1),
config.NewStaticDevice[api.Meter](config.Named{Name: "bat3"}, m3),
}
site.updateBatteryMeters()
assert.Equal(t, 0.0, site.GetBatteryMaxDischargePower())
}