Skip to content

Optimizer: split grid peak shaping into demand, feed-in and combined strategies#32108

Merged
andig merged 2 commits into
masterfrom
feat/optimizer-peak-strategies
Jul 24, 2026
Merged

Optimizer: split grid peak shaping into demand, feed-in and combined strategies#32108
andig merged 2 commits into
masterfrom
feat/optimizer-peak-strategies

Conversation

@andig

@andig andig commented Jul 24, 2026

Copy link
Copy Markdown
Member

Picks up evcc-io/optimizer#96, which reworks the attenuate_grid_peaks secondary goal. Peak shaping is now a penalty on the horizon maximum of the grid power, so charging spreads over several slots at partial power instead of running a single slot at full power, and the metered side it applies to is selectable:

strategy levels
attenuate_demand_peaks grid import profile
attenuate_feedin_peaks grid export profile
attenuate_grid_peaks both

attenuate_grid_peaks keeps its name and now means "both sides", so existing settings keep peak shaping on the side they expected plus the feed-in side.

Both new strategies are added to the accepted list and therefore show up in the secondary goal selector on the optimize page.


🤖 Generated with Claude Code

@andig andig added enhancement New feature or request experimental Experimental feature labels Jul 24, 2026

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hey - I've found 1 issue

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

## Individual Comments

### Comment 1
<location path="assets/js/components/Optimize/OptimizeHeader.vue" line_range="126-127" />
<code_context>
 // themselves come from backend state to avoid drift if the enum changes
 const STRATEGY_LABELS: Record<string, string> = {
 	charge_before_export: "fill battery first",
+	attenuate_demand_peaks: "reduce grid import peaks",
+	attenuate_feedin_peaks: "reduce grid feed-in peaks",
 	attenuate_grid_peaks: "reduce grid peaks",
 	none: "no preference",
</code_context>
<issue_to_address>
**suggestion:** Tighten the type of STRATEGY_LABELS to the known strategy key union instead of `Record<string, string>`.

Because these keys correspond to a finite backend enum, typing this as `Record<OptimizerChargingStrategy, string>` or a union of the literal keys will catch typos and missing strategies at compile time instead of only at runtime, and will scale better as the list grows.

Suggested implementation:

```
type OptimizerChargingStrategy =
	| "charge_before_export"
	| "attenuate_demand_peaks"
	| "attenuate_feedin_peaks"
	| "attenuate_grid_peaks"
	| "none";

// themselves come from backend state to avoid drift if the enum changes
const STRATEGY_LABELS: Record<OptimizerChargingStrategy, string> = {
	charge_before_export: "fill battery first",
	attenuate_demand_peaks: "reduce grid import peaks",
	attenuate_feedin_peaks: "reduce grid feed-in peaks",
	attenuate_grid_peaks: "reduce grid peaks",
	none: "no preference",
};

```

If a shared `OptimizerChargingStrategy` type already exists in your backend-typed models (e.g. in a `types` or `api` module), prefer importing that instead of defining the local union:

1. Remove the local `type OptimizerChargingStrategy = ...` definition.
2. Add `import type { OptimizerChargingStrategy } from "<appropriate-path>";` at the top of the `<script>` block.
3. Keep `const STRATEGY_LABELS: Record<OptimizerChargingStrategy, string> = { ... }` as-is.

This ensures the labels stay in sync with the backend enum and that missing/extra strategies are caught at compile time.
</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.

Comment on lines +126 to +127
attenuate_demand_peaks: "reduce grid import peaks",
attenuate_feedin_peaks: "reduce grid feed-in peaks",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

suggestion: Tighten the type of STRATEGY_LABELS to the known strategy key union instead of Record<string, string>.

Because these keys correspond to a finite backend enum, typing this as Record<OptimizerChargingStrategy, string> or a union of the literal keys will catch typos and missing strategies at compile time instead of only at runtime, and will scale better as the list grows.

Suggested implementation:

type OptimizerChargingStrategy =
	| "charge_before_export"
	| "attenuate_demand_peaks"
	| "attenuate_feedin_peaks"
	| "attenuate_grid_peaks"
	| "none";

// themselves come from backend state to avoid drift if the enum changes
const STRATEGY_LABELS: Record<OptimizerChargingStrategy, string> = {
	charge_before_export: "fill battery first",
	attenuate_demand_peaks: "reduce grid import peaks",
	attenuate_feedin_peaks: "reduce grid feed-in peaks",
	attenuate_grid_peaks: "reduce grid peaks",
	none: "no preference",
};

If a shared OptimizerChargingStrategy type already exists in your backend-typed models (e.g. in a types or api module), prefer importing that instead of defining the local union:

  1. Remove the local type OptimizerChargingStrategy = ... definition.
  2. Add import type { OptimizerChargingStrategy } from "<appropriate-path>"; at the top of the <script> block.
  3. Keep const STRATEGY_LABELS: Record<OptimizerChargingStrategy, string> = { ... } as-is.

This ensures the labels stay in sync with the backend enum and that missing/extra strategies are caught at compile time.

@andig
andig merged commit 771fc20 into master Jul 24, 2026
9 checks passed
@andig
andig deleted the feat/optimizer-peak-strategies branch July 24, 2026 09:26
@andig

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

✅ Nightly build from master finished.

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

Labels

enhancement New feature or request experimental Experimental feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant