Power BI DAX & Power Query EV Infrastructure

Which charging sites actually earn their hardware?

Nine years of public charging data from Palo Alto, turned into a seven-page Power BI report. The biggest site isn't the best one, pricing cost demand but freed up capacity, and the first version of my own model was wrong. All three are in here.

A portfolio project built on real, public data. The sessions come from the City of Palo Alto's open charging dataset (published on Kaggle). No client, no NDA — just the method, shown end to end.
259,384
Charging sessions analysed, 2011–2020
46 / 9
Ports across nine sites
2,216 MWh
Energy delivered over the period
7 pages
Including a drill-through for every site

Three minutes through the report

Filters, a site drill-through and the validation pages, recorded live. The headlines and chart titles you'll see change with the filters, because they're calculated in DAX rather than typed.

Captions available. Prefer YouTube? Watch it there ↗

Three findings worth a decision

Each one comes with the caveat that keeps it honest. A finding without its limits is just an opinion with a chart attached.

1.9×

Bigger isn't busier

Webster's 3 ports deliver 62.9 kWh per port per day, almost twice the network's 33.9. The largest sites sit below the line. Bryant delivers the most energy overall, but it needs six ports to do it.

Port-level

Weak sites can hide working ports

MPL ranks near the bottom as a site. Drill in, and a few of its ports deliver a fraction of the network rate while the rest sit close to average. The answer there isn't more ports. It's finding out what's wrong with the ones it has.

−26%

Pricing had a cost, and a payoff

Fees arrived in August 2017. Sessions per port fell 26%, comparing 2015–16 with 2018–19, while average idle time dropped from 44 to 18 minutes per session. That's timing, not proof of cause, and the report says so.

Seven pages, one argument

Each page answers one question, and the next page picks up where it leaves off.

  1. Executive OverviewNetwork size, growth since 2012, and who works hardest per port
  2. Demand PatternsWeekday peaks, weekends per day, and when charging turns into parking
  3. Site & Station PerformanceMap, port-sized scatter and utilisation ranking
  4. Site DetailDrill-through for any site, every number benchmarked against the network
  5. Users & RevenueFees against demand, idle time, and how concentrated usage is
  6. Data & ModelSource, star schema, and the raw-to-analysed reconciliation
  7. Assumptions & ValidationEvery assumption, definition and correction, written down

Under the hood

  • Star schema: one session fact table, five dimensions
  • Power Query cleaning: duplicates, non-USD sessions, Excel-serial dates, missing user IDs
  • A port-days measure that counts each port only from its first session
  • Network benchmark measures, so a site is always judged against the whole

Built to survive a filter

  • Headlines and chart titles are DAX measures, so they can't contradict the chart
  • Claims are guarded: "strongest case for expansion" only appears when every port is busy
  • Sites with fewer than 500 sessions are flagged, not ranked
  • Colour thresholds are relative, so formatting holds at any filter

The first answer was wrong

The most useful page in the report is the one nobody asks for. These are the corrections that changed what the report says.

Ports aren't live before they exist

My first utilisation measure treated every port as available from 2011. Sites that opened later looked idle, simply because they were being judged on years before they were built. Counting each port from its first session fixed it, and the top site changed: Webster, not Hamilton.

The hypothesis I started with didn't hold

The original plan assumed fees hadn't reduced usage. Per port, they had. The report states the finding the data supports, and the blueprint was rewritten to match.

Weekends compared per day, not in total

Five weekdays against two weekend days makes weekends look a third as busy. Per day, they run at about 78% of weekday volume, which is a capacity story, not a quiet one.

Blanks are not a user

Missing user IDs were stored as empty text, which quietly turned 7,677 anonymous sessions into one very active "driver". Converting them to null took them out of every user measure.

Power BI DAX Power Query Star schema Drill-through Azure Maps Data validation EV charging

Got charging data that isn't telling you much?

Most networks do. Plenty of numbers, not many decisions. Six years in EV infrastructure taught me which questions are worth asking of it.