EEBus OHPCF: keep enabled state when enable fails (#32263)
This commit is contained in:
parent
20ce660d7a
commit
6187b965ca
4 changed files with 24 additions and 9 deletions
|
|
@ -148,7 +148,7 @@ func (c *EEBusOHPCF) UseCaseEvent(_ spineapi.DeviceRemoteInterface, entity spine
|
||||||
// react immediately to a freshly announced schedule/resume opportunity
|
// react immediately to a freshly announced schedule/resume opportunity
|
||||||
// instead of waiting for the next reboost tick, which may miss it (#31549)
|
// instead of waiting for the next reboost tick, which may miss it (#31549)
|
||||||
if c.lastEnabled() {
|
if c.lastEnabled() {
|
||||||
if err := c.apply(); err != nil {
|
if err := c.apply(true); err != nil {
|
||||||
c.log.DEBUG.Printf("apply: %v", err)
|
c.log.DEBUG.Printf("apply: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -252,13 +252,19 @@ func (c *EEBusOHPCF) Enabled() (bool, error) {
|
||||||
// Enable schedules/resumes the optional consumption when on, pauses/aborts it
|
// Enable schedules/resumes the optional consumption when on, pauses/aborts it
|
||||||
// when off; while on a reboost loop reschedules newly announced consumption.
|
// when off; while on a reboost loop reschedules newly announced consumption.
|
||||||
func (c *EEBusOHPCF) Enable(enable bool) error {
|
func (c *EEBusOHPCF) Enable(enable bool) error {
|
||||||
|
// record the intent only once accepted, otherwise Enabled() would report a
|
||||||
|
// state the compressor never reached and the loadpoint runs out of sync
|
||||||
|
if err := c.apply(enable); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
c.setEnabled(enable)
|
c.setEnabled(enable)
|
||||||
|
|
||||||
if enable {
|
if enable {
|
||||||
c.startReboost()
|
c.startReboost()
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.apply()
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// startReboost launches the reboost loop, unless one is already running or no
|
// startReboost launches the reboost loop, unless one is already running or no
|
||||||
|
|
@ -296,7 +302,7 @@ func (c *EEBusOHPCF) reboostLoop() {
|
||||||
if !c.lastEnabled() {
|
if !c.lastEnabled() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := c.apply(); err != nil {
|
if err := c.apply(true); err != nil {
|
||||||
c.log.DEBUG.Printf("reboost: %v", err)
|
c.log.DEBUG.Printf("reboost: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -355,7 +361,7 @@ func (c *EEBusOHPCF) stop(entity spineapi.EntityRemoteInterface) error {
|
||||||
// MaxCurrent implements the api.Charger interface. OHPCF is on/off and cannot
|
// MaxCurrent implements the api.Charger interface. OHPCF is on/off and cannot
|
||||||
// be modulated, so the offered current is ignored.
|
// be modulated, so the offered current is ignored.
|
||||||
func (c *EEBusOHPCF) MaxCurrent(int64) error {
|
func (c *EEBusOHPCF) MaxCurrent(int64) error {
|
||||||
return c.apply()
|
return c.apply(c.lastEnabled())
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ api.Dimmer = (*EEBusOHPCF)(nil)
|
var _ api.Dimmer = (*EEBusOHPCF)(nil)
|
||||||
|
|
@ -406,7 +412,7 @@ func (c *EEBusOHPCF) Dim(dim bool) error {
|
||||||
|
|
||||||
// apply issues the command to align the optional consumption with the on/off
|
// apply issues the command to align the optional consumption with the on/off
|
||||||
// intent. It is idempotent: ohpcfControlAction only acts on a state transition.
|
// intent. It is idempotent: ohpcfControlAction only acts on a state transition.
|
||||||
func (c *EEBusOHPCF) apply() error {
|
func (c *EEBusOHPCF) apply(enable bool) error {
|
||||||
entity, ok := c.connectedCompressor()
|
entity, ok := c.connectedCompressor()
|
||||||
if !ok {
|
if !ok {
|
||||||
return errNotConnected
|
return errNotConnected
|
||||||
|
|
@ -418,7 +424,7 @@ func (c *EEBusOHPCF) apply() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ohpcfControlAction(state, c.lastEnabled()) {
|
switch ohpcfControlAction(state, enable) {
|
||||||
case ohpcfSchedule:
|
case ohpcfSchedule:
|
||||||
return eebus.Await(func(cb func(model.ResultDataType, model.MsgCounterType)) (*model.MsgCounterType, error) {
|
return eebus.Await(func(cb func(model.ResultDataType, model.MsgCounterType)) (*model.MsgCounterType, error) {
|
||||||
// 0 = start immediately (relative schedule, see SchedulePowerConsumptionProcess)
|
// 0 = start immediately (relative schedule, see SchedulePowerConsumptionProcess)
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,15 @@ func TestEEBusOHPCFNotConnected(t *testing.T) {
|
||||||
require.ErrorIs(t, c.Dim(true), api.ErrNotAvailable)
|
require.ErrorIs(t, c.Dim(true), api.ErrNotAvailable)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// a failed enable must not persist the intent, otherwise Enabled() reports a
|
||||||
|
// state the compressor never accepted and the loadpoint runs out of sync (#32252).
|
||||||
|
func TestOHPCFEnableFailureKeepsState(t *testing.T) {
|
||||||
|
c := &EEBusOHPCF{}
|
||||||
|
|
||||||
|
require.ErrorIs(t, c.Enable(true), errNotConnected)
|
||||||
|
assert.False(t, c.lastEnabled())
|
||||||
|
}
|
||||||
|
|
||||||
// status mapping: running is C, every other connected state (incl. completed
|
// status mapping: running is C, every other connected state (incl. completed
|
||||||
// and stopped after a boost) is standby B, never disconnected.
|
// and stopped after a boost) is standby B, never disconnected.
|
||||||
func TestOHPCFStatus(t *testing.T) {
|
func TestOHPCFStatus(t *testing.T) {
|
||||||
|
|
|
||||||
2
go.mod
2
go.mod
|
|
@ -268,6 +268,6 @@ replace github.com/grid-x/modbus => github.com/evcc-io/modbus v0.0.0-20250501165
|
||||||
|
|
||||||
replace github.com/lorenzodonini/ocpp-go => github.com/evcc-io/ocpp-go v0.0.0-20260727074919-195c10b8758d
|
replace github.com/lorenzodonini/ocpp-go => github.com/evcc-io/ocpp-go v0.0.0-20260727074919-195c10b8758d
|
||||||
|
|
||||||
replace github.com/enbility/spine-go => github.com/andig/spine-go v0.7.1-0.20260725155511-6f83690e6238
|
replace github.com/enbility/spine-go => github.com/andig/spine-go v0.7.1-0.20260729105813-e3e33d07b702
|
||||||
|
|
||||||
replace github.com/enbility/eebus-go => github.com/andig/eebus-go v0.0.0-20260725155950-e735091ff165
|
replace github.com/enbility/eebus-go => github.com/andig/eebus-go v0.0.0-20260725155950-e735091ff165
|
||||||
|
|
|
||||||
4
go.sum
4
go.sum
|
|
@ -30,8 +30,8 @@ github.com/andig/gosunspec v0.0.0-20260705113727-6d585e133512 h1:1y8dS4GaBB9WUu/
|
||||||
github.com/andig/gosunspec v0.0.0-20260705113727-6d585e133512/go.mod h1:c6P6szcR+ROkqZruOR4f6qbDKFjZX6OitPpj+yJ/r8k=
|
github.com/andig/gosunspec v0.0.0-20260705113727-6d585e133512/go.mod h1:c6P6szcR+ROkqZruOR4f6qbDKFjZX6OitPpj+yJ/r8k=
|
||||||
github.com/andig/mbserver v0.0.0-20230310211055-1d29cbb5820e h1:m/NTP3JWpR7M0ljLxiQU4fzR25jjhe1LDtxLMNcoNJQ=
|
github.com/andig/mbserver v0.0.0-20230310211055-1d29cbb5820e h1:m/NTP3JWpR7M0ljLxiQU4fzR25jjhe1LDtxLMNcoNJQ=
|
||||||
github.com/andig/mbserver v0.0.0-20230310211055-1d29cbb5820e/go.mod h1:4VtYzTm//oUipwvO3yh0g/udTE7pYJM+U/kyAuFDsgM=
|
github.com/andig/mbserver v0.0.0-20230310211055-1d29cbb5820e/go.mod h1:4VtYzTm//oUipwvO3yh0g/udTE7pYJM+U/kyAuFDsgM=
|
||||||
github.com/andig/spine-go v0.7.1-0.20260725155511-6f83690e6238 h1:VoAFMoBmdIhC6ki4IirAQVd7OPI3xhJG4wJIQpuDSts=
|
github.com/andig/spine-go v0.7.1-0.20260729105813-e3e33d07b702 h1:aSME6GPyu2LeTp282plM4nrCFBwBiNnnjWxuAIYGnhs=
|
||||||
github.com/andig/spine-go v0.7.1-0.20260725155511-6f83690e6238/go.mod h1:ddWZU5BQGyzRGF20Z7rUKFFzbCp+cfu9mZgYtOMW/fM=
|
github.com/andig/spine-go v0.7.1-0.20260729105813-e3e33d07b702/go.mod h1:ddWZU5BQGyzRGF20Z7rUKFFzbCp+cfu9mZgYtOMW/fM=
|
||||||
github.com/andybalholm/cascadia v1.3.3 h1:AG2YHrzJIm4BZ19iwJ/DAua6Btl3IwJX+VI4kktS1LM=
|
github.com/andybalholm/cascadia v1.3.3 h1:AG2YHrzJIm4BZ19iwJ/DAua6Btl3IwJX+VI4kktS1LM=
|
||||||
github.com/andybalholm/cascadia v1.3.3/go.mod h1:xNd9bqTn98Ln4DwST8/nG+H0yuB8Hmgu1YHNnWw0GeA=
|
github.com/andybalholm/cascadia v1.3.3/go.mod h1:xNd9bqTn98Ln4DwST8/nG+H0yuB8Hmgu1YHNnWw0GeA=
|
||||||
github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg=
|
github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg=
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue