初心者向けガイド:EV充電アプリはどうやって充電器と通信し、充電量と料金を計算しているのか?

電気自動車(EV)が普及する中で、ユーザーはスマートで直感的な充電体験を求めています。本記事では、Flaskを使ってEV充電システムを開発している方や初心者向けに、次のようなポイントをわかりやすく解説します。

  • モバイルアプリがバックエンドとEVSE(充電器)とどう連携しているのか
  • 充電セッションのエネルギー消費をどう測定するか
  • 料金はどう計算されるのか
  • SOC(State of Charge/バッテリー残量)をどう有効化するか
  • FlaskとOCPPを使った実装例つき

🧩 EV充電システムの基本構成(4つの要素)

コンポーネント 役割
モバイルアプリ ユーザーが充電器を探して、充電を開始・停止するために使用
Flaskバックエンド アプリとEVSEの間の橋渡しをするサーバ
EVSE(Charger) 実際に電気を車に供給するハードウェア
OCPPプロトコル バックエンドと充電器が通信するための業界標準のプロトコル

🔄 通信の流れ(図解)

アプリが直接EVSE(充電器)と通信するわけではありません。実際には以下のような流れです:

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

MeterStartMeterStop によるエネルギー追跡

EVSE(Charger)は内蔵されたメーターで、充電開始と終了時の電力量を測定します。

内容
MeterStart 充電開始時の電力量(Wh)
MeterStop 充電終了時の電力量(Wh)

計算例:

MeterStart = 154200 Wh  
MeterStop = 156700 Wh  
使用電力量 = (156700 - 154200) / 1000 = 2.5 kWh

💰 料金の計算方法

基本的な料金計算式:

料金 = 使用電力量 (kWh) × 単価(kWhあたりの料金)

Flaskのサンプルコード:

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)

出力例:

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

🔋 ボーナス:SOC(バッテリー残量)を有効化する方法

SOC(State of Charge)はEVのバッテリー残量(例:74%)を示すデータです。対応する充電器であれば、OCPPコマンドでSOCのレポート機能を有効化できます。


✅ ステップ1:SOCがサポートされているか確認

@app.route('/station/<cp_id>/check-soc', methods=['GET'])
def check_soc(cp_id):
    ws = get_websocket(cp_id)  # WebSocket接続を取得
    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})

✅ ステップ2:SOCを有効化する

@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"})

📊 MeterValues にSOCが含まれるようになる

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

アプリ画面の表示例:

🔋 バッテリー:74%
⚡ 使用電力量:2.1 kWh
💰 料金:$0.53

📱 アプリ側へのAPIレスポンス例

{
  "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"
}

🧱 推奨される技術スタック(バックエンド)

推奨技術
Webフレームワーク Flask
EVSE通信プロトコル OCPP 1.6(Mobility Houseライブラリ)
データベース PostgreSQL または MongoDB
モバイルアプリ Flutter または React Native
決済ゲートウェイ Stripe、PayPal、PromptPay(タイ向け)

✅ まとめ

このガイドで、以下の内容が理解できたと思います:

  • FlaskバックエンドがアプリとEVSE(Charger)をつなぐ役割
  • MeterStartMeterStop によるエネルギー追跡と料金計算
  • SOC(State of Charge)機能の有効化方法
  • OCPPとFlaskを組み合わせて、実用的なEV充電アプリの構築が可能

🚀 EV充電プラットフォームの開発を始めませんか?

初めてのシステム構築でも、ネットワーク運用でも、お気軽にご相談ください。

📬 お問い合わせ:www.simplico.net
💬 技術サポートや連携のご相談も可能です!

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