HEMS: add per-hems tests for nil statements when unconfigured or not connected (#31430)
This commit is contained in:
parent
5e6f1e7356
commit
b6cca9ea1b
4 changed files with 66 additions and 43 deletions
|
|
@ -339,6 +339,11 @@ func (c *EEBus) CurtailedPercent() *int {
|
|||
c.mux.RLock()
|
||||
defer c.mux.RUnlock()
|
||||
|
||||
// no statement until first connected
|
||||
if c.productionLimitActivated == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// without a nominal reference the W limit cannot be expressed as a percent
|
||||
if c.productionNominalMax <= 0 {
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
ucapi "github.com/enbility/eebus-go/usecases/api"
|
||||
"github.com/evcc-io/evcc/core/site"
|
||||
"github.com/evcc-io/evcc/hems/hems"
|
||||
"github.com/evcc-io/evcc/server/db"
|
||||
"github.com/evcc-io/evcc/server/eebus"
|
||||
"github.com/evcc-io/evcc/util"
|
||||
|
|
@ -168,6 +169,18 @@ func TestRun_ProductionLimitReleasedEarly(t *testing.T) {
|
|||
assertProductionLimit(t, c, false)
|
||||
}
|
||||
|
||||
// TestNotConnected verifies that all api.HEMS getters make no statement while
|
||||
// no upstream controlbox has connected yet.
|
||||
func TestNotConnected(t *testing.T) {
|
||||
c := newTestEEBus(t) // Connector never connected
|
||||
|
||||
assert.Nil(t, c.MaxConsumptionPower())
|
||||
assert.Nil(t, c.MaxProductionPower())
|
||||
assert.Nil(t, c.CurtailedPercent())
|
||||
assert.Nil(t, hems.Dimmed(c))
|
||||
assert.Nil(t, hems.Curtailed(c))
|
||||
}
|
||||
|
||||
// TestRun_ProductionLimitWithoutNominalMax verifies an incoming LPP limit
|
||||
// errors instead of being silently ignored when productionNominalMax is unset (#31469).
|
||||
func TestRun_ProductionLimitWithoutNominalMax(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/evcc-io/evcc/core/site"
|
||||
"github.com/evcc-io/evcc/hems/hems"
|
||||
"github.com/evcc-io/evcc/server/db"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
|
@ -15,32 +17,35 @@ type stubSite struct {
|
|||
|
||||
func (s *stubSite) GetGridPower() float64 { return 0 }
|
||||
|
||||
func TestFnn(t *testing.T) {
|
||||
require.NoError(t, db.NewInstance("sqlite", ":memory:"))
|
||||
|
||||
fnn, err := NewFnn(&stubSite{}, 1e3, 1e3, nil, nil, nil, func() (bool, error) {
|
||||
return true, nil
|
||||
}, 0)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, fnn.CurtailedPercent())
|
||||
func boolG(v bool) func() (bool, error) {
|
||||
return func() (bool, error) { return v, nil }
|
||||
}
|
||||
|
||||
// TestFnnNilWhenNotConfigured verifies "nil = limiting undefined": nil unless
|
||||
// the relay input is configured, else valid right after NewFnn returns.
|
||||
func TestFnnNilWhenNotConfigured(t *testing.T) {
|
||||
// TestCurtailmentNotConfigured verifies that without W3 no curtailment
|
||||
// statement is made, while dimming via W4 remains available.
|
||||
func TestCurtailmentNotConfigured(t *testing.T) {
|
||||
require.NoError(t, db.NewInstance("sqlite", ":memory:"))
|
||||
|
||||
unconfigured, err := NewFnn(&stubSite{}, 1e3, 1e3, nil, nil, nil, nil, 0)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, unconfigured.MaxConsumptionPower())
|
||||
require.Nil(t, unconfigured.MaxProductionPower())
|
||||
|
||||
off := func() (bool, error) { return false, nil }
|
||||
configured, err := NewFnn(&stubSite{}, 1e3, 1e3, off, nil, nil, off, 0)
|
||||
fnn, err := NewFnn(&stubSite{}, 1e3, 1e3, nil, nil, nil, boolG(true), 0)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NotNil(t, configured.MaxConsumptionPower())
|
||||
require.Equal(t, 0.0, *configured.MaxConsumptionPower())
|
||||
require.NotNil(t, configured.MaxProductionPower())
|
||||
require.Equal(t, 0.0, *configured.MaxProductionPower())
|
||||
assert.Nil(t, fnn.CurtailedPercent())
|
||||
assert.Nil(t, fnn.MaxProductionPower())
|
||||
assert.Nil(t, hems.Curtailed(fnn))
|
||||
|
||||
assert.NotNil(t, fnn.MaxConsumptionPower())
|
||||
assert.NotNil(t, hems.Dimmed(fnn))
|
||||
}
|
||||
|
||||
// TestDimmingNotConfigured verifies that without W4 no dimming statement is
|
||||
// made, while curtailment via W3 remains available.
|
||||
func TestDimmingNotConfigured(t *testing.T) {
|
||||
fnn, err := NewFnn(&stubSite{}, 0, 1e3, boolG(false), nil, nil, nil, 0)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Nil(t, fnn.MaxConsumptionPower())
|
||||
assert.Nil(t, hems.Dimmed(fnn))
|
||||
|
||||
assert.NotNil(t, fnn.CurtailedPercent())
|
||||
assert.NotNil(t, hems.Curtailed(fnn))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,28 +3,28 @@ package relay
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/evcc-io/evcc/core/site"
|
||||
"github.com/evcc-io/evcc/server/db"
|
||||
"github.com/evcc-io/evcc/hems/hems"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// stubSite implements site.API for testing — only GetGridPower is exercised.
|
||||
type stubSite struct {
|
||||
site.API
|
||||
}
|
||||
|
||||
func (s *stubSite) GetGridPower() float64 { return 0 }
|
||||
|
||||
// TestRelayNoNilState verifies MaxConsumptionPower is always determinable (w1
|
||||
// is mandatory) — NewRelay reads it once so the state is valid immediately.
|
||||
func TestRelayNoNilState(t *testing.T) {
|
||||
require.NoError(t, db.NewInstance("sqlite", ":memory:"))
|
||||
|
||||
off := func() (bool, error) { return false, nil }
|
||||
c, err := NewRelay(&stubSite{}, off, nil, 1000, 0)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NotNil(t, c.MaxConsumptionPower())
|
||||
require.Equal(t, 0.0, *c.MaxConsumptionPower())
|
||||
require.Nil(t, c.MaxProductionPower()) // scaffolding only, always nil
|
||||
// TestCurtailmentNotConfigured verifies that relay never makes a curtailment
|
||||
// statement, and that an active relay dims to maxPower.
|
||||
func TestCurtailmentNotConfigured(t *testing.T) {
|
||||
c := new(Relay)
|
||||
|
||||
// relay never makes a curtailment statement
|
||||
assert.Nil(t, c.CurtailedPercent())
|
||||
assert.Nil(t, c.MaxProductionPower())
|
||||
assert.Nil(t, hems.Curtailed(c))
|
||||
|
||||
// active relay dims to maxPower
|
||||
c.maxPower = 1e3
|
||||
require.NoError(t, c.setConsumptionLimit(c.maxPower))
|
||||
assert.Equal(t, new(1e3), c.MaxConsumptionPower())
|
||||
assert.Equal(t, new(true), hems.Dimmed(c))
|
||||
|
||||
// curtailment statement unaffected by relay activity
|
||||
assert.Nil(t, c.CurtailedPercent())
|
||||
assert.Nil(t, hems.Curtailed(c))
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue