ステップ・バイ・ステップ・ガイド

Index

イントロダクション

このガイドでは、デバイスを外部の NGSI ブローカ (別名 Context Broker) に接続するための MQTT-JSON IoT Agentのデプロイと設定方法を段階的に示します。

MQTT-JSON IoT エージェントは、NGSI ブローカ、または NGSI プロトコルを使用する他のものと MQTT プロトコルを使用してデバイスを通信するためのゲートウェイとして機能します。通信は、一連の単一方向 MQTT トピックに基づいています、つまり、各トピックは、デバイス情報の公開またはエンティティ更新のサブスクライブに使用されますが、両方ではありません。すべてのトピックには、同じプレフィックスが付きます :

/<apiKey>/<deviceId>/topicSpecificPart

ここで API Key は、デバイスを論理的におよびセキュリティ上の問題をグループ化するために使用される英数字の文字列であり、deviceId はデバイスを一意に識別する ID です。API Key は、IoT エージェントのインスタンスに対して、または特定のデバイスグループに対してグローバルに設定できます。次のセクションで説明します。

プロトコルの詳細な仕様はここにあります。

このガイドでは、個々のデバイスがプロビジョニングされている場合と、新しい API Key を持つデバイスのグループが最初にプロビジョニングされている場合の両方で、IoT エージェントのセットアップから測定レポートへのエージェントの使用までの最も一般的なシナリオについて、ステップ・バイ・ステップの例を示します。ガイドを開始する前に、次のセクションのすべての要件を満たしていることを確認してください。

チュートリアルを始める前に、デプロイしようとしているサービスに関するいくつかの情報が必要です。Smart Home アプリケーションをシミュレートして、次のデータを使用します :

  • Service: myhome
  • Subservice: /environment
  • DevId: sensor01, sensor02 and actuator01

前提条件

このステップ・バイ・ステップガイドでは、すべてのソフトウェアを Red Hat 6.5 Linux インストールで単一のマシンにインストールすることを前提としています。したがって、本番用の適切なアーキテクチャーではありませんが、MQTT IoT エージェントをテストするための開発マシンとして機能するはずです。すべてのコマンドは、curl や mosquitto-pub コマンドでも、同じマシンから実行されることを意図していますが、それらを外部マシンから実行するように変更するのは簡単な作業です。

このチュートリアルで選択した MQTT Broker は Mosquitto でしたが、他の標準 MQTT ブローカ に置き換えることもできました。このガイドでは、Mosquitto コマンドツールを使用してインストールをテストし、シミュレートされたデバイスとコンテキスト・ブローカ間で交換された情報を表示します。

以下のリストは、前提条件となるソフトウェアとバージョンを示しています :

  • Orion Context Broker (v0.26)
  • Node.js (v0.12.0)
  • Mosquitto (v1.4.7) (out-of-the-box setup)
  • Curl (v7.19.7)
  • Git (v1.7.1)

これらは、このチュートリアルを書く際に使用されたバージョンですが、ここに示したものより新しいバージョンも同様に動作します。以前のバージョンでも動作する可能性がありますが、そうでない可能性もあります。

読みやすくするために、すべてのコマンドは root として実行されます。他のユーザを使用するには、適切な権限を与えて、通常、sudo を使用します。RPM パッケージからインストールするとエージェントの特別なユーザが作成されますが、このチュートリアルでは使用しません。

デフォルトの API Key を使用して単一のデバイスをプロビジョニング

IoT Agent のインストール

IoT Agent をインストールする方法はいくつかあります。このチュートリアルでは、リポジトリからエージェントの最新バージョンを複製します。異なる設定については、メインの README.md ファイルのインストール・ガイドを参照してください。

IoT Agent を '/opt' リポジトリにインストールします。これを行うには、フォルダに移動して、次のコマンドを使用してリポジトリをクローンします :

cd /opt
git clone https://github.com/telefonicaid/iotagent-json.git

リポジトリが複製され、新しいディレクトリを入力し、依存関係をインストールするには、次のコマンドを実行します :

cd iotagent-json
npm install

次に、バックグラウンドでエージェントを実行して実行します :

nohup bin/iotagent-json &> /var/log/iotAgent&

エージェントは、ノースバウンド・ポートをリッスンする必要があります。デフォルトは 4041 です。それを netstat コマンドでチェックしてください :

netstat -ntpl | grep 4041

次のような出力が表示されます :

tcp        0      0 0.0.0.0:4041                0.0.0.0:*                   LISTEN      18388/node 

すべてが動作していることを確認する簡単な方法は、ノースバウン API からバージョンを取得することです :

curl http://localhost:4041/iot/about

結果は、使用中の MQTT-JSON IoT Agent バージョンと、IIoT Agent ライブラリのバージョンを示す JSON ドキュメントになります :

{
  "libVersion":"0.9.5",
  "port":4041,
  "baseRoot":"/",
  "version":"0.1.5"
}

また、nohup コマンドで作成した /var/log/iotAgent ファイルのログを確認することもできます。

IoTAgent の設定

IoT Agentgent のすべての設定は、1つのファイル config.js を変更することで行うことができます。デフォルト値はこのチュートリアルのニーズを満たす必要があります。

これらの値の詳細については、IoT Agentgent-node-lib configuration documentation を参照してください。

このチュートリアルの後に変更したい設定値がありますが、これは logLevel です。インストラクションに従った問題がある場合、または IoT Agent 内部で何が起こっているのかをもっと知りたい場合は、その値を DEBUG に設定してください。

また、deviceRegistry の設定タイプが memory にセットされていることにも注意してください。つまり、IoT Agentgent が再起動すると、Device Registry のすべての内容がメモリから消去されます。これはテスト環境で使用するためのもので、エージェントを再起動するとすべてのデバイスを再度プロビジョニングする必要があります。永続化レジストリについては、IoT Agent を MongoDB インスタンスに接続する方法のドキュメントを参照してください。

コマンドライン・クライアントの使用

IoT Agent には、インストールの初期テストに使用できるコマンドライン・クライアントが付属しています。このクライアントは、測定、デバイス、設定のプロビジョニング要求およびコンテキスト・ブローカへの NGSI クエリを仕用して MQTT リクエストをシミュレートするコマンドを提供し、結果のテストに使用できます。

コマンドライン・クライアントを起動するには、次のように入力します :

bin/iotaJsonTester.js

コマンドの完全なリストの簡単な説明は help を入力すること確認できます。

Mosquitto には、IoT Agent の MQTT サウス・バウンドをテストするために使用できる2つのコマンドライン・ユーティリティも付属しています。

Mosquitto-sub は、特定のトピックをサブスクライブして、コンソール出力でトピックに送信されたすべての情報を表示するために使用できます。トピックをサブスクライブするには、以下を使用します :

mosquitto_sub -h <mosquittoIp> -t /<apiKey>/<devId>/attrs

ここで、 は、Mosquitto ブローカのインスタンスがリッスンしているです。そして、使用しているデバイスによって異なります。localhost で作業している場合は、-h パラメータを省略できます。

Mosquitto-pub は、トピックに情報を送信するために使用できます。これは典型的な実行例です :

mosquitto_pub -h <mosquittoIp> -t /<apiKey>/<devId>/attrs -m '{"L":4,"T": "31.5","H":30}'

異なるウィンドウで両方のコマンドを実行すると、後者のコマンドを実行すると、前のコマンドに現れる文字列 {"L":4,"T": "31.5","H":30} が表示されます。

このチュートリアルでは、主に mosquitto クライアントと curl コマンドを使用して、ノーズバウンドとサウスバウンドの両方の APIs がどのように機能するかを詳しく説明します。コマンドが必要なときはいつでも、実行される正確なコマンドが与えられます。

デバイスのプロビジョニング

IoT Agent の使用を開始するには、新しいデバイスを準備する必要があります。curl コマンドを使用して作成します。次のコマンドを実行します :

curl -X POST -H "Fiware-Service: myHome" -H "Fiware-ServicePath: /environment" -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d '{ 
    "devices": [ 
        { 
            "device_id": "sensor01", 
            "entity_name": "LivingRoomSensor", 
            "entity_type": "multiSensor", 
            "attributes": [ 
                  { "object_id": "t", "name": "Temperature", "type": "celsius" },
                  { "object_id": "l", "name": "Luminosity", "type": "lumens" }                  
            ]
        }
    ]
}

' 'http://localhost:4041/iot/devices'
このコマンドは、最も単純な種類のデバイスを作成します。これには、温度と輝度の2つのアクティブな属性が宣言されています。

デバイスのための特定の設定を作成していないので、API Key は IoT Agent 用の default key の 1234 です。このデフォルト API Key は、設定ファイルで変更できます。

Sending measures with the device

これで、デバイスからいくつかの測定値をシミュレートできます。デバイスは、DeviceID sensor01 を持ち、使用している API Key はデフォルトの 1234 なので、次のコマンドを使用して、mosquitto コマンドライン・クライアントで測定値を送信できます :

mosquitto_pub -t /1234/sensor01/attrs -m '{"l":4,"t": "31.5"}'

このコマンドは、コンテキスト・ブローカのすべての情報をパブリッシュする必要があります。デバイス・エンティティに対する queryContext オペレーションは、公開された情報を提供します :

curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H "Fiware-Service: myHome" -H "Fiware-ServicePath: /environment" -d '{
    "entities": [
        {
            "isPattern": "false",
            "id": "LivingRoomSensor",
            "type": "multiSensor"
        }
    ]
}' 'http://localhost:1026/v1/queryContext'

結果のレスポンスは次のようになります :

{
  "contextResponses" : [
    {
      "contextElement" : {
        "type" : "multiSensor",
        "isPattern" : "false",
        "id" : "LivingRoomSensor",
        "attributes" : [
          {
            "name" : "Luminosity",
            "type" : "lumens",
            "value" : "4"
          },
          {
            "name" : "Temperature",
            "type" : "celsius",
            "value" : "31.5"
          }
        ]
      },
      "statusCode" : {
        "code" : "200",
        "reasonPhrase" : "OK"
      }
    }
  ]
}

コンテキスト・ブローカからの設定パラメータの取得

MQTT-JSON IoT Agent は、デバイス設定のために、デバイス・エンティティから情報を取り出す特別なメカニズムを提供します。このメカニズムは、/configuration/commands/configuration/values のサフィックスで、2 つの特別なトピックに基づいています。

この機能性をテストするために、最初にデバイスを表す Context Broker のエンティティにいくつかの設定属性を追加します。次の NGSI リクエストを伴う sleepTime 属性を追加します :

curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H "Fiware-Service: myHome" -H "Fiware-ServicePath: /environment" -H "Cache-Control: no-cache" -d '{
"value" : "300"
}' 'http://localhost:1026/v1/contextEntities/LivingRoomSensor/attributes/sleepTime'

IoT Agent に設定値が要求されると、Context Broker にその値を問い合わせます。それらを収集すると、'/configuration/values' のサフィックスを持つトピックのデバイスに送信します。シミュレートされたデバイスでこのオペレーションを確認するには、次の行を実行します :

mosquitto_sub -t /1234/sensor01/configuration/values

次の手順を実行している間は、別のウィンドウでこのコマンドを実行してください。

次に、IoT Agent に、次のような MQTT リクエストを送信する属性値を尋ねることができます :

mosquitto_pub -t /1234/sensor01/configuration/commands -m '{ "type": "configuration", "fields": [ "sleepTime" ] }'

ここでサブスクリプション・ウィンドウに戻ると、sleepTime コマンドの値を確認できるはずです :

{"sleepTime":"300","dt":"20160209T111442Z"}

デバイスが要求したすべての情報に加えて、IoT Agentgent はレスポンスの dt フィールドにサーバ時間を報告します。

設定を使用して複数のデバイスをプロビジョニング

同様の特性を持つデバイスのグループをプロビジョニングする場合は、共通の設定を作成できます。この設定プロビジョンは、グループごとに特定の API Key を設定することによって、サービス間でデバイスメッセージを分離するために使用できます。これは、特定のデバイスグループのアクセスを保護するために使用できます。その方法の例は、Mosquitto MQTT Broker の最後のセクションに示されています。

設定のプロビジョニング

最初に、導入セクションで定義したデータを使用して新しい構成をプロビジョニングします。これを行うために、次のコマンドを発行します :

curl -X POST -H "Fiware-Service: myHome" -H "Fiware-ServicePath: /environment" -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d '{ 
    "services": [ 
      {
          "resource": "",
          "apikey": "AAFF9977",
          "type": "potSensor"
      }
    ]
}

' 'http://localhost:4041/iot/services'

これにより、そのサービス、サブサービスおよびタイプにプロビジョニングされたデバイスは、提供された API Key を MQTT トピックの API Key プレフィックスとして使用します。ご覧のように、resource フィールドは空白のままです。このIoT Agent はこのフィールドを使用しませんが、API では必須の属性なので、常に空の文字列で送信する必要があります。

デバイスのプロビジョニング

自動デバイスプロビジョニングをサポートする IoT Agents の場合、構成をプロビジョニングするだけで、その構成を使用するデバイスを使用することができます。そうでないものは、deviceID を Device Registry に保存するために、それぞれの特定のデバイスをプロビジョニングする必要があります。デバイスの提供は、単一のデバイスのものと非常に似ています :

curl -X POST -H "Fiware-Service: myHome" -H "Fiware-ServicePath: /environment" -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d '{ 
    "devices": [ 
        { 
            "device_id": "sensor02", 
            "entity_name": "RosesPot", 
            "entity_type": "potSensor",
            "attributes": [
              {
                "name": "humidity",
                "type": "degrees"
              },
              {
                "name": "happiness",
                "type": "subjective"
              }
            ]
        }
    ]
}

' 'http://localhost:4041/iot/devices'

測定値を送信

これで、単一デバイスのプロビジョン場合のように測定値をシミュレートできます。新しいシミュレートされた測定値を送信するには、次のコマンドを使用します :

mosquitto_pub -t /AAFF9977/sensor02/attrs -m '{"humidity": 76,"happiness": "Not bad"}'

この場合、 API Key はデフォルトではなく、Configuration API で定義したものです。

Context Broker をもう一度呼び出して、すべてが OK になったことを確認できます :

curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H "Fiware-Service: myHome" -H "Fiware-ServicePath: /environment" -d '{
    "entities": [
        {
            "isPattern": "false",
            "id": "RosesPot",
            "type": "potSensor"
        }
    ]
}' 'http://localhost:1026/v1/queryContext'

次のようなレスポンスが返ります :

{
  "contextResponses" : [
    {
      "contextElement" : {
        "type" : "potSensor",
        "isPattern" : "false",
        "id" : "RosesPot",
        "attributes" : [
          {
            "name" : "happiness",
            "type" : "subjective",
            "value" : "Not bad"
          },
          {
            "name" : "humidity",
            "type" : "degrees",
            "value" : "76"
          }
        ]
      },
      "statusCode" : {
        "code" : "200",
        "reasonPhrase" : "OK"
      }
    }
  ]
}

これは、測定値と共に送信された情報が Context Broker に適切に書き込まれたことを示しています。

ACL を使用してプロビジョニング・アクセスを保護

概要

特別な API Keys を使用することにより、IoT Agentgent の管理者は、さまざまな認可メカニズムを使用してグループ間のアクセスを分離することで、デバイスのグループごとに異なる MQTT-Broker レベルの権限を設定できます。

単純な設定の Mosquitto のセットアップでは、あるデバイス (実際には MQTT クライアント) は、他のデバイスを偽装する情報を送信したり、エンティティ内の情報を読み取ったり、AP Key および deviceId を知ることができます。この問題を回避するために、設定に特別な権限を与えるACLと、デバイスと密かに共有する必要のあるグループのデバイスの資格情報を作成します。シンプルにするために、グループのすべてのデバイスに同じユーザ資格とパスワード資格情報を使用します。他の認証方法は証明書として使用でき、他のオプションについては Mosquitto のドキュメントを参照してください。

IoT Agent はデフォルトでは匿名の他の MQTT クライアントであるため、IoT Agent のアクセスの場合、デバイス偽装と同じ問題が発生する可能性があります。IoT Agent の対話を保護するために、別のユーザを作成します。

設定

ユーザを作成するために、mosquitto が提供するパスワードツールを使用します。次のコマンドを実行します :

touch /etc/mosquitto/pwfile
mosquitto_passwd -b /etc/mosquitto/pwfile iota iota
mosquitto_passwd -b /etc/mosquitto/pwfile potteduser pottedpass

これにより、IoT Agent/IoT Agent と、potteduser/pottedpass という2つの資格情報(ログイン/パスワード)が作成されます。

ACL ファイルを使用すると、異なるトピックの権限を与えることができます。作成するには、次の内容の新しい /etc/mosquitto/aclfile ファイルを作成します :

topic read $SYS/#

topic write /1234/+/attrs
topic write /1234/+/attrs/#
topic write /1234/+/configuration/commands
topic read /1234/+/configuration/values

user iota
topic /#

user potteduser
topic write /AAFF9977/+/attrs
topic write /AAFF9977/+/attrs/#
topic write /AAFF9977/+/configuration/commands
topic read /AAFF9977/+/configuration/values

pattern write $SYS/broker/connection/%c/state

このファイルには3つのセクションがあります :

  • 最初のセクションでは、デフォルトの API Key (この場合 1234) のトピックのセットが定義されています。これらのトピックには、そのトピックで行われているアクションデバイスに応じて、書き込みまたは読み取りが設定されています。定義されたもの以外のアクションや、読まれたトピックへのパブリッシュ、または逆の動作に対するアクセスは禁止されています。これにより、デバイスが IoT Agent を偽装することができないことが保証されますが、1つのデバイスが他のデバイスを偽装することは禁じられていません。このアクセスは匿名です

  • 認証された IoT Agent ユーザは、ブローカの所有者であると考えられるすべてのものにアクセスできます。管理者だけがこのユーザにアクセスできる必要があります

  • potteduser アカウントの場合、アクセス許可は匿名のデバイスのアクセス許可に似ていますが、プレフィックスと異なる API Key を使用します。これにより、他のグループから来て、有効な資格情報を持っていないと思われるデバイスが、そのグループのデバイスを偽装したり、グループデバイスから送信された情報に登録したりすることはありません

テストを再開する前にさらに2つの変更が必要です。まず、IoT Agent Mosquitto の資格情報を IoT Agent 設定に追加して、 MQTT Broker のトピックに完全にアクセスできるようにする必要があります。これを行うには、/opt/IoT Agentjson/config.js ファイルを編集し、config.mqtt セクションを次のように変更します :

config.mqtt = {
    host: 'localhost',
    port: 1883,
    defaultKey: '1234',
    username: 'iota',
    password: 'iota'
};

最後に実行するアクションは、設定を aclfile, pwfile ファイルに追加するため、 /etc/mosquitto/mosquitto.conf を編集することです。完成した設定は次のようになります :

pid_file /var/run/mosquitto.pid

persistence true
persistence_location /var/lib/mosquitto/

log_dest file /var/log/mosquitto/mosquitto.log

#acl_file /etc/mosquitto/aclfile
password_file /etc/mosquitto/pwfile
include_dir /etc/mosquitto/conf.d

すべての変更が完了したら、mosquitto を再起動します :

service mosquitto restart

IoT Agent を再実行します。ps また netstat で PID をチェックして、それを終了できます。

テスト

設定とデバイスのプロビジョニング

ACL ファイルをテストするには、前の章で行ったように設定とデバイスをプロビジョニングしますが、別のデバイスとデータを使用して次の手順を実行します :

  • Name: DaisyPot
  • DevId: sensor03

ACL で宣言したのとまったく同じ API Key を使用して設定をプロビジョニングすることが重要です。

デバイスのプロビジョニングのリクエストは、次のようになります :

curl -X POST -H "Fiware-Service: myHome" -H "Fiware-ServicePath: /environment" -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d '{ 
    "devices": [ 
        { 
            "device_id": "sensor03", 
            "entity_name": "DaisyPot", 
            "entity_type": "potSensor",
            "attributes": [
              {
                "name": "humidity",
                "type": "degrees"
              },
              {
                "name": "happiness",
                "type": "subjective"
              }
            ]
        }
    ]
}

' 'http://localhost:4041/iot/devices'

測定値を送信

今度は、最初のケースで使用したのと同じコマンドで新しい測定値をプロビジョニングすることができます :

mosquitto_pub -t /AAFF9977/sensor03/attrs -m '{"humidity": 76,"happiness": "Not bad"}'

Context Broker に変更が進んだかどうかを確認するために、queryContext を使用すると、それらの測定値が無視されていることがわかります :

curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H "Fiware-Service: myHome" -H "Fiware-ServicePath: /environment" -d '{
    "entities": [
        {
            "isPattern": "false",
            "id": "DaisyPot",
            "type": "potSensor"
        }
    ]
}' 'http://localhost:1026/v1/queryContext'

IoT Agent ログを確認すると、リクエストが完全に無視されたことがわかります。 問題は、ユーザ potteduser のみが新しいメッセージをパブリッシュできるようにした ACL で保護されたトピックで、クライアントが、匿名パブリッシュを作成しようとしたことでした。ユーザ用に生成した認証情報を使用して再試行した場合 :

mosquitto_pub -t /AAFF9977/sensor03/attrs -m '{"humidity": 76,"happiness": "Not bad"}' -u potteduser -P pottedpass

queryContext をもう一度実行すると、更新されたエンティティが取得できます :

{
  "contextResponses" : [
    {
      "contextElement" : {
        "type" : "potSensor",
        "isPattern" : "false",
        "id" : "DaisyPot",
        "attributes" : [
          {
            "name" : "happiness",
            "type" : "subjective",
            "value" : " "
          },
          {
            "name" : "humidity",
            "type" : "degrees",
            "value" : " "
          }
        ]
      },
      "statusCode" : {
        "code" : "200",
        "reasonPhrase" : "OK"
      }
    }
  ]
}