Elli Charger Connect/Pro (Gen 1) — Local reboot via REST API, with safety checks

TL;DR

The Elli Charger Connect/Pro (Gen 1) — sold also as VW ID. Charger, SEAT/CUPRA Charger, ŠKODA iV Charger — has no Reboot button in its local web UI for end users, even though the VW mobile app can reboot it via the cloud. The local REST API actually exposes the reboot endpoint to any logged-in user, just without surfacing it in the UI. This post shows how to call it directly from Home Assistant with a rest_command, including:

  • a vehicle-connected safety check (don't reboot while charging or paused),
  • login lockout protection (5 wrong passwords → PUK reset),
  • and an optional auto-recovery automation tied to your existing online-state sensor.

Works fully on the LAN, no cloud dependency. Confirmed working on Gen 1 firmware as of mid-2026.


The problem

My Elli Charger has been intermittently going into the UNKNOWN state. The app — when it can reach the wallbox via cloud OCPP — has a reboot button that fixes it within 60 s. Locally, however:

  • The web UI at https://<wallbox-ip> doesn't show any reboot control for normal users.
  • The EEBUS connection used by evcc has no reboot command in the spec.
  • The wallbox is hard-wired, so power-cycling means a trip to the breaker panel.

Some options exist but none satisfying:

  1. Redirect OCPP to a local server — voids the Elli app integration and isn't officially supported on Gen 1.
  2. Hardware solution (contactor in front of the wallbox) — clean, but a non-trivial install.

Then I checked the local web UI more carefully, and — option 3 — the REST endpoint is just sitting there.

Finding the endpoint

The local Config Manager is an Angular SPA. Every endpoint the UI knows about is in the main JS bundle, even ones that are conditionally hidden. Procedure:

  1. Open the wallbox UI in Chrome, log in normally.
  2. F12 → Sources → find main-*.js under the IP. Pretty-print with {}.
  3. Search for reboot.

Result:

this.httpClient.post(
  `${this.configuration.basePath}/sys-settings/reboot`,
  null,                                  // body is null, not {}
  { withCredentials: true, ... }
)

So the endpoint is POST /api/v1/sys-settings/reboot with no body and a Bearer token. Server responds 201 Created. The reason it doesn't appear in the UI is just that the rendering logic hides it when the wallbox isn't in a specific state — the API itself accepts the call from a normal logged-in user.

Login is equally simple:

POST /api/v1/auth/login
Content-Type: application/json
{"password": "<Configuration Page Password from the sticker>"}

→ {"access_token": "...", "refresh_token": "..."}

The access token has a 5-minute TTL, so the cleanest design is to log in fresh on every reboot rather than cache tokens.

Implementation in Home Assistant

1. secrets.yaml

elli_wallbox_password: "<your Configuration Page Password>"

This is the normal login password printed on the sticker that came with the wallbox — not the PUK. If you've lost the sticker, you can use the PUK at the "forgot password" flow to set a new one, then put the new one here.

2. configuration.yaml (or split file)

rest_command:
  elli_wallbox_login:
    url: "https://192.168.178.4/api/v1/auth/login"
    method: POST
    content_type: "application/json"
    payload: '{"password": "{{ password }}"}'
    verify_ssl: false
    timeout: 10

  elli_wallbox_reboot:
    url: "https://192.168.178.4/api/v1/sys-settings/reboot"
    method: POST
    headers:
      Authorization: "Bearer {{ token }}"
    verify_ssl: false
    timeout: 10

verify_ssl: false is required because the wallbox uses a self-signed certificate.

3. scripts.yaml

wallbox_reboot:
  alias: "Reboot Elli wallbox"
  icon: mdi:restart
  mode: single
  sequence:
    # 1) Safety: never reboot with a vehicle plugged in
    - if:
        - condition: template
          value_template: "{{ states('sensor.evcc_wallbox_status') in ['B', 'C', 'D', 'E', 'F'] }}"
      then:
        - action: persistent_notification.create
          data:
            title: "Wallbox reboot cancelled"
            message: "Vehicle is plugged in — reboot skipped."
        - stop: "Vehicle connected — aborting"

    # 2) Login
    - action: rest_command.elli_wallbox_login
      data:
        password: !secret elli_wallbox_password
      response_variable: login_response

    # 3) Lockout protection: do NOT retry on login failure
    - if:
        - condition: template
          value_template: >
            {{ login_response is not defined
               or login_response.status != 200
               or 'access_token' not in (login_response.content | default({})) }}
      then:
        - action: persistent_notification.create
          data:
            title: "Wallbox reboot failed"
            message: >
              Login to wallbox unsuccessful
              (status: {{ login_response.status | default('unknown') }}).
              Reboot NOT attempted (lockout protection — 5 wrong tries permanently lock the account).
        - stop: "Login failed"

    # 4) Reboot using the freshly obtained access token
    - action: rest_command.elli_wallbox_reboot
      data:
        token: "{{ login_response.content.access_token }}"

    # 5) Report success
    - action: persistent_notification.create
      data:
        title: "Wallbox reboot"
        message: "Reboot command sent. Wallbox should be back in ~60 s."

The vehicle-connected sensor name above is just an example. Adjust to whatever you use:

  • evcc users: the evcc HA integration exposes binary_sensor.<loadpoint>_vehicle_connected, or via MQTT under evcc/loadpoints/<n>/connected.
  • Direct EEBUS / native integration: check your sensors for a status that's A (idle) vs B/C (connected/charging). If you have a status code sensor, use:
    value_template: "{{ states('sensor.wallbox_status') not in ['A', 'unavailable', 'unknown'] }}"
    

4. Optional: auto-recovery automation

If you already monitor the wallbox's online state — e.g. an aggregate sensor over ICMP ping, TCP port 4712 (EEBUS), and evcc connectivity — auto-reboot it when it's been down for 5 minutes, with a 1-hour cooldown to prevent loops:

- id: wallbox_auto_reboot
  alias: "Wallbox: auto-reboot when offline"
  trigger:
    - platform: state
      entity_id: binary_sensor.wallbox_ping
      to: "off"
      for: "00:05:00"
  condition:
    - condition: template
      value_template: >
        {{ states.script.wallbox_reboot.last_triggered is none
           or (now() - states.script.wallbox_reboot.last_triggered).total_seconds() > 3600 }}
    - condition: template
      value_template: "{{ states('sensor.evcc_wallbox_status') not in ['B', 'C', 'D', 'E', 'F'] }}"
  action:
    - action: script.wallbox_reboot

The vehicle check is duplicated here (script also checks) on purpose — keeps the trace logs cleaner if the condition is the reason the automation didn't fire.

Caveats and notes

  • Lockout risk. Five consecutive failed logins lock the account until you reset it with the PUK from the sticker. The script above explicitly does not retry. Verify your password works in the browser before enabling the automation.
  • Don't expose factory-reset. The bundle also reveals POST /api/v1/sys-settings/factory-reset (same auth model, no body). Resist the temptation to wire that up — accidental trigger wipes the configuration.
  • Gen 2 hardware has a different web UI (and probably different endpoints) — I haven't verified this. If you have a Gen 2 (Charger Connect 2 / Pro 2), the JS-bundle approach in the "Finding the endpoint" section will still work, just expect different paths.
  • Other Elli wallboxes (ID. Charger, SEAT/CUPRA Charger, ŠKODA iV Charger) share the same firmware — this should work on all of them, but report back if you confirm.
  • Token TTL is short (5 min), refresh tokens last 7 days. The script ignores the refresh token entirely and just logs in fresh on every invocation — simpler, no state to persist, and the login call is cheap.

What this doesn't solve

  • Reading charging state from the wallbox directly (still needs evcc/EEBUS or MQTT).
  • Changing OCPP/backend URL — that endpoint isn't exposed in the user-level API; it's a service-user feature.
  • Reboot if the wallbox is fully unreachable on the LAN (no Wi-Fi/Ethernet).

Hope this saves someone else the breaker-panel trip.

Thanks to Claude for the big help here :wink: