This project provides open-source firmware for the ESP32 to transform a standard Heidelberg Wallbox (including Energy Control models) into a fully local, network-enabled smart EV charger. It gives you complete control and monitoring capabilities through popular smart home platforms like Home Assistant, Node-RED, or any system that supports MQTT.
The repository name for this project is esp32-hwc
.
Many modern smart devices rely on manufacturer clouds. This can lead to privacy concerns, vendor lock-in, and the risk of a product losing functionality if the company discontinues its service. This project is built on a "local-first" philosophy.
Key benefits over integrated cloud solutions:
- 100% Data Privacy: Your charging data never leaves your home network.
- No Cloud Dependency: It works even if your internet is down.
- Unlimited Customization: Integrate your wallbox with any system. Want to charge only with excess solar power? Prioritize charging based on electricity prices? You have full control.
- Long-Term Viability: Built on open standards (MQTT, Modbus), ensuring it will work for years to come.
Let's talk about cost and value. A typical "smart" wallbox with cloud features can easily cost €800-€1200. This project achieves superior functionality for a fraction of that price.
- Heidelberg Wallbox Energy Control (7.5m cable): Originally acquired for approximately €200.
- Project Hardware (ESP32, RS485 module, wires): Approximately €15.
- Original Total Cost for a Fully Local, Highly Customizable Smart Wallbox: ~€215
A Note on Current Pricing & Market Dynamics: This project was initiated when a temporary collapse in German EV sales in early 2024 made these high-quality wallboxes available for an exceptional price. As market demand has recovered, prices have since normalized.
Currently, the market price is around €395. You can track live pricing on comparison sites like Geizhals.de.
Even at this higher price point, the total investment remains significantly below that of competing proprietary smart chargers, while offering vastly superior flexibility and privacy.
- Home Assistant Auto-Discovery: The device automatically appears in Home Assistant with all its sensors and controls.
- Full MQTT Integration: Complete control and status reporting for any smart home system.
- Web Configuration Portal: An easy-to-use web interface to configure WiFi and MQTT settings.
- Telnet Debug Interface: A real-time stream of debug and status messages for power users.
- Over-The-Air (OTA) Updates: Update the firmware wirelessly after initial setup.
- Modular C++ Codebase: Easy to understand, maintain, and extend.
- ESP32 Development Board: An ESP32-WROOM-32 based board is recommended (e.g., ESP32-DevKitC).
- RS485 to TTL Converter: A 3.3V compatible module is essential.
- Important: This firmware is written for a converter with DE/RE control pins. This provides precise, reliable control over data transmission. Using a module with automatic direction control is not recommended as it may cause stability issues.
- Check with a multimeter whether the output of of A and B is 120 Ohm. If not you need to bridge these output with 120 OHM resistor. For instance (100+ 20) Ohm.
- Power Supply: A reliable 5V or 3.3V power supply.
- Cabling and Enclosure: Wires for connections and an optional enclosure.
For detailed instructions on wiring, soldering, and a full component list, please refer to the complete guide: ➡️ Hardware Setup and Safety Guide
Installation ![]() I know cable management can be done better ;D. |
Soldered Platine ![]() The board took about 15 minutes to assemble. |
- Visual Studio Code with the PlatformIO IDE extension installed.
- A USB cable to connect your ESP32 to your computer for the first-time flash.
This process is required only once for a new device to install the firmware and the configuration filesystem.
Clone or download this project to your computer and open the project folder in Visual Studio Code.
Your private settings (like WiFi passwords) are stored in a config.json
file, which is kept separate from the main code for security.
-
In the VS Code file explorer, navigate to the
data/
directory. -
Find the template file named
config-example.json
. -
Right-click on it and select "Copy", then right-click on the
data
folder and select "Paste". -
Rename the new file to exactly
config.json
. -
Open your new
config.json
and edit the placeholder values with your own network and MQTT broker details:{ "wifi_ssid": "YourWiFi_SSID", "wifi_pass": "YourWiFi_Password", "mqtt_broker_ip": "192.168.1.123", "mqtt_broker_port": 1883, "mqtt_client_id": "esp32-hwc", "wallbox_slave_id": 1 }
This step sends your config.json
file to the ESP32's internal memory.
- Connect the ESP32 to your computer via USB.
- Click the PlatformIO icon (alien head) in the left sidebar of VS Code.
- Expand the
esp32dev-serial
environment. - Find the task named "Upload Filesystem Image" and click the "Run Task" arrow next to it.
- Wait for the process to complete successfully.
Now, upload the main program code.
- In the same
esp32dev-serial
environment task list, find the task named "Upload". - Click the "Run Task" arrow next to it.
- PlatformIO will compile the project and flash the firmware to your ESP32.
This step is mandatory for the first boot to confirm the device is working and to find its IP address.
- In the
esp32dev-serial
environment task list, find the task named "Monitor". - Click the "Run Task" arrow. A terminal will open.
- Watch the log messages. If your configuration is correct, you will see the device connect to WiFi and print its IP address:
WiFi connected! IP address: 192.168.1.123
- Note this IP address. You will need it if the hostname method for OTA updates fails. You can access the live logs anytime via Telnet with the command:
telnet <ESP32_IP_ADDRESS>
.
After the first USB upload, all future firmware updates can be sent wirelessly. The system is configured to use the hostname esp32-hwc
by default.
- To update, open the PlatformIO sidebar in VS Code.
- Expand the
esp32dev-ota
environment. - Click the "Run Task" arrow next to its
Upload
task.
PlatformIO will attempt to find the device on your network at esp32-hwc.local
and send the update.
If OTA Fails: If the hostname is not found (this can happen on some networks), you can update the platformio.ini
file to use the device's direct IP address instead.
- Open the
platformio.ini
file. - Find the
[env:esp32dev-ota]
section. - Change the
upload_port
fromesp32-hwc
to the IP address you noted earlier.[env:esp32dev-ota] extends = common_env_settings upload_protocol = espota ; The IP address or mDNS hostname (e.g., esp32-hwc.local) of the device ; This MUST be set by the user before uploading. upload_port = 192.168.1.123 ; <-- CHANGE THIS if esp32-hwc fails
- Save the file and run the
Upload
task for theesp32dev-ota
environment again.
If you only need to change a setting (like your WiFi password or MQTT broker), you do not need to re-upload the main firmware. Choose the easiest method for you.
This is the easiest way to change settings.
- Navigate to the controller's IP address in your web browser (e.g.,
http://192.168.1.123
). - Go to the "Settings" or "Configuration" page.
- Enter your new details in the form and click "Save".
- The controller will save the new configuration and automatically reboot to apply the changes.
If you cannot access the web portal but have the device on WiFi, you can send an updated configuration file wirelessly.
- On your computer, edit the
data/config.json
file. - In
platformio.ini
, make sure theupload_port
in the[env:esp32dev-ota]
section is set to your device's hostname or IP address. - In the PlatformIO sidebar, expand the
esp32dev-ota
environment and run itsUpload Filesystem Image
task. - Reboot the device to apply the changes.
Use this method if the device is not connected to WiFi.
- On your computer, edit the
data/config.json
file. - Connect the device to your computer via USB.
- In the PlatformIO sidebar, expand the
esp32dev-serial
environment and run itsUpload Filesystem Image
task. - Reboot the device to apply the changes.
This project uses MQTT for all communication. This allows for easy integration into any smart home system like Home Assistant, Node-RED, ioBroker, or custom scripts.
The MQTT-status-prefix and all command topics are defined in the src/constants.h
file and can be customized to fit your existing topic structure if needed.
The controller uses MQTT for status reporting and receiving commands. All topics are based on the root topic wallbox/
.
- Client ID: Configurable via the Web Portal (defaults to
esp32-hwc
). - Availability (LWT): The controller uses the MQTT Last Will and Testament feature to report its connection status.
- Availability Topic:
wallbox/status/availability
- Online Payload:
online
- Offline Payload:
offline
- Availability Topic:
- Retained Messages: All status topics are published as retained messages, so new clients receive the most recent state immediately upon subscribing.
Commands are sent to the ESP32 controller to control the wallbox.
Command Topic | Example Payload | Description |
---|---|---|
wallbox/set/charging |
ON or OFF |
Enable/Disable Charging: ON sets current to failsafe, OFF sets to 0A . |
wallbox/set/amps |
10.5 |
Set Max Current: Sets the charging current in Amps (Float, 6.0 to 16.0). |
wallbox/set/fail_save_amps |
6.0 |
Set Failsafe Current: Sets the fallback current if the watchdog expires. |
wallbox/set/standby |
4 |
Set Standby: 0 = Enable, 4 = Disable (Standby). |
wallbox/set/lock |
0 |
Set Lock: 0 = Lock Wallbox, 1 = Unlock Wallbox. |
wallbox/set/timeout |
30 |
Set Watchdog Timeout: Sets the failsafe timer in seconds. 0 disables it. |
wallbox/set/restart |
1 |
Restart Controller: Sends 1 to reboot the ESP32 device. |
Status messages are published from the ESP32 controller. The topics listed here are the suffixes appended to the base wallbox/status/
topic.
Topic Suffix | Example Payload | Description |
---|---|---|
--- Logical State --- | ||
charging |
ON or OFF |
Logical state of the main charging switch. |
--- Wallbox Status --- | ||
version |
v1.0.8 |
Firmware version of the Heidelberg Wallbox itself. |
charging_state |
C2: Charging Active |
Human-readable charging status from the wallbox. |
pcb_temp_c |
35.1 |
Temperature of the wallbox's internal PCB in Celsius. |
current_l1_a , ...l2_a , ...l3_a |
9.8 |
Current on each Phase in Amps. |
voltage_l1_n_v , ...l2... , ...l3... |
231 |
Voltage on each Phase in Volts. |
total_power_va |
6900 |
Total apparent power across all phases in Volt-Amps (VA). |
energy_session_kwh |
5.72 |
Energy delivered in the current charging session in kWh. |
energy_total_kwh |
1234.5 |
Total energy delivered by the wallbox over its lifetime in kWh. |
--- Read-Back of Settings --- | These topics report the current settings active on the wallbox. | |
max_current_a |
10.5 |
The current maximum charging current setting in Amps. |
fail_save_amps |
6.0 |
The current failsafe current setting in Amps. |
standby |
0 |
Current standby state (0 =Active, 4 =Standby). |
remote_lock |
1 |
Current remote lock state (0 =Locked, 1 =Unlocked). |
timeout |
30 |
Current watchdog timeout setting in seconds. |
extern_lock_status |
0 |
Reports the external hardware lock status of the wallbox. |
hw_max_current_a |
160 |
Maximum current allowed by the DIP switch setting (in 0.1A). |
hw_min_current_a |
60 |
Minimum current allowed by the hardware (in 0.1A). |
--- ESP32 System Status --- | These topics relate to the controller hardware itself. | |
system/wifi_signal |
-55 |
WiFi signal strength in dBm. |
system/uptime_s |
3600 |
Time since the ESP32 last booted, in seconds. |
system/free_heap |
150240 |
Available RAM on the ESP32 in bytes. |
system/ip_address |
192.168.1.123 |
The current IP address of the controller. |
system/last_seen |
2023-10-27T12:30:00Z |
ISO 8601 timestamp of the last update. |
Contributing: Contributions are welcome! Please feel free to open an issue to report a bug or suggest a feature, or submit a pull request with your improvements.
This project is provided "AS IS" and without any warranty. It involves working with high-voltage AC electricity and controls a high-power device. You should only attempt to build and use this project if you are experienced and knowledgeable in electronics and electrical safety.
By using this software, you agree that the author is not responsible for any damage to your property (including your wallbox, vehicle, or home), personal injury, or any other negative outcome. You assume all risks associated with the use of this firmware. Always take appropriate safety precautions.
This project is licensed under the MIT License. See the LICENSE file for details.