Beginner’s Guide: How EV Charging Apps Communicate, Track Charging, and Calculate Costs

Electric Vehicles (EVs) are the future — and smart, user-friendly charging apps are a big part of the EV experience. If you're building an EV charging solution with a Flask backend, this guide is for you.

We'll walk through:

  • How your mobile app talks to the backend and the EVSE (Charger)
  • How energy usage is tracked and billed
  • How to enable SOC (State of Charge) reporting
  • Code examples using Flask and OCPP
  • A clear and complete technical overview — for beginners

🧩 The 4 Main Components of an EV Charging System

Component Role
Mobile App Used by EV drivers to find, start, and stop charging sessions
Flask Backend Your server that talks to the app and sends commands to chargers
EVSE (Charger) The physical station that delivers electricity to the vehicle
OCPP Protocol The language your backend uses to communicate with the charger

🔄 Communication Flow (Simplified)

Even though it looks like the app talks to the charger directly, it doesn’t.

Here’s how it really works:

sequenceDiagram
    participant User
    participant App
    participant Flask Backend
    participant EVSE (Charger)

    User->>App: Start Charging
    App->>Flask Backend: POST /start_session
    Flask Backend->>EVSE (Charger): OCPP RemoteStartTransaction
    EVSE (Charger)-->>Flask Backend: MeterStart = 154200 Wh
    Flask Backend-->>App: Charging session started

    Note over EVSE (Charger): Charging in progress...

    User->>App: Stop Charging
    App->>Flask Backend: POST /stop_session
    Flask Backend->>EVSE (Charger): OCPP RemoteStopTransaction
    EVSE (Charger)-->>Flask Backend: MeterStop = 156700 Wh
    Flask Backend-->>App: Energy used = 2.5 kWh

⚡ Charging Session Tracking: MeterStart and MeterStop

Every EVSE (Charger) has a built-in energy meter. When charging starts and stops, it reports the energy readings:

Value Meaning
MeterStart Energy reading when session begins (Wh)
MeterStop Energy reading when session ends (Wh)

Example:

MeterStart = 154200 Wh  
MeterStop = 156700 Wh  
Energy used = (156700 - 154200) / 1000 = 2.5 kWh

💰 How Cost is Calculated

To calculate cost, multiply the energy used by the rate per kWh.

Flask Example:

def calculate_cost(meter_start, meter_stop, rate_per_kwh=0.25):
    energy_wh = meter_stop - meter_start
    energy_kwh = energy_wh / 1000
    return round(energy_kwh * rate_per_kwh, 2)

Sample Response:

{
  "energy_kwh": 2.5,
  "rate_per_kwh": 0.25,
  "total_cost": 0.63
}

🔋 Bonus: Enable State of Charge (SOC) Reporting

SOC (State of Charge) is the percentage of the EV's battery during charging. Some chargers support it, but you may need to enable it manually.


✅ Step 1: Check if SOC is Supported

Using OCPP's GetConfiguration command:

@app.route('/station/<cp_id>/check-soc', methods=['GET'])
def check_soc(cp_id):
    ws = get_websocket(cp_id)  # Your connection manager
    request = call.GetConfigurationPayload(key=["MeterValuesSampledData"])
    asyncio.run(ws.send(request))
    response = asyncio.run(ws.receive())

    for item in response.configuration_key:
        if "StateOfCharge" in item.value:
            return jsonify({"soc_supported": True})
    return jsonify({"soc_supported": False})

✅ Step 2: Enable SOC if Not Enabled

Send a ChangeConfiguration request:

@app.route('/station/<cp_id>/enable-soc', methods=['POST'])
def enable_soc(cp_id):
    ws = get_websocket(cp_id)
    request = call.ChangeConfigurationPayload(
        key="MeterValuesSampledData",
        value="StateOfCharge,Energy.Active.Import.Register"
    )
    asyncio.run(ws.send(request))
    response = asyncio.run(ws.receive())

    if response.status == "Accepted":
        return jsonify({"status": "success", "message": "SOC enabled"})
    return jsonify({"status": "failed", "message": "Change rejected"})

🧾 Example MeterValues Response After Enabling SOC

{
  "meterValue": [{
    "timestamp": "2025-05-26T03:25:00Z",
    "sampledValue": [
      {"measurand": "Energy.Active.Import.Register", "value": "156300"},
      {"measurand": "StateOfCharge", "value": "74"}
    ]
  }]
}

You can show this in your app:

🔋 Battery: 74%
⚡ Energy Used: 2.1 kWh
💰 Cost: $0.53

📱 Final Output to the App (API Response)

{
  "session_id": "sess_001",
  "meter_start": 154200,
  "meter_stop": 156700,
  "energy_kwh": 2.5,
  "rate_per_kwh": 0.25,
  "total_cost": 0.63,
  "soc": 74,
  "start_time": "2025-05-26T03:14:00Z",
  "end_time": "2025-05-26T03:54:00Z"
}

🧱 Recommended Backend Tech Stack

Layer Suggested Technology
Web Framework Flask
Charger Protocol OCPP 1.6 with Mobility House lib
Database PostgreSQL or MongoDB
Mobile App Frontend Flutter or React Native
Payments Stripe, PromptPay, or PayPal

✅ Final Summary

With just a mobile app, Flask backend, and OCPP connection, you can build a smart EV charging platform that:

  • Starts and stops charging sessions
  • Tracks energy used with MeterStart and MeterStop
  • Calculates billing
  • Enables State of Charge (SOC) for battery insights
  • Sends real-time updates to users

This system is modular, scalable, and beginner-friendly.


🚀 Ready to Build Your EV Charging Platform?

Whether you're just getting started or scaling a network of chargers, we can help you build and connect your EV ecosystem.

📬 Reach out at www.simplico.net
💬 Or message us for a free technical consultation!

Related Posts

Our Products


Related Posts

Our Products


Get in Touch with us

Speak to Us or Whatsapp(+66) 83001 0222

Chat with Us on LINEiiitum1984

Our HeadquartersChanthaburi, Thailand