{"id":50266221,"url":"https://github.com/botts7/esp32-wallbox","last_synced_at":"2026-05-27T14:01:20.513Z","repository":{"id":358865921,"uuid":"1214088212","full_name":"botts7/esp32-wallbox","owner":"botts7","description":"Local BLE to MQTT gateway for Wallbox Pulsar MAX. No cloud. Home Assistant auto-discovery.","archived":false,"fork":false,"pushed_at":"2026-05-27T12:09:33.000Z","size":6558,"stargazers_count":3,"open_issues_count":4,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-05-27T13:25:10.701Z","etag":null,"topics":["ble","bluetooth-low-energy","esp32","esp32-s3","ev-charger","home-assistant","iot","mqtt","pulsar-max","wallbox"],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/botts7.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-18T05:27:04.000Z","updated_at":"2026-05-26T09:37:12.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/botts7/esp32-wallbox","commit_stats":null,"previous_names":["botts7/esp32-wallbox"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/botts7/esp32-wallbox","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/botts7%2Fesp32-wallbox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/botts7%2Fesp32-wallbox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/botts7%2Fesp32-wallbox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/botts7%2Fesp32-wallbox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/botts7","download_url":"https://codeload.github.com/botts7/esp32-wallbox/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/botts7%2Fesp32-wallbox/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33568859,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-27T02:00:06.184Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ble","bluetooth-low-energy","esp32","esp32-s3","ev-charger","home-assistant","iot","mqtt","pulsar-max","wallbox"],"created_at":"2026-05-27T14:01:19.636Z","updated_at":"2026-05-27T14:01:20.499Z","avatar_url":"https://github.com/botts7.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ESP32 Wallbox BLE Gateway\n\n\u003e **Local BLE → MQTT gateway for the Wallbox Pulsar MAX. Full Home Assistant control with zero cloud, in ~$15 of hardware.**\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/screenshots/dashboard.png\" alt=\"Wallbox Gateway dashboard\" width=\"320\"\u003e\n\u003c/p\u003e\n\n[![Build](https://img.shields.io/github/actions/workflow/status/botts7/esp32-wallbox/build.yml?branch=main\u0026label=build)](https://github.com/botts7/esp32-wallbox/actions/workflows/build.yml)\n[![Latest release](https://img.shields.io/github/v/release/botts7/esp32-wallbox?color=4fc3f7)](https://github.com/botts7/esp32-wallbox/releases/latest)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n[![Stars](https://img.shields.io/github/stars/botts7/esp32-wallbox?style=flat\u0026color=yellow)](https://github.com/botts7/esp32-wallbox/stargazers)\n[![PlatformIO](https://img.shields.io/badge/PlatformIO-ESP32--S3-orange)](https://platformio.org/)\n[![Home Assistant](https://img.shields.io/badge/Home%20Assistant-MQTT%20Discovery-blue)](https://www.home-assistant.io/)\n\n✓ **No cloud** · talks BLE directly to your charger\n✓ **HA Energy dashboard** ready — lifetime kWh sensor wired\n✓ **~30 entities** auto-discovered (start/stop, schedules, eco-smart, halo, current limit…)\n✓ **Self-hosted web UI** — dashboard, weekly heatmap, daily charging totals, CSV export\n✓ **OTA updates** with rollback, captive-portal first-boot\n\n\u003e **Disclaimer:** Independent open-source project. Not affiliated with, endorsed by, or connected to Wallbox Chargers SL. Use at your own risk; modifying charger settings may void your warranty.\n\n## More screenshots\n\n| Sessions / Heatmap | Home Assistant |\n|---|---|\n| ![Settings](docs/screenshots/settings.png) | ![HA Device](docs/screenshots/ha-device.png) |\n\n## Why this exists\n\nThe Wallbox app requires cloud connectivity for everything — even pressing \"start charging\" goes\nthrough their servers, adds latency, and breaks when the internet is down. This gateway talks\n**directly to your charger over Bluetooth**, giving you:\n\n- **Instant response** (no cloud round-trip)\n- **Works offline** (internet down? gateway still works)\n- **Private** (nothing leaves your local network)\n- **Scriptable** (full MQTT API for automations)\n\n## Architecture\n\n```\nHome Assistant  ◄──MQTT──►  ESP32 Gateway  ◄──BLE (BAPI)──►  Wallbox Charger\n```\n\nThe ESP32 sits within Bluetooth range (~10m) of your charger, maintains a persistent BLE\nconnection, and bridges BLE commands to MQTT with full Home Assistant auto-discovery.\n\n## Features\n\n### Live monitoring\n- Charging power (kW), current per phase (A), session energy (kWh)\n- Total lifetime energy from the charger's MID meter\n- Mains voltage, whole-house power consumption\n- Charger status (Ready / Plugged In / Charging / Scheduled / etc.)\n- BLE signal strength\n\n### Control\n- Start / stop / pause / resume charging\n- Lock / unlock charger socket\n- Adjust max charging current (6-32A slider)\n- Reboot charger\n\n### Settings\n- Charge schedules with day/time/power/energy limits (full UI editor)\n- Auto-lock configuration (enable + timeout)\n- Eco Smart solar charging modes (Off / Solar+Grid / Full Green)\n- Power sharing, phase switching\n- Halo LED brightness\n- OCPP configuration (URL, charger ID, password)\n- Timezone selection\n- Weekly sessions heatmap\n\n### Home Assistant integration\n- 30+ auto-discovered entities (sensors, switches, numbers, selects, buttons)\n- Proper native HA types (Eco Smart = select dropdown, Auto Lock = switch, etc.)\n- Energy Dashboard compatible\n- Time-of-use cost tracking examples in [HA docs](docs/HOME_ASSISTANT.md)\n\n### Web UI\n- Dark-themed responsive dashboard\n- 4-page navigation: Dashboard, Settings, Config, Info\n- PWA installable (\"Add to Home Screen\" on mobile)\n- Toast notifications, inline editors, loading spinners\n\n### Admin\n- Captive portal AP mode for first-boot setup\n- Web config UI with NVS persistence\n- OTA updates (web upload + ArduinoOTA)\n- Dual partition table with automatic rollback on failed updates\n- mDNS: `http://wallbox-gw.local`\n- Optional web authentication (rate limiting + lockout)\n- CSRF protection on state-changing endpoints\n\n## Compatible Chargers\n\n| Model | Status |\n|---|---|\n| **Pulsar MAX** (FW 6.11.16 and earlier) | ✅ Fully tested |\n| **Pulsar MAX** (FW 6.11.26+) | ✅ Working in v2.3.0+ (encrypted BLE handled) |\n| **Pulsar Plus** | 🟡 Active prep, looking for testers |\n| **Copper SB**, **Commander 2**, **Quasar / Quasar 2** | ⚪ Untested — reports welcome |\n\nSee **[COMPATIBILITY.md](COMPATIBILITY.md)** for the full matrix including\ngateway-board recommendations, BLE signal-strength thresholds, and how to\ncontribute a report. The BAPI protocol is shared across Wallbox models;\nwhere the BLE radio differs (u-blox / Nordic / Zentri etc.) the gateway\nexposes UUID overrides in Config → Advanced.\n\n**Want to add your charger to the supported list?** Open an issue using\nthe [`pulsar-plus-compat`](https://github.com/botts7/esp32-wallbox/issues/new/choose)\ntemplate (works for any model — just fill in your details) or post in\n[Discussions](https://github.com/botts7/esp32-wallbox/discussions).\n\n## Hardware\n\n- **ESP32-S3** dev board (recommended) or any ESP32 with BLE 4.2+\n  - [ESP32-S3-WROOM-1U-N16R8](https://www.espressif.com/en/products/modules/esp32-s3) with IPEX antenna = best range\n  - ESP32-S3-DevKitC-1 = easiest (built-in antenna)\n- USB-C cable for initial flashing (OTA thereafter)\n- 5V USB power supply (any phone charger works)\n\nNo wiring, sensors, or peripherals needed — just the ESP32.\n\n## Quick Start\n\n### 🪄 One-click install (Chrome / Edge)\n\nPlug the ESP32-S3 in via USB, then click the button below. The browser\nhandles erase + flash of all three files at the correct offsets — no\nterminal, no esptool, no manual offsets.\n\n\u003c!-- HTML below renders the install button on GitHub-rendered Markdown via raw HTML pass-through.\n     If GitHub strips it, the link still works as a manual fallback. --\u003e\n\u003cscript type=\"module\" src=\"https://unpkg.com/esp-web-tools@10/dist/web/install-button.js?module\"\u003e\u003c/script\u003e\n\n\u003cp\u003e\n  \u003cesp-web-install-button manifest=\"https://github.com/botts7/esp32-wallbox/releases/latest/download/install.json\"\u003e\n    \u003cspan slot=\"unsupported\"\u003e⚠️ ESP Web Tools needs Chrome or Edge — see \u003ca href=\"INSTALL.md\"\u003eINSTALL.md\u003c/a\u003e for other options.\u003c/span\u003e\n  \u003c/esp-web-install-button\u003e\n\u003c/p\u003e\n\nAfter flashing:\n\n1. Connect to WiFi AP `WallboxGW-Setup` (password `wallbox123`)\n2. Open `http://192.168.4.1/` in a browser\n3. Configure WiFi, MQTT, BLE address (tap **Scan** to find your charger)\n4. Save \u0026 Reboot → gateway appears at `http://wallbox-gw.local/`\n\n### Other install methods\n\nSee **[INSTALL.md](INSTALL.md)** for:\n- Browser-based flashing with [esptool.spacehuhn.com](https://esptool.spacehuhn.com) (Safari / Firefox)\n- Command-line `esptool.py` (automation, scripts)\n- Build from source with PlatformIO\n- **Recovering a board that won't boot**\n\n### After first-boot setup\n\n- Dashboard: `http://wallbox-gw.local/` (or the IP shown in Config page)\n- Future updates via **OTA**: open `/ota` and upload the new firmware\n  `.bin` only — no need to re-flash bootloader / partitions\n- HA entities appear automatically under device \"Wallbox Pulsar MAX\"\n\n## Home Assistant Setup\n\nSee [docs/HOME_ASSISTANT.md](docs/HOME_ASSISTANT.md) for:\n- Complete entity list\n- Dashboard YAML examples\n- Automation recipes (solar surplus charging, charge complete alerts, off-peak scheduling)\n- Time-of-use cost tracking with `utility_meter` (2-tier, 4-tier, seasonal)\n- Energy Dashboard configuration\n\n## Security\n\n### BLE Security\n\nMost Wallbox chargers ship with **no BLE PIN set** — anyone within ~10m of your charger can\ncontrol it. The gateway will warn you about this on the dashboard.\n\n**To secure BLE**:\n1. Open the Wallbox app, Settings → Security, set a PIN\n2. In gateway Config → BLE → enter the same PIN\n3. Gateway will auto-authenticate on each connection\n\n### Web UI Security\n\nOptional username/password authentication (Config → Web Security):\n- Rate limiting: 1s delay per failed login\n- 30s lockout after 5 failures\n- CSRF tokens on all state-changing endpoints\n- HTTPS not supported (ESP32 limitation — keep on trusted LAN)\n\n### OTA Security\n\n- ArduinoOTA password protected — defaults to `wb-XXXXXX` (last 6 hex of MAC, shown in serial log on boot). If a web auth password is set, that's used instead.\n- Web OTA validates firmware magic byte before writing\n- Smart rollback: firmware only validated after WiFi reconnects successfully\n- BLE paused during OTA for reliable upload\n\n## Troubleshooting\n\n### BLE not connecting\n\n**\"Charger not visible — out of range or asleep\"**\n- Charger may be in sleep mode. Touch the keypad or plug in a car to wake it.\n- RSSI weaker than -80 dBm = unreliable. Move ESP32 closer (even 2m makes a huge difference).\n- If your ESP32 has an IPEX connector, ensure the external antenna is firmly seated.\n\n**\"Connection failed (RSSI -XX)\"**\n- Signal is borderline. Move closer or use external antenna.\n- PC Bluetooth may be holding a connection. Disable BT on your PC to test.\n\n### HA entities show \"Unavailable\"\n\n- Gateway marks entities offline after 60s of BLE disconnect\n- Check `http://wallbox-gw.local/` — if BLE bar is red, charger is out of range\n- Restart HA MQTT integration if entities don't reappear within 2 minutes\n\n### Can't reach `wallbox-gw.local`\n\n- mDNS doesn't work on all devices (especially Android Chrome without DNS-SD)\n- Use IP address directly — the gateway shows it on boot in serial and in HA as `Gateway IP` sensor\n- Best fix: DHCP reservation on your router for a permanent IP\n\n### Web UI shows cached old version\n\n- Hard refresh: `Ctrl+Shift+R` (desktop) or clear site data in phone browser\n- Gateway uses boot-time version query string to bust cache on new firmware\n- Service worker purges cache on every install\n\n### OTA upload \"No response\"\n\n- ESP32 is busy with BLE command. Retry — should work on second attempt.\n- Check serial: if BLE is actively connecting, wait 30s and retry.\n\n## MQTT Reference\n\n### Published Topics\n\n| Topic | Content | Interval |\n|-------|---------|----------|\n| `wallbox/status` | r_dat response (power, current, session energy) | 10s |\n| `wallbox/realtime` | r_sta response (detailed status, lock, phases) | 30s |\n| `wallbox/settings` | Merged settings (auto lock, eco smart, etc.) | 30s |\n| `wallbox/response/meter` | r_dca response (voltage, house power, lifetime energy) | 10s |\n| `wallbox/response/gateway` | Gateway diagnostics (IP, uptime, heap, RSSI) | 60s |\n| `wallbox/availability` | `online` / `offline` | 30s + on change |\n\n### Command Topics\n\n| Topic | Payload | Action |\n|-------|---------|--------|\n| `wallbox/cmd/charging` | `start` / `stop` | Start/stop charging |\n| `wallbox/cmd/current` | `6`-`32` | Set max current (A) |\n| `wallbox/cmd/lock` | `lock` / `unlock` | Socket lock |\n| `wallbox/cmd/reboot` | `1` | Reboot charger |\n| `wallbox/cmd/autolock_enable` | `1`/`0` or `ON`/`OFF` | Auto lock switch |\n| `wallbox/cmd/autolock_time` | `60`-`600` | Lock timeout (seconds) |\n| `wallbox/cmd/eco_mode` | `Off` / `Solar + Grid` / `Full Green (Solar Only)` | Eco Smart mode |\n| `wallbox/cmd/eco_power` | `0`-`100` | Solar target (%) |\n| `wallbox/cmd/power_sharing` | `1`/`0` | Dynamic power sharing |\n| `wallbox/cmd/phase_switch` | `1`/`0` | Phase switching |\n| `wallbox/cmd/halo` | `Off` / `Low` / `Medium` / `High` | LED brightness |\n| `wallbox/cmd/timezone` | `Australia/Sydney` (any IANA zone) | Set timezone |\n| `wallbox/bapi` | `{\"met\":\"r_dat\",\"par\":null}` | Raw BAPI command |\n\n## Development\n\n### Project structure\n\n```\nesp32-wallbox/\n├── src/\n│   ├── main.cpp              # Setup, polling loop, OTA, mDNS\n│   ├── wb_ble.cpp            # BLE client, BAPI framing, reconnect logic\n│   ├── wb_mqtt.cpp           # MQTT bridge, HA auto-discovery\n│   ├── wb_web.cpp            # 4-page web UI + APIs\n│   ├── wb_config.cpp         # NVS config manager\n│   └── bapi.cpp              # BAPI protocol framing + parser\n├── include/\n│   ├── wb_ble.h, wb_mqtt.h, wb_web.h, wb_config.h\n│   └── bapi.h                # 70+ BAPI method constants\n├── docs/\n│   └── HOME_ASSISTANT.md     # HA integration guide\n├── tools/\n│   └── ble_monitor.py        # Serial diagnostic tool\n├── partitions_ota.csv        # Dual OTA partition table\n└── platformio.ini            # Build config (ESP32-S3 + OTA env)\n```\n\n### BAPI Protocol\n\nThe BAPI (Bluetooth API) protocol uses JSON over BLE GATT:\n\n```\nRequest:  EaE | length(1B) | JSON | checksum(1B)\nExample:  EaE\\x20{\"met\":\"r_dat\",\"par\":null,\"id\":1}\\x09\n\nResponse: Raw JSON (no framing)\nExample:  {\"id\":1,\"r\":{\"L1\":0,\"L2\":0,\"L3\":0,\"cp\":0.0,\"cur\":32,...}}\n```\n\nSee `include/bapi.h` for all 70+ method names (r_dat, r_sta, w_cha, w_mxI, s_alo, s_ecos, etc.)\n\n### Tools\n\n- `tools/ble_monitor.py` — Parse serial output, show scan success rate, response times,\n  and disconnects. Usage: `python ble_monitor.py --port COM4`\n- Importable as module: `from ble_monitor import WallboxMonitor`\n\n## Contributing\n\nContributions welcome! Please:\n1. Open an issue first to discuss significant changes\n2. Follow existing code style (C++ follows Arduino conventions)\n3. Test on actual hardware before submitting PR\n4. Update CHANGELOG.md with your change\n\n### Contributors\n\n- [@benvanmierloo](https://github.com/benvanmierloo) — BLE SMP pairing for\n  newer Wallbox firmware (≥ 6.11.26), telnet log server\n  ([#1](https://github.com/botts7/esp32-wallbox/pull/1))\n\n## Related Projects\n\n- [Official HA Wallbox integration](https://www.home-assistant.io/integrations/wallbox/) —\n  cloud-based, covers session cost / billing history. Complements this gateway (local vs. cloud).\n- [`jagheterfredrik/wallbox-ble`](https://github.com/jagheterfredrik/wallbox-ble) — HA\n  component for local BLE control of the Pulsar **Plus** (sibling to this project).\n- [`jagheterfredrik/wallbox-mqtt-bridge`](https://github.com/jagheterfredrik/wallbox-mqtt-bridge) —\n  Runs **on the Wallbox itself** (requires rooting). 1 Hz polling via internal Redis, no\n  BLE. Supports Pulsar Plus / Copper SB. Different trade-off than ours: faster updates,\n  but you have to root the charger.\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n\n\"Wallbox\" and \"Pulsar\" are trademarks of Wallbox Chargers SL. This project is not\naffiliated with, endorsed by, or connected to them in any way.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbotts7%2Fesp32-wallbox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbotts7%2Fesp32-wallbox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbotts7%2Fesp32-wallbox/lists"}