Information
- OpenAPI version:
3.0.3
サイトに設置された EMS が、J-EMS Cloud から制御スケジュールを受け取り、状態と計測値を返すためのプロトコルである。
この API では、サイトに設置されて J-EMS と通信する機器またはソフトウェアを、EMS 本体か、EMS を外部につなぐゲートウェイかを問わず、まとめて EMS と呼ぶ。EMS は蓄電池・PCS・計量器とつながり、それらを制御・計測する。1サイトには通常1台の EMS があり、予備機を常時接続しておくホットスタンバイ構成では2台になる。サイトはパスの site_id で指定し、どの EMS からの呼び出しかは J-EMS が認証トークンで判別する。EMS の側で EMS 自身の ID を扱う必要はない。
この API の OpenAPI 定義(YAML)は site-control.yml からダウンロードできる。クライアントコードの生成や、リクエストの検証に使える。
通信はすべて EMS から外向きの HTTPS で始まるので、EMS の側に受信ポートも VPN もメッセージブローカーも用意する必要がない。
J-EMS が EMS に制御の指示を渡す手段は、GET /desired で取得する desired スケジュールだけである。desired スケジュールは、EMS が指定した期間(現在から最大 24 時間先まで、省略時は 3 時間先まで)について、どの時点で何をするかを書き切ったものである。EMS は受け取るたびに、手元のスケジュールを丸ごと置き換える。状態と計測値は、EMS からの2つの呼び出しで返す。
| 呼び出し | 向き | 意味 |
|---|---|---|
GET /desired |
クラウド → EMS | 指定した期間の desired スケジュール。ポーリングで取得し、中身が変わっていなければ 304 が返る。 |
PUT /reported |
EMS → クラウド | EMS の現在の状態。PUT のたびに前回の状態を置き換える。 |
POST /telemetry |
EMS → クラウド | 計測値。追記され、sample_id で重複が除かれる。 |
EMS は、次の3つのやり取りをそれぞれ独立した周期で繰り返す。
sequenceDiagram
participant EMS
participant J as J-EMS
loop poll_interval_seconds ごと
EMS->>J: GET /desired(horizon_hours、If-None-Match)
alt 指定した期間の中身が変わっていない
J-->>EMS: 304
else 変わった
J-->>EMS: 200 スケジュール(ETag)
EMS->>EMS: 全体を検証し、問題がなければ丸ごと置き換える
end
end
loop 状態が変わったとき、および 60 秒ごと
EMS->>J: PUT /reported(applied_version など)
J-->>EMS: 204
end
loop 計測のたび
EMS->>J: POST /telemetry(サンプルのバッチ)
J-->>EMS: 200 サンプルごとの結果
end
それぞれの手順の詳細は次のとおりである。
horizon_hours で指定し、保持しているスケジュールの ETag を If-None-Match に入れて GET /desired を呼ぶ。間隔は直近のスケジュールの poll_interval_seconds に従い、まだ1件も取得していなければ 10 秒とする。200 が返ったら、スケジュール全体を検証する。問題がなければ、手元のスケジュールを捨てて、受け取ったスケジュールに一度に切り替える。一部でも不正ならスケジュール全体を拒否し、前のスケジュールの実行を続ける。PUT /reported を送り、変化がなくても 60 秒ごとには送る。J-EMS はこの PUT の途絶えで EMS の停止を検知する。POST /telemetry を送り、オフラインの間はローカルに溜めておく。スケジュールは区間の並びである。各区間は、その start から次の区間の start まで続き、最後の区間は horizon_end まで続く。区間に終わりの時刻を持たせないのは、隣の区間との隙間や重なりが起こらない形にするためである。区間の開始は分の境界(秒が 0)にそろい、最初の区間の開始は horizon_start と一致する。
J-EMS は、同じ指示が続く間を1区間にまとめ、指示が変わる時刻にだけ新しい区間を置く。コマの中で出力を分単位で変える場合(計画した電力量を計量点で達成するための配分など)も、J-EMS が分単位の POWER 区間に分解して送る。したがって EMS がコマ内の配分を計算することはなく、J-EMS も EMS が各分に何をするかを把握できる。
受け取ったスケジュールは、手元のスケジュールを丸ごと置き換える。前回もっと長い期間を受け取っていても、今回の horizon_end より後ろの分は捨てる。古い分を残して新しい分とつなぎ合わせると、どちらの指示が効くかを EMS が決めることになり、スケジュールを1件だけ持つ意味がなくなるからである。
スケジュールが区間の途中で届いた場合も、現在時刻を含む区間は即座に適用する。区間の開始を待つと、その区間の残りを前のスケジュールの指示で運転することになるからである。
設備が実現できない設定値は拒否せず、実現できる最も近い値に丸めて実行し、SETPOINT_UNREACHABLE アラートで報告する。拒否すると蓄電池が前のスケジュールの指示のまま動き続け、クラウドが意図した方向とは逆の運転になることがあるため、丸めて近づけるほうを選ぶ。
J-EMS に接続できない間、EMS は最後に受理したスケジュールの実行を続ける。そして horizon_end で実行をやめ、新しいスケジュールが届くまで IDLE(0 kW)を保つ。手元のスケジュールを独自に延長することはしない。延長した運転は市場での約定と一致する保証がないからである。
したがって、通信が途絶えても運転を続けられる時間は、最後に受け取った期間の長さで決まる。horizon_hours を省略した 3 時間では、通信が途絶えてから最大約 3 時間で IDLE になる。通信の途絶えで運転を止めたくない EMS は、horizon_hours=24 で取得する。
J-EMS は、EMS から届く reported と telemetry をもとに、次の異常を検知して運用担当者に通知する。そのため、下の表で必須としている情報は、どの EMS も送る必要がある。必須と任意の区別は、各フィールドと telemetry_sample.metric の表にも記載している。
| 検知する異常 | 使う情報 | 必須 |
|---|---|---|
| EMS との通信断 | PUT /reported の受信間隔(60 秒ごと) |
必須 |
| 設備の故障・警告 | reported.alerts(severity、component) |
必須 |
| PCS を制御できない状態 | reported.operating_state、reported.alerts |
必須 |
| スケジュールを実行していない | reported.applied_version、reported.rejected_version |
必須 |
| 計画した電力量との乖離 | meter_import_energy_kwh、meter_export_energy_kwh(1 分) |
必須 |
| 一次調整力の予定外の作動・未作動 | reported.frequency_control_active |
必須 |
| 一次調整力の応動不良 | 一次調整力の区間の battery_power_kw と grid_frequency_hz(1 秒) |
必須 |
| 系統周波数の異常 | grid_frequency_hz(1 分ごとの最小値) |
必須 |
| SOC 不足の見込み | battery_soc_percent(1 分)、reported.ratings |
必須 |
| 出力制御との矛盾 | reported.curtailment |
必須 |
J-EMS は受け取った reported をすべて履歴として保存する。reported は状態が変わるたびに送る決まりなので、この履歴から状態の変化を時刻付きで追える。
battery_power_kw が正なら放電であり、計量点では正が逆潮流(送電)である。_kw、_kwh、_percent、_hz)。暗黙の単位はない。0 を代わりに送ると、実測の 0 と区別できなくなる。/v1 の中ではフィールドを追加するだけで、削除や意味の変更はしない。EMS は知らないフィールドを無視する。現場の EMS を最適化クラウドにつなぐ方法としては、MQTT によるコマンド配信がよく使われる。クラウドがスケジュールをコマンドとしてパブリッシュし、EMS はそれをサブスクライブして、応答用のトピックに確認応答を返す構成である。この節では、この構成と比べて EMS の側で何が要らなくなるかを示す。
MQTT のコマンド配信で EMS の負担が大きくなる主な理由は、1通のコマンドが、タイムラインのうちそのコマンドが覆う時間帯だけを上書きする差分である点にある。EMS は、まだ期間の残っている以前のコマンドを保持し、優先度・発行時刻・到着順の規則で重ね合わせて、今どの指示が効いているかを自分で計算しなければならない。コマンドが届かなかった場合、EMS は前のスケジュールのまま運転を続けることになり、欠落に気付けるのはクラウドの側だけである。そのうえで、ブローカーとの常時接続と切断時の再接続も EMS が担う。
この API では、クラウドが複数の計画の合成、優先順位付け、取り消しを済ませ、その結果を desired スケジュールとして渡す。EMS がすることは、最新のスケジュールを HTTPS で取得し、検証し、実行することだけである。
以下では、MQTT のコマンド配信で EMS に必要になる実装を3種類に分けて、この API での扱いと並べる。
コマンドが差分なので、どの時点にどの指示が効くかを EMS が決める必要がある。
| MQTT のコマンド配信で EMS が実装すること | この API での扱い |
|---|---|
| 優先度の異なる複数のスケジュール(短期と長期など)を重ね合わせる | 合成済みのスケジュールが1件届く |
| 同じ時間帯を覆う複数のコマンドから、発行時刻と到着順で採るものを決める | 最後に受け取ったスケジュールを使うだけ |
| 新しいコマンドが覆わない時間帯を、古いコマンドで埋める | 計画期間のすべての時間帯が書かれている。何もしない時間帯も IDLE と明記される |
| 取り消し専用のコマンドを解釈する | 取り消したい部分を含まないスケジュールが届くだけ |
| 不正な部分を含むコマンドを全体ごと拒否する。一部だけ適用すると、置き換えたはずの古いコマンドが隙間の補完で復活するため | 拒否したら前のスケジュールを続けるだけ。古い指示が復活する仕組みがない |
リクエストと応答が別々のメッセージになり、届いたかどうかを送り手が確認できないので、その突き合わせを EMS が担う。
| MQTT のコマンド配信で EMS が実装すること | この API での扱い |
|---|---|
| 応答用のトピックに、どのコマンドへの応答かを示す ID を付けて返す。本文を解析できないときは代用の値を入れる | HTTP の応答がそのまま結果になる。受理・拒否は reported の applied_version と rejected_version で伝える。どのスケジュールかは ETag で分かる |
| 同じコマンドが二度届いたときに、二重に適用しない | 中身が同じなら 304 が返るだけで、何も起きない |
| ホットスタンバイの予備機には、届いたコマンドへの確認応答を返させない | 各 EMS が自分の状態を報告するだけ |
| 届かなかったコマンドは、EMS からは気付けない | EMS が取りに行くので、取れなければ EMS 自身が気付く。J-EMS も EMS ごとの最終取得時刻を見られる |
ブローカーとの接続を張り続け、その制約の中で送受信する必要がある。
| MQTT のコマンド配信で EMS が実装すること | この API での扱い |
|---|---|
| ブローカーとの常時接続、セッションの維持、切断時の再接続 | 必要なときに HTTPS のリクエストを送るだけ |
| EMS ごとの X.509 証明書の管理。1枚の証明書で張れる同時接続を1本に制限するブローカーもある | EMS ごとの Bearer トークン |
| ブローカーのポート(通常 8883)への外向き TLS を、現場のネットワークで通す | 外向き HTTPS(443)。多くの社内プロキシを通過できる |
| ペイロードの上限(128 KB が多い)や接続ごとの送信回数の上限に合わせて、送るデータを分割・間引く | 計測値は1リクエスト 3,600 件まで |
| 異常系の試験のために、モックのブローカーを用意する。EMS の認証情報では、コマンド用トピックにパブリッシュできないことが多い | 任意の HTTP スタブから固定のスケジュールを返せば試験できる |
一方で、次の要件は設備と系統に由来するので、どちらの方式でも EMS が実装する。
MQTT のコマンド配信が上回るのは、新しいスケジュールが EMS に届くまでの速さである。MQTT ではほぼ即時に届くのに対し、この API では、スケジュールの変更が EMS に届くまで最大で poll_interval_seconds 秒遅れる。遅れを縮めたい時間帯(一次調整力のコマ、需給調整市場の指令が来うる時間帯など)には、J-EMS がスケジュールに含める poll_interval_seconds を小さくし、EMS はその間隔で取得する。新しい間隔も EMS が次に取得したときに届くので、J-EMS はその時間帯より前に値を切り替える。EMS の側で追加の設定や実装は要らない。
J-EMS が EMS ごとに発行する API トークン。Authorization: Bearer <token> で送る。
Security scheme type: http