From 6f1333946a7cb8adad78232b5831399239314b04 Mon Sep 17 00:00:00 2001 From: andig Date: Thu, 13 Apr 2023 09:01:04 +0200 Subject: [PATCH] Websocket plugin: fix and simplify --- provider/http.go | 43 ++++++++++------ provider/socket.go | 119 ++++++++++++++++++--------------------------- 2 files changed, 73 insertions(+), 89 deletions(-) diff --git a/provider/http.go b/provider/http.go index 31dd43bf99..36afb5893c 100644 --- a/provider/http.go +++ b/provider/http.go @@ -168,6 +168,23 @@ func (p *HTTP) request(url string, body ...string) ([]byte, error) { return p.val, p.err } +var _ StringProvider = (*HTTP)(nil) + +// StringGetter sends string request +func (p *HTTP) StringGetter() func() (string, error) { + return func() (string, error) { + b, err := p.request(p.url, p.body) + + if err == nil && p.pipeline != nil { + b, err = p.pipeline.Process(b) + } + + return string(b), err + } +} + +var _ FloatProvider = (*HTTP)(nil) + // FloatGetter parses float from request func (p *HTTP) FloatGetter() func() (float64, error) { g := p.StringGetter() @@ -179,14 +196,13 @@ func (p *HTTP) FloatGetter() func() (float64, error) { } f, err := strconv.ParseFloat(s, 64) - if err == nil { - f *= p.scale - } - return f, err + return f * p.scale, err } } +var _ IntProvider = (*HTTP)(nil) + // IntGetter parses int64 from request func (p *HTTP) IntGetter() func() (int64, error) { g := p.FloatGetter() @@ -197,18 +213,7 @@ func (p *HTTP) IntGetter() func() (int64, error) { } } -// StringGetter sends string request -func (p *HTTP) StringGetter() func() (string, error) { - return func() (string, error) { - b, err := p.request(p.url, p.body) - - if err == nil && p.pipeline != nil { - b, err = p.pipeline.Process(b) - } - - return string(b), err - } -} +var _ BoolProvider = (*HTTP)(nil) // BoolGetter parses bool from request func (p *HTTP) BoolGetter() func() (bool, error) { @@ -236,6 +241,8 @@ func (p *HTTP) set(param string, val interface{}) error { return err } +var _ SetIntProvider = (*HTTP)(nil) + // IntSetter sends int request func (p *HTTP) IntSetter(param string) func(int64) error { return func(val int64) error { @@ -243,6 +250,8 @@ func (p *HTTP) IntSetter(param string) func(int64) error { } } +var _ SetStringProvider = (*HTTP)(nil) + // StringSetter sends string request func (p *HTTP) StringSetter(param string) func(string) error { return func(val string) error { @@ -250,6 +259,8 @@ func (p *HTTP) StringSetter(param string) func(string) error { } } +var _ SetBoolProvider = (*HTTP)(nil) + // BoolSetter sends bool request func (p *HTTP) BoolSetter(param string) func(bool) error { return func(val bool) error { diff --git a/provider/socket.go b/provider/socket.go index 4669d4bd8b..46c5fbf720 100644 --- a/provider/socket.go +++ b/provider/socket.go @@ -8,12 +8,11 @@ import ( "sync" "time" + "github.com/evcc-io/evcc/provider/pipeline" "github.com/evcc-io/evcc/util" - "github.com/evcc-io/evcc/util/jq" "github.com/evcc-io/evcc/util/request" "github.com/evcc-io/evcc/util/transport" "github.com/gorilla/websocket" - "github.com/itchyny/gojq" ) const retryDelay = 5 * time.Second @@ -21,14 +20,14 @@ const retryDelay = 5 * time.Second // Socket implements websocket request provider type Socket struct { *request.Helper - log *util.Logger - mux sync.Mutex - wait *util.Waiter - url string - headers map[string]string - scale float64 - jq *gojq.Query - val interface{} + log *util.Logger + mux sync.Mutex + wait *util.Waiter + url string + headers map[string]string + scale float64 + pipeline *pipeline.Pipeline + val []byte // Cached http response value } func init() { @@ -39,15 +38,16 @@ func init() { // NewSocketProviderFromConfig creates a HTTP provider func NewSocketProviderFromConfig(other map[string]interface{}) (IntProvider, error) { cc := struct { - URI string - Headers map[string]string - Jq string - Scale float64 - Insecure bool - Auth Auth - Timeout time.Duration + URI string + Headers map[string]string + pipeline.Settings `mapstructure:",squash"` + Scale float64 + Insecure bool + Auth Auth + Timeout time.Duration }{ Headers: make(map[string]string), + Scale: 1, } if err := util.DecodeOther(other, &cc); err != nil { @@ -83,13 +83,9 @@ func NewSocketProviderFromConfig(other map[string]interface{}) (IntProvider, err p.Client.Transport = request.NewTripper(log, transport.Insecure()) } - if cc.Jq != "" { - op, err := gojq.Parse(cc.Jq) - if err != nil { - return nil, fmt.Errorf("invalid jq query: %s", p.jq) - } - - p.jq = op + var err error + if p.pipeline, err = pipeline.New(cc.Settings); err != nil { + return nil, err } go p.listen() @@ -127,22 +123,14 @@ func (p *Socket) listen() { p.log.TRACE.Printf("recv: %s", b) p.mux.Lock() - if p.jq != nil { - v, err := jq.Query(p.jq, b) - if err == nil { - p.val = v - p.wait.Update() - } - } else { - p.val = string(b) - p.wait.Update() - } + p.val = b + p.wait.Update() p.mux.Unlock() } } } -func (p *Socket) hasValue() (interface{}, error) { +func (p *Socket) hasValue() ([]byte, error) { if late := p.wait.Overdue(); late > 0 { return nil, fmt.Errorf("outdated: %v", late.Truncate(time.Second)) } @@ -153,75 +141,60 @@ func (p *Socket) hasValue() (interface{}, error) { return p.val, nil } +var _ StringProvider = (*Socket)(nil) + // StringGetter sends string request func (p *Socket) StringGetter() func() (string, error) { return func() (string, error) { - v, err := p.hasValue() + b, err := p.hasValue() if err != nil { return "", err } - return jq.String(v) + v, err := p.pipeline.Process(b) + + return string(v), err } } +var _ FloatProvider = (*Socket)(nil) + // FloatGetter parses float from string getter func (p *Socket) FloatGetter() func() (float64, error) { + g := p.StringGetter() + return func() (float64, error) { - v, err := p.hasValue() + s, err := g() if err != nil { return 0, err } - // v is always string when jq not used - if p.jq == nil { - v, err = strconv.ParseFloat(v.(string), 64) - if err != nil { - return 0, err - } - } + f, err := strconv.ParseFloat(s, 64) - f, err := jq.Float64(v) return f * p.scale, err } } +var _ IntProvider = (*Socket)(nil) + // IntGetter parses int64 from float getter func (p *Socket) IntGetter() func() (int64, error) { - return func() (int64, error) { - v, err := p.hasValue() - if err != nil { - return 0, err - } - - // v is always string when jq not used - if p.jq == nil { - v, err = strconv.ParseInt(v.(string), 10, 64) - if err != nil { - return 0, err - } - } - - i, err := jq.Int64(v) - f := float64(i) * p.scale + g := p.FloatGetter() + return func() (int64, error) { + f, err := g() return int64(math.Round(f)), err } } +var _ BoolProvider = (*Socket)(nil) + // BoolGetter parses bool from string getter func (p *Socket) BoolGetter() func() (bool, error) { - return func() (bool, error) { - v, err := p.hasValue() - if err != nil { - return false, err - } + g := p.StringGetter() - // v is always string when jq not used - if p.jq == nil { - v = util.Truish(v.(string)) - } - - return jq.Bool(v) + return func() (bool, error) { + s, err := g() + return util.Truish(s), err } }