履歴データの公開

このセクションでは、すでにTour Guide Applicationで動作するいくつかのセンサーがあることを前提としています。 そうしていない場合は、前のIoTデータ管理を参照してください。

Orionからのデータを永続化するために、Cygnusコネクタを使用してMySQLデータベースにデータを送信して保存します。

Cygnusの構成

デフォルトの設定では、パスワードとしてmysqlを使用してデフォルトのデータベースとrootユーザを持つMySQLコンテナを使用します。 この構成を変更したい場合は、tourguide configure cygnusコマンドを使用してこれらの資格情報を変更することができます。

$ ./tour-guide configure cygnus --help
Usage: tour-guide configure cygnus [-h | --help] [-u <username> | --mysql-user <username>]
                                   [-p <password> | --mysql-password <password>]

Apply configuration changes for cygnus.

Command options:

  -h  --help                         Show this help.
  -u  --mysql-user <username>        Set the MySQL database user to use.
                                     Default value is 'root'.
  -p  --mysql-password <password>    Set the MySQL database password to use.
                                     Default value is 'mysql'.

つまり、Cygnusで使用されるMySQL資格情報をmyusermypasswordに変更するには、次のコマンドを発行します:

$ ./tour-guide configure cygnus --mysql-user myuser --mysql-password mypassword

これにより、docker-compose.ymlファイルが更新され、Cygnusコンテナの次の変数が設定されます:

- CYGNUS_MYSQL_USER=myuser
- CYGNUS_MYSQL_PASS=mypassword

この変数は、コンテナの起動時に、Cygnusコンテナによって使用され、agent.conf設定ファイルで次のMySQL資格情報を更新します:

cygnus-ngsi.sinks.mysql-sink.mysql_username = myuser
cygnus-ngsi.sinks.mysql-sink.mysql_password = mypassword
Cygnusコンテナのその他の設定オプションの詳細については、Cygnusリポジトリでのイメージの使用を参照してください。より複雑な設定オプションについては、Cygnusの公式ドキュメントを参照してください。

Cygnusコンテナの変更に加えて、MySQLコンテナには次の変数が設定されます:

- MYSQL_USER=myuser
- MYSQL_PASSWORD=mypassword
- MYSQL_DATABASE=tourguide

MYSQL_DATABASE変数は、使用するデータベースを定義します。スーパーユーザ権限のないユーザを使用しているので、データベースを作成するようにMySQLコンテナに指示する必要があります。データベース名は、センサーに使用される'Fiware Service'と同じになります。デフォルトでは、Tour Guide Application用にtourguideに設定されています。 rootユーザを使用している場合は、必要に応じて作成されるので、データベース名を指定する必要はありません。

サブスクリプション

システムが設定され実行されたら、データが変更されたときにデータを送信するようにOrionに指示する必要があります。これを行うには、CygnusのためにOrionにサブスクリプションを登録する必要があります。

一定の期間にわたってレストランの温度変化を保存したいとします。レストランの温度センサーの値が変わるたびに、Orionに情報を送信するように指示する必要があります。これを行うには、以下の情報が必要です:

  • レストランのID、例えば、0115206c51f60b48b77e4c937835795c33bb953f
  • センサーの種類、例えば、temperature
  • センサーの部屋、例えば、kitchen

この情報を使用して、http://localhost:1026/v1/subscribeContextに対して、次のようなペイロードでPOSTリクエストを送信します:

{
    "entities": [
        {
            "type": "Restaurant",
            "isPattern": "false",
            "id": "0115206c51f60b48b77e4c937835795c33bb953f"
        }
    ],
    "attributes": [
        "temperature:kitchen"
    ],
    "reference": "http://cygnus:5050/notify",
    "duration": "P1M",
    "notifyConditions": [
        {
            "type": "ONCHANGE",
            "condValues": [
                "temperature:kitchen"
            ]
        }
    ],
    "throttling": "PT1S"
}
referenceフィールドは、使用するCygnusエンドポイントを指定します。コンテナで使用されるデフォルトは、http://cygnus:5050/notifyです。センサーの値が変更されるたびに、Orionはこの変更をCygnusに通知を送信し、Cygnusはそれをデータベースに保存します。この例では、1つのレストランで1つのセンサーの変更をリクエストするだけです。より複雑なもの、またはサブスクリプションの詳細な説明については、Orion Context Brokerの公式ドキュメントでNGSI10を使用したコンテキスト管理Context subscriptionsを参照してください。

TourGuideには、 docker/cygnus/subscriptionsで利用可能な2つのサンプル・サブスクリプション・スクリプトがあります:

  • subscription-therm-sensors.sh
  • subscription-humidity-sensors.sh

これらのスクリプトを使用するには、ホストファイルを実行する前に、実行中のコンテナ(tourguide configure hosts --helpコマンドを参照)でhostsファイルを更新する必要があることに注意してください。

サブスクリプションを済ませたら、現在のデータで初期通知を受け取ります。これは、Cygnusコンテナのログに表示されます:

$ docker logs cygnus
次のようなものが表示されます:
time=2016-09-28T13:40:46.872Z | ... | srv=tourguide | subsrv=/Franchise1 | comp=cygnus-ngsi | op=getEvents | msg=com.telefonica.iot.cygnus.handlers.NGSIRestHandler[264] : Received data ({  "subscriptionId" : "57ebc85e0698bea0a46bc2b1",  "originator" : "localhost",  "contextResponses" : [    {   "contextElement" : {        "type" : "Restaurant",      "isPattern" : "false",      "id" : "0115206c51f60b48b77e4c937835795c33bb953f",      "attributes" : [        {           "name" : "temperature:kitchen",         "type" : "Number",          "value" : "25"          }       ]   },      "statusCode" : {        "code" : "200",     "reasonPhrase" : "OK"   }   }  ]})

...

time=2016-09-28T13:40:50.930Z | ... | srv=tourguide | subsrv=/Franchise1 | comp=cygnus-ngsi | op=processNewBatches | msg=com.telefonica.iot.cygnus.sinks.NGSISink[417] : Batch completed, persisting it
time=2016-09-28T13:40:50.931Z | ... | srv=tourguide | subsrv=/Franchise1 | comp=cygnus-ngsi | op=persistAggregation | msg=com.telefonica.iot.cygnus.sinks.NGSIMySQLSink[455] : [mysql-sink] Persisting data at OrionMySQLSink. Database (tourguide), Table (Franchise1_0115206c51f60b48b77e4c937835795c33bb953f_Restaurant), Fields ((recvTimeTs,recvTime,fiwareServicePath,entityId,entityType,attrName,attrType,attrValue,attrMd)), Values (('1475070046874','2016-09-28T13:40:46.874','/Franchise1','0115206c51f60b48b77e4c937835795c33bb953f','Restaurant','temperature:kitchen','Number','25','[]'))

そこでは、CygnusがtourguideデータベースのFranchise1_0115206c51f60b48b77e4c937835795c33bb953f_Restaurantテーブルに情報を保存しているはずです。 MySQLデータベースに接続することでこれが正しいかどうかを確認できます:

$ docker exec -i -t mysql mysql -u root -p tourguide

mysql> show tables;
+----------------------------------------------------------------+
| Tables_in_tourguide                                           |
+----------------------------------------------------------------+
| Franchise1_0115206c51f60b48b77e4c937835795c33bb953f_Restaurant |
+----------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> select * from Franchise1_0115206c51f60b48b77e4c937835795c33bb953f_Restaurant;
+---------------+-------------------------+-------------------+------------------------------------------+------------+---------------------+----------+-----------+--------+
| recvTimeTs    | recvTime              | fiwareServicePath | entityId                              | entityType | attrName         | attrType | attrValue | attrMd |
+---------------+-------------------------+-------------------+------------------------------------------+------------+---------------------+----------+-----------+--------+
| 1475070046874 | 2016-09-28T13:40:46.874 | /Franchise1     | 0115206c51f60b48b77e4c937835795c33bb953f | Restaurant | temperature:kitchen | Number   | 25       | []    |
+---------------+-------------------------+-------------------+------------------------------------------+------------+---------------------+----------+-----------+--------+
1 row in set (0.00 sec)

ご覧の通り、ID 0115206c51f60b48b77e4c937835795c33bb953fのレストランのキッチンの温度は25度です。 温度が変化したときに何が起こるかを見てみましょう。これを行うには、次のコマンドを使用します:

$ ./tour-guide sensors send-data -i "0115206c51f60b48b77e4c937835795c33bb953f-kitchen-temperature" -d "t|21"

Orionが温度変化とともに新しい通知を送信することがわかります:

time=2016-09-28T14:01:42.136Z | ... | srv=tourguide | subsrv=/Franchise1 | comp=cygnus-ngsi | op=getEvents | msg=com.telefonica.iot.cygnus.handlers.NGSIRestHandler[264] : Received data ({  "subscriptionId" : "57ebc85e0698bea0a46bc2b1",  "originator" : "localhost",  "contextResponses" : [    {   "contextElement" : {        "type" : "Restaurant",      "isPattern" : "false",      "id" : "0115206c51f60b48b77e4c937835795c33bb953f",      "attributes" : [        {           "name" : "temperature:kitchen",         "type" : "Number",          "value" : "21"          }       ]   },      "statusCode" : {        "code" : "200",     "reasonPhrase" : "OK"   }   }  ]})
time=2016-09-28T14:01:42.141Z | ... | srv=tourguide | subsrv=/Franchise1 | comp=cygnus-ngsi | op=processNewBatches | msg=com.telefonica.iot.cygnus.sinks.NGSISink[363] : Batch accumulation time reached, the batch will be processed as it is
time=2016-09-28T14:01:42.142Z | ... | srv=tourguide | subsrv=/Franchise1 | comp=cygnus-ngsi | op=processNewBatches | msg=com.telefonica.iot.cygnus.sinks.NGSISink[417] : Batch completed, persisting it

再度、データベースをチェックすると、新しい値が古い値とともに保存されていることがわかります:

$ docker exec -i -t mysql mysql -u root -p tourguide

mysql> select * from Franchise1_0115206c51f60b48b77e4c937835795c33bb953f_Restaurant;
+---------------+-------------------------+-------------------+------------------------------------------+------------+---------------------+----------+-----------+--------+
| recvTimeTs    | recvTime              | fiwareServicePath | entityId                              | entityType | attrName         | attrType | attrValue | attrMd |
+---------------+-------------------------+-------------------+------------------------------------------+------------+---------------------+----------+-----------+--------+
| 1475070046874 | 2016-09-28T13:40:46.874 | /Franchise1     | 0115206c51f60b48b77e4c937835795c33bb953f | Restaurant | temperature:kitchen | Number   | 25       | []    |
| 1475071302136 | 2016-09-28T14:01:42.136 | /Franchise1     | 0115206c51f60b48b77e4c937835795c33bb953f | Restaurant | temperature:kitchen | Number   | 21       | []    |
+---------------+-------------------------+-------------------+------------------------------------------+------------+---------------------+----------+-----------+--------+
2 rows in set (0.00 sec)

この値がOrionに格納されている値であることを確認できます:

curl --header 'Fiware-Service: tourguide' --header 'Accept: text/plain' http://localhost:1026/v2/entities/0115206c51f60b48b77e4c937835795c33bb953f/attrs/temperature:kitchen/value
これが返されるはずです:
"21"

温度が変化し続けると、新しい値がCygnusに通知され、データベースに保存されます。