リレーを安全に制御
ユースケース
このパターンは、リレー操作が実際の機器に影響し、呼び出し側がリトライ、不確実な結果、複数のリレーチャネルを、重複する副作用を生まずに処理する必要がある場合に使います。
推奨フロー
1台のデバイスに対するすべてのリレー変更は、1つの relays 配列にまとめて送信してください。1回のバッチが1つのデバイスコマンドになり、デバイスが確実に処理できない可能性のある連続送信を避けられます。
段階的な実装
- デバイスタイプ定義一覧の取得(英語)を使って、
device.relay.set、リレー数、許可されている操作を確認します。 - 目標とするリレー配列を組み立てます。単一チャネルの制御には1つの要素を、協調した変更には複数の一意なインデックスを使います。
- この操作の意図に対して、呼び出し側が所有する新しい
Idempotency-Keyを生成します。 device:controlとともにリレーコマンドの実行(英語)を呼び出します。data.command.idとdata.command.statusを読み取ります。ステータスがSENTの場合は、終端状態に達するか、自分で設定した上限のポーリング期限までコマンド結果の取得(英語)を使用します。- デバイスの確認応答に
data.stateが含まれている場合はそれを使用してください。任意項目を埋めるためだけに別の更新を発行しないでください。 - 結果が
TIMEOUTの場合は、別の操作が安全かどうかを判断する前に、現在のデバイス状態を読み取ってください。
コマンドのライフサイクル
| 結果 | 意味 | クライアントの対応 |
|---|---|---|
HTTP 202 + COMMAND_ACCEPTED | プラットフォームがリクエストを受け付けた。独立したコマンドステータスではない | data.command.status を読み取り、コマンドIDを保持する |
SENT | コマンドはまだ確認待ちである | 上限のあるポーリングで結果を照会する |
SUCCESS | デバイスが実行を確認した | 返された状態があれば適用する |
FAILED | プラットフォームがコマンドの未完了を確認した | 自動リトライを停止し、失敗を処理する |
TIMEOUT | 待機ウィンドウ内に最終確認が届かなかった | デバイスが実行したかどうかを想定せず、まず現在の状態を読み取る |
主なインターフェース
- リレーコマンドの実行(英語)
- コマンド結果の取得(英語)
- デバイス状態の取得(英語)
- レート制限と冪等性(英語)
- WebSocketでのリレー制御(英語)
障害と復旧
- ネットワーク障害によりHTTPの結果が不明な場合は、同じ
Idempotency-Keyで同一のリクエストを再試行してください。 429 RATE_LIMITEDの後はRetry-Afterを待ち、元のキーで同じ操作を再試行してください。- 別のデバイス、別のリレー配列、別の操作にキーを再利用しないでください。それは
IDEMPOTENCY_CONFLICTを返します。 TIMEOUTの後は、まず状態を更新してください。状態がまだ不明な場合は、別の物理操作を送信する前にビジネス上の判断を求めてください。- 以前のレスポンスが失われていた場合でも、
JOGなどの機器操作を繰り返すと実際の副作用が発生する可能性があります。それに応じて確認手順とオペレーター向けの安全策を設計してください。
本番運用上の考慮事項
- 監査と復旧のために、冪等性キー、コマンドID、リクエストしたリレー配列、ステータス、
requestIdをまとめて保存してください。 - 同じデバイスを対象とする操作は、アプリケーション内で直列化または調整してください。
- 上限のある結果ポーリングを使い、レート制限を守ってください。
- UIや自動化ルールから制御を許可する前に、対象チャネルと物理的な安全性を検証してください。
