概要
RESTはHTTP(S)およびTCPを基本とする、非常にシンプルでセキュアなプロトコルです。現在、非常にシンプルなデバイスから大規模なITに至るまで、すべてのネットワーク・プログラミング環境でサポートされている事実上のインターネット標準となっています。RESTを紹介している多くの本の中の1つにRESTful Web Servicesがあります。
このセクションでは、Things Cloud のRESTインターフェースを使用してデバイスをThings Cloudに統合する方法を説明します。
この説明は、「リファレンス ガイド」のデバイスおよびセンサー・ライブラリだけでなく、各インターフェースについて詳しく説明する Things Cloud OpenAPI仕様 と密接にリンクしています。
- REST実装: すべての一般的な概念のリファレンス
- デバイス管理ライブラリ: デバイス管理のデータモデルの具体的説明
- センサー・ライブラリ: センサーおよび制御装置向けのデータモデルの具体的説明
サポートされている開発ボードを使用する場合は、デバイスガイド内の該当する説明もご覧ください。
デバイスインテグレーション
デバイスをThings Cloudに統合するための基本的なライフサイクルは、「Things Cloud コンセプトガイド」のデバイスのインターフェースで説明されています。このセクションでは、このライフサイクルがRESTレベルでどのように実装されるかを説明します。 ライフサイクルは、スタートアップフェーズとサイクルフェーズの2つのフェーズで構成されます。
スタートアップフェーズでは、デバイスをThings Cloudに接続し、インベントリのデバイスデータを更新します。 また、オペレーションに必要なクリーンアップタスクも実行します。次の手順で構成されます。
- ステップ 0: デバイスの認証情報をリクエストします。
- ステップ 1: デバイスがすでに登録されているかどうかを確認します。
- ステップ 2: デバイスが登録されていなければ、インベントリにデバイスを作成します。
- ステップ 3: デバイスを新規登録します。
- ステップ 4: ステップ1でデバイスが登録されている場合、インベントリのデバイスを更新します。
- ステップ 5: 子デバイスを検出し、インベントリにそれらのデバイスを作成または更新します。
- ステップ 6: 再起動が必要なオペレーションを完了し、新しいオペレーションをサブスクライブします。
サイクルフェーズへと続きます。 インベントリを継続的に更新し、メジャーメント、アラーム、イベントを書き込み、必要に応じてオペレーションを実行します。 これは、デバイスの電源が切れるまで実行される、デバイスの「メインループ」となります。 このループは次の手順で構成されます。
- ステップ 7: オペレーションを実行します。
- ステップ 8: インベントリを更新します。
- ステップ 9: メジャーメントを送信します。
- ステップ 10: イベントを送信します。
- ステップ 11: アラームを送信します。
データの参照モデルについては「リファレンスガイド」のデバイス管理ライブラリ と センサー・ライブラリ をご覧ください。
スタートアップフェーズ
ステップ 0: デバイスの認証情報をリクエストする
Things Cloudへのすべてのリクエストは認証される必要があり、デバイスからのリクエストも認証される必要があります。個々の認証情報をデバイスに割り当てる場合は、デバイス認証情報APIを使用して新しい認証情報を自動的に生成できます。これを行うには、最初の起動時にAPIを介してデバイスの認証情報をリクエストし、それ以降のリクエストに備えてデバイス上のローカルに保存します。
このプロセスは次のように動作します。
- Things Cloudは、各デバイスが何らかの固有のIDを持つことを前提としています。適切なデバイス識別子は、ネットワークアダプタのMACアドレス、モバイルデバイスのIMEI、またはハードウェアシリアル番号となります。
- 新しいデバイスを使用する場合は、この固有IDをThings Cloudの「デバイス登録」に入力し、デバイスを起動します。
- デバイスはThings Cloudに接続し、固有IDを繰り返し送信します。そのため、Things Cloudでは静的なブートストラップ用認証情報を提供しており、Things Cloud Supportにて問い合わせることができます。
- 「デバイス登録」よりデバイスからの接続を受け入れることができ、その場合Things Cloudは生成された認証情報をデバイスに送信します。
- デバイスは、以降のすべてのリクエストにこれらの認証情報を使用します。
デバイス側の視点から見ると、これは単一のRESTのリクエストです:
POST /devicecontrol/deviceCredentials
Content-Type: application/vnd.com.nsn.cumulocity.devicecredentials+json
Authorization: Basic <<Base64 encoded bootstrap credentials>>
{
"id" : "0000000017b769d5"
}
デバイスはこのリクエストを繰り返し発行します。ユーザーがデバイスを登録してデバイス管理アプリで承認していない間は、リクエストは「404 Not Found」を返します。デバイスが承認されると、次のレスポンスが返されます:
HTTP/1.1 200 OK
Content-Type: application/vnd.com.nsn.cumulocity.devicecredentials+json;charset=UTF-8;ver=...
Content-Length: ...
{
"id" : "0000000017b769d5",
"self" : "<<URL of new request>>",
"tenantId" : "test",
"username" : "device_0000000017b769d5",
"password" : "3rasfst4swfa"
}
これで、デバイスはテナントID、ユーザー名、パスワードを使用してThings Cloudに接続できます。ユーザーエイリアスはデバイスではサポートされていません。
テナント名がテナントIDと同じであると想定することはもはや安全ではありません。認証情報リクエストではテナントIDのみを返します。これをサブドメインとして使用したり、ドメイン名と組み合わせて、ユーザー名(およびパスワード)のみでアクセスできるテナントURLを提供したりすることはできません。正しいテナントへのアクセスは、認証にテナントIDとユーザー名を使用することによってのみ保証できます。例えば、 <tenant-ID>/<username>
と認証情報リクエストによって返却されたパスワードのような形式です。この場合、サブドメインは関係ありません。
リクエストヘッダーは次のようになります。
Authorization: Basic <<Base64 encoded credentials <tenant ID>/<username>:<password> >>
例えば、xyz.je1.thingscloud.ntt.com に追加されたデバイスの認証情報リクエストは、「t123456789」のユーザーID、パスワード、およびテナントIDを返す可能性があります。テナントID「t123456789」は、ユーザーIDとパスワードを使用したリクエストのサブドメイン(t123456789.je1.thingscloud.ntt.com )として使用できません。「http403」が返されます。テナントIDは、パスワードとともに「t123456789/<userid>」の形式のユーザーIDとともに使用する必要があります。この場合、実際のサブドメインは無関係です。 t123456789.je1.thingscloud.ntt.com または management.je1.thingscloud.ntt.com、あるいは anything.je1.thingscloud.ntt.com も使用できます。
Things Cloudは、ユーザーIDで指定されたテナントIDを使用して、完全な認証と正しいテナントへのリクエストのルーティングを行います。
有効なテナントURLがわかっている場合(上記の例の xyz.je1.thingscloud.ntt.com )、認証にユーザー名の前に<tenantID>/
を付ける必要はありません。
ステップ 1: デバイスが登録済みかどうかを確認する
デバイスの固有IDは、デバイスをインベントリに登録するためにも使用されます。登録はIdentity APIを用いて行います。ID APIでは、各マネージドオブジェクトをタイプで識別される複数の識別子に関連付けることができます。例えば、ハードウェアシリアル番号の場合は「c8y_Serial」、MACアドレスの場合は「c8y_MAC」、IMEIの場合は「c8y_IMEI」となります。
デバイスがすでに登録されているかどうかを確認するには、デバイス識別子とそのタイプを使用して、Identity APIのGETリクエストを使用します。次の例では、ハードウェアシリアル番号「0000000017b769d5」のRaspberry Piをチェックしています。
GET /identity/externalIds/c8y_Serial/raspi-0000000017b769d5 HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/vnd.com.nsn.cumulocity.externalid+json; charset=UTF-8; ver=0.9
...
{
"externalId": "raspi-0000000017b769d5",
"managedObject": {
"id": "2480300",
"self": "https://.../managedObjects/2480300"
},
"self": "https://.../identity/externalIds/c8y_Serial/raspi-0000000017b769d5",
"type": "c8y_Serial"
}
MACアドレスはグローバルで固有であることが保証されていますが、ハードウェアのシリアル番号は異なるハードウェア間で重複する可能性があることに注意してください。したがって、上記の例では、デバイス登録時、シリアル番号の前に「raspiー」を付けています(ステップ3参照)。
ここでは、デバイスはすでに登録されており、ステータスコード200が返されます。レスポンスでは、インベントリのデバイスへのURLが「managedObject.self」に返されます。このURLは、後でデバイスを操作するために使用することができます。
デバイスがまだ登録されていない場合は、ステータスコード404とエラーメッセージが返されます。
GET /identity/externalIds/c8y_Serial/raspi-0000000017b769d6 HTTP/1.1
HTTP/1.1 404 Not Found
Content-Type: application/vnd.com.nsn.cumulocity.error+json;charset=UTF-8;ver=0.9
...
{
"error": "identity/Not Found",
"info": "https://www.cumulocity.com/guides/reference/#error_reporting",
"message": "External id not found; external id = ID [type=c8y_Serial, value=raspi-0000000017b769d6]"
}
ステップ 2: インベントリにデバイスを作成する
上記のステップ1でデバイスを表すマネージドオブジェクトが存在しなかった場合、Things Cloud上にマネージドオブジェクトが作成されます。 マネージドオブジェクトは、デバイスとそのインスタンスとメタデータの両方を記述します。 インスタンスデータには、ハードウェアおよびソフトウェアの情報、シリアル番号、デバイス構成データが含まれます。 メタデータには、サポートされているオペレーションを含むデバイスの機能が記述されています。
マネージドオブジェクトを作成するには、インベントリAPIのマネージドオブジェクトコレクションに対してPOSTリクエストを出します。 次の例では、Linuxエージェントを使用してRaspberry Piを作成しています。
POST /inventory/managedObjects HTTP/1.1
Content-Type: application/vnd.com.nsn.cumulocity.managedobject+json
Accept: application/vnd.com.nsn.cumulocity.managedobject+json
...
{
"name": "RaspPi BCM2708 0000000017b769d5",
"type": "c8y_Linux",
"c8y_IsDevice": {},
"com_cumulocity_model_Agent": {},
"c8y_SupportedOperations": [ "c8y_Restart", "c8y_Configuration", "c8y_Software", "c8y_Firmware" ],
"c8y_Hardware": {
"revision": "000e",
"model": "RaspPi BCM2708",
"serialNumber": "0000000017b769d5"
},
"c8y_Configuration": {
"config": "#Fri Aug 30 09:13:56 BST 2013\nc8y.log.eventLevel=INFO\n..."
},
"c8y_Mobile": {
"imei": "861145013087177",
"cellId": "4904-A496",
"iccid": "89490200000876620613"
},
"c8y_Firmware": {
"name": "raspberrypi-bootloader",
"version": "1.20130207-1"
},
"c8y_Software": {
"pi-driver": "pi-driver-3.4.5.jar",
"pi4j-gpio-extension": "pi4j-gpio-extension-0.0.5.jar",
...
}
}
HTTP/1.1 201 Created
Content-Type: application/vnd.com.nsn.cumulocity.managedobject+json;charset=UTF-8;ver=0.9
...
{
"id": "2480300",
"lastUpdated": "2013-08-30T10:12:24.378+02:00",
"name": "RaspPi BCM2708 0000000017b769d5",
"owner": "admin",
"self": "https://.../inventory/managedObjects/2480300",
"type": "c8y_Linux",
"c8y_IsDevice": {},
...
"assetParents": {
"references": [],
"self": "https://.../inventory/managedObjects/2480300/assetParents"
},
"childAssets": {
"references": [],
"self": "https://.../inventory/managedObjects/2480300/childAssets"
},
"childDevices": {
"references": [],
"self": "https://.../inventory/managedObjects/2480300/childDevices"
},
"deviceParents": {
"references": [],
"self": "https://.../inventory/managedObjects/2480300/deviceParents"
}
}
上記の例では、デバイスの多数のメタデータ項目が含まれています。
- 「c8y_IsDevice」 は、Things Cloudのデバイス管理アプリを使用して管理できるデバイスを示します。
- 「com_cumulocity_model_Agent」 は、Things Cloudエージェントを実行しているデバイスを示します。 これらのデバイスは、ルーティングのためにデバイス自体とその子を対象とするすべてのオペレーションを受け取ります。
- 「c8y_SupportedOperations」 は、このデバイスを再起動および構成できることを示しています。 さらに、ソフトウェアおよびファームウェアの更新も実行できます。
詳細は「リファレンスガイド」の デバイス管理ライブラリ をご覧ください。
デバイスが正常に作成された場合は、ステータスコード201が返されます。 例にあるように、元のリクエストに「Accept」ヘッダーが含まれる場合、今後のリクエストでオブジェクトを参照するためのIDとURLを含む、作成されたオブジェクト全体が返されます。 返されるオブジェクトには、子デバイスのコレクションへのリファレンスと、子をデバイスに追加するために使用できる子アセットも含まれます(下記参照)。
ステップ 3: デバイスを登録する
新しいデバイスを作成後、ステップ1で説明したように、そのデバイスを組み込み識別子と関連付けることができます。これにより、デバイスは次回の電源投入後にThings Cloudで検出できるようになります。
上記の例に続き、新しく作成したデバイス「2480300」をそのハードウェアのシリアル番号に関連付けます。
POST /identity/globalIds/2480300/externalIds HTTP/1.1
Content-Type: application/vnd.com.nsn.cumulocity.externalid+json
Accept: application/vnd.com.nsn.cumulocity.externalid+json
...
{
"type" : "c8y_Serial",
"externalId" : "raspi-0000000017b769d5"
}
HTTP/1.1 201 Created
Content-Type: application/vnd.com.nsn.cumulocity.externalid+json;charset=UTF-8;ver=0.9
...
{
"externalId": "raspi-0000000017b769d5",
"managedObject": {
"id": "2480300",
"self": "https://.../inventory/managedObjects/2480300"
},
"self": "https://.../identity/externalIds/c8y_Serial/raspi-0000000017b769d5",
"type": "c8y_Serial"
}
ステップ 4: インベントリのデバイスを更新する
ステップ1で、デバイスが以前に登録されていると返された場合、インベントリのデバイスの表記が最新であるかを確認する必要があります。 そのために、PUTリクエストがインベントリのデバイスのURLへ送信されます。 変更可能なフラグメントのみが転送されることに注意してください(フラグメントの詳細については、「Things Cloud コンセプトガイド」のThings Cloudのドメインモデルをご覧ください)。
例えば、デバイスのハードウェア情報は通常変更されませんが、ソフトウェアのインストールが変更されている可能性があります。 したがって、デバイスの再起動後に、インベントリのソフトウェア情報を最新の状態にする必要があリます。
PUT /inventory/managedObjects/2480300 HTTP/1.1
Content-Type: application/vnd.com.nsn.cumulocity.managedobject+json
...
{
"c8y_Software": {
"pi-driver": "pi-driver-3.4.6.jar",
"pi4j-gpio-extension": "pi4j-gpio-extension-0.0.5.jar"
}
}
HTTP/1.1 200 OK
ステップ 5: 子デバイスを検出し、インベントリでそれらを作成または更新する
センサーネットワークの複雑さに応じて、デバイスは、関連する子デバイスを有することができます。家庭のさまざまな部屋にさまざまなセンサーやコントロールを設置するホームオートメーションゲートウェイなどがその良い例です。子デバイスの基本登録方法は、子デバイスが通常エージェントインスタンスを実行しないというところまでは、メインデバイスの登録と同じです(したがって、「com_cumulocity_model_Agent」フラグメントは省略されます)。 デバイスを子にリンクするには、オブジェクトの作成時に返された子デバイスのURLへ、POSTリクエストを送信します(上記参照)。
例えば、下記URLを持つ子デバイスが作成されたとします。
“https://…/inventory/managedObjects/2543801"
このデバイスを親デバイスとリンクするには、次のコマンドを発行します。
POST /inventory/managedObjects/2480300/childDevices HTTP/1.1
Content-Type: application/vnd.com.nsn.cumulocity.managedobjectreference+json
{
"managedObject" : {
"id" : "2543801"
}
}
HTTP/1.1 201 Created
最後に、URLにDELETEリクエストを発行することによって、デバイスと参照を削除することができます。例えば、作成したばかりの親デバイスから子デバイスへの参照を削除するには、次のコマンドを発行します。
DELETE /inventory/managedObjects/2480300/childDevices/2543801 HTTP/1.1
HTTP/1.1 204 No Content
この場合、インベントリのデバイス自体は削除されず、参照のみが削除されます。デバイスを削除するには、次のコマンドを発行します。
DELETE /inventory/managedObjects/2543801 HTTP/1.1
HTTP/1.1 204 No Content
このリクエストは、登録情報、メジャーメント、アラーム、イベント、オペレーションなど、デバイスに関連するすべてのデータを削除します。 通常、デバイスを自動的に削除することはお勧めできません。例えば、デバイスの接続が一時的に失われただけの場合、通常そのデバイスに関連するすべての履歴情報を失いたくないでしょう。
ステップ 6: オペレーションを完了し、サブスクライブする
Things Cloudの各オペレーションは、実行フローを通じて循環されます。Things Cloudアプリケーションを介してオペレーションが作成されると、PENDING状態になります(つまり、実行のためにキューに入れられてはいても、まだ実行されていない状態です)。エージェントがオペレーションを選択して実行を開始すると、そのオペレーションにはThings Cloudで「EXECUTING」というマークが付けられます。その後、エージェントは、デバイスまたはその子デバイスに対してオペレーションを実行します(例えば、デバイスを再起動したり、リレーを設定したりします)。その後、デバイスまたはその子デバイスの新しい状態を反映してインベントリを更新するでしょう (例:インベントリのリレーの現在の状態を更新します)。次に、エージェントはThings Cloud内のオペレーションを「SUCCESSFUL」または「FAILED」のいずれかとしてマークし、場合によってはエラーを表示します。
この実行フローの利点は、オフラインで一時的に通信範囲外にあるデバイスにも対応できることです。 また、ファームウェアのアップグレードなど、再起動が必要なオペレーションをデバイスが対応できるようになります。再起動後、デバイスは以前に実行した内容を知る必要があるため、すべての「EXECUTING」オペレーションを照会して成功したかどうかを確認する必要があります。また、キューに入れられた新しいオペレーションをリッスンする必要があります。
まだステータスが「EXECUTING」であるオペレーションをクリーンナップするには、エージェントIDおよび状況別にオペレーションを照会します。 下記の例では、リクエストは次のようになります。
GET /devicecontrol/operations?agentId=2480300&status=EXECUTING HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/vnd.com.nsn.cumulocity.operationcollection+json;charset=UTF-8;ver=0.9
...
{
"next": "https://.../devicecontrol/operations?agentId=2480300&status=EXECUTING",
"operations": [
{
"creationTime": "2013-08-29T19:49:15.239+02:00",
"deviceId": "2480300",
"id": "2593101",
"self": "https://.../devicecontrol/operations/2480300",
"status": "EXECUTING",
"c8y_Restart": {
}
}
],
"statistics": {
"currentPage": 1,
"pageSize": 2000
},
"self": "https://.../devicecontrol/operations?agentId=2480300&status=EXECUTING"
}
再起動はうまくいったようです – もとに戻りました。オペレーションを「SUCCESSFUL」に設定します。
PUT /devicecontrol/operations/2593101 HTTP/1.1
Content-Type: application/vnd.com.nsn.cumulocity.operation+json
{
"status": "SUCCESSFUL"
}
HTTP/1.1 200 OK
次に、Things Cloudで作成された新しいオペレーションをリッスンします。 このメカニズムは、Things Cloud OpenAPI仕様のDevice control notification APIで記述されており、標準Bayeuxプロトコルに基づいています。 まず、ハンドシェイクが必要です。 ハンドシェイクは、エージェントが通知用として対応しているプロトコルをThings Cloudに伝え、クライアントIDをエージェントに割り当てます。
POST /devicecontrol/notifications HTTP/1.1
Content-Type: application/json
...
[ {
"channel": "/meta/handshake",
"version": "1.0"
} ]
HTTP/1.1 200 OK
...
[ {
"minimumVersion": "1.0",
"clientId": "139jhm07u1dlry92fdl63rmq2c",
"supportedConnectionTypes": [
"long-polling",
"smartrest-long-polling",
"websocket"
],
"channel": "/meta/handshake",
"version": "1.0",
"successful": true
} ]
その後、それぞれのデバイスのエージェントはオペレーションを実行する為の通知にサブスクライブする必要があります。 これは、デバイスのIDをサブスクリプションのチャネルとして使用するPOSTリクエストで行います。 次の例では、Raspberry Piがエージェントを実行し、IDは2480300です:
POST /devicecontrol/notifications HTTP/1.1
Content-Type: application/json
...
[ {
"channel": "/meta/subscribe",
"subscription": "/2480300",
"clientId":"139jhm07u1dlry92fdl63rmq2c"
}]
HTTP/1.1 200 OK
...
[ {
"channel": "/meta/subscribe",
"subscription": "/2480300",
"successful": true
} ]
最後に、デバイスは接続され、オペレーションが送信されるのを待ちます。
POST /devicecontrol/notifications HTTP/1.1
Content-Type: application/json
...
[ {
"connectionType": "long-polling",
"channel": "/meta/connect",
"clientId": "139jhm07u1dlry92fdl63rmq2c"
} ]
このリクエストは、オペレーションが通るまで保留されます。つまり、HTTPサーバーがすぐに応答できずとも、デバイスのオペレーションが行われるまで待機します(ロングポーリング)。
新しいオペレーションをサブスクライブするとき、「PENDING」のオペレーションがある可能性に注意してください。これらをすべて照会する必要があります。クエリとサブスクリプションの間のオペレーションが失われないよう、これらはサブスクリプション後に実行されます。この技術的な処理は、前述の「EXECUTING」オペレーションと同じですが、代わりに「PENDING」を使用します。
GET /devicecontrol/operations?agentId=2480300&status=PENDING HTTP/1.1
サイクルフェーズ
ステップ 7: オペレーションを実行する
まず、エージェントのオペレーションがキューに入れられていると仮定します。これにより、上記のロングポーリングのリクエストがオペレーションで返されます。下記は、単一の構成オペレーションでのレスポンスの一例です。
HTTP/1.1 200 OK
...
[
{
"id": "139",
"data": {
"creationTime":"2013-09-04T10:53:35.128+02:00",
"deviceId": "2480300",
"id": "2546600",
"self": "https://.../devicecontrol/operations/2546600",
"status": "PENDING",
"description": "Configuration update",
"c8y_Configuration": { "config": "#Wed Sep 04 10:54:06 CEST 2013\n..." }
},
"channel": "/2480300"
}, {
"id": "3",
"successful": true,
"channel": "/meta/connect"
}
]
エージェントがオペレーションを取得すると、Things Cloud上ではPUTリクエストを使用して「EXECUTING」状態になります(上記の「FAILED」の例を参照)。 デバイスでオペレーションを実行し、Things Cloudインベントリで必要な更新を実行します。最後に、結果に応じてオペレーションは「SUCCESSFUL」または「FAILED」に設定されます。 そして、上記のように 「/devicecontrol/notifications」 に再接続し、次のオペレーションを待ちます。
ステップ 8: インベントリを更新する
通常、デバイスのインベントリ内容は最新の状態を表すので、継続的な更新の対象になります。 例として、GPSチップを搭載したデバイスを考えてみましょう。このデバイスは、インベントリの現在地を最新の状態に保ちます。 同時に、位置の更新とイベントを報告して、位置の追跡を維持します。技術的にこのような更新は、ステップ4と同じリクエストで報告されます。
ステップ 9: メジャーメントを送信する
Things Cloudで新しいメジャーメントを作成するには、メジャーメントとともにPOSTリクエストを発行します。 下記は、信号強度のメジャーメントを作成する例になります。
POST /measurement/measurements HTTP/1.1
Content-Type: application/vnd.com.nsn.cumulocity.measurement+json
...
{
"source": { "id": "2480300" },
"time": "2013-07-02T16:32:30.152+02:00",
"type": "SignalStrength",
"c8y_SignalStrength": {
"rssi": { "value": -53, "unit": "dBm" },
"ber": { "value": 0.14, "unit": "%" }
}
}
HTTP/1.1 201 Created
ステップ 10: イベントを送信する
同様に、イベントにもPOSTリクエストを使用します。 次の例は、GPSセンサーからの位置の更新を示しています。
POST /event/events HTTP/1.1
Content-Type: application/vnd.com.nsn.cumulocity.event+json
...
{
"source": { "id": "2480300" },
"text": "Location updated",
"time": "2013-07-19T09:07:22.598+02:00",
"type": "LocationUpdate",
"c8y_Position": {
"alt": 73.9,
"lng": 6.151782,
"lat": 51.211971
}
}
HTTP/1.1 201 Created
Things Cloudのすべてのデータタイプには、追加でフラグメントという形の任意の拡張を含むことができます。上記では、イベントに位置情報が含まれていますが、自己定義のフラグメントを追加することも可能です。
ステップ 11: アラームを送信する
アラームとは、解決するために人の介入を必要とするイベントを表します。例えば、デバイスのバッテリーが切れた場合、誰かがデバイスのバッテリーを交換する必要があります。 アラームの作成は、技術的にはイベントの作成と非常によく似ています。
POST /alarm/alarms HTTP/1.1
Content-Type: application/vnd.com.nsn.cumulocity.alarm+json
Accept: application/vnd.com.nsn.cumulocity.alarm+json
...
{
"source": { "id": "10400" },
"text": "Tracker lost power",
"time": "2013-08-19T21:31:22.740+02:00",
"type": "c8y_PowerAlarm",
"status": "ACTIVE",
"severity": "MAJOR",
}
HTTP/1.1 201 Created
Content-Type: application/vnd.com.nsn.cumulocity.alarm+json
...
{
"id": "214600",
"self": "https://.../alarm/alarms/214600",
...
}
ただし、同じようなアラームがシステム内ですでに有効になっている場合は、デバイスのアラームを作成しない方がよいでしょう。多数のアラームを作成すると、ユーザーインターフェースがいっぱいになり、すべてのアラームを手動でクリアする必要が生じる場合があります。上の例は、Raspberry Piのアクティブアラームを見つけるためのものです。
GET /alarm/alarms?source=2480300&status=ACTIVE HTTP/1.1
イベントとは異なり、アラームは更新ができます。 問題が解決した場合(例:バッテリーが交換され、電源が復旧した場合)、対応するアラームが自動的にクリアされ、手動での作業が不要になります。これは、アラームのURLへのPUT要求によって実行できます。 上記のアラーム作成の例では、「Accept」ヘッダーを使用して、レスポンス内の新しいアラームのURLを取得しました。このURLを使用してアラームをクリアできます。
PUT /alarm/alarms/214600 HTTP/1.1
Content-Type: application/vnd.com.nsn.cumulocity.alarm+json
...
{
"status": "CLEARED"
}
HTTP/1.1 200 OK
イベントの送信、あるいはアラームの発生のどちらを選ぶか判断ができない場合は、とりあえずイベントを発生させて、ユーザー自身にリアルタイム処理 より、イベントをアラームへ変換するかどうか決定させるとよいでしょう。
物理デバイスの交換
すでにThings Cloudプラットフォームに接続されている物理デバイスを、その外部 ID とデバイスが収集したデータを維持したまま交換できます。 下記を実行します。
- 古い物理デバイスの電源を切ります。
- 通常のデバイスと同様に、新しいデバイスを登録と起動します。
- デバイスが新しいマネージドオブジェクトを作成した後、新しい物理デバイスの電源をオフにします。
- Things Cloudのデバイス管理 アプリで新しいデバイスオブジェクトを開き、デバイスの所有者とデバイスの外部 ID を検索します。
- デバイスから外部 ID を削除します。
- Things Cloudのデバイス管理アプリで古いデバイスを開き、その所有者を調べたものに変更し、新しいデバイスから削除した外部 ID も追加します。
- 以前に作成した新しいデバイスオブジェクトを削除し、デバイスユーザーは保持します。
- 新しい物理デバイスの電源を入れます。
新しい物理デバイスは、データを既存のマネージドオブジェクトに送信します。
Hello REST!
概要
このセクションでは、Things Cloudでデバイス表現を作成する方法と、その後、関連するメジャーメントデータを送信する方法の基本的な例を示します。
すべての手順は、RESTインターフェースを呼び出すことによって実行されます。これらのRESTコールは、CURL ステートメントによってコマンドラインで実行できます。
CURLの簡単な紹介については、RESTインターフェースの使用法の 概要 をご覧ください。
前提条件
このチュートリアルを実行するには、次の前提条件が満たされているかどうかを確認してください。
- Things Cloudにアクセスするための有効なテナント、ユーザー、パスワードを保持している。
- コマンドラインツールのCURLがシステムにインストールされている。
RESTコールを実行する
次に、2つのRESTコールのシーケンスを実行します。詳細は次で説明します。
- ステップ1: Things Cloudのインベントリに新しいデバイスを作成する
- ステップ2: そのデバイスに関連するメジャーメントデータを送信する
実際には、これらのステップは 「デバイスエージェント」 によって実行されます。
ステップ1は、デバイスが初めてThings Cloudに接続されたときに1回だけ実行されます。
その後、このステップを実行したときに返される内部IDによってデバイスを参照することで、そのデバイスに関連するアクションを実行することができます。
新しいデバイスの作成
Things Cloudのインベントリに新しいデバイスを作成するには、次のRESTリクエストが必要です。
POST /inventory/managedObjects HTTP/1.1
Content-Type: application/vnd.com.nsn.cumulocity.managedobject+json
Accept: application/vnd.com.nsn.cumulocity.managedobject+json
Authorization: Basic <<Base64 encoded credentials <tenant ID>/<username>:<password> >>
...
{
"c8y_IsDevice" : {},
"name" : "HelloWorldDevice"
}
このコールは、次のCURLステートメントを実行することによって実行できます。
curl -v -u <username>:<password> \
-H 'Accept: application/vnd.com.nsn.cumulocity.managedobject+json' \
-H 'Content-type: application/vnd.com.nsn.cumulocity.managedobject+json' \
-X POST \
-d '{"c8y_IsDevice":{},"name":"HelloWorldDevice"}' \
https://<Things Cloud tenant domain>/inventory/managedObjects
Things Cloudに登録するときに、<username>
、<password>
、<tenant-ID>
を適切な認証情報に置き換えます。
Things Cloud Web GUIへのアクセスに使用するものと同じ認証情報を使用してRESTコールを実行することができます。
次のようなレスポンスが表示されます。
HTTP/1.1 201 Created
Content-Type: application/vnd.com.nsn.cumulocity.managedobject+json; charset=UTF-8; ver=0.9
Authorization: Basic <<Base64 encoded credentials <tenant ID>/<username>:<password> >>
...
{
"id": "1231234"
"lastUpdated": "2014-12-15T14:58:26.279+01:00",
"name": "HelloWorldDevice",
"owner": "<username>",
"self": "https://.../inventory/managedObjects/1231234",
"c8y_IsDevice": {},
...
}
デバイスを作成する場合、Things CloudはIDを生成します。このIDは、デバイスを参照するために以降のコールで必要になります。 このIDは、レスポンスの中に「ID」属性と値のペアとして存在します。
メジャーメントデータの送信
デバイスが作成された後、メジャーメントデータを送信できます。
この例では、特定の時間に収集された摂氏単位の温度メジャーメントを送信します。
POST /measurement/measurements
Content-Type: application/vnd.com.nsn.cumulocity.measurement+json
Accept: application/vnd.com.nsn.cumulocity.measurement+json
...
{
"c8y_TemperatureMeasurement": {
"T": {
"value": 21.23,
"unit":"C"
}
},
"time": "2014-12-15T13:00:00.123+02:00",
"source": {
"id": "1231234"
},
"type":"c8y_PTCMeasurement"
}
idの値を、最初の手順で取得した適切な値に置き換えます。
さらに、時間値を最近のタイムスタンプに更新し、後でThings Cloud UIでメジャーメントを見つけやすくする必要があります。
Swagger/OpenAPI Specificationのdate-time
で説明されているタイムスタンプ値のデータ形式に注意してください。
curl -v -u <username>:<password> \
-H 'Accept: application/vnd.com.nsn.cumulocity.measurement+json' \
-H 'Content-type: application/vnd.com.nsn.cumulocity.measurement+json' \
-X POST \
-d '{"c8y_TemperatureMeasurement":{"T":{"value":21.23,"unit":"C"}},"time":"2014-12-15T13:00:00.123+02:00","source":{"id":"1231234"},"type":"c8y_PTCMeasurement"}' \
https://<Things Cloud tenant domain>/measurement/measurements/
このリクエストに対するレスポンスは次のようになります。
HTTP/1.1 201 Created
Content-Type: application/vnd.com.nsn.cumulocity.measurement+json; charset=UTF-8; ver=0.9
...
{
"id": "4711",
"self": "https://.../measurement/measurements/4711",
"source": {
"id": "1231234",
"self": "https://.../inventory/managedObjects/1231234"
},
"time": "2014-12-15T12:00:00.123+01:00",
"type": "c8y_PTCMeasurement",
"c8y_TemperatureMeasurement": {
"T" : {
"unit" : "C",
"value" : 21.23
}
}
}
必要に応じて、メジャーメントの送信を繰り返すことができます。リクエストを再送信する前に、タイムシリーズを作成するためにタイムスタンプ(属性「time」の値)を更新する必要があります。
以上で完了です。Things Cloud UIにデバイス管理アプリケーションを入力し、「すべてのデバイス」ページでデバイスを選択し、「計測値(メジャーメント)」タブに切り替えます。ここにメジャーメントデータが表示されます。
データが表示されない場合は、送信したメジャーメントで使用したタイムスタンプを含めるために、フィルター設定を「直近1週間」などに変更してください。
詳細
ここで示したRESTコールのシーケンスはデバイスインテグレーションで説明した手順を短縮したものにすぎません。 最初のステップ(新規デバイスの作成)は「スタートアップフェーズ」の一部ですが、ステップ2(メジャーメントの送信)はサイクルフェーズを指します。
実際のエージェントの実装に必要な情報については、デバイスインテグレーション をご覧ください。