ノース・バウンド NGSI の相互作用

インデックス

概要

このドキュメントの目的は、IoTAgent がこのライブラリでサポートされている、すべての可能 なIoT シナリオで Context Broker とどのように対話するかを詳細に説明することです。

このドキュメントには 2つのセクションがあります。最初のセクションでは、すべてのインタラクション・モデルを理論的にシーケンス図で説明します。シーケンス図には、それぞれのシナリオの長所と短所が含まれます。2番目のセクションでは、netcat や curl など、ほとんどの OS で使用できるコマンドライン・ツールを使用して、これらのすべての対話の例を示します。

すべての例は、Telefonica の IoT プラットフォームと連携するように作成されているため、NGSI データとともに、次の情報を常に送信する必要があります :

  • サービスとサブ・サービスのヘッダ。サブ・サービス "/iota2ngsi" を持つサービス "workshop" を使用します
  • X-Auth-Token ヘッダにサブ・サービス内の管理者権限を持つ有効な期限切れのトークンが含まれています。この場合、ユーザ "adminiota2ngsi" はすべてのインタラクションに使用されます

要件

このドキュメントの実用的な部分には、次の要件があります :

  • Unix ライク のコマンドライン・インタプリタ。すべてのワークショップはコマンドラインで行われ、さまざまなコマンド・ラインツールを使用してさまざまな相互作用をシミュレートします
  • Curl コマンドライン HTTP クライアントをインストールする必要があります
  • Netcat ネットワーク・ユーティリティをインストールする必要があります。
  • Keystone, Steelskin PEP, Orion Context Broker などの構成要素を持つアクセシブルな IoT プラットフォーム
  • NGSI モデルと HTTP インタフェースの基礎知識

セオリー

概要

IoT Agent の一般的な目的

FIWARE アーキテクチャの中では、IoT Agent はプロトコル変換ゲートウェイとして機能し、サウス・バウンドのプロトコル (一般的には制約されたデバイスを対象とする軽量プロトコル) と FIWARE コンポーネントを通信するために使用される NGSI プロトコルの間のギャップを埋めるために使用されます。この変換プロセスは、デバイス・プロビジョニング API を使用して、プロビジョニング手順でユーザがカスタマイズできます。

したがって、すべての IoT Agent は、3つの異なるアクターと対話します :

  • サウス・バウンドの Devices
  • Provisioning API による Users
  • Context Broker

このドキュメントでは、IoTAgents と Context Broker の間の NGSI の相互作用に焦点を当てる予定ですが、3つのアクターは、最終的にシーケンス図で表示されます。そのすべてが相互作用のある時点で参加するためです。

IoTAgent と Context Broker との間のすべてのやりとりは、標準的な NGSI です。Fiware Orion Context Broker manual を参照してください。

両方のコンポーネント間の相互作用の一般的な目的は、次のとおりです :

  • IoTA に到着するデバイス情報を Context Broker 内の NGSI エンティティにマップします
  • コンテキスト・プロバイダ・メカニズムを介して Context Broker からデバイス・データをリクエストします
  • Context Broker 内のデバイス・エンティティの変更に基づいてデバイスにコマンドを送信します

この相互作用は、3つの異なるシナリオにマッピングすることができます。詳細は後で説明します。

同期インタラクション

このドキュメントでは、"同期インタラクション" (synchronous interaction) という用語が広く使用するため、ここでは具体的な意味を定義します。IoTAgents のドキュメントの範囲内では、"同期シナリオ" には次の定義があります :

同期シナリオは、通信を開始するアクターが、すべての対話シナリオが終了するまで、レスポンスを待って HTTP ソケットを開いたままにし、リクエストを開始したソケットと同じソケットを介して結果を受け取るシナリオです。

データ相互作用ペイロード (NGSI10)

IoTAgents と Context Broker の間には、NGSI10で説明されている queryContext と updateContext の2つの対話しかありません。多くの例は、Fiware Orion Context Broker manual のマニュアルに記載されていますが、このセクションではそれぞれの例をいくつか示しています。

この相互作用には、6種類のペイロードが表示されます :

  • P1 - UpdateContext (リクエスト) - POST /v1/updateContext に対するリクエストのペイロード
  • R1 - UpdateContext (レスポンス) - 成功した POST /v1/updateContext に対する回答
  • P2 - QueryContext (リクエスト) - POST /v1/queryContext に対するリクエストのペイロード
  • R2 - QueryContext (レスポンス) - 成功した POST /v1/queryContext に対する回答
  • E1 - エラー - 常にリクエストに対するレスポンス (queryContext または updateContextの両方)

以降の説明では、すべての相互作用に 2文字の頭字語が付いています。

この2つのコンポーネント間の相互作用には他の種類のペイロードは発行できません。

以下のサブセクションでは、それぞれの例と簡単な説明を示します。詳細は、リンクされた NGSI のドキュメントを参照してください。

P1 - UpdateContext (リクエスト)

このペイロードは更新操作 (POST /v1/updateContext) に関連付けられています。

{
    "contextElements": [
        {
            "type": "Room",
            "isPattern": "false",
            "id": "Room1",
            "attributes": [
                {
                    "name": "temperature",
                    "type": "float",
                    "value": "23"
                },
                {
                    "name": "pressure",
                    "type": "integer",
                    "value": "720"
                }
            ]
        }
    ],
    "updateAction": "APPEND"
}

この例では、ペイロードは次の属性を持つ JSON オブジェクトです :

  • ターゲット・エンティティ id および type 属性を識別するために必要な情報とともに、attributes 属性のターゲット・エンティティで更新されるデータを含む contextElements 属性。この属性は配列なので、1つの updateContext 操作を使用して更新できます

  • 更新の種類を示す updateAction : この属性の値が "APPEND" の場合、存在しない場合は適切なエンティティと属性が作成されます。 値が "UPDATE" の場合、ターゲット・リソースが存在しない場合はエラーがスローされます

R1 - UpdateContext(レスポンス)

{
    "contextResponses": [
        {
            "contextElement": {
                "attributes": [
                    {
                        "name": "temperature",
                        "type": "float",
                        "value": ""
                    },
                    {
                        "name": "pressure",
                        "type": "integer",
                        "value": ""
                    }
                ],
                "id": "Room1",
                "isPattern": "false",
                "type": "Room"
            },
            "statusCode": {
                "code": "200",
                "reasonPhrase": "OK"
            }
        }
    ]
}

この例が示すように、updateContext へのレスポンスは、基本的に、操作が成功 (またはエラーの可能性) したかどうかを示す statusCode 属性とともに、リクエスト・ペイロードの空のコピーです。

アプリケーション・レベルのエラーは、このペイロード内の各エンティティに指定できます。

P2 - QueryContext (リクエスト)

このペイロードは、クエリ操作 (POST /v1/queryContext) に関連付けられています。

{
    "entities": [
        {
            "type": "Room",
            "isPattern": "false",
            "id": "Room1"
        }
    ],
    "attributes": [
        "temperature"
    ]
}

ペイロードは、次の情報を指定します :

  • 情報が取り出されるターゲット・エンティティのリスト
  • 取得されるエンティティの属性のリスト

R2 - QueryContext (レスポンス)

{
    "contextResponses": [
        {
            "contextElement": {
                "attributes": [
                    {
                        "name": "temperature",
                        "type": "float",
                        "value": "23"
                    }
                ],
                "id": "Room1",
                "isPattern": "false",
                "type": "Room"
            },
            "statusCode": {
                "code": "200",
                "reasonPhrase": "OK"
            }
        }
    ]
}

この場合、QueryContext へのレスポンスは、リクエストされたエンティティごとに1つのレスポンスのリストであり、情報が statusCode フィールド内で正常に取り出されたかどうか、および ContextElement 属性内のリクエストされたコンテキスト情報であるかどうかを示します。

アプリケーション・レベルのエラーは、このペイロード内の各エンティティに指定できます。

E1 - エラー

{
    "errorCode": {
        "code": "404",
        "reasonPhrase": "No context element registrations found"
    }
}

この特別なペイロードを使用して、特定のコンテキスト要素には関連付けられておらず、リクエスト全体としての一般的なエラーをリクエストで指定することができます

シナリオ1 : アクティブな属性

General

このシナリオでは、デバイスによってインタラクションが開始されます。デバイスが積極的にデータをプラットフォームに送信します。IoTAgent は、データを受信すると、P1 リクエストを介して Context Broker に送信します。Context Broker はその情報をローカルに格納し、リクエストが成功したことを示す R1 を返します。この対話は、デバイスの観点から 100%同期しています。すべての対話は、同じソケット内の単一の HTTP リクエストとレスポンスを通じて行われます。

このシナリオでは、すべてのデータが Context Broker にローカルに格納されているため、ユーザは Context Broker が提供する標準 NGSI API (サブスクリプションを含む) を使用してクエリできます。このデータ・クエリは、更新プロセスとは完全に分離されており、プロセスが完全に異なる場合、いつでも発生する可能性があります。

シナリオ2 : 遅延属性

General

このシナリオでは、リクエストされる属性は、レジストレーション・プロセス (NGSI9) を通じて IoT Agent によって提供されたものとしてマークされている必要があります。このレジストレーション・プロセスの例は、このドキュメントの実用的なセクションで提供されます。Orion Context Broker は、コンテキスト・プロバイダによって提供されているように登録された属性に関するデータをローカルに格納しないことに言及することは重要です。レジストレーションされた属性に対するすべてのクエリと更新は、コンテキスト・プロバイダにリダイレクトされます。

この相互作用のシナリオは、Context Broker にクエリ・リクエスト P2 を行うユーザによって開始さます (1) 。後で、属性のコンテキスト・プロバイダを検出すると、まったく同じクエリ P2 が IoTAgent に転送されます (2)。IoTA は、デバイスに必要な情報をリクエストします、または、データのコピーを保存する場合は、独自のデータベースから取得します。その情報で、元のContext Broker リクエスト の HTTP レスポンスとして、R2 レスポンス・ペイロードで Context Broker にレスポンスします (3)。この R2 レスポンス・ペイロードは、元のリクエストでユーザがリクエストしたすべての情報を含むペイロードです。Context Broker は、すべての情報を取得すると、元の HTTP リクエスト へのレスポンスとして、したがって、リクエストを開始したの同じ HTTP ソケットへのレスポンスとして、同じ R2 リクエストをユーザに返します (4)。

このシナリオは、ユーザの観点から 100%同期しています。また、Context Broker の観点からも 100%同期しています。

このシナリオは、更新とクエリの両方に使用できます。両方の用途の唯一の違いは、使用する一連のアクションです。更新のための updateContext アクション、したがって、P1 および R1 ペイロードです。クエリのためのqueryContextアクション、したがって P2 および R2 ペイロードです。

シナリオ3:コマンド

General

このシナリオでは、リクエストされる属性は、レジストレーション・プロセス (NGSI9) を通じて IoT Agent によって提供されたものとしてマークされている必要があります。このレジストレーション・プロセスの例は、このドキュメントの実用的なセクションで提供されます。Orion Context Broker は、コンテキスト・プロバイダによって提供されているように登録プロセスされた属性に関するデータをローカルに格納しないことに言及することは重要です。登録プロセスされた属性に対するすべてのクエリと更新は、コンテキスト・プロバイダにリダイレクトされます。

このシナリオは、エンティティの属性セットを使用する際のシナリオとは少し異なります。このシナリオでは、次の 3種類の属性を使用します。

  • 属性は 入力属性 (input attribute)、つまり、コンテキスト・プロバイダに登録された属性 として使用されます。この入力属性は、IoTAgent に発行されたコマンド (ここではシナリオの名前から)で、その値がコマンドの引数のセットであると考えることができます。updateContext 操作のみがこの属性と対話するために使用されます。

  • 他の属性が 結果属性 (result attribute) として使用されます。この属性は、IoTAgent と Context Broker に格納されている、その値から更新されます。この属性には、コマンドの結果が含まれます。この結果は、コマンドが "information retrieval" コマンドの場合は情報、"actuator command の場合はアクションの結果です。通常、この属性の名前は入力属性と同じになり、追加のサフィックス (_info) が付きます。

  • 後で同じ特性を持つ別の属性が、コマンドが正常に終了したかどうか、またはエラーが報告されたかどうかを示すために使用されます。

このシナリオでは、対話はユーザによって開始されます。ユーザは、更新リクエスト P1 を Context Broker に入力属性に送信することによってシナリオを開始します (1)。Context Broker は、この同じペイロードを属性のコンテキスト・プロバイダ (IoTAgent)にリダイレクトします (2)。IoTA は、R1 を発行して即座にそのリクエストに答えます (3)。このレスポンスはクエリに対する最終的な回答ではなく、ステータス・コードとは別の有用なデータを含んでいません。このリクエストに対して 200 コードで答えることは、IoTAgent がコマンドを受け入れたがまだ処理していないことを意味します。IoTA がコマンドを処理すると、情報を更新します。Context Broker は、この同じレスポンスを、対話を開始したユーザに転送し、すべての HTTP 接続を閉じます (4)。シナリオのこの部分は、ユーザの 100%同期ですが、ユーザにクエリされたデータは提供されません。非同期バックグラウンド・プロセスを開始するだけです。

将来のある時点で、IoTAgent はコマンドを処理するために必要なデータを取得します。次に、Context Broker に P1 更新リクエストを送信して、Context Broker との新しい対話を開始します (5)。この P1 ペイロードは、ユーザがリクエストしたすべての情報を含むペイロードです。その情報は結果属性で更新され、このリクエストでは入力属性への参照は行われません。Context Broker は、IoTA に R1 レスポンスを返し、HTTP 相互作用を終了します (6)。

このシナリオでは、すべてのデータが Context Broker にローカルに保存されるため、ユーザは Context Broker が提供する標準 NGSI API を使用してクエリを実行できます。図の (7) および (8) のリクエストを参照してください。このデータ・クエリは、更新プロセスとは完全に分離されており、プロセスが完全に異なる場合、いつでも発生する可能性があります。

シナリオの選択方法

3つの異なるシナリオは、さまざまな状況で使用できます :

  • シナリオ1 : このシナリオは、デバイスによって積極的に開始された対話を目的としています
  • シナリオ2 : ユーザが開始した、HTTP タイムアウトの時間内に同期的に実行するのに十分速い対話用に設計されています
  • シナリオ 3 : ユーザが開始した相互作用が遅すぎて同期的に実行できないように設計されています

練習

概要

以下のセクションでは、各シナリオで見つけられるすべてのインタラクションの一連の例を示します。

初期リクエストは完全な Curl コマンドとして表示されます。これは例を再現するために使用できます)。

Context Broker からのリダイレクトは、HTTP リクエストとして表示されます。TCP ソケット経由で送信されるリクエスト全体が表示されます。

レスポンスには、ステータス・コードとレスポンス・ペイロードだけが表示されます。

インタラクションを再現する前に、それぞれのシナリオがどのように機能するのかを理解してください。セオリーのセクションを参照してください。

このドキュメントでは、IP アドレスとパスワードが隠されています。あなた自身の秘密のパスワードで置き換えてください。

この例の再現を助けるために、このドキュメント沿った、postman collection があります。ここ にあります。

トークンの取得

このシナリオでは、IoTAgent が Steelskin PEP によって保護された Orion Context Broker に接続されているため、Context Broker に対するすべてのリクエストを認証する必要があります。

Keystone Identity Manager からトークンを取得するには、次のリクエストを使用できます :

curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -d '{
    "auth": {
        "identity": {
            "methods": [
                "password"
            ],
            "password": {
                "user": {
                    "domain": {
                        "name": "workshop"
                    },
                    "name": "adminiota2ngsi",
                    "password": "<password-for-user>"
                }
            }
        }
    }

}' "http://<platform-ip>:5001/v3/auth/tokens"

Keystone は、次の内容 (201 Created) で返信します :

{
  "token": {
    "issued_at": "2016-10-10T07:32:40.160439Z",
    "extras": {
      "password_creation_time": "2016-10-07T13:28:48Z",
      "password_expiration_time": "2017-10-07T13:28:48Z"
    },
    "methods": [
      "password"
    ],
    "expires_at": "2016-10-10T08:32:40.160408Z",
    "user": {
      "domain": {
        "id": "<domain-id>",
        "name": "workshop"
      },
      "id": "<user-id>",
      "name": "adminiota2ngsi"
    }
  }
}

承認ヘッダで使用する必要があるユーザ・トークンは、X-Subject-Token のヘッダセクションに返されます。この値は、例で見られるように、Context Broker に対して行われたすべてのリクエストに対して X-Auth-Token ヘッダーに追加する必要があります。

シナリオ1 : アクティブな属性 (ハッピー・パス)

このシナリオでは、デバイスが積極的にデータを IoT Agent に送信し、そのデータを Context Broker に送信されるNGSI リクエストに変換します。このリクエストは次の形式 (P1) を持ちます :

curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H "Fiware-Service: workshop" \
    -H "Fiware-ServicePath:  /iota2ngsi " -H "X-Auth-Token: <Token>" -d '{
    "contextElements": [
        {
            "type": "device",
            "isPattern": "false",
            "id": "Dev0001",
            "attributes": [
                {
                    "name": "temperature",
                    "type": "number",
                    "value": "54"
                }
            ]
        }
    ],
    "updateAction": "APPEND"
} ' "https://<platform-ip>:10027/v1/updateContext"

リクエストが正しい場合、Context Broker は次の R1 レスポンス (200 OK) で返信します :

{
  "contextResponses": [
    {
      "contextElement": {
        "type": "device",
        "isPattern": "false",
        "id": "Dev0001",
        "attributes": [
          {
            "name": "temperature",
            "type": "number",
            "value": ""
          }
        ]
      },
      "statusCode": {
        "code": "200",
        "reasonPhrase": "OK"
      }
    }
  ]
}

これにより、その属性 temperature が Context Broker にローカルに格納され、その値がクエリできることが確認されます。

ユーザはこの値をクエリしたいときはいつでも、データを検索するために NGSI メカニズムのいずれかを使用できます。たとえば、次のような標準の queryContext リクエストを使用できます (P2) :

curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H "Fiware-Service: workshop" \
  -H "Fiware-ServicePath:  /iota2ngsi " -H "X-Auth-Token: <token>" -d '{
    "entities": [
        {
            "isPattern": "false",
            "id": "Dev0001",
            "type": "device"
        }
    ],
    "attributes": [
        "temperature"
    ]
}' "https://<platform-ip>:10027/v1/queryContext"

Context Broker は、更新されたデータ値を R2 形式 (200 OK) で返信します :

{
  "contextResponses": [
    {
      "contextElement": {
        "type": "device",
        "isPattern": "false",
        "id": "Dev0001",
        "attributes": [
          {
            "name": "temperature",
            "type": "number",
            "value": "54"
          }
        ]
      },
      "statusCode": {
        "code": "200",
        "reasonPhrase": "OK"
      }
    }
  ]
}

シナリオ1 : アクティブな属性 (エラー)

このシナリオでは、2種類のエラーが発生することがあります。情報の更新中にエラーが発生すると、Context Broker は次のようなペイロードを再生します :

{
  "contextResponses": [
    {
      "contextElement": {
        "type": "device",
        "isPattern": "false",
        "id": "Dev0001",
        "attributes": [
          {
            "name": "UnexistentAttribute",
            "type": "number",
            "value": ""
          }
        ]
      },
      "statusCode": {
        "code": "472",
        "reasonPhrase": "request parameter is invalid/not allowed",
        "details": "action: UPDATE - entity: [Dev0001, device] - offending attribute: UnexistentAttribute"
      }
    }
  ]
}

標準の NGSI のように、Context Broker が 200 OK のステータス・コードで返信し、HTTP コードがトランスポート・プロトコル・レベルのエラーを参照し、ペイロード内のステータス・コードがアプリケーション・レベルのプロトコルに関する情報を返すことに言及することは重要です。

この例は、APPEND の代わりに UPDATE を使用するために、存在しない属性を更新する際のエラーを示しています。

次のエラー。ペイロードは、標準 NGSI でも有効です :

{
  "errorCode": {
    "code": "404",
    "reasonPhrase": "No context element found"
  }
}

さまざまな種類のエラーが異なる形式で情報を返す可能性があるため、NGSI 実装は両方の存在をチェックする必要があります。

シナリオ 2: 遅延属性 (ハッピー・パス)

シナリオ2は、Context Broker のコンテキスト・プロバイダのメカニズムに依存します。このシナリオが機能するには、IoTAgent は各デバイスの遅延属性を次のようなリクエストで登録する必要があります :

curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H "Fiware-service: workshop" \
  -H "fiware-servicepath:  /iota2ngsi " -H "x-auth-token: <token>" -d '{
    "contextRegistrations": [
        {
            "entities": [
                {
                    "type": "device",
                    "isPattern": "false",
                    "id": "Dev0001"
                }
            ],
            "attributes": [
                {
                    "name": "config-value",
                    "type": "parameter",
                    "isDomain": "false"
                }
            ],
            "providingApplication": "http://<target-host>:1026"
        }
    ],
    "duration": "P1M"
}
' "https://<platform-ip>:10027/v1/registry/registerContext"

すべてが OK になったら、Context Broker は次のペイロードを返します :

{
  "duration": "P1M",
  "registrationId": "57fb4642fdc8301538a65a04"
}

この ID を使用して、今後、レジストレーションを更新することができます。

属性のレジストレーションは、デバイスの有効期間内に1回実行されます。

このシナリオでは、ユーザがデバイスから特定のデータを積極的にリクエストします。このシナリオは、ユーザからContext Broker へのリクエストから始まります (P2) :

curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H "Fiware-Service: workshop" \
  -H "Fiware-ServicePath:  /iota2ngsi " -H "X-Auth-Token: <token>" -d '{
    "entities": [
        {
            "isPattern": "false",
            "id": "Dev0001",
            "type": "device"
        }
    ],
    "attributes": [
        "config-value"
    ]
}' "https://<platform-ip>:10027/v1/queryContext"

Context Broker はこのリクエストを受信し、コンテキスト・プロバイダ (IoT Agent)がサービスを提供できることを検出するため、まったく同じリクエストを IoT Agent にリダイレクトします。次の抜粋は、リダイレクト・データを含む完全な HTTP フレームを示しています :

POST /v1/queryContext HTTP/1.1
Host: <target-host>:1026
fiware-service: workshop
Fiware-ServicePath: /iota2ngsi
X-Auth-Token: <token>
Accept: application/json
Content-length: 157
Content-type: application/json; charset=utf-8
Fiware-Correlator: f77eea0a-8ebe-11e6-bab7-fa163e78b904

{
  "entities" : [
    {
      "type" : "device",
      "isPattern" : "false",
      "id" : "Dev0001"
    }
  ],
  "attributes" : [
    "config-value"
  ]
}

リクエストされたデータが IoT Agent で利用可能な場合、R2 のレスポンス (200 OK) でレスポンスします :

{
  "contextResponses": [
    {
      "contextElement": {
        "type": "device",
        "isPattern": "false",
        "id": "Dev0001",
        "attributes": [
          {
            "name": "config-value",
            "type": "number",
            "value": "94"
          }
        ]
      },
      "statusCode": {
        "code": "200",
        "reasonPhrase": "OK"
      }
    }
  ]
}

Context Broker が IoTAgent レスポンスを受け取ると、ユーザは元のリクエスト (200 OK) に使用したのと同じソケット内のユーザにそれを転送します :

{
  "contextResponses": [
    {
      "contextElement": {
        "type": "device",
        "isPattern": "false",
        "id": "Dev0001",
        "attributes": [
          {
            "name": "config-value",
            "type": "number",
            "value": "94"
          }
        ]
      },
      "statusCode": {
        "code": "200",
        "reasonPhrase": "OK"
      }
    }
  ]
}

シナリオ2 : 遅延属性 (エラー)

完全に同期している場合、シナリオ2のエラーは、シナリオ1と同じパターンに従います。IoTAgent がエラーを返す場合、そのエラーは、上で定義したシナリオ1のエラーで説明した NGSI ペイロードに従わなければなりません。

シナリオ3 : コマンド (ハッピー・パス)

コンテキスト・プロバイダの登録

シナリオ3は、Context Broker のコンテキスト・プロバイダのメカニズムに依存します。このシナリオが機能するには、IoTAgent は各デバイスのコマンドを次のようなリクエストで登録する必要があります :

curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H "Fiware-service: workshop" \
  -H "fiware-servicepath:  /iota2ngsi " -H "x-auth-token: <token>" -d '{
    "contextRegistrations": [
        {
            "entities": [
                {
                    "type": "device",
                    "isPattern": "false",
                    "id": "Dev0001"
                }
            ],
            "attributes": [
                {
                    "name": "switch",
                    "type": "command",
                    "isDomain": "false"
                }
            ],
            "providingApplication": "http://<target-host>:1026/v1"
        }
    ],
    "duration": "P1M"
}
' "https://<platform-ip>:10027/v1/registry/registerContext"

すべてが OK になったら、Context Broker は次のペイロードを返します :

{
  "duration": "P1M",
  "registrationId": "41adf79dc5a0bba830a6f3824"
}

この ID を使用して、今後、レジストレーションを更新することができます。

コマンドのレジストレーションは、デバイスの有効期間内に1回実行されます。

コマンド実行

シナリオ3は、ユーザからContext Brokerへのコマンドのリクエストで始まります (P1) :

curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H "Fiware-Service: workshop" \
  -H "Fiware-ServicePath:  /iota2ngsi " -H "X-Auth-Token: <token>" -d '{
    "contextElements": [
        {
            "type": "device",
            "isPattern": "false",
            "id": "Dev0001",
            "attributes": [
                {
                    "name": "switch",
                    "type": "command",
                    "value": "54, 12"
                }
            ]
        }
    ],
    "updateAction": "UPDATE"
} ' "https://<platform-ip>:10027/v1/updateContext"

Context Broker はこのコマンドを受信し、コンテキスト・プロバイダ (IoT Agent)がサービスを提供できることを検出するため、まったく同じリクエストを IoT Agent にリダイレクトします。次の抜粋は、リダイレクト・データを含む完全な HTTP フレームを示しています :

POST /v1/updateContext HTTP/1.1
Host: <target-host>:1026
fiware-service: workshop
Fiware-ServicePath: /iota2ngsi
X-Auth-Token: <token>
Accept: application/json
Content-length: 290
Content-type: application/json; charset=utf-8
Fiware-Correlator: 9cae9496-8ec7-11e6-80fc-fa163e734aab

{
  "contextElements" : [
    {
      "type" : "device",
      "isPattern" : "false",
      "id" : "Dev0001",
      "attributes" : [
        {
          "name" : "switch",
          "type" : "command",
          "value" : "54, 12"
        }
      ]
    }
  ],
  "updateAction" : "UPDATE"
}

IoT Agent は、選択された属性がコマンドであることを検出し、次のペイロード (200 OK) で Context Broker にレスポンスします :

{
  "contextResponses": [
    {
      "contextElement": {
        "type": "device",
        "isPattern": "false",
        "id": "Dev0001",
        "attributes": [
          {
            "name": "switch",
            "type": "command",
            "value": ""
          }
        ]
      },
      "statusCode": {
        "code": "200",
        "reasonPhrase": "OK"
      }
    }
  ]
}

このレスポンスは、IoT Agent がコマンドを正常に受信したことを示し、リクエストされた情報またはコマンドの実行に関する情報を提供しません。

Context Broker は、ユーザに同じレスポンスを転送して、元のリクエストにレスポンスします (200 OK) :

{
  "contextResponses": [
    {
      "contextElement": {
        "type": "device",
        "isPattern": "false",
        "id": "Dev0001",
        "attributes": [
          {
            "name": "switch",
            "type": "command",
            "value": ""
          }
        ]
      },
      "statusCode": {
        "code": "200",
        "reasonPhrase": "OK"
      }
    }
  ]
}

この時点で、コマンドは IoTAgent に発行されており、ユーザはリクエストの結果が何であるかまだ分かりません。

結果報告

IoT Agent がコマンドを実行するか、デバイスから情報を取得すると、updateContext を使用して Context Broker に結果を報告します (P1) :

curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H "Fiware-Service: workshop" \
  -H "Fiware-ServicePath:  /iota2ngsi " -H "X-Auth-Token: <token>" -d '{
    "contextElements": [
        {
            "type": "device",
            "isPattern": "false",
            "id": "Dev0001",
            "attributes": [
                {
                    "name": "switch_info",
                    "type": "command_info",
                    "value": "Switched successfully!"
                },
                {
                    "name": "switch_status",
                    "type": "command_status",
                    "value": "OK"
                }
            ]
        }
    ],
    "updateAction": "APPEND"
} ' "https://<platform-ip>:10027/v1/updateContext"

このアップデートでは、元のコマンド属性は変更されませんが、IoT Agent では提供されない2つの補助属性が変更されます。通常、これらの属性はコマンドと同じ名前で、サフィックスが追加されています。

Context Broker は、R1 ペイロード (200 OK) を使用して IoT Agent にレスポンスします :

{
  "contextResponses": [
    {
      "contextElement": {
        "type": "device",
        "isPattern": "false",
        "id": "Dev0001",
        "attributes": [
          {
            "name": "switch_info",
            "type": "command_info",
            "value": ""
          },
          {
            "name": "switch_status",
            "type": "command_status",
            "value": ""
          }
        ]
      },
      "statusCode": {
        "code": "200",
        "reasonPhrase": "OK"
      }
    }
  ]
}

この操作は、取得した値を Context Broker にローカルに格納するため、標準の NGSI メカニズムで取得できます。

結果のクエリ

ユーザは、コマンドのステータスと結果を知りたいときはいつでも、たとえば、標準の queryContext リクエストを使用して、Context Broker 内の情報を問い合わせることができます (P2) :

curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H "Fiware-Service: workshop" \
  -H "Fiware-ServicePath:  /iota2ngsi " -H "X-Auth-Token: <token>" -d '{
    "entities": [
        {
            "isPattern": "false",
            "id": "Dev0001",
            "type": "device"
        }
    ],
    "attributes": [
        "switch_info",
        "switch_status"
    ]
}' "https://<platform-ip>:10027/v1/queryContext"

Context Broker は、必要なすべてのデータを R2 形式 (200 OK) でレスポンスします :

{
  "contextResponses": [
    {
      "contextElement": {
        "type": "device",
        "isPattern": "false",
        "id": "Dev0001",
        "attributes": [
          {
            "name": "switch_info",
            "type": "command_info",
            "value": "Switched successfully!"
          },
          {
            "name": "switch_status",
            "type": "command_status",
            "value": "OK"
          }
        ]
      },
      "statusCode": {
        "code": "200",
        "reasonPhrase": "OK"
      }
    }
  ]
}

シナリオ3 : コマンド(エラー)

シナリオ3では、主なやり取りのうち、非同期的にエラーが発生する可能性があります。IoTAgent が基になるコマンドを実行しているエラーを検出すると (つまり、デバイスに接続中のエラーまたはデバイス自体のエラー)、エラー情報は、結果報告に使用されたものと同じメカニズムで更新できます。例えば :

curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H "Fiware-Service: workshop" \
  -H "Fiware-ServicePath:  /iota2ngsi " -H "X-Auth-Token: <token>" -d '{
    "contextElements": [
        {
            "type": "device",
            "isPattern": "false",
            "id": "Dev0001",
            "attributes": [
                {
                    "name": "switch_info",
                    "type": "command_info",
                    "value": "The switch could not be switched due to the following error: switch blocked"
                },
                {
                    "name": "switch_status",
                    "type": "command_status",
                    "value": "ERROR"
                }
            ]
        }
    ],
    "updateAction": "APPEND"
} ' "https://<platform-ip>:10027/v1/updateContext"

この場合、Context Broker は次のレスポンス (200 OK) でレスポンスします :

{
  "contextResponses": [
    {
      "contextElement": {
        "type": "device",
        "isPattern": "false",
        "id": "Dev0001",
        "attributes": [
          {
            "name": "switch_info",
            "type": "command_info",
            "value": ""
          },
          {
            "name": "switch_status",
            "type": "command_status",
            "value": ""
          }
        ]
      },
      "statusCode": {
        "code": "200",
        "reasonPhrase": "OK"
      }
    }
  ]
}

ユーザは、次回、Context Broker にコマンドに関する情報をクエリするときにエラーを確認します。