Add EEG §9 curtailment api (#25887)

This commit is contained in:
andig 2025-12-29 17:29:27 +01:00 • committed by GitHub
parent cef1c78e86
commit e702924fe3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 65 additions and 5 deletions

View file

@ -192,12 +192,18 @@ type SocLimiter interface {
GetLimitSoc() (int64, error)
}
// Dimmer provides §14a dimming
// Dimmer provides EnWG §14a dimming
type Dimmer interface {
Dimmed() (bool, error)
Dim(bool) error
}
// Curtailer provides EEG §9 curtailment
type Curtailer interface {
Curtailed() (bool, error)
Curtail(bool) error
}
// ChargeController allows to start/stop the charging session on the vehicle side
type ChargeController interface {
ChargeEnable(bool) error
@ -272,9 +278,13 @@ type Circuit interface {
ValidateCurrent(old, new float64) float64
ValidatePower(old, new float64) float64
// §14a
// EnWG §14a - reduce demand/consumption
Dim(bool)
Dimmed() bool
// EEG §9 - reduce feed-in to the grid
Curtail(bool)
Curtailed() bool
}
// Redactor is an interface to redact sensitive data

View file

@ -856,6 +856,32 @@ func (m *MockCircuit) EXPECT() *MockCircuitMockRecorder {
return m.recorder
}
// Curtail mocks base method.
func (m *MockCircuit) Curtail(arg0 bool) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "Curtail", arg0)
}
// Curtail indicates an expected call of Curtail.
func (mr *MockCircuitMockRecorder) Curtail(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Curtail", reflect.TypeOf((*MockCircuit)(nil).Curtail), arg0)
}
// Curtailed mocks base method.
func (m *MockCircuit) Curtailed() bool {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Curtailed")
ret0, _ := ret[0].(bool)
return ret0
}
// Curtailed indicates an expected call of Curtailed.
func (mr *MockCircuitMockRecorder) Curtailed() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Curtailed", reflect.TypeOf((*MockCircuit)(nil).Curtailed))
}
// Dim mocks base method.
func (m *MockCircuit) Dim(arg0 bool) {
m.ctrl.T.Helper()

View file

@ -34,9 +34,10 @@ type Circuit struct {
getMaxCurrent func() (float64, error) // dynamic max allowed current
getMaxPower func() (float64, error) // dynamic max allowed power
current float64
power float64
dimmed bool
current float64
power float64
dimmed bool
curtailed bool
currentUpdated time.Time
powerUpdated time.Time
@ -402,3 +403,24 @@ func (c *Circuit) Dimmed() bool {
return c.parent.Dimmed()
}
func (c *Circuit) Curtail(curtail bool) {
c.mu.Lock()
defer c.mu.Unlock()
c.curtailed = curtail
}
func (c *Circuit) Curtailed() bool {
c.mu.RLock()
defer c.mu.RUnlock()
if c.curtailed {
return true
}
if c.parent == nil {
return false
}
return c.parent.Curtailed()
}

View file

@ -19,6 +19,7 @@ type circuitStruct struct {
MaxPower float64 `json:"maxPower,omitempty"`
MaxCurrent float64 `json:"maxCurrent,omitempty"`
Dimmed bool `json:"dimmed"`
Curtailed bool `json:"curtailed"`
}
// publishCircuits returns a list of circuit titles
@ -37,6 +38,7 @@ func (site *Site) publishCircuits() {
MaxPower: instance.GetMaxPower(),
MaxCurrent: instance.GetMaxCurrent(),
Dimmed: instance.Dimmed(),
Curtailed: instance.Curtailed(),
}
if instance.GetMaxCurrent() > 0 {