計測値を送信する
const url = 'https://api.example.com/site-control/v1/sites/st_7k2m9q/telemetry';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"samples":[{"aggregation":"INSTANT","metric":"battery_power_kw","sample_id":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","test_mode":false,"ts":"2026-10-01T10:00:00+09:00","value":1480.5,"window":"PT1S"}]}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.example.com/site-control/v1/sites/st_7k2m9q/telemetry \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "samples": [ { "aggregation": "INSTANT", "metric": "battery_power_kw", "sample_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "test_mode": false, "ts": "2026-10-01T10:00:00+09:00", "value": 1480.5, "window": "PT1S" } ] }'EMS が計測値を J-EMS に送る。1回の呼び出しで、複数のサンプルをまとめて送れる(最大 3,600 件)。
受理するか拒否するかはサンプルごとに決まる。不正なサンプルが1件あっても、残りのサンプルは保存される。
各サンプルには、計測したときに一度だけ sample_id を付ける。J-EMS はこの ID で重複を見分けるので、送信に失敗したときは同じ内容をそのまま送り直してよい。保存済みのサンプルは重複として数えられ、エラーにはならない。ただし、同じ sample_id を別の内容に使うと DUPLICATE で拒否される。
通信が途絶えている間は、未送信のサンプルを最低 60 日分保持しておき、接続が戻ったら送る。送る順序は最新の計測値を先に、溜めていた分を後にする。遅れて届いたサンプルも受け付ける。
どの計測値をどの間隔で送るかは、telemetry_sample.metric の表にまとめている。
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
object
AVERAGE:[ts, ts + window) の平均値。MIN:同じ期間の最小値。
| metric | 必須 | 最低サンプリング間隔 | 備考 |
|---|---|---|---|
battery_power_kw |
必須 | 1 分。一次調整力の区間は 1 秒 | 正は放電。 |
battery_soc_percent |
必須 | 1 分 | ratings.usable_energy_kwh に対する割合。 |
meter_import_energy_kwh |
必須 | 1 分 | 系統の計量点の、設置以来の積算。計量器の交換時を除き減らない。 |
meter_export_energy_kwh |
必須 | 1 分 | 系統の計量点の、設置以来の積算。 |
grid_frequency_hz |
必須 | 1 分(aggregation: MIN)。一次調整力の区間は 1 秒 |
連系点で実測する。分解能 0.01 Hz 以上。1 分ごとの値は、その1分間の最小値を送る。瞬時値では数秒の周波数低下を見逃すため。 |
meter_power_kw |
任意 | 1 分 | 系統の計量点での正味。正は逆潮流。一次調整力に受電点で参入するサイトでは、一次調整力の区間の 1 秒値が必須。 |
pv_power_kw |
任意 | 1 分 | 太陽光のあるサイトで送る。 |
「一次調整力の区間」は mode: FREQUENCY_CONTROL の区間を指す。その区間の 1 秒ごとの電力と周波数は、一次調整力のアセスメントⅡで応動を評価する材料になる。欠けた秒があるとその分だけ評価に使える点が減るので、後から送る分も含めて欠かさず送る。
計測したときに一度だけ生成し、再送のたびに同じものを使う。
サイトが注入した模擬周波数で事前審査の試験をしている間は true。こうしたサンプルは運用データと分けて扱う。
計測時刻。AVERAGE と MIN の場合は集計した期間の開始時刻。
Example
2026-10-01T10:00:00+09:00Example
1480.5集計した期間の長さ(ISO 8601 の期間表記)。aggregation が AVERAGE または MIN のときは必須。
Example
PT1SResponses
Section titled “Responses”サンプルごとの結果。再送するのは rejected のうち、再試行できるコード(INTERNAL_ERROR)のものだけ。
object
新たに保存したサンプル数。
同じ内容で保存済みだったサンプル数。成功として扱う。
object
object
TIME_WINDOW_INVALID:区間の start が昇順でない、分の境界にない、最初の区間の start が horizon_start と一致しない、horizon_end 以降にある。出力制御スケジュールでは start >= end。
EXPIRED:horizon_end がすでに過ぎている。
DUPLICATE:同じ sample_id が別の内容に使われた。
INTERNAL_ERROR:受信側の障害。そのまま再試行する価値があるのはこのコードだけ。
問題のあるフィールドへのパス。
リクエストの samples 配列内の位置。
読み取れる sample_id がなかったサンプルでは入らない。
Example
{ "rejected": [ { "error": { "code": "MALFORMED", "field_path": "slots[2].power_kw" } } ]}本文が有効なバッチではない(JSON でない、または samples 配列がない)。何も保存していない。
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" } ]}サンプルが 3,600 件を超えた、または本文が 1 MiB を超えた。バッチを分割する。
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" } ]}