Use mockable clock (#26)
This commit is contained in:
parent
44388cdc26
commit
2bfeed5451
3 changed files with 27 additions and 22 deletions
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/andig/evcc/push"
|
||||
|
||||
evbus "github.com/asaskevich/EventBus"
|
||||
"github.com/benbjohnson/clock"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -34,6 +35,7 @@ func powerToCurrent(power, voltage float64, phases int64) int64 {
|
|||
// SoC needs and power availability.
|
||||
type LoadPoint struct {
|
||||
sync.Mutex // guard status
|
||||
clock clock.Clock // mockable time
|
||||
bus evbus.Bus // event bus
|
||||
triggerChan chan struct{} // API updates
|
||||
notificationChan chan<- push.Event // notifications
|
||||
|
|
@ -76,6 +78,7 @@ type LoadPoint struct {
|
|||
// NewLoadPoint creates a LoadPoint with sane defaults
|
||||
func NewLoadPoint() *LoadPoint {
|
||||
return &LoadPoint{
|
||||
clock: clock.New(),
|
||||
bus: evbus.New(),
|
||||
triggerChan: make(chan struct{}, 1),
|
||||
Name: "Main",
|
||||
|
|
@ -85,7 +88,7 @@ func NewLoadPoint() *LoadPoint {
|
|||
Voltage: 230, // V
|
||||
MinCurrent: 6, // A
|
||||
MaxCurrent: 16, // A
|
||||
Steepness: 1, // A
|
||||
Steepness: 10, // A
|
||||
targetCurrent: 0, // A
|
||||
GuardDuration: 10 * time.Minute,
|
||||
}
|
||||
|
|
@ -204,16 +207,17 @@ func (lp *LoadPoint) Prepare(uiChan chan<- Param, notificationChan chan<- push.E
|
|||
_ = lp.bus.Subscribe(evStopCharge, lp.evChargeStopHandler)
|
||||
|
||||
// read initial enabled state
|
||||
var err error
|
||||
if lp.enabled, err = lp.Charger.Enabled(); err != nil {
|
||||
log.ERROR.Printf("%s charger error: %v", lp.Name, err)
|
||||
} else {
|
||||
enabled, err := lp.Charger.Enabled()
|
||||
if err == nil {
|
||||
lp.enabled = enabled
|
||||
log.INFO.Printf("%s charger %s", lp.Name, status[lp.enabled])
|
||||
|
||||
// prevent immediately disabling charger
|
||||
if lp.enabled {
|
||||
lp.guardUpdated = time.Now()
|
||||
lp.guardUpdated = lp.clock.Now()
|
||||
}
|
||||
} else {
|
||||
log.ERROR.Printf("%s charger error: %v", lp.Name, err)
|
||||
}
|
||||
|
||||
// set current to known value
|
||||
|
|
@ -234,7 +238,7 @@ func (lp *LoadPoint) chargerEnable(enable bool) error {
|
|||
log.FATAL.Fatal("charger enable/disable called without setting min current first")
|
||||
}
|
||||
|
||||
if remaining := lp.GuardDuration - time.Since(lp.guardUpdated).Truncate(time.Second); remaining > 0 {
|
||||
if remaining := (lp.GuardDuration - time.Since(lp.guardUpdated)).Truncate(time.Second); remaining > 0 {
|
||||
log.DEBUG.Printf("%s charger %s - contactor delay %v", lp.Name, status[enable], remaining)
|
||||
return nil
|
||||
}
|
||||
|
|
@ -243,7 +247,7 @@ func (lp *LoadPoint) chargerEnable(enable bool) error {
|
|||
if err == nil {
|
||||
lp.enabled = enable // cache
|
||||
log.INFO.Printf("%s charger %s", lp.Name, status[enable])
|
||||
lp.guardUpdated = time.Now()
|
||||
lp.guardUpdated = lp.clock.Now()
|
||||
|
||||
// if not enabled, current will be reduced to 0 in handler
|
||||
lp.bus.Publish(evChargeCurrent, lp.MinCurrent)
|
||||
|
|
@ -290,7 +294,7 @@ func (lp *LoadPoint) updateChargeStatus() api.ChargeStatus {
|
|||
log.INFO.Printf("%s car connected (%s)", lp.Name, string(status))
|
||||
if lp.enabled {
|
||||
// when car connected don't disable right away
|
||||
lp.guardUpdated = time.Now()
|
||||
lp.guardUpdated = lp.clock.Now()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -417,13 +421,14 @@ func (lp *LoadPoint) updateModePV(mode api.ChargeMode) error {
|
|||
|
||||
// updateMeter updates and publishes single meter
|
||||
func (lp *LoadPoint) updateMeter(name string, meter api.Meter, power *float64) {
|
||||
var err error
|
||||
*power, err = meter.CurrentPower()
|
||||
value, err := meter.CurrentPower()
|
||||
if err != nil {
|
||||
log.ERROR.Printf("%s %v", lp.Name, err)
|
||||
return
|
||||
}
|
||||
|
||||
*power = value // update value if no error
|
||||
|
||||
log.DEBUG.Printf("%s %s power: %.1fW", lp.Name, name, *power)
|
||||
lp.publish(name+"Power", *power)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import (
|
|||
|
||||
// Cached wraps a getter with a cache
|
||||
type Cached struct {
|
||||
clck clock.Clock
|
||||
clock clock.Clock
|
||||
updated time.Time
|
||||
cache time.Duration
|
||||
getter interface{}
|
||||
|
|
@ -18,7 +18,7 @@ type Cached struct {
|
|||
// NewCached wraps a getter with a cache
|
||||
func NewCached(getter interface{}, cache time.Duration) *Cached {
|
||||
return &Cached{
|
||||
clck: clock.New(),
|
||||
clock: clock.New(),
|
||||
getter: getter,
|
||||
cache: cache,
|
||||
}
|
||||
|
|
@ -35,13 +35,13 @@ func (c *Cached) FloatGetter() FloatGetter {
|
|||
}
|
||||
|
||||
return FloatGetter(func() (float64, error) {
|
||||
if c.clck.Since(c.updated) > c.cache {
|
||||
if c.clock.Since(c.updated) > c.cache {
|
||||
val, err := g()
|
||||
if err != nil {
|
||||
return val, err
|
||||
}
|
||||
|
||||
c.updated = c.clck.Now()
|
||||
c.updated = c.clock.Now()
|
||||
c.val = val
|
||||
}
|
||||
|
||||
|
|
@ -60,13 +60,13 @@ func (c *Cached) IntGetter() IntGetter {
|
|||
}
|
||||
|
||||
return IntGetter(func() (int64, error) {
|
||||
if c.clck.Since(c.updated) > c.cache {
|
||||
if c.clock.Since(c.updated) > c.cache {
|
||||
val, err := g()
|
||||
if err != nil {
|
||||
return val, err
|
||||
}
|
||||
|
||||
c.updated = c.clck.Now()
|
||||
c.updated = c.clock.Now()
|
||||
c.val = val
|
||||
}
|
||||
|
||||
|
|
@ -85,14 +85,14 @@ func (c *Cached) StringGetter() StringGetter {
|
|||
}
|
||||
|
||||
return StringGetter(func() (string, error) {
|
||||
if c.clck.Since(c.updated) > c.cache {
|
||||
if c.clock.Since(c.updated) > c.cache {
|
||||
|
||||
val, err := g()
|
||||
if err != nil {
|
||||
return val, err
|
||||
}
|
||||
|
||||
c.updated = c.clck.Now()
|
||||
c.updated = c.clock.Now()
|
||||
c.val = val
|
||||
}
|
||||
|
||||
|
|
@ -111,14 +111,14 @@ func (c *Cached) BoolGetter() BoolGetter {
|
|||
}
|
||||
|
||||
return BoolGetter(func() (bool, error) {
|
||||
if c.clck.Since(c.updated) > c.cache {
|
||||
if c.clock.Since(c.updated) > c.cache {
|
||||
|
||||
val, err := g()
|
||||
if err != nil {
|
||||
return val, err
|
||||
}
|
||||
|
||||
c.updated = c.clck.Now()
|
||||
c.updated = c.clock.Now()
|
||||
c.val = val
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ func TestCachedGetter(t *testing.T) {
|
|||
duration := time.Second
|
||||
c := NewCached(g, duration)
|
||||
clck := clock.NewMock()
|
||||
c.clck = clck
|
||||
c.clock = clck
|
||||
getter := c.FloatGetter()
|
||||
|
||||
expect := func(s struct {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue