電力網の負荷を最適化する SetChargingProfile の実装ポイントを C++17 で 5〜10 分で解説
OCPPのスマート充電は、電力網全体の負荷を平準化したり、特定の時間帯に充電を集中させたりするための重要機能です。本記事ではその中核メッセージである SetChargingProfile
の実装ポイントをC++17で解説します。
1. スマート充電とは
スマート充電は、CSMSからの指示に基づき、CS(充電器)が充電電力や電流を動的に制御する仕組みです。
- デマンドレスポンス: 電力需要が高い時間帯に充電を抑制
- 負荷分散: 複数台の充電器で利用可能な総電力を分け合う
- 時間帯別料金連携: 電気料金が安い夜間に充電をスケジュール
これらは SetChargingProfile
メッセージで送信される充電プロファイルによって実現されます。
アクターと役割(誰が)
- CSMS(Charging Station Management System): 充電器群を集中管理し、中央スマート充電の主要な制御主体。
- 充電ステーション(Charging Station, CS): 1台以上のEVSEを持つ実機。受信したプロファイルに従い出力を制御。
- EV(Electric Vehicle): ISO 15118対応時は自身の充電ニーズを提供可能。
- ローカルコントローラー(Local Controller, LC): 複数のCSを束ねてローカルに制御する論理コンポーネント。
- 外部制御システム(EMS/DSO 等): OCPP以外(OpenADR/OSCP等)で容量制限を指示。
制御形態とフロー(どのように)
- 内部負荷分散(Internal Load Balancing)
- CS内部でEVSE間の出力を最適配分。
- CSMSは
ChargingStationMaxProfile
で装置全体の上限を与え、CSはその範囲で局所最適化。
- 中央スマート充電(Central Smart Charging)
- CSMSが外部要因(系統容量、料金等)を加味してスケジュールを計算し、
SetChargingProfile
で各EVSE/トランザクションにTxProfile
を適用。
- CSMSが外部要因(系統容量、料金等)を加味してスケジュールを計算し、
- ローカルスマート充電(Local Smart Charging)
- LCが駐車場などの接続容量をグループ内のCSに配分。CSMSからLCへ上限設定、あるいはLC独自ロジックで分配。
- 外部制御信号(External Control Signals)
- EMS/DSO等がOCPP外プロトコルで制限を付与。CSは
NotifyChargingLimit
でCSMSへ報告。
- EMS/DSO等がOCPP外プロトコルで制限を付与。CSは
2. 主要メッセージ
メッセージ | 方向 | 目的 |
---|---|---|
SetChargingProfile | CSMS → CS | 充電プロファイル(電力・電流スケジュール)を設定 |
ClearChargingProfile | CSMS → CS | 設定済みのプロファイルを削除 |
GetChargingProfiles | CSMS → CS | 現在適用中のプロファイル一覧を問い合わせ |
ClearedChargingProfile | CS → CSMS | (v2.0.1) プロファイルが自動的にクリアされたことを通知 |
NotifyChargingLimit | CS → CSMS | 外部/ローカル要因で課せられた充電上限を通知 |
NotifyEVChargingNeeds | CS → CSMS | ISO 15118経由で得たEVの充電ニーズを通知 |
NotifyEVChargingSchedule | CS → CSMS | EVが選択/合意したスケジュールを通知 |
3. ChargingProfile
データ構造の要点
SetChargingProfile
のペイロードは複雑ですが、主要なパラメーターは次の通りです。
chargingProfileId
: プロファイルの一意なIDstackLevel
: 複数のプロファイルが競合した場合の優先度(数値が大きいほど優先)chargingProfilePurpose
:ChargingStationMaxProfile
(装置全体の上限)、TxDefaultProfile
(トランザクションの既定)、TxProfile
(進行中トランザクションの上限)chargingProfileKind
:Absolute
(絶対値)、Recurring
(繰り返し)、Relative
(相対値)chargingSchedule
: 時間ごとの電力/電流上限を定義する配列(chargingSchedulePeriod
)。chargingRateUnit
はA
もしくはW
。
評価ルールの要点:
- 有効な複数プロファイルとローカル/ハード的な制限が同時に存在する場合、最終的に適用されるのはその中の「最小の上限」。
- 同一目的内で複数プロファイルが重なる場合は
stackLevel
の高いものが優先される。
chargingSchedulePeriod
例
json
"chargingSchedule": [{
"duration": 3600,
"startSchedule": "2025-08-04T22:00:00Z",
"chargingRateUnit": "A",
"chargingSchedulePeriod": [
{"startPeriod": 0, "limit": 16.0},
{"startPeriod": 1800, "limit": 8.0}
]
}]
上記は「22:00から30分間は16A、次の30分間は8A」を意味します。
4. 実装アーキテクチャ
- Handler: 受信したプロファイルを検証し、
ProfileStore
に保存。 - ProfileStore:
chargingProfileId
をキーにプロファイルを管理。stackLevel
(降順)とpurpose
でソートする機能を持つ。 - Scheduler: 1秒ごとなど定期的に
ProfileStore
を評価。もっとも優先度の高いプロファイルのlimit
を計算し、EVSE Controller
に指示を出す。
5. C++ 実装のポイント
プロファイルストア
std::vector
と std::map
を組み合わせ、stackLevel
でソート済みの状態を維持します。
cpp
class ProfileStore {
std::map<int, ChargingProfile> profiles_by_id_;
std::vector<std::shared_ptr<ChargingProfile>> sorted_profiles_;
public:
void add_profile(const ChargingProfile& p) {
// ... id重複チェック、挿入 ...
sort_by_stack_level();
}
// ...
};
スケジューラ
現在時刻にもっとも合致するlimit
を返します。
cpp
double Scheduler::calculate_limit(std::time_t now) {
// 1. Get highest priority profile from store
auto profile = store_.get_highest_priority_profile();
if (!profile) return default_limit;
// 2. Find the active period in the schedule
for (const auto& period : profile->chargingSchedule.periods) {
if (now >= period.start && now < period.start + period.duration) {
return period.limit;
}
}
return default_limit;
}
6. ISO 15118 連携(任意)
- EVは希望エネルギー量・出発予定などのニーズを提供し、CSはこれを
NotifyEVChargingNeeds
でCSMSへ転送。 - CSMSはニーズや系統制約を考慮し、最大3つの料金プランを含むスケジュール(
SAScheduleList
)をEVへ提示。EVは選択結果をNotifyEVChargingSchedule
で通知。 - 充電中にスケジュール/プロファイルの再交渉が発生しうる。
7. オフライン時の動作
- CSがオフラインになっても、事前に受信した
TxProfile
はトランザクション終了まで有効。 - 通信断でトランザクションを開始する場合でも、装置に設定済みの
TxDefaultProfile
があればそれに従い充電可能。
8. まとめ
- スマート充電の実装は プロファイルの管理 と スケジューリングロジック が肝。
stackLevel
(大きい方が優先)とchargingProfilePurpose
(ChargingStationMaxProfile
/TxDefaultProfile
/TxProfile
)のルールを正確に解釈する。- 有効なプロファイルとローカル制限の最小値が最終的な上限となる評価を正しく実装する。
- 2.0.1固有の電文(
NotifyChargingLimit
、NotifyEVChargingNeeds
、NotifyEVChargingSchedule
等)との連携やオフライン時の挙動も考慮する。