Skip to content

Conversation

@guido4096
Copy link
Contributor

I have a usecase where I need to use "max" in the calc plugin. This PR is to add that functionality and while at it, I think it should then also support "min".

If the idea of this PR is acceptable, I will also update the documentation. Note: current documentation misses noting that "div" and "abs" are already supported and hence will add that to the documentation section.

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey there - I've reviewed your changes and they look great!

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location> `plugin/calc.go:74` </location>
<code_context>
 		o.div = append(o.div, f)
 	}

+	for idx, cc := range cc.Min {
+		f, err := cc.FloatGetter(ctx)
+		if err != nil {
</code_context>

<issue_to_address>
**issue (complexity):** Consider refactoring repeated loop and aggregation logic into reusable helper functions to simplify the code.

```suggestion
You can eliminate most of the near-duplicate loops by introducing two small helpers:

1) buildFuncs – turns a []Config into []func() (float64,error) with the proper error wrap  
2) aggregate – reduces a slice of float getters with an initial value + combiner

Example:

```go
// in calc.go

// helper to build and wrap getters
func buildFuncs(ctx context.Context, cfgs []Config, name string) ([]func() (float64, error), error) {
    var out []func() (float64, error)
    for i, cfg := range cfgs {
        f, err := cfg.FloatGetter(ctx)
        if err != nil {
            return nil, fmt.Errorf("%s[%d]: %w", name, i, err)
        }
        out = append(out, f)
    }
    return out, nil
}

// generic aggregator for add, mul, min, max
func aggregate(
    fs []func() (float64, error),
    init float64,
    combine func(acc, v float64) float64,
) (float64, error) {
    acc := init
    for i, f := range fs {
        v, err := f()
        if err != nil {
            return 0, fmt.Errorf("aggregate[%d]: %w", i, err)
        }
        if i == 0 {
            acc = v
        } else {
            acc = combine(acc, v)
        }
    }
    return acc, nil
}
```

Then in `NewCalcFromConfig`:

```go
o.add, _ = buildFuncs(ctx, cc.Add, "add")
o.mul, _ = buildFuncs(ctx, cc.Mul, "mul")
o.div, _ = buildFuncs(ctx, cc.Div, "div")
o.min, _ = buildFuncs(ctx, cc.Min, "min")
o.max, _ = buildFuncs(ctx, cc.Max, "max")
```

And in your switch-case:

```go
case len(o.min) > 0:
    return aggregate(o.min, 0, math.Min)
case len(o.max) > 0:
    return aggregate(o.max, 0, math.Max)
case len(o.add) > 0:
    return aggregate(o.add, 0, func(a, b float64) float64 { return a + b })
case len(o.mul) > 0:
    return aggregate(o.mul, 1, func(a, b float64) float64 { return a * b })
```

This collapses all of the repeated loops and switch blocks into two concise, reusable helpers while preserving the exact functionality.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@andig andig added the infrastructure Basic functionality label Oct 22, 2025
@andig andig changed the title support min/max calculations Calc: add min/max Oct 22, 2025
@andig andig added the needs documentation Triggers issue creation in evcc-io/docs label Oct 23, 2025
@andig andig merged commit 6bf9f99 into evcc-io:master Oct 23, 2025
7 checks passed
iseeberg79 added a commit to iseeberg79/evcc that referenced this pull request Oct 25, 2025
* chore: remove invalid false require definitions (evcc-io#24625)

* Hardy-Barth Salia: enable new api at 2.3.64 (evcc-io#24636)

* Fronius GEN24: document ECA (evcc-io#24653)

* Calc plugin: add min/max (evcc-io#24652)

* Config UI: fix grid title (evcc-io#24661)

* chore: escape doc templates (evcc-io#24660)

* Optimizer: handle smart cost limit (evcc-io#24655)

* chore: reduce database writes (evcc-io#24672)

* chore: minor

* Planner: fix missing costs for precondition slots (evcc-io#24645)

* chore: reduce amount of optimizer requests in case of error

* chore: lock optimizer against piling goroutines

* chore: add pprof

* Tibber: fix formula not used

* docs: remove telemetry get endpoint (evcc-io#24691)

* InfluxDB: add meter titles (evcc-io#24610)

* FoxEss H3 Smart: fix power (evcc-io#24626)

* Messaging: resolve pointer values

* OpenWB Pro: add wakeup (cp interrupt) (evcc-io#24706)

* cli/token: fix database vehicles ignored (evcc-io#24716)

* chore: replace with AGENTS.md

* Wattsonic Gen3: add min/max soc (evcc-io#24720)

* chore: add missing api endpoints (evcc-io#24721)

* chore: simplify repeating plans (evcc-io#24719)

* resolve merge conflicts
@guido4096
Copy link
Contributor Author

guido4096 commented Nov 1, 2025

Docs are in evcc-io/docs#917. The 916 version was created on an old branch and the easiest fix was to restart from scratch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

infrastructure Basic functionality needs documentation Triggers issue creation in evcc-io/docs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants