OpenEVSE
Local-LAN driver for OpenEVSE Level-2 EV charging stations running the OpenEVSE WiFi v4 firmware (the ESP32-based gateway board). The driver polls /status and /config, surfaces telemetry as device attributes, and exposes control verbs (enable / disable / sleep / current-limit) via the unit's documented HTTP endpoints and the RAPI passthrough at /r?json=1&rapi=....
Prerequisites
- OpenEVSE controller hardware with the OpenEVSE WiFi v4 firmware (formerly "OpenEVSE WiFi Gateway"). The earlier v1/v2 EmonCMS-only firmware exposes a different, smaller HTTP surface and is not supported by this driver.
- The EVSE must be joined to the building LAN. The boot AP (SSID
OpenEVSE_xxxx) is for commissioning only. - A DHCP reservation on the unit's MAC. The driver talks to a fixed IP — there is no mDNS resolution path.
- If you set an HTTP password on the unit (Settings → Security on the EVSE web UI), record it for the
username+passwordattributes here.
Setup steps
- Reserve the OpenEVSE's IP on your DHCP server.
- Verify the API in a browser at
http://<ip>/status. You should see a JSON document withstate,amp,voltage, andwhfields. If it returns a login challenge, the unit has a web password set. - In GEM, Admin → Devices → Add Device, pick driver
openevse, setip. If the unit has a web password, also setusername(defaultopenevse) andpassword. - Save. Telemetry attributes will populate after the first poll cycle (~10s).
Attribute reference
Required
| Attribute | Type | Description |
|---|---|---|
ip | string | LAN IP of the OpenEVSE WiFi v4 controller. |
Optional
| Attribute | Type | Default | Description |
|---|---|---|---|
port | int | 80 | HTTP port. |
username | string | openevse | HTTP basic-auth username. Ignored when no password is set. |
password | string (secure) | — | HTTP basic-auth password set in the OpenEVSE UI. Auto-encrypted by GEM's secure-attribute hook. |
status_interval | int | 10000 | Poll interval in ms. |
request_timeout | int | 10000 | HTTP request timeout in ms. |
Telemetry attributes (set by the driver)
| Attribute | Type | Source |
|---|---|---|
evse_state | string | /status.state mapped to not_connected, connected, charging, sleeping, disabled, vent_required, diode_check_failed, gfci_fault, no_ground, stuck_relay, gfci_self_test_failed, over_temperature, over_current. Unknown codes pass through as state_<n>. |
evse_state_code | int | Raw /status.state numeric code. |
charging_current_a | float | /status.amp (milliamps) ÷ 1000. |
voltage_v | int | /status.voltage. Some units without an active CT report 0 between sessions. |
charging_power_w | int | charging_current_a × voltage_v. |
session_energy_wh | int | /status.wh — energy delivered in current session. |
session_seconds | int | /status.elapsed. |
pilot_amps | int | /status.pilot — current pilot signal duty cycle (amps). |
ambient_temp_c | float | /status.temp1 ÷ 10 (skipped when the sensor returns the "no sensor" sentinel -2560). |
mcp9808_temp_c | float | /status.temp2 ÷ 10. |
ds3231_temp_c | float | /status.temp3 ÷ 10. |
wifi_rssi | int | /status.srssi. |
uptime_seconds | int | /status.up. |
override_state | string | Current manual override (active, disabled, sleeping, or absent). |
charge_rate | int | Current configured charge rate in amps (/status.charge_rate). |
divert_active | bool | True when divert mode (solar) is currently sourcing — /status.divertmode == 2. |
Commands
| Command | Args | Effect |
|---|---|---|
get_status | — | Returns /status JSON. |
get_config | — | Returns /config JSON. |
enable | — | Enable charging (RAPI $FE). |
disable | — | Disable charging entirely (RAPI $FD). |
sleep | — | Sleep mode — allow plug-in but no charge (RAPI $FS). |
set_current_limit | amps (6–80) | Set soft current limit (RAPI $SC <amps>). Clamped to panel max by the ESP. |
override | state (active/disabled/sleeping or null) | POST /override. Null clears the override. Falls back to RAPI on older firmware that lacks /override. |
restart | — | POST /restart — reboots the ESP. |
rapi | cmd (string starting with $) | Raw RAPI passthrough. Advanced — use sparingly. |
refresh | — | Force an immediate status poll. |
Zone address format
This driver does not use zones (supports_zones: false). All telemetry and control live on the device row.
Known limitations
- Current-limit clamping.
set_current_limitis silently clamped toconfig.max_current_softby the firmware. Requests above panel max appear to succeed but the unit holds the lower value. voltagemay read 0. Units without an active CT report 0 voltage between sessions. Treat 0 as "no measurement" rather than a fault.- Firmware quirk on
/override. Older OpenEVSE WiFi v4 builds (pre-4.1.x) do not expose/override. The driver detects the 404 and falls back to the equivalent RAPI command. Pure v1/v2 firmware is not supported at all. - RAPI return strings, not JSON. RAPI replies are
$OK/$NKstrings; the driver normalizes them to{ok:true}/{error:'rapi NK'}. The rawretstring is included for debugging. - MQTT / Emoncms reporting paths are not used. The driver is HTTP-only. If you have an existing MQTT integration on the unit it will continue to publish in parallel.
Troubleshooting
- 401 Unauthorized on
/statusor/config. The unit has a web password set but nopasswordattribute is configured in GEM. Set bothusernameandpassword. charging_current_aflickers between 0 and a small value. Normal between sessions — the pilot duty cycle still draws a few mA on the CT. Use>= 1Athresholds for triggers.evse_statestuck atdisabledafter a restart. Sendenable(RAPI$FE); some firmware persists the disabled state across reboots.set_current_limitappears ignored. Compare againstmax_current_softinget_config— the ESP clamps silently.