Overview
An EV charger’s maximum charging power is a ceiling the charger operates under, not a one-off command, so it is a device setting:max_charge_rate, in kw. Write it once and it persists across sessions until you change it or the charger reverts to its own defaults. Use it to balance against household consumption, throttle to a cheaper tariff window, or coordinate multiple chargers behind a single supply.
The charger’s two commands stay clean intents. charge begins or resumes a session; idle pauses it, holding the session. The power cap survives both. Commands run through POST /ev-charger/{deviceId}; the setting runs through POST /ev-charger/{deviceId}/settings. See canonical actions on the actions-versus-settings boundary.
Coming soon. Live control for EV chargers. The sandbox environment serves the full
commands and settings surface, so the walkthrough below works against a sandbox device today. A live EV charger push returns 422 COMMAND_NOT_SUPPORTED until the live path opens.Step 1: Read the current state
Every response is wrapped in{ success, data, meta }; the device sits under data.
data.settings.max_charge_rate is the writable ceiling, bounded 0 to 50 kw. metadata.source reports where the reading came from. Sandbox device reads always carry source: "projection" because sandbox devices are simulated, not physical hardware. In live, the value is one of cache, live, or fallback, naming the data-freshness tier the read came back from.
Step 2: Cap the power
Writemax_charge_rate through the settings endpoint. The body is a sparse map: send only the settings you want to change. The value is the canonical {value, unit} shape.
- curl
- Node
- Python
data envelope.
SETTING_OUT_OF_RANGE. An unknown key returns 422 UNSUPPORTED_SETTING; a read-only key returns 422 READ_ONLY_SETTING. The bounds come from the device read, so check data.settings on the GET before you write.
Step 3: Verify the cap applied
Read the device again. The new ceiling shows ondata.settings, and live throughput settles to the cap.
Start and stop a session
The cap is configuration; starting and stopping a session is intent.charge and idle are commands, sent in the canonical action envelope.
| Command | Use |
|---|---|
charge | Begin or resume a session on a connected vehicle. |
idle | Pause the session, holding it. |
acknowledged rather than passing through scheduled. To pause without unplugging, push idle. Only one command is in flight at a time; submit a second while the first is acknowledged and you get 409 CONFLICT. Add onConflict: "cancel_and_replace" to drop the in-flight action and run the new one. EV chargers declare only cancel_and_replace, so queue_after returns 422 STRATEGY_NOT_SUPPORTED.
Why this works
The split between themax_charge_rate setting and the charge and idle commands is the actions-versus-settings boundary applied to a charger. A ceiling is persistent and non-conflicting, so it is a setting; starting a session is a time-bound intent, so it is a command. The same boundary puts a battery’s safety_reserve on settings and its charge on commands. See canonical actions and capabilities.
What next
Subscribe to webhooks
Get push.completed events on charger state changes.
Handle conflicts
Resolve 409s when a charger write is already in flight.
Hold an HVAC device
The mirrored command pattern on a thermostat.
Canonical actions
Where EV charger commands sit in the canonical model.