evcc-io/provider/cache.go
andig e34167ce7d
Implement multiple loadpoints and new UI (#199)
* Support multiple loadpoints

* Finalize loadpoint site split

* Simplify global voltage

* Fix push template error stopping main process

* Show only last error on retry

* Improve influx v1 compatibility

* Update push templates

* Revert influx v1 user change
2020-07-16 09:34:58 +02:00

97 lines
1.9 KiB
Go

package provider
import (
"time"
"github.com/andig/evcc/util"
"github.com/benbjohnson/clock"
)
// Cached wraps a getter with a cache
type Cached struct {
log *util.Logger
clock clock.Clock
updated time.Time
cache time.Duration
getter interface{}
val interface{}
err error
}
// NewCached wraps a getter with a cache
func NewCached(log *util.Logger, getter interface{}, cache time.Duration) *Cached {
return &Cached{
log: log,
clock: clock.New(),
getter: getter,
cache: cache,
}
}
// FloatGetter gets float value
func (c *Cached) FloatGetter() func() (float64, error) {
g, ok := c.getter.(func() (float64, error))
if !ok {
c.log.FATAL.Fatalf("invalid type: %T", c.getter)
}
return func() (float64, error) {
if c.clock.Since(c.updated) > c.cache {
c.val, c.err = g()
c.updated = c.clock.Now()
}
return c.val.(float64), c.err
}
}
// IntGetter gets int value
func (c *Cached) IntGetter() func() (int64, error) {
g, ok := c.getter.(func() (int64, error))
if !ok {
c.log.FATAL.Fatalf("invalid type: %T", c.getter)
}
return func() (int64, error) {
if c.clock.Since(c.updated) > c.cache {
c.val, c.err = g()
c.updated = c.clock.Now()
}
return c.val.(int64), c.err
}
}
// StringGetter gets string value
func (c *Cached) StringGetter() func() (string, error) {
g, ok := c.getter.(func() (string, error))
if !ok {
c.log.FATAL.Fatalf("invalid type: %T", c.getter)
}
return func() (string, error) {
if c.clock.Since(c.updated) > c.cache {
c.val, c.err = g()
c.updated = c.clock.Now()
}
return c.val.(string), c.err
}
}
// BoolGetter gets bool value
func (c *Cached) BoolGetter() func() (bool, error) {
g, ok := c.getter.(func() (bool, error))
if !ok {
c.log.FATAL.Fatalf("invalid type: %T", c.getter)
}
return func() (bool, error) {
if c.clock.Since(c.updated) > c.cache {
c.val, c.err = g()
c.updated = c.clock.Now()
}
return c.val.(bool), c.err
}
}