Cloud-integrated driver for Zaptec Go, Pro and Sense EV chargers via the Zaptec Portal REST API (api.zaptec.com). Common in Nordic and EU commercial installations where per-tenant billing and installation-level load balancing are managed inside the Portal — Zaptec chargers speak OCPP outbound to the Portal, so there is no LAN-side control path and all commands land through the cloud.
Prerequisites
- A Zaptec Portal account with access to the installation. A dedicated service account with only Charger Read/Write scope is preferred over a personal user.
- The account added to the installation in Portal → Installation → Users. Owner or installer role — end-user role cannot list chargers via the API.
- MFA disabled on the service account. The Portal exposes an OAuth2 password grant, which does not support multi-factor challenges.
- Chargers commissioned in the Portal and reporting online. If a charger cannot phone home to Zaptec, it is unreachable from GEM.
Setup
- In portal.zaptec.com, create or nominate a service account and add it to the installation as an owner or installer.
- In GEM, open Admin → Devices → Add Device and pick driver zaptec.
- Enter the Portal
username and password.
- Optional: enter
installation_id to scope discovery to a single installation. Leave blank to enumerate every charger the account can read.
- Run the
get_chargers command. Each entry returns a stable charger id (UUID), a friendly label, the parent installation_id, and a mid / serial_no.
- Create one GEM zone per charger. Use the charger
id as the zone address.
Attribute reference
Device (required)
| Attribute | Description |
|---|
username | Portal account email. Prefer a service account. |
password | Portal account password. Stored encrypted. |
Device (optional)
| Attribute | Default | Description |
|---|
api_base | https://api.zaptec.com | Override for regional / staging endpoints. Leave at default unless Zaptec support directs otherwise. |
installation_id | (blank) | Optional. Restrict get_chargers to one installation. |
status_interval | 30000 ms | Poll cadence for per-charger state. Zaptec telemetry updates ~once per minute in the Portal, so anything under 30 s mostly re-reads cached values. |
default_current_amps | 16 | Fallback current for set_current when no explicit current argument is passed. |
Zone
| Attribute | Description |
|---|
address (required) | Charger id (UUID) as returned by get_chargers. Also visible in the Portal under Charger → Details → ID. |
Charger UUIDs look like 1a2b3c4d-…. Copy the value verbatim from the Portal or from a get_chargers result — the driver does not tolerate a truncated / lower-case prefix.
Commands
| Command | Args | Notes |
|---|
on / start_charging | address | Start or resume the current session on the charger. |
off / stop_charging | address | Pause the session; the cable stays locked. |
authorize | address | Authorize the plugged vehicle to start (installations that require per-session authorization). |
deauthorize | address | Revoke authorization. Session stops and does not auto-restart. |
restart_charger | address | Reboot the charger. |
set_current | address, current | Change the session max current in amps. Bounded server-side by the installation ceiling — see limitations below. |
get_status | address | Read the raw state block for the charger. |
get_chargers | | Enumerate every charger visible to the account. |
get_installations | | Enumerate installations visible to the account. |
raw_command | address, command_id | Escape hatch: send any Zaptec command id. Use only when Zaptec support asks. |
State surfaced onto the zone
Each poll writes the following zone attributes when the underlying state ids are present:
| Zone attribute | Zaptec state id | Notes |
|---|
state | 710 (OperatingMode) | Normalized to disconnected, waiting, charging, finished, error. |
power_w | 553 (TotalChargePower) | Instantaneous session power in watts, rounded. |
session_energy_kwh | 909 (SessionEnergy) | Energy delivered in the current session, kWh. |
total_energy_kwh | 554 (TotalChargeEnergy) | Lifetime energy on the charger, kWh. |
max_current_a | 513 (ChargerMaxCurrent) | Current ceiling reported by the charger. |
Connection and polling
- Login retries. If the Portal cannot be reached, or rejects the login, when the device connects, the driver tries again after 30 seconds, then doubles the wait after each failure up to 15 minutes. You no longer need to reload the device after a WAN or Portal outage at boot. The failure is logged once, not on every retry.
- Polling backs off. If a whole poll cycle fails to read any charger (Portal maintenance, WAN down, credentials changed), the next poll waits longer: from the second failed cycle the interval doubles up to 10 minutes, and it never drops below your configured
status_interval. The first successful read brings it back to status_interval.
- Recovery after a dropped request. A single failed request marks the device disconnected, but polling continues and the next successful read marks it connected again.
status_interval limits. A blank, non-numeric, zero or negative value uses the 30-second default. A value under one second is raised to one second.
- Token refresh. If several requests find the token expired at the same moment, they wait for a single login.
Known limitations
- No LAN control. Zaptec speaks OCPP to the Portal outbound only. If the WAN link is down, no commands land.
- No MFA support on the account. The Portal exposes a password grant only; MFA-enabled accounts will fail the token step.
- Current setpoints are advisory to Zaptec. A
set_current above the installation-level ceiling is silently clamped by the Portal. This driver does not read the ceiling back to warn callers.
- Firmware upgrade is exposed only through
raw_command (command id 200). Not wired as its own verb by design.
- End-user roles cannot list chargers. If the account is not an owner or installer on the installation,
get_chargers returns an empty list.
- A malformed Portal answer also reads as an empty list. A 200 whose body is neither a list nor a
Data envelope (an error object, an HTML maintenance page) yields an empty charger, installation or state list, and the driver logs zaptec … response was not a list so it can be told apart from a permissions problem.
Troubleshooting
| Symptom | Check |
|---|
401 on every request | Sign in to portal.zaptec.com with the same username and password. If MFA is enabled, provision a dedicated service account without MFA. |
get_chargers returns [] | Confirm the account is an owner or installer on the installation, not just an end-user. End-user roles cannot enumerate. |
start_charging returns 400 charger_not_authorized | The installation requires per-session authorization. Call authorize first, or disable the requirement in the Portal. |
Zone state stuck on disconnected | The charger is offline in the Portal too. Check the LTE / Ethernet uplink at the charger. |
set_current lands but the charger keeps drawing the old current | Installation-level AvailableCurrent is capped elsewhere in the Portal (dynamic load balancing group). The driver writes at the installation level; per-charger overrides in the Portal win. |
A protocol-level Zaptec Portal integration overview under Integrations is pending.