The local mode, offered by the menu that picks the mode

Modbus TCP has been a working control path since the server learned to dial
the charger, and the Charging page has asked for the address it needs — but
the Control mode selector never listed it. The mode could be reached only by
writing it through the API, which is to say not at all.

Both selectors now offer it, and both stop offering what it does not use: the
OCPP provisioning card and its "Use this one" button are gated on the modes
where the charger dials us, and Modbus gets a line saying where its address is
asked for instead. On the phone that gate is more than tidiness — the field is
a DropdownButtonFormField, so a mode saved from the web left it holding a value
none of its items matched.

Strings added in en/da/pl for both apps. The mode hint no longer says control
happens "over OCPP", because it no longer always does.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
tajniak81andClaude Opus 5 committed 2026-09-01 18:26:21 +02:00
1 parent 1aedc0ddc7
commit f025dc100f
9 files changed
+55 -16

No files matched your search

+19 -3
View File
@@ -507,6 +507,12 @@ function fillAnkerForm() {
// Effective OCPP control mode (off | own | proxy) — gates the control panel.
const ankerControlMode = computed(() => anker.value?.controlMode || "off");
// Only the OCPP modes are provisioned here. Modbus has no token and no endpoint
// to hand the charger — the one thing it needs is the charger's own address,
// which is asked for beside the controls on the Charging page.
const ankerControlIsOcpp = computed(
() => ankerControlMode.value === "own" || ankerControlMode.value === "proxy",
);
// --- Anker Solix OCPP control (per-charger provisioning + connection status) ---
const ankerCtlSerial = ref("");
@@ -1501,6 +1507,7 @@ onBeforeUnmount(() => {
<option value="off">{{ t("settings.integrations.controlOff") }}</option>
<option value="own">{{ t("settings.integrations.controlOwn") }}</option>
<option value="proxy">{{ t("settings.integrations.controlProxy") }}</option>
<option value="modbus">{{ t("settings.integrations.controlModbus") }}</option>
</select>
<p v-if="ankerField('controlMode').locked" class="mt-1 text-xs text-muted">{{ ankerSourceLabel('controlMode') }}</p>
<p v-else class="mt-1 text-xs text-muted">{{ t("settings.integrations.controlModeHint") }}</p>
@@ -1569,7 +1576,7 @@ onBeforeUnmount(() => {
{{ ankerStateLabel(c.statusDesc) }}
</span>
<button
v-if="ankerControlMode !== 'off'"
v-if="ankerControlIsOcpp"
class="dh-btn dh-btn-ghost"
@click="useAnkerCharger(c.sn)"
>
@@ -1584,8 +1591,17 @@ onBeforeUnmount(() => {
<p v-if="ankerChargersError" class="mt-2 text-sm text-danger">{{ ankerChargersError }}</p>
</div>
<!-- OCPP control provisioning (only when a control mode is active) -->
<div v-if="ankerControlMode !== 'off'" class="mt-5 rounded-control border border-subtle bg-sunken/40 p-4">
<!-- Modbus is reached rather than provisioned, so this card gives
the address it wants instead of an endpoint to point it at. -->
<p
v-if="ankerControlMode === 'modbus'"
class="mt-5 rounded-control border border-subtle bg-sunken/40 p-4 text-xs text-muted"
>
{{ t("settings.integrations.controlModbusHint") }}
</p>
<!-- OCPP control provisioning (only in the modes the charger dials) -->
<div v-if="ankerControlIsOcpp" class="mt-5 rounded-control border border-subtle bg-sunken/40 p-4">
<p class="text-sm font-semibold text-strong">{{ t("settings.integrations.controlTitle") }}</p>
<p class="mt-0.5 text-xs text-muted">
{{ ankerControlMode === 'own' ? t("settings.integrations.controlOwnHint") : t("settings.integrations.controlProxyHint") }}