Skip to content

Commit

Permalink
Calc: add abs (#17530)
Browse files Browse the repository at this point in the history
  • Loading branch information
andig authored Dec 2, 2024
1 parent c39990c commit bd59d96
Showing 1 changed file with 30 additions and 8 deletions.
38 changes: 30 additions & 8 deletions provider/calc.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import (
"context"
"errors"
"fmt"
"math"

"github.com/evcc-io/evcc/util"
)

type calcProvider struct {
add, mul, div []func() (float64, error)
sign func() (float64, error)
abs, sign func() (float64, error)
}

func init() {
Expand All @@ -23,21 +24,27 @@ func NewCalcFromConfig(ctx context.Context, other map[string]interface{}) (Provi
Add []Config
Mul []Config
Div []Config
Abs *Config
Sign *Config
}

if err := util.DecodeOther(other, &cc); err != nil {
return nil, err
}

o := &calcProvider{}
if i := min(len(cc.Add), 1) + min(len(cc.Mul), 1) + min(len(cc.Div), 1); i > 1 ||
(len(cc.Add) > 0 && cc.Sign != nil) ||
(len(cc.Mul) > 0 && cc.Sign != nil) ||
(len(cc.Div) > 0 && cc.Sign != nil) {
return nil, errors.New("can only have either add, mul, div or sign")
cnt := min(len(cc.Add), 1) + min(len(cc.Mul), 1) + min(len(cc.Div), 1)
if cc.Abs != nil {
cnt++
}
if cc.Sign != nil {
cnt++
}
if cnt != 1 {
return nil, errors.New("can only have either add, mul, div, abs or sign")
}

o := &calcProvider{}

for idx, cc := range cc.Add {
f, err := NewFloatGetterFromConfig(ctx, cc)
if err != nil {
Expand All @@ -62,6 +69,14 @@ func NewCalcFromConfig(ctx context.Context, other map[string]interface{}) (Provi
o.div = append(o.div, f)
}

if cc.Abs != nil {
f, err := NewFloatGetterFromConfig(ctx, *cc.Abs)
if err != nil {
return nil, fmt.Errorf("abs: %w", err)
}
o.abs = f
}

if cc.Sign != nil {
f, err := NewFloatGetterFromConfig(ctx, *cc.Sign)
if err != nil {
Expand Down Expand Up @@ -139,12 +154,19 @@ func (o *calcProvider) floatGetter() (float64, error) {
}
}

case o.abs != nil:
v, err := o.abs()
if err != nil {
return 0, fmt.Errorf("abs: %w", err)
}
res = math.Abs(v)

default:
v, err := o.sign()
if err != nil {
return 0, fmt.Errorf("sign: %w", err)
}
res = map[bool]float64{false: -1, true: 1}[v >= 0]
res = math.Copysign(1, v)
}

return res, nil
Expand Down

0 comments on commit bd59d96

Please sign in to comment.