A Home Assistant custom integration for the Dutch NDW (Nationaal
Dataportaal Wegverkeer) DAFNE
charge-point-data
API. Search near an address or draw a bounding box, pick a charge point,
and monitor its live availability, connector info and location as native
Home Assistant entities.
- Search for charge points near an address (also finds ones just across the border in Belgium/Germany), or by drawing a bounding box (e.g. with bboxfinder.com)
- One Home Assistant device per charge point, added and removed independently of any others
- Live available/total connectors, connector type and format, power rating, address, operator and GPS location
- Icons that match the actual connector (Type 2, CCS, CHAdeMO, Tesla, ...)
- English and Dutch translations
- Automatically respects the NDW API's rate limit and pagination
- Click the badge above (or in HACS, add this repository as a custom repository manually, category: Integration).
- Install "NDW Charge Points".
- Restart Home Assistant.
- Copy
custom_components/ndw_charge_pointsinto your Home Assistantconfig/custom_components/folder. - Restart Home Assistant.
- Go to Settings → Devices & services → Add integration and search for NDW Charge Points.
- Choose how to search:
- Search near an address: enter an address in the Netherlands and a search radius (0.2–5 km). Also finds charge points just across the border in Belgium or Germany.
- Draw a bounding box: draw a rectangle on
bboxfinder.com and paste the coordinates
shown under Box (format
min_lon,min_lat,max_lon,max_lat).
- Home Assistant fetches every charge point in that area and shows a list with address, operator and current availability. Pick the one you want to monitor and finish the flow. It's created as its own device.
- To monitor another charge point (from the same or a different area), repeat the flow (Add integration again). To stop monitoring one, delete its device from Settings → Devices & services. This doesn't affect any other charge points you've added. Each device's Configure option only changes its polling interval.
Each monitored charge point is its own device with the following entities:
| Entity | Domain | Description |
|---|---|---|
| Available connectors | sensor |
Number of available connectors, with a full per-connector breakdown as attributes |
| Total connectors | sensor |
Total number of connectors |
| Connector type | sensor |
E.g. "Type 2 (IEC 62196, Mennekes)"; if a station has multiple, the most common one is shown, full list in the types attribute |
| Connector format | sensor |
"Tethered cable" or "Socket (bring your own cable)" |
| Highest/Lowest power rating | sensor |
Rated power range across connectors, in whole kW (see note below) |
| Power type | sensor |
E.g. "AC (3-phase)" |
| Address | sensor |
Street address |
| Operator | sensor |
Operator name |
| Location | device_tracker |
GPS coordinates, shown on the Home Assistant map |
| Last updated, Country, Station ID | sensor (diagnostic) |
Freshness timestamp, ISO country code, and the raw NDW feature ID |
Icons dynamically match the actual connector where possible (e.g. a CHAdeMO station shows the CHAdeMO icon), rather than a generic plug icon.
Notes on the data:
- Power ratings are each connector's rated maximum, not a live measurement. A car often draws less (e.g. 11 kW on a 22 kW-rated connector) because it's limited by its own onboard charger.
- The Operator sensor falls back to the short NDW operator code (e.g.
GFX,LMS,EFL) when no friendlier name is available. Look these up in the Benelux ID-register.
Available in English and Dutch, using Home Assistant's standard entity
translation format. Home Assistant picks the language automatically based
on each user's profile setting. To add another language, copy
translations/en.json
to e.g. translations/de.json and translate the values; no code changes
needed.
- Polls every 120 seconds by default (configurable per device, 30–3600 seconds). The (possibly large) area you searched in during setup is only used to find candidates once; once you pick a charge point, its device polls a small area tightly around just that one station, not the whole original search area.
- Every request this integration makes, across all devices and the setup flow, shares one rate limiter capped at ~8 requests/second, comfortably under the API's 10/s limit. This holds even when many charge points are configured, including right after Home Assistant starts.
- Address search uses OpenStreetMap Nominatim (© OpenStreetMap contributors), rate-limited separately to stay within their usage policy, and only queried once per address you enter (no autocomplete).
- Data is provided by NDW. This integration is not affiliated with or endorsed by NDW; the NDW logo above is used for attribution only.
The DAFNE API enforces:
- Max bounding box area: 1.0 square degree. The setup flow rejects larger boxes before calling the API.
- Max 1000 features per response. If a bounding box returns 1000 results, the selection screen warns that the list may be incomplete. Use a smaller box to be sure you see every station.
- Max 10 requests/second. Handled by the shared rate limiter described above.
- Pagination. Bounding boxes with many results are paginated
(
cursorquery param,Link: rel="next"header). This integration follows those links automatically until it has every feature for the bbox, so a dense bounding box won't silently return an incomplete list.
Parts of this code were developed with AI assistance.