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
MeterStartandMeterStop - 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!
Get in Touch with us
Related Posts
- FarmScript:我们如何从零设计一门农业IoT领域特定语言
- FarmScript: How We Designed a Programming Language for Chanthaburi Durian Farmers
- 智慧农业项目为何止步于试点阶段
- Why Smart Farming Projects Fail Before They Leave the Pilot Stage
- ERP项目为何总是超支、延期,最终令人失望
- ERP Projects: Why They Cost More, Take Longer, and Disappoint More Than Expected
- AI Security in Production: What Enterprise Teams Must Know in 2026
- 弹性无人机蜂群设计:具备安全通信的无领导者容错网状网络
- Designing Resilient Drone Swarms: Leaderless-Tolerant Mesh Networks with Secure Communications
- NumPy广播规则详解:为什么`(3,)`和`(3,1)`行为不同——以及它何时会悄悄给出错误答案
- NumPy Broadcasting Rules: Why `(3,)` and `(3,1)` Behave Differently — and When It Silently Gives Wrong Answers
- 关键基础设施遭受攻击:从乌克兰电网战争看工业IT/OT安全
- Critical Infrastructure Under Fire: What IT/OT Security Teams Can Learn from Ukraine’s Energy Grid
- LM Studio代码开发的系统提示词工程:`temperature`、`context_length`与`stop`词详解
- LM Studio System Prompt Engineering for Code: `temperature`, `context_length`, and `stop` Tokens Explained
- LlamaIndex + pgvector: Production RAG for Thai and Japanese Business Documents
- simpliShop:专为泰国市场打造的按需定制多语言电商平台
- simpliShop: The Thai E-Commerce Platform for Made-to-Order and Multi-Language Stores
- ERP项目为何失败(以及如何让你的项目成功)
- Why ERP Projects Fail (And How to Make Yours Succeed)













