Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
2a5b778
Issue: hint to search issues and try nightly before reporting a bug (…
naltatis Oct 9, 2026
34297ed
Vehicle (Mercedes): discover fleet vehicles (#34556)
github-actions[bot] Oct 9, 2026
fff1bd9
CI: read build-toolchain node version from .node-version (#34585)
andig Oct 9, 2026
bbb6fd1
CI: run kin-openapi validator as go tool (#34583)
andig Oct 9, 2026
ac4a32e
CI: bump Cloudsmith CLI to 1.28.0, managed by dependabot (#34575)
andig Oct 9, 2026
359a472
Bump docker/setup-buildx-action from 4.2.0 to 4.4.1 (#34591)
dependabot[bot] Oct 9, 2026
b38be08
Bump actions/checkout from 7.0.0 to 7.0.1 (#34589)
dependabot[bot] Oct 9, 2026
14a64dd
Bump anthropics/claude-code-action from 1.0.236 to 1.0.244 (#34588)
dependabot[bot] Oct 9, 2026
6873579
Tariffs: pvnode-v2 temperature forecast (#34571)
FrankvdAa Oct 9, 2026
ce66fb0
CI: copy issue labels onto agent-created PRs (#34592)
andig Oct 9, 2026
f8561ae
Bump source-map-js from 1.2.1 to 1.2.2 (#34590)
dependabot[bot] Oct 9, 2026
2e6e6d0
Bump voidzero-dev/setup-vp from 1.15.0 to 1.21.1 (#34587)
dependabot[bot] Oct 9, 2026
3110416
CI: pin Redocly CLI as devDependency (#34584)
andig Oct 9, 2026
88e1868
Bump voidzero-dev/vite-plus from 1.0.0 to 1.1.0 (#34586)
dependabot[bot] Oct 9, 2026
4d8b649
Tariffs (Ostrom): accept fractional numbers in static price response …
github-actions[bot] Oct 9, 2026
8629bb9
Marstek: allow charging in hold mode (#34497)
andig Oct 9, 2026
6834c99
Config UI: fix enabling disabled temperature forecast (#34595)
github-actions[bot] Oct 9, 2026
d1dc3a7
Energy: build overview slots from all series (#34618)
naltatis Oct 10, 2026
06d0844
SunSpec: nan option to substitute the not-implemented sentinel (#34370)
andig Oct 10, 2026
daa6fa5
Planner: only skip short slot if more slots follow (#34604)
naltatis Oct 10, 2026
ebe213e
Kostal Plenticore: restore manual maxacpower configuration (#34133)
iseeberg79 Oct 10, 2026
8630dcb
chore: simplify error handling (#34615)
qustavo Oct 10, 2026
942890d
Home Assistant charger: add temperature entity for heating devices (#…
CDank Oct 10, 2026
f399a40
Tibber: apply charge zones without other charges (#34643)
andig Oct 10, 2026
d3ab6d3
Translations update from Hosted Weblate (#34076)
weblate Oct 10, 2026
ced79e3
Optimizer: energy plan goal from remaining plan energy (#34644)
andig Oct 11, 2026
f056979
Optimizer: add automatic mode (#32881)
andig Oct 11, 2026
f417436
Optimizer: ignore grid solver noise in battery suggestion (#34678)
andig Oct 11, 2026
c5ed5f8
Templates: render battery params for Sessy, ioBroker and Victron VRM …
andig Oct 11, 2026
bd3ac4c
MySkoda: add wake-up via charging/start (#34686)
andig Oct 11, 2026
d2941ea
Battery: only offer grid discharge for batteries supporting discharge…
andig Oct 11, 2026
0306287
SENEC Connect: add .Home V4 product (#34688)
andig Oct 11, 2026
f28efb9
Optimizer: ignore prioritySoc on loadpoints it controls (#34689)
andig Oct 11, 2026
63544a3
Config: fix "false" placeholder on fields without default value (#34655)
naltatis Oct 11, 2026
dfc0468
Home Assistant: improved entity suggestions (#34654)
naltatis Oct 11, 2026
470fd6a
Tibber: rich vehicle suggestions (#34693)
andig Oct 11, 2026
bc539ee
Octopus: rich device suggestions (#34694)
andig Oct 11, 2026
f15588c
Circuit: drop stale service todo on meter param (#34695)
andig Oct 11, 2026
2919f74
EEBus: rich device suggestions for SKI (#34696)
andig Oct 11, 2026
90d8366
Viessmann: rich equipment suggestions (#34697)
andig Oct 11, 2026
af62776
Fritz!DECT: rich device suggestions (#34692)
andig Oct 11, 2026
12bc7ee
Tasmota: channel suggestions (#34703)
andig Oct 11, 2026
78ae0ee
Shelly: channel suggestions (#34701)
andig Oct 11, 2026
c27b74d
Modbus: rich serial port suggestions (#34700)
andig Oct 11, 2026
08bf5fd
Service: http/get label and hint for rich suggestions (#34699)
andig Oct 11, 2026
fff5c5d
Modbus proxy: report upstream timeouts as gateway target failure (#34…
andig Oct 11, 2026
1a8eeaf
Easee: lock 3p at charger level instead of switching to auto (#34640)
andig Oct 12, 2026
95680c4
Config UI: fill empty optional params in service urls (#34702)
andig Oct 12, 2026
c4ff64b
Optimizer: hourly slots beyond 48 hours (#34738)
andig Oct 12, 2026
bbdccca
Battery UI: replace German "Speicher" with "Hausbatterie"/"Ladestand"…
github-actions[bot] Oct 12, 2026
4bee189
Config UI: keep auth provider action visible for long titles (#34737)
github-actions[bot] Oct 12, 2026
4d82901
Energy UI: align KPI card inset with battery view on phones (#34744)
naltatis Oct 12, 2026
a896b93
Phases: stop 3p min charging within one disable delay when 1p not sus…
andig Oct 12, 2026
8297246
Phases: project the 1p switch from the actual draw (#34755)
andig Oct 12, 2026
9783020
Loadpoint: fix fractional min current on circuit (#34750)
github-actions[bot] Oct 12, 2026
ed7828c
mDNS: stable instance name per installation (BC) (#34691)
andig Oct 12, 2026
4df6e1f
Merge evcc master ed7828c43 (Automatik-Modus, evcc PR 32881)
SolarPower2024 Oct 12, 2026
87d19b5
Update-Check: Batterie-Vermessung nur bei Wirkungsgrad melden
SolarPower2024 Oct 12, 2026
bafc900
Optimizer: Netzladeziele folgen den Stunden-Slots des gehosteten Opti…
SolarPower2024 Oct 12, 2026
49e1bae
Phasen: 1p-Hooks an die neue Phasenlogik von evcc angepasst
SolarPower2024 Oct 12, 2026
3751535
Update-Check: weitere Schreibweisen für Batterie-Vermessung
SolarPower2024 Oct 12, 2026
b5d0cfd
Fork tests: evccs Automatik-Tests im Race-Schritt auslassen
SolarPower2024 Oct 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/actions/build-toolchain/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ runs:

- uses: voidzero-dev/setup-vp@250f29ce396baf5e8f24498e17c0dfdebabc26eb # v1
with:
node-version: "26"
node-version-file: ".node-version"
cache: true

# Writes are namespaced by cache-scope so a PR build cannot poison the
Expand Down
6 changes: 6 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,9 @@ updates:
open-pull-requests-limit: 0
labels:
- "infrastructure"
- package-ecosystem: "pip"
directory: "/.github"
schedule:
interval: "monthly"
labels:
- "infrastructure"
1 change: 1 addition & 0 deletions .github/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
cloudsmith-cli==1.28.0
2 changes: 1 addition & 1 deletion .github/upstream-check/watch.json
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@
{
"name": "Batterie-Vermessung (Kapazität, Wirkungsgrad)",
"files": ["core/site_battery_ident.go"],
"keywords": ["roundtrip", "round trip", "RoundTrip", "usable capacity"]
"keywords": ["roundtrip efficiency", "round trip efficiency", "round-trip efficiency", "RoundTripEfficiency", "roundTripEfficiency", "RoundtripEfficiency", "usable capacity", "UsableCapacity"]
},
{
"name": "Zweiter Einspeisetarif (EEG) / Energieseite",
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/claude-code-review-run.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ jobs:

# Default checkout (base ref) only — do NOT check out the untrusted PR head.
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 1

Expand All @@ -102,7 +102,7 @@ jobs:
continue-on-error: true # always report status below, even on failure
# pinned: v1 (Claude Code 2.1.216) fails every Bash call with
# "bwrap: Can't create file at /home/.mcp.json: Permission denied"
uses: anthropics/claude-code-action@8ce9314fa9a404564fa7e954cd84f25bcba2b829 # v1 @ 2.1.215
uses: anthropics/claude-code-action@58985842b834ed26087302ba27d07bc24ca8697a # v1 @ 2.1.215
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
# Provided explicitly so the review can post on fork PRs; also required
Expand Down
9 changes: 5 additions & 4 deletions .github/workflows/claude-issue-agent-run.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ jobs:
- name: Run Claude
# pinned: v1 (Claude Code 2.1.216) fails every Bash call with
# "bwrap: Can't create file at /home/.mcp.json: Permission denied"
uses: anthropics/claude-code-action@8ce9314fa9a404564fa7e954cd84f25bcba2b829 # v1 @ 2.1.215
uses: anthropics/claude-code-action@58985842b834ed26087302ba27d07bc24ca8697a # v1 @ 2.1.215
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
github_token: ${{ secrets.GITHUB_TOKEN }}
Expand Down Expand Up @@ -399,7 +399,8 @@ jobs:
if [ "$MODE" = triage ]; then
args+=(--draft)
fi
if [ "$(gh api "repos/$GITHUB_REPOSITORY/issues/$ISSUE" --jq '.type.name // empty')" = Bug ]; then
args+=(--label bug)
fi
# carry the triaged issue labels over: the PR labeling job skips bot authors
mapfile -t labels < <(gh api "repos/$GITHUB_REPOSITORY/issues/$ISSUE" \
--jq '[.labels[].name] + (if .type.name == "Bug" then ["bug"] else [] end) | unique | .[]')
for l in "${labels[@]}"; do args+=(--label "$l"); done
gh pr create "${args[@]}"
2 changes: 1 addition & 1 deletion .github/workflows/claude-issue-agent.yml
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ jobs:
- name: Run Claude PR Labeler
# pinned: v1 (Claude Code 2.1.216) fails every Bash call with
# "bwrap: Can't create file at /home/.mcp.json: Permission denied"
uses: anthropics/claude-code-action@8ce9314fa9a404564fa7e954cd84f25bcba2b829 # v1 @ 2.1.215
uses: anthropics/claude-code-action@58985842b834ed26087302ba27d07bc24ca8697a # v1 @ 2.1.215
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
github_token: ${{ secrets.GITHUB_TOKEN }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/cli-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
with:
go-version-file: go.mod

- uses: voidzero-dev/setup-vp@250f29ce396baf5e8f24498e17c0dfdebabc26eb # v1
- uses: voidzero-dev/setup-vp@3754dd7dbdb32bd8f6d28b6043de13ad3a75f21f # v1.21.1
with:
node-version-file: ".node-version"
cache: true
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/command-pr-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ jobs:

- name: Setup Buildx
id: buildx
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4

- name: Restore build cache
uses: ./.github/actions/docker-cache
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ jobs:
go-version-file: go.mod
id: go

- uses: voidzero-dev/setup-vp@250f29ce396baf5e8f24498e17c0dfdebabc26eb # v1
- uses: voidzero-dev/setup-vp@3754dd7dbdb32bd8f6d28b6043de13ad3a75f21f # v1.21.1
with:
node-version-file: ".node-version"
cache: true
Expand Down Expand Up @@ -127,7 +127,7 @@ jobs:
with:
persist-credentials: false

- uses: voidzero-dev/setup-vp@250f29ce396baf5e8f24498e17c0dfdebabc26eb # v1
- uses: voidzero-dev/setup-vp@3754dd7dbdb32bd8f6d28b6043de13ad3a75f21f # v1.21.1
with:
node-version-file: ".node-version"
cache: true
Expand Down Expand Up @@ -210,7 +210,7 @@ jobs:
go-version-file: go.mod
id: go

- uses: voidzero-dev/setup-vp@250f29ce396baf5e8f24498e17c0dfdebabc26eb # v1
- uses: voidzero-dev/setup-vp@3754dd7dbdb32bd8f6d28b6043de13ad3a75f21f # v1.21.1
with:
node-version-file: ".node-version"
cache: true
Expand Down Expand Up @@ -332,7 +332,7 @@ jobs:
with:
persist-credentials: false

- uses: voidzero-dev/setup-vp@250f29ce396baf5e8f24498e17c0dfdebabc26eb # v1
- uses: voidzero-dev/setup-vp@3754dd7dbdb32bd8f6d28b6043de13ad3a75f21f # v1.21.1
with:
node-version-file: ".node-version"
cache: true
Expand Down
10 changes: 9 additions & 1 deletion .github/workflows/documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,18 @@ jobs:
with:
persist-credentials: false

- uses: voidzero-dev/setup-vp@250f29ce396baf5e8f24498e17c0dfdebabc26eb # v1
with:
node-version-file: ".node-version"
cache: true

- name: Install
run: make install-ui

- name: Prepare OpenAPI spec
run: |
mkdir -p ./openapi-deploy
npx --yes @redocly/cli@2 bundle ./server/openapi.yaml -o ./openapi-deploy/openapi.yaml
npx redocly bundle ./server/openapi.yaml -o ./openapi-deploy/openapi.yaml

- name: Deploy OpenAPI spec to docs repo
uses: peaceiris/actions-gh-pages@84c30a85c19949d7eee79c4ff27748b70285e453 # v4
Expand Down
8 changes: 6 additions & 2 deletions .github/workflows/fork-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,13 @@ jobs:
- name: Race detector
run: |
set -o pipefail
# charger: only the fork's tests, evcc's TestTemplates has an intermittent race of its own
# charger: only the fork's tests, evcc's TestTemplates has an intermittent race of its own.
# core: evcc's enableAutomatic (optimizer_automatic_test.go) writes sponsor.Subject while an
# optimizer run started by an earlier evcc test still reads it; evcc runs no race detector
evccRace='^(TestAutomaticLevels|TestOptimizerGate|TestOptimizerSurplusRegime|TestOptimizerStopFollowsSurplus|TestOptimizerFlexibility|TestOptimizerGateInactive|TestOptimizerGateStale|TestSmartCostLimitUnavailable|TestBatteryModeAutomatic|TestBatteryGridChargeLimitUnavailable)$'
{
go test -race -count=1 ./core/lm/... ./core/peak/ ./core/ ./server/ &&
go test -race -count=1 ./core/lm/... ./core/peak/ ./server/ &&
go test -race -count=1 -skip "$evccRace" ./core/ &&
go test -race -count=1 -run 'TestSwitchStages|TestSwitchSocketRatedPower' ./charger/
} 2>&1 | tee /tmp/race.log || {
grep -E "^(--- FAIL|FAIL|panic:)" /tmp/race.log | head -20 | sed "s/^/::error::/"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ jobs:
python-version: 3.12

- name: Install Cloudsmith CLI
run: pip install cloudsmith-cli==1.16.0
run: pip install -r .github/requirements.txt

- name: Publish .deb to Cloudsmith
env:
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/openapi-validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ on:
- "server/openapi.yaml"
- "server/openapi.state.yaml"
- ".github/workflows/openapi-validate.yml"
- "go.mod" # validator version follows go.mod

jobs:
validate-openapi:
Expand All @@ -23,4 +24,4 @@ jobs:
with:
go-version-file: go.mod
- name: Validate OpenAPI spec
run: go run github.com/getkin/kin-openapi/cmd/validate@v0.133.0 -ext -- server/openapi.yaml
run: go tool validate -ext -- server/openapi.yaml
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ jobs:
python-version: 3.12

- name: Install Cloudsmith CLI
run: pip install cloudsmith-cli==1.16.0
run: pip install -r .github/requirements.txt

- name: Publish .deb to Cloudsmith
env:
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ Deep documentation on specific subsystems is available in `docs/agents/`. Load w

- Use CSS Custom Properties for theming (semantic names: `--evcc-green`, `--evcc-battery`)
- No inline `style` attributes; use Bootstrap utility classes or scoped CSS (inline only for truly dynamic values)
- Use existing custom media queries for responsive breakpoints
- Use the custom media queries from `assets/css/breakpoints.css` (`@media (--sm-and-up)`) for responsive breakpoints, never raw px `min-width`/`max-width`. Write mobile-first and override upwards instead of adding max-width queries
- Use `$t()` function for all user-facing strings
- Update both `i18n/en.json` and `i18n/de.json` for new strings
- Use hierarchical namespace: `{section}.{component}.{purpose}`
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# STEP 1 build ui
FROM --platform=$BUILDPLATFORM ghcr.io/voidzero-dev/vite-plus:1.0.0@sha256:8d788678fb9783ba8994c4fe5652af3316bfc414f7ef6ead0136932ee6075b8b AS node
FROM --platform=$BUILDPLATFORM ghcr.io/voidzero-dev/vite-plus:1.1.0@sha256:15dedad6ab1f100c096aaebac6b0fb40ccf1f3dd0dd0169141e2a56588489b60 AS node

USER root

Expand Down
6 changes: 6 additions & 0 deletions assets/css/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@
"Noto Color Emoji";
--bs-success: var(--evcc-primary);
--bs-success-rgb: var(--bs-primary-rgb);
--evcc-success-bg: oklch(from var(--evcc-darker-green) 96% 0.035 h);
--evcc-success-text: oklch(from var(--evcc-darker-green) 45% 0.11 h);
--evcc-success-text-secondary: oklch(from var(--evcc-darker-green) 52% 0.08 h);
--bs-code-color: var(--evcc-darkest-green);
--evcc-backdrop: #93949eaa; /* --bs-gray-medium + transparent */

Expand Down Expand Up @@ -127,6 +130,9 @@
--bs-border-color-translucent: rgba(255, 255, 255, 0.08);
--bs-code-color: var(--evcc-dark-green);
--evcc-backdrop: #000000aa; /* black + transparent */
--evcc-success-bg: oklch(from var(--evcc-darker-green) 30% 0.06 h);
--evcc-success-text: oklch(from var(--evcc-darker-green) 82% 0.17 h);
--evcc-success-text-secondary: oklch(from var(--evcc-darker-green) 80% 0.07 h);
--tab-bar-background: var(--evcc-box);
color-scheme: dark;
}
Expand Down
79 changes: 71 additions & 8 deletions assets/js/components/Battery/BatteryConfigCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
class="text-primary flex-shrink-0 mt-1"
></shopicon-regular-sun>
<div>
<div class="fw-bold mb-1">{{ $t("battery.config.priorityTitle") }}</div>
<div class="fw-bold mb-1">
{{ $t("battery.config.priorityTitle") }}
</div>
<i18n-t
:keypath="
selectedPrioritySoc > 0
Expand Down Expand Up @@ -37,7 +39,9 @@
class="text-primary flex-shrink-0 mt-1"
></shopicon-regular-lightning>
<div>
<div class="fw-bold mb-1">{{ $t("battery.config.bufferTitle") }}</div>
<div class="fw-bold mb-1">
{{ $t("battery.config.bufferTitle") }}
</div>
<i18n-t
:keypath="
selectedBufferSoc < 100
Expand Down Expand Up @@ -71,22 +75,55 @@
</div>
</div>

<p
v-if="optimizerControlledTitles.length"
class="d-flex gap-3 text-muted small mb-0"
data-testid="battery-optimizer-hint"
>
<OptimizerAuto class="flex-shrink-0" />
<i18n-t keypath="battery.config.optimizerControlledHint" tag="span" scope="global">
<template #loadpoints>{{ controlledTitleList }}</template>
<template #optimizer>
<router-link to="/optimize" class="text-muted">
{{ $t("config.optimizer.linkWord") }}
</router-link>
</template>
</i18n-t>
</p>

<template v-if="controllable">
<hr class="my-3" />
<div class="form-check form-switch">
<div
class="form-check form-switch"
:class="{ 'opacity-25 pe-none': optimizerAutomatic }"
>
<input
id="batteryDischarge"
:checked="batteryDischargeControl"
:checked="batteryDischargeControl && !optimizerAutomatic"
class="form-check-input"
type="checkbox"
role="switch"
:disabled="optimizerAutomatic"
@change="changeDischargeControl"
/>
<label class="form-check-label" for="batteryDischarge">
{{ $t("battery.config.discharge") }}
</label>
</div>
<div v-if="experimental" class="form-check form-switch mt-2">
<p
v-if="optimizerAutomatic"
class="switch-indent d-flex gap-3 text-muted small mt-2 mb-3"
>
<OptimizerAuto class="flex-shrink-0" />
<i18n-t keypath="config.optimizer.controlled" tag="span" scope="global">
<template #optimizer>
<router-link to="/optimize" class="text-muted">
{{ $t("config.optimizer.linkWord") }}
</router-link>
</template>
</i18n-t>
</p>
<div v-if="gridDischargeVisible" class="form-check form-switch mt-2">
<input
id="batteryGridDischarge"
:checked="batteryGridDischarge"
Expand Down Expand Up @@ -123,7 +160,8 @@
>
<template #link>
<router-link :to="siteConfigRoute" @click="closeGridDischargeConfirm">
{{ $t("config.main.title") }} › {{ $t("config.general.site") }}
{{ $t("config.main.title") }} ›
{{ $t("config.general.site") }}
</router-link>
</template>
</i18n-t>
Expand All @@ -142,11 +180,12 @@ import type { Battery } from "@/types/evcc";
import Card from "../Helper/Card.vue";
import ConfirmModal from "../Helper/ConfirmModal.vue";
import InlineSocSelect from "./InlineSocSelect.vue";
import OptimizerAuto from "../MaterialIcon/OptimizerAuto.vue";

// Battery usage controls: surplus priority, charging buffer and discharge switches.
export default defineComponent({
name: "BatteryConfigCard",
components: { Card, ConfirmModal, InlineSocSelect },
components: { Card, ConfirmModal, InlineSocSelect, OptimizerAuto },
mixins: [formatter],
props: {
bufferSoc: { type: Number, default: 100 },
Expand All @@ -156,6 +195,11 @@ export default defineComponent({
batteryGridDischarge: Boolean,
battery: { type: Object as PropType<Battery> },
experimental: Boolean,
optimizerAutomatic: Boolean,
optimizerControlledTitles: {
type: Array as PropType<string[]>,
default: () => [],
},
country: String,
},
data() {
Expand All @@ -166,6 +210,16 @@ export default defineComponent({
};
},
computed: {
// keep visible while enabled so it can be switched off
gridDischargeVisible(): boolean {
const supported = (this.battery?.devices ?? []).some((d) =>
d.modes?.includes("discharge")
);
return this.experimental && (supported || this.batteryGridDischarge);
},
controlledTitleList(): string {
return new Intl.ListFormat(this.$i18n?.locale).format(this.optimizerControlledTitles);
},
siteConfigRoute() {
return { path: "/config", query: { site: "" } };
},
Expand Down Expand Up @@ -326,11 +380,20 @@ export default defineComponent({
},
getBufferStartName(value: number) {
const key = value === 0 ? "never" : value === 100 ? "full" : "above";
return this.$t(`battery.config.bufferStart.${key}`, { soc: this.fmtSoc(value) });
return this.$t(`battery.config.bufferStart.${key}`, {
soc: this.fmtSoc(value),
});
},
fmtSoc(soc: number) {
return this.fmtPercentage(soc);
},
},
});
</script>

<style scoped>
/* matches .form-switch padding so the note aligns with the label text */
.switch-indent {
padding-left: 2.5rem;
}
</style>
1 change: 1 addition & 0 deletions assets/js/components/ChargingPlans/ChargingPlanModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
:effectivePlanTime="loadpoint?.effectivePlanTime ?? undefined"
:effectivePlanSoc="loadpoint?.effectivePlanSoc"
:effectivePlanStrategy="loadpoint?.effectivePlanStrategy"
:activePlan="loadpoint?.plan"
:planEnergy="loadpoint?.planEnergy"
:limitEnergy="loadpoint?.limitEnergy"
:socBasedPlanning="!!loadpoint?.socBasedPlanning"
Expand Down
Loading
Loading