状態を報告する
const url = 'https://api.example.com/site-control/v1/sites/st_7k2m9q/reported';const options = { method: 'PUT', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"active":true,"alerts":[{"code":"BATTERY_COMM_LOST","component":"PCS1","detail":"example","severity":"WARNING","since":"2026-10-01T10:00:00+09:00"}],"applied_version":"b41e08d3","curtailment":[{"end":"2026-10-01T10:30:00+09:00","limit_percent":1,"start":"2026-10-01T10:00:00+09:00"}],"frequency_control_active":true,"operating_state":"RUNNING","ratings":{"max_charge_kw":2000,"max_discharge_kw":2000,"usable_energy_kwh":2800},"rejected_version":"example","rejection_errors":[{"code":"MALFORMED","detail":"example","field_path":"slots[2].power_kw"}],"reported_at":"2026-10-01T10:00:00+09:00","software_version":"acme-ems 4.2.1"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request PUT \ --url https://api.example.com/site-control/v1/sites/st_7k2m9q/reported \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "active": true, "alerts": [ { "code": "BATTERY_COMM_LOST", "component": "PCS1", "detail": "example", "severity": "WARNING", "since": "2026-10-01T10:00:00+09:00" } ], "applied_version": "b41e08d3", "curtailment": [ { "end": "2026-10-01T10:30:00+09:00", "limit_percent": 1, "start": "2026-10-01T10:00:00+09:00" } ], "frequency_control_active": true, "operating_state": "RUNNING", "ratings": { "max_charge_kw": 2000, "max_discharge_kw": 2000, "usable_energy_kwh": 2800 }, "rejected_version": "example", "rejection_errors": [ { "code": "MALFORMED", "detail": "example", "field_path": "slots[2].power_kw" } ], "reported_at": "2026-10-01T10:00:00+09:00", "software_version": "acme-ems 4.2.1" }'EMS が自分の現在の状態を J-EMS に報告する。報告するのは、どのスケジュールを実行しているか、PCS の運転状態、設備の能力、発生中のアラート、出力制御のスケジュールである。
呼び出すたびに、J-EMS が保持しているその EMS の状態は丸ごと置き換わる。そのため変わった項目だけでなく、毎回すべての項目を送る。どの EMS からの報告かは、J-EMS が認証トークンで判別する。
報告は、いずれかの項目が変わったときに送り、変化がなくても 60 秒ごとには送る。J-EMS は、180 秒報告が届かない EMS をオフラインとみなす。
取得したスケジュールを受理したか拒否したかも、この報告の applied_version と rejected_version で伝える。受理・拒否を伝える専用の呼び出しはない。
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Example
st_7k2m9qサイト ID。サイトの登録時に J-EMS が発行する。
Request Bodyrequired
Section titled “Request Bodyrequired”object
現在サイトを制御している EMS なら true。ホットスタンバイ構成では、true を報告するのはちょうど1台。スタンバイ機も desired を取得して状態を PUT するが、実行はしない。
現在発生中のアラートすべて。空配列は正常を意味する。解消したアラートは次の PUT から外すだけでよい。
object
SETPOINT_UNREACHABLE:区間の設定値を丸めて実行している。制約となった条件を detail に書く。
GRID_ABNORMAL:系統の喪失、保護継電器のトリップ、連系点での電圧・周波数の逸脱。
OTHER:上記以外。内容を detail に書く。
アラートが出ている機器。同じ code が複数の機器で出る場合に区別するために使う。例:PCS1、BMS。
Example
PCS1運用担当者向けの自由記述。
FAULT:設備の一部または全部が動作できない。WARNING:動作は続いているが、放置すると問題になる。J-EMS は FAULT を緊急、WARNING を通常の優先度で通知する。
その状態になった時刻。
Example
2026-10-01T10:00:00+09:00現在実行しているスケジュールの version(ETag と同じ値)。最初のスケジュールを受理するまでは入れない。
Example
b41e08d3EMS が一般送配電事業者から受け取った、実際に効く出力制御スケジュール(固定スケジュールと更新スケジュールを統合済みのもの)。把握しているスケジュール全体を毎回送る。太陽光を併設しないサイトでも出力制御の対象になりうるので、すべてのサイトで必須とする。受け取っているスケジュールがない場合は空配列を送る。
object
Example
2026-10-01T10:30:00+09:00許容される出力。連系容量に対する割合。
Example
2026-10-01T10:00:00+09:00一次調整力の制御が実際に有効になっているか。スケジュールの指示ではなく、PCS に設定されている状態を報告する。J-EMS はこれとスケジュールを突き合わせて、予定外の作動と未作動を検知する。
PCS の実際の状態。FAULT はスケジュールに従えない状態で、理由は alerts に入れる。
設備が現時点でできること。劣化やストリングの停止、BMS が許容する充放電電力の変化などで値が変わったら、その時点で報告する。
object
Example
2000Example
2000劣化を考慮した、現時点で空から満充電までに使える電力量。battery_soc_percent はこれに対する割合。
Example
2800直近に取得して拒否したスケジュールの ETag。ETag はヘッダーから取れるので、本文を解析できなかった場合でも分かる。その後に別のスケジュールを受理したら入れない。
rejected_version で見つかった問題をすべて列挙する(最初の1件だけにしない)。クラウドが1往復で直せるようにするため。
object
TIME_WINDOW_INVALID:区間の start が昇順でない、分の境界にない、最初の区間の start が horizon_start と一致しない、horizon_end 以降にある。出力制御スケジュールでは start >= end。
EXPIRED:horizon_end がすでに過ぎている。
DUPLICATE:同じ sample_id が別の内容に使われた。
INTERNAL_ERROR:受信側の障害。そのまま再試行する価値があるのはこのコードだけ。
問題のあるフィールドへのパス。
Example
slots[2].power_kwEMS がこの状態をまとめた時刻。
Example
2026-10-01T10:00:00+09:00EMS のソフトウェアバージョン。問い合わせ対応に使う。
Example
acme-ems 4.2.1Responses
Section titled “Responses”保存した。
本文が検証に失敗した。何も保存していない。
object
400 のときの、フィールド単位の問題。
object
TIME_WINDOW_INVALID:区間の start が昇順でない、分の境界にない、最初の区間の start が horizon_start と一致しない、horizon_end 以降にある。出力制御スケジュールでは start >= end。
EXPIRED:horizon_end がすでに過ぎている。
DUPLICATE:同じ sample_id が別の内容に使われた。
INTERNAL_ERROR:受信側の障害。そのまま再試行する価値があるのはこのコードだけ。
問題のあるフィールドへのパス。
Example
{ "code": "UNAUTHORIZED", "errors": [ { "code": "MALFORMED", "field_path": "slots[2].power_kw" } ]}Bearer トークンがない、または無効。
object
400 のときの、フィールド単位の問題。
object
TIME_WINDOW_INVALID:区間の start が昇順でない、分の境界にない、最初の区間の start が horizon_start と一致しない、horizon_end 以降にある。出力制御スケジュールでは start >= end。
EXPIRED:horizon_end がすでに過ぎている。
DUPLICATE:同じ sample_id が別の内容に使われた。
INTERNAL_ERROR:受信側の障害。そのまま再試行する価値があるのはこのコードだけ。
問題のあるフィールドへのパス。
Example
{ "code": "UNAUTHORIZED", "errors": [ { "code": "MALFORMED", "field_path": "slots[2].power_kw" } ]}トークンは有効だが、このサイト向けに発行されたものではない。
object
400 のときの、フィールド単位の問題。
object
TIME_WINDOW_INVALID:区間の start が昇順でない、分の境界にない、最初の区間の start が horizon_start と一致しない、horizon_end 以降にある。出力制御スケジュールでは start >= end。
EXPIRED:horizon_end がすでに過ぎている。
DUPLICATE:同じ sample_id が別の内容に使われた。
INTERNAL_ERROR:受信側の障害。そのまま再試行する価値があるのはこのコードだけ。
問題のあるフィールドへのパス。
Example
{ "code": "UNAUTHORIZED", "errors": [ { "code": "MALFORMED", "field_path": "slots[2].power_kw" } ]}サイトが存在しない。
object
400 のときの、フィールド単位の問題。
object
TIME_WINDOW_INVALID:区間の start が昇順でない、分の境界にない、最初の区間の start が horizon_start と一致しない、horizon_end 以降にある。出力制御スケジュールでは start >= end。
EXPIRED:horizon_end がすでに過ぎている。
DUPLICATE:同じ sample_id が別の内容に使われた。
INTERNAL_ERROR:受信側の障害。そのまま再試行する価値があるのはこのコードだけ。
問題のあるフィールドへのパス。
Example
{ "code": "UNAUTHORIZED", "errors": [ { "code": "MALFORMED", "field_path": "slots[2].power_kw" } ]}リクエストが多すぎる。指数バックオフで再試行する。
object
400 のときの、フィールド単位の問題。
object
TIME_WINDOW_INVALID:区間の start が昇順でない、分の境界にない、最初の区間の start が horizon_start と一致しない、horizon_end 以降にある。出力制御スケジュールでは start >= end。
EXPIRED:horizon_end がすでに過ぎている。
DUPLICATE:同じ sample_id が別の内容に使われた。
INTERNAL_ERROR:受信側の障害。そのまま再試行する価値があるのはこのコードだけ。
問題のあるフィールドへのパス。
Example
{ "code": "UNAUTHORIZED", "errors": [ { "code": "MALFORMED", "field_path": "slots[2].power_kw" } ]}サーバーの一時的な障害。指数バックオフで再試行する。
object
400 のときの、フィールド単位の問題。
object
TIME_WINDOW_INVALID:区間の start が昇順でない、分の境界にない、最初の区間の start が horizon_start と一致しない、horizon_end 以降にある。出力制御スケジュールでは start >= end。
EXPIRED:horizon_end がすでに過ぎている。
DUPLICATE:同じ sample_id が別の内容に使われた。
INTERNAL_ERROR:受信側の障害。そのまま再試行する価値があるのはこのコードだけ。
問題のあるフィールドへのパス。
Example
{ "code": "UNAUTHORIZED", "errors": [ { "code": "MALFORMED", "field_path": "slots[2].power_kw" } ]}