A charging map can look correct while its underlying data model is wrong. Four connector records might represent four independently usable charging positions, or several alternatives attached to fewer positions. Two records with similar addresses might describe the same site, neighboring operators, or different floors of a parking garage. These distinctions affect search, availability counts, and the ability to identify equipment later.
The goal is a model that preserves what the source actually knows while remaining useful to your application. This article develops an internal structure for station data, explains where normalization helps, and shows how to handle changes without silently rewriting history.
Define location, EVSE, and connector separately
The official OCPI Locations module provides a useful reference hierarchy. A Location groups EVSEs, while each EVSE contains connectors. In that model, alternative connectors belonging to one EVSE cannot be used simultaneously. Connector identifiers are scoped to their EVSE, and update timestamps exist at multiple levels. Use the exact specification when implementing OCPI; the application design below is an illustrative internal model.
Location: where the driver goes
Put the address, map coordinates, entrance directions, opening information, and site-level amenities here. Keep a display name separate from identity. A hotel changing its name should not create a new charging site. Consider whether the coordinates represent an entrance, a building centroid, or the equipment itself, and retain that distinction when the source provides it.
EVSE: one charging opportunity
Use an EVSE-level record to represent the operational unit relevant to one vehicle charging at a time in this hierarchy. Attach connector alternatives beneath it. Preserve the source's equipment relationships rather than reconstructing them from connector counts. A source that only reports site totals cannot support a detailed EVSE inventory without additional evidence.
Connector: the connection option
Store connector category, cable or socket format, electrical characteristics, and any documented connector-specific references. Separate connector compatibility from availability and access. A driver may have a compatible vehicle yet lack permission to enter the site. The charging station API guide explains how these dimensions affect discovery.
Make relationships explicit in storage
A relational design can use locations, EVSEs, and connectors as separate tables. A document store can retain the same hierarchy with nested objects. Choose around your queries and update patterns. Relational constraints simplify checking parent relationships; nested documents simplify fetching a small location bundle. Either approach needs a clear answer for partial updates and concurrent writes.
For an illustrative site called Harbor Garage, suppose two EVSEs serve two charging positions. The first offers two alternative connector types, and the second offers one. Your application can display two charging opportunities and three connector options, provided the source establishes those relationships. Counting every connector as an independently usable charger would overstate the site's capacity.
Give each record an internal identifier and an explicit parent reference. For example, internal EVSE evse_harbor_01 belongs to location loc_harbor, while connector connector_harbor_01_a belongs to that EVSE. These are invented application identifiers for illustration, not official equipment IDs or values accepted by an external service.
Keep external identities in their own namespace
Store a mapping from your internal record to the source system, source entity type, and source identifier. Include the owning party or network where necessary to make that identifier unambiguous. Keep externally significant strings as strings: leading zeros, case, punctuation, and length may matter to a provider even when a value looks numeric.
Avoid using latitude and longitude as a primary key. Coordinates can improve through correction, and several charging assets can share the same point. Addresses have similar problems. Use them as matching evidence. When merging suspected duplicates, retain both source identities and record why you linked them, so the decision can be reviewed or reversed.
Distinguish a confirmed match from a candidate match. A conservative workflow can automatically combine exact trusted identifiers while sending a fuzzy address match for review. A duplicate marker is usually easier to explain than accidentally combining two operators' equipment, access conditions, or command targets.
Normalize without discarding the original meaning
Define an application vocabulary for connector categories, access conditions, and operational states. Build an explicit mapping for each provider. Store the original source value beside the normalized value, including unfamiliar values. That lets you improve a mapping later without guessing what the source originally said. Unknown should be a valid outcome of normalization.
Units deserve the same care. A suggested field such as maximum_power_w makes storage intent clear, while the interface can format watts as kilowatts. Preserve decimal precision when converting values that need it. Keep maximum equipment capability separate from measured delivery and from a site's shared supply limit; those quantities answer different questions.
Do not turn missing prices into zero or missing access restrictions into public access. Where useful, represent value state explicitly: known, unknown, not supplied, or not applicable. This may feel verbose, but it stops a rendering fallback from becoming an unsupported product claim.
Model time at the level of the observation
Use separate fields for source update time, ingestion time, and observation time when available. A later import does not make old data fresh. Keep timestamps as unambiguous instants, and use the location's time zone for displaying local schedules. Store opening hours separately from timestamped events so a weekly pattern is not mistaken for a historical occurrence.
Different facts can have different ages. A location's name may be current even when its availability observation is old. Consider separate observation records for values that change frequently. Each can include the subject, value, source, observation time, and time received. Your current view can then select a suitable observation while history remains available for diagnosis.
Define ordering rules before consuming updates. If a delayed event arrives after a newer observation, decide whether to store it as history, reject it, or flag a conflict. Comparing timestamps alone may be insufficient when source clocks are unreliable; use documented sequence or version information where available.
Give lifecycle changes a deliberate path
Separate temporary operational state from the lifecycle of an asset. A charging unit undergoing maintenance can remain part of the inventory. A removed unit should disappear from current discovery while remaining identifiable in historical sessions. Retiring a record therefore need not mean deleting its identity or breaking old references.
Agree on snapshot and change-feed semantics with each source. Absence from one failed or filtered import should not retire a station. For a complete snapshot, stage the import, verify completion, and only then apply the source's documented removal rules. For incremental updates, use explicit lifecycle signals and retain an audit trail of their application.
When equipment is replaced, ask whether the upstream identity continues or changes. Preserve physical continuity and equipment identity as separate concepts if your use case needs both. A replacement at the same parking bay may deserve the same location reference while requiring a new equipment record.
Test the model with difficult questions
Review concrete queries before committing to a schema. Can you find compatible connector options without overstating simultaneous capacity? Can you explain why a station is shown as accessible? Can you trace a displayed status to its source and time? Can a historical session still identify a retired asset? These questions reveal missing relationships more effectively than a list of fields.
Use fixtures with shared coordinates, repeated external IDs across providers, absent connector details, corrected addresses, and out-of-order updates. Revisit the practical EV charging API guide for ingestion workflow design, and the developer resources for implementation planning.
Conclusion: preserve distinctions that users depend on
A durable station model gives location, EVSE, connector, source identity, and observation time their own roles. Normalize enough to support clear queries, but retain the evidence behind every transformation. That discipline produces better maps today and leaves room for additional providers, equipment changes, and operational features tomorrow.



