MQTT

Things Cloud の MQTT 実装には、次の利点があります。

  • マルチテナントのサポート: 1 つのエンドポイントが複数のテナントに対応します。
  • デバイスID管理: デバイス固有の認証情報を使用してデバイスを認証します。
  • デバイス登録: カスタマイズしていない非パーソナライズなデバイスは、Things Cloud テナントとペアリングすることでご利用可能となります。
  • デバイス管理: 定義済みの豊富なデバイス管理ペイロード形式により、多数のデバイスを簡単に管理できます。
  • 標準IoTペイロード形式: IoT センサーの読み取り、アラーム管理、リモートコントロール、デバイス階層をサポートするために事前定義されたペイロード形式です。
  • カスタムペイロード形式: ペイロード形式を追加できます。
  • トラフィックオーバーヘッドを小さくできます。
  • 処理モード: データを Things Cloud データベースに保存する、リアルタイム処理に一時的に渡す、リアルタイム通知を無効化にする QUIESCENT モードを使用して処理する、リアルタイム通知が無効化された場合にのみデータをリアルタイム処理エンジンに一時的に送信する CEP モードを使用して処理する、のいずれかを制御します。
  • 完全な双方向通信が可能で、デバイス、サーバー間のメッセージを簡単に送受信できます。
  • Web ソケットのMQTT接続をサポートします。
  • TLS をサポートします。
  • 完全な水平方向の拡張性をサポートします。

SmartREST ドキュメントも参照してください。

このセクションでは、MQTT 通信の基本については説明しません。MQTT に慣れていない場合は、インターネットにある数多くの入門書等を参照することをお勧めします。参考文献のいくつかは、MQTT の Web サイト にあります。

備考
プラットフォームへのすべての MQTT 接続は、最大許容メッセージサイズは 16,384 バイト(約 16 キロバイト)です。メッセージヘッダーと本文の両方が含まれます。ヘッダーサイズはさまざまですが、最小サイズは 2 バイトです。本文のサイズはトピックとペイロードを合わせたサイズです。

統合ライフサイクル

基本的なデバイスを Things Cloud に統合するライフサイクルについては、デバイスのインターフェース で説明されています。

このセクションでは、MQTT 実装を使用してこのライフサイクルを管理する方法を示します。

ライフサイクルは、スタートアップフェーズとサイクルフェーズの2つのフェーズで構成されています。

スタートアップフェーズ は、認証情報を確認するだけでも短くなる場合があります。

  • ステップ 0: デバイスの認証情報をリクエストします(まだ要求されていない場合)。
  • ステップ 1: デバイスが存在することを確認します。
  • ステップ 2: デバイスの子が存在することを確認します。
  • ステップ 3: トピックにサブスクライブします。

サイクルフェーズ は、2種類のアクションで構成されています。

MQTT フェーズ

必要条件
  • ブートストラップユーザー認証情報を介してアクセスします。ブートストラップ認証情報の取得と使用方法については、デバイスの認証情報 を参照してください。

スタートアップフェーズ

ステップ 0: デバイスの認証情報を要求する

Things Cloud では、すべての MQTT 接続は認証される必要があります。デバイスの認証情報を生成するために、MQTT 実装のデバイス認証情報トピックを使用できます。

デバイスが認証情報を取得したら、今後の接続のためにそれらをローカルに保存する必要があります。

接続を確立するには、次のパラメータを構成する必要があります。

  • ホスト: <your_cumulocity_url>
  • ユーザー: <tenantID>/<username>(ユーザーエイリアスはサポートされていません)
  • パスワード: <your_cumulocity_password>

詳細については、Hello MQTT セクションを参照してください。

プロセスは次の通りです。

  • Things Cloud は、各デバイスが何らかの形式の固有IDを持っていると仮定しています。たとえば、適切なデバイス識別子はネットワークアダプタの MACアドレス、モバイルデバイスの IMEI、またはハードウェアシリアル番号です。
  • 新しいデバイスを使用する際、この固有IDをデバイス登録に入力し、デバイス管理アプリケーション内でデバイスを起動します。
  • デバイスはこのIDを MQTT ClientId の一部として使用し、製品サポートから問い合わせ可能な静的ユーザー認証情報を使用します。
  • デバイスはトピック s/dcr にサブスクライブします。
  • デバイスはトピック s/ucr に連続した空のメッセージのパブリッシュを開始し、認証情報を取得する準備ができたことをサーバーに通知します。
  • 次に、デバイス登録ページでデバイスからの接続を承認する必要があります。
  • デバイスが次の空のメッセージを送信すると、70,<tenantID>,<username>,<password> の形式の認証情報を受け取ることができます。

認証情報を受信した後、デバイスはMQTT接続を閉じて、受信した認証情報で新しい接続を作成できます。

ステップ 1: デバイスを確認する

クライアントがデータを送信しデバイスが存在しないときに MQTTはデバイスの自動作成をサポートするため、このステップはデバイスを手動で作成する場合にのみ必要です。

デバイスの作成は、静的テンプレート 100 を使用して実行できます。このテンプレートは、デバイスがまだ存在しない場合にのみ作成するため、デバイスのブートのたびに何もせずに使用できます。

デバイスは、クライアントがMQTT ClientIdで使用するIDに自動的にリンクされます。

100,Device Name,Device Type
備考
Things Cloud があらかじめ用意している静的テンプレートに使われているトピックは s/us です。

ステップ 2: 子デバイスを確認する

ルートデバイスと同様に、その子デバイスも自動デバイス作成の対象となります。

このステップを手動で行うには、子デバイスを作成するための 静的テンプレート 101 を送信します。テンプレートは、子デバイスが存在しない場合にのみ作成します。

101,Unique Child ID,Child Name,Child Type

ステップ 3: トピックにサブスクライブする

デバイスがオペレーションをサポートしている場合は、必要なすべてのトピック(静的テンプレートおよびSmartREST 2.0)をサブスクライブする必要があります。

サイクルフェーズ

ステップ A: CSV データを送信する

デバイスはアクティブなMQTT接続を保持している間、静的テンプレートのトピックまたはSmartRESTテンプレートのトピックのいずれかでパブリッシュして、サーバーにデータを送信できます。

MQTT ClientId に基づいて、物理デバイスは Things Cloud 内のデバイスオブジェクトに直接接続されます。したがって、送信するデータは自動的にデバイスに接続されます。

子デバイスにデータを送信するには、デバイス階層 で説明されているトピックにデータをパブリッシュします。

ステップ B: CSV オペレーションを受信する

トピックをサブスクライブすると、デバイスは自動的に Things Cloud にオペレーションを受け取りたいことを伝えます。作成されたオペレーションは、静的テンプレートまたはデバイスが定義するテンプレートを使用して自動的に解析されます。

MQTT の実装

このセクションでは、MQTTプロトコルの実装の詳細を示します。 Things Cloudの実装は、MQTTバージョン3.1.1をサポートしています。

MQTT 標準接続

Things Cloud は TCP と Web ソケットの両方で MQTT をサポートしています。URL として、利用しているテナントのドメイン(例:mytenant.je1.thingscloud.ntt.com/mqtt)、もしくは次の形式のインスタンスのドメイン mqtt.<instance_domain>(例:mqtt.je1.thingscloud.ntt.com)を利用できます(例: mqtt.je1.thingscloud.ntt.com)。

使用可能なポート:

  TCP WebSockets
SSL 8883 443
no SSL 1883 80
備考
クラウドシステムではポート 80 が無効になります。

ポート 8883 は、クライアント認証に証明書を使用する双方向 SSL と、クライアント認証にユーザー名とパスワードを使用する一方向 SSL の 2 種類の SSL をサポートします。 双方向 SSL サポートはデフォルトで有効になっています。無効にするには、製品サポート にお問い合わせください。

備考
WebSocketsを使用するには、パス/mqttに接続し、WebSocket通信のMQTT標準に従う必要があります。

SmartREST ペイロード

Things Cloud の MQTT 実装は、SmartREST をペイロードとして使用します。 SmartRESTは、CSVに似たメッセージプロトコルで、サーバーサイドのテンプレートを使用してThings Cloudでデータを作成します。REST APIの高い表現力を取り入れていますが、組み込みデバイスのJSON解析の複雑さを回避するために、JSONをカンマ区切り値(CSV)に置き換えています。 さらに、CSVのシンプルでコンパクトな構文により、モバイルネットワークを介したIoT通信でも非常に効率的です。 他のHTTP APIと比較して、モバイルトラフィックを最大80%節約できます。

備考
プラットフォームへのすべてのMQTT接続は、最大許容メッセージサイズは16,184バイト(約16キロバイト)です。メッセージヘッダーと本文の両方が含まれます。ヘッダーサイズはさまざまですが、最小サイズは2バイトです。本文のサイズはトピックとペイロードを合わせたサイズです。

SmartREST の基本

SmartRESTメッセージは、各パラメータがカンマで区切られた1行で構成されています。最初のパラメータはメッセージを定義するIDです。メッセージ間に改行を使用することで、1回のパブリッシュで複数のメッセージを送信できます。

SmartRESTエスケープ

CSV(カンマ区切り値)形式は、SmartRESTエンドポイントとの通信に使用されます。正常に通信するためには以下の規則に従う必要があります。

  • すべての行は\nで終了する必要があります
  • 値は常にカンマ(,)で区切られている必要があります
  • 値に二重引用符(")、カンマ(,)、前後の空白、改行(\n)、キャリッジリターン(\r)、タブを含む場合、二重引用符(")で囲む必要があります。二重引用符(")は、バックスラッシュ(\)を前に付けてエスケープする必要があります。

サーバーからクライアントに送信されるメッセージにも同様のエスケープ規則が適用されます。

パブリッシュの例:

100,"This value, needs escaping",This value does not need escaping

サブスクライブの例:

511,myDeviceSerial,"execute this\nand this\nand ""this"""
備考
\nは出力(例: コンソールやUI)中では新規の行を作成しません。新規の行を作成するには、改行文字(ASCII 0A)を使用する必要があります。

デバイス階層

MQTTセッションは1つのデバイスにリンクされますが、このデバイスの下には自由に設定可能なデバイス階層を持つことができます。

すべての子デバイスには、デバイスの作成時に定義された一意のIDが必要です。ルートデバイスの一意のIDと階層内の一意のIDを組み合わせて使用することをお勧めします。

ルートデバイスの代わりに子デバイスのデータを作成するには、子デバイスの一意のIDをトピックの別のセクションとして追加します(例: s/us/myChildDeviceIdentifier)。

クライアントは、それぞれのトピックをサブスクライブすることにより、階層内のすべての子デバイスに対するオペレーションを自動的に受信します。子デバイスごとにサブスクライブする必要はありません。

受信されたすべてのオペレーションには、テンプレートIDの後に、そのオペレーションが作成されたデバイス/子デバイスのIDが含まれます(その後に他のオペレーションパラメータが続きます)。

MQTT機能

MQTT認証

Things Cloudとの通信において、MQTTは以下の2つの方法で認証をサポートしています。

  • ユーザー名とパスワード。MQTTユーザー名は、<tenantID/username>の形式でテナントIDとユーザー名を含める必要があります。
  • デバイス証明書。デバイスには、信頼されたルート証明書につながる証明書のチェーン全体が含まれている必要があります。 また、デバイス証明書のみが提供される場合、直近の発行者証明書をプラットフォームのトラストストアにアップロードする必要があります。さらに、サーバー証明書も自身のトラストストアに含める必要があります。

トラブルシューティング

デバイスから正しいユーザー名とパスワードが送信されるが、同時に不正な証明書も送信される

プラットフォームが双方向 SSL をサポートするように構成されており、デバイスに無効な証明書を含む構成されたキーストアがあり、基本認証を使用したい場合は、接続中に証明書の送信をオフにすることをお勧めします。 証明書の有効期限が切れているか、ルート証明書がプラットフォームにアップロードされていないため、証明書が無効である可能性があります。 デバイスのソフトウェアでの証明書の送信をオフにしてください。 それが不可能な場合、接続を機能させるには次の点を確認してください。

  • プラットフォームのトラストストアを空にすることはできません。 少なくとも 1 つの信頼できる証明書をプラットフォームにアップロードする必要があります。
  • デバイスの MQTT クライアントは、ハンドシェイク中にサーバーから返された承認された発行者リストにルート証明書が見つからない場合、証明書を送信しないように構成する必要があります。 ほとんどの場合、これは自動的に行われます。 MQTT クライアントと Java 11 では動作しないことが知られていますが、Java 8 では動作します。
  • この状況をサポートするには、プラットフォームをそれに応じて構成する必要があります。 製品サポートまでお問い合わせください。
  • 上記のすべてのケースが満たされているにも関わらず、証明書の検証によりデバイス接続が拒否される場合は、おそらく他のテナントが、デバイスから送信された証明書の 1 つと同じ「コモンネーム」を持つ証明書をアップロードした可能性があります。 この場合、デバイスは常に証明書を使用して独自に認証しようとします。

MQTT ClientId

MQTT ClientIdは、接続されている各クライアントを一意に識別するフィールドです。 Things Cloud実装もClientIdを使用して、クライアントを直接デバイスにリンクします。したがって、ClientIdには次の形式を使用する必要があります。

connectionType:deviceIdentifier:defaultTemplateIdentifier

フィールド 必須 説明
connectionType いいえ 接続タイプのデフォルト表示:d(デバイス)
deviceIdentifier はい デバイスの一意の識別子。例:IMEI、シリアル番号
defaultTemplateIdentifier いいえ テンプレート識別子に関する詳細は
MQTT静的テンプレートを確認してください

クライアントの最も単純なバージョンでは、MQTT ClientIdは単にdeviceIdentfierにすることができます。デバイス接続として自動的に解釈されます。

重要
コロン文字はThings Cloudでは特別な意味を持つため、deviceIdentifierでは使用しないでください。

ClientIdの例:

mySerialNumber
d:mySerialNumber
d:mySerialNumber:myDefaultTemplate

MQTT ClientIdの一意性は、deviceIdentifierによってのみ決定されます。したがって、上記の例では、同時に接続できるクライアントは1つだけです。 証明書によるSSL接続では、deviceIdentifierは使用されている証明書(デバイスにより提供される証明書チェーンのうち最初のもの)の「コモンネーム」と一致している必要があります。

MQTTサービス品質(QoS)

Things Cloud実装は、MQTT QoSの3つのレベルすべてをサポートします。

  • QoS 0: 最大1回
    • クライアントは一度だけメッセージを送信します。
    • サーバーからの応答はありません。
  • QoS 1: 1回以上
    • クライアントはサーバーからの確認応答を受け取るまでメッセージを送信し続けます。
  • QoS 2: 1回のみ
    • クライアントはメッセージを送信します。
    • サーバーは確認応答を返します(メッセージは保持されます)。
    • クライアントはリリースコマンドを送信します。
    • サーバーはメッセージを処理し、再度確認応答を返します。

オペレーショントピックまたはエラートピックをサブスクライブする場合は、トピックのサブスクライブ時にクライアントが定義したQoS内のすべてのメッセージを配信します。

MQTTクリーンセッション

Things Cloudは、クリーンセッションを「1」(true)に設定する必要があります。現在のところ、クリーンセッションを無効にしても完全に動作することは保証できませんので、常にクリーンセッションを有効にすることを推奨します。

MQTT保持フラグ

現在のThings Cloud実装では、デバイスがデータをパブリッシュするトピックへのサブスクリプションは許可されていません。このトピックに保持フラグを付けてデータをパブリッシュすることはできますが、フラグを付けずにデータを送信することと実質的な違いはありません。 Things Cloudがパブリッシュするオペレーションやエラーなどのメッセージには、保持フラグは含まれません。

MQTT last will

MQTTでは、「last will」は接続時に指定し、クライアントが接続を失ったときに実行されるメッセージです。例えば、last willメッセージとして 400,c8y_ConnectionEvent,"デバイス接続が失われました。" 、last willトピックとして s/usを指定すると、デバイスが接続を失うたびにイベントが発生します。

備考
「last will」が実行されると、デバイスの可用性が更新されます。

MQTT リターンコード

MQTT エラーが発生した場合、プラットフォームはゼロ以外のリターンコードを含むCONNACKメッセージで応答します。 このメッセージは、問題があることを示す最初の手がかりです。 このようなリターンコードは、401 などの REST API HTTP コードと同様に扱うことができます。 これらは、予期しないエラーや権限の不足などの理由で返される可能性があります。

CONNACKCONNECTメッセージに対する応答であるだけでなく、プラットフォームで発生したエラーを通知する方法でもあります。 したがって、通常の接続中に直接アクションを行わなくても、このメッセージを 2 回目に受信する可能性があります。 ほとんどの MQTT クライアントは、接続を閉じる必要があるかのように0以外のコードでCONNACKを扱うため、これは接続の終了を知らせる方法でもあります。 詳細は以下を参照してください。

以下の表は、Things Cloudによって返されるエラーのリストを示しています。

コード 標準メッセージ トラブルシューティング
0 Connection accepted 問題ありません。接続は機能しています。
1 Connection refused,
unacceptable protocol version
MQTT プロトコルのサポートされていないバージョン。
現在、Things Cloudでは 3.1 と 3.1.1 のみが許可されています。
2 Connection refused, identifier rejected ClientId がプラットフォームに受け入れられません。
3 Connection refused, Server unavailable 一般的なプラットフォーム側のエラー。
内部エラーや不明な認証の問題で受信されることもあります。
ネットワークの問題で受信できます。
このエラーは一時的なものでありデバイスの状態とは
無関係であるため、通常の解決策は後で再試行することです。
4 Connection refused, bad username or password 認証情報が正しくありません (パスワードが空ではありませんが、
ユーザー名やパスワードが間違っています)。
証明書を使用して認証する場合、
このエラーが返されることはありません。
5 Connection refused, not authorized ほとんどがデバイス側に関連した問題で、
デバイスにアクセス許可がない、または禁止されている操作を行っている場合に使用されます。
例えば、クライアントが不正なメッセージを送信したり、
メッセージの公開など、最初に認証を行わずに操作を実行しようとした場合などです。
証明書の認証に関する問題(コモンネームが間違っている、
自動登録が失敗したなど)が発生した場合にスローされます。
また、デバイス データの受信に関する一般的な問題や、
プラットフォーム上のデバイスの状態に関連する
その他の認証の問題でもスローされます。
例えば、デバイスのマネージドオブジェクト問題や、
アクセス権限が突然削除された場合などです。
この状況では、プラットフォーム上で調査と修正の適用を
行う必要がある場合があります。
MQTT バージョン 3.1 を使用している場合、clientId が長すぎると、
このエラーが発生する可能性があります。
これは、clientId が 24 文字以上の場合に発生する可能性があります。
最後に、特に接続中のパフォーマンスの問題など、
予期しない例外が発生した場合にもスローされる可能性があります。
したがって、一時的なパフォーマンスの問題を解決するには、接続を数回繰り返すことが良い方法です。

公式の MQTT 接続リターン コードの詳細については、MQTT Version 3.1.1 > 3.2 CONNACK - Acknowledge connection requestを参照してください。

デバッグ

開発中に開発者をサポートするために、トピックs/eをサブスクライブできます。このトピックでは、デバイスからパブリッシュ中に発生するデバッグメッセージおよびエラーメッセージを取得できます。

備考
このトピックは、純粋にクライアントの開発をサポートするために設計されています。メッセージが冗長であり、データ使用量を大幅に増加させる可能性があるため、常にこのチャネルをサブスクライブすることはお勧めしません。また、このトピックを使用して、そのトピックで受信した内容に基づいてデバイスのアクションをトリガーしないでください。レスポンスチャネルではありません。

MQTTブローカ証明書

MQTT ブローカーは、メイン環境ドメインに割り当てられた証明書を使用します。 MQTT ブローカーは、常にTLS ハンドシェイク中に、これらの証明書をデバイスに送信します。 さらに、エンタープライズテナント(親テナント)はSSL管理機能を経由してMQTTブローカの証明書をカスタマイズすることはできません。

MQTT JWTセッショントークンの取得

x.509 証明書を使用してプラットフォームに接続する、Java で実装された Things Cloud MQTT サンプル クライアントのコードは、ここから入手できます: https://github.com/Cumulocity-IoT//cumulocity-examples/tree/develop/mqtt-client。 このサンプル クライアントでは、Eclipse Paho の実装が使用されています。詳細については、Webサイト (https://www.eclipse.org/paho/index.php?page=documentation.php) で説明されています。

以下は、Eclipse Paho クライアントを使用するために必要な依存関係を Maven に追加する方法を示す例です。

<dependency>
    <groupId>org.eclipse.paho</groupId>
    <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
    <version>${paho.version}</version>
</dependency>

次に、MQTT クライアントのインスタンスを 1 行で作成できます。

MqttClient mqttClient = new MqttClient(BROKER_URL, "d:" + CLIENT_ID, new MemoryPersistence());

BROKER_URL には、ssl://<cumulocity url>:8883のように、クライアントが接続するプロトコル、URL、ポートが含まれている必要があります。 CLIENT_ID 値は、使用されるデバイス証明書のコモンネームの値と一致する必要があります。 証明書のコモンネームには : 文字を含めることはできません。詳細は MQTT ClientId を参照してください。 「d:」プレフィクスは、デバイス接続のためにThings Cloud で使用されているため、削除または変更しないでください。SSL 接続を確立するために設定する必要があるのは、コードフラグメントにパスを入力することだけです。

sslProperties.put(SSLSocketFactoryFactory.KEYSTORE, getClass().getClassLoader().getResource(KEYSTORE_NAME).getPath());
sslProperties.put(SSLSocketFactoryFactory.KEYSTOREPWD, KEYSTORE_PASSWORD);
sslProperties.put(SSLSocketFactoryFactory.KEYSTORETYPE, KEYSTORE_FORMAT);
sslProperties.put(SSLSocketFactoryFactory.TRUSTSTORE, getClass().getClassLoader().getResource(TRUSTSTORE_NAME).getPath());
sslProperties.put(SSLSocketFactoryFactory.TRUSTSTOREPWD, TRUSTSTORE_PASSWORD);
sslProperties.put(SSLSocketFactoryFactory.TRUSTSTORETYPE, TRUSTSTORE_FORMAT);
  • 証明書のコモンネームには : 文字を含めることはできません。詳細は MQTT ClientId を参照してください。
  • KEYSTORE_NAMEは、キーストアへのパスです。キーストアには、デバイス自体を認証するために使用する秘密鍵と証明書のチェーンが含まれています。
  • KEYSTORE_PASSWORD は、キーストアがその秘密鍵を使用するために作成されたパスワードです。
  • KEYSTORE_FORMAT - はファイル形式に応じて「JKS」または「PKCS12」にする必要があります。 パスは KEYSTORE_NAME によって提供されます。
  • TRUSTSTORE_NAME は、サーバーの証明書が含まれるトラストストアへのパスです。
  • TRUSTSTORE_PASSWORD はトラストストアにアクセスするためのパスワードです。
  • TRUSTSTORE_FORMAT は、ファイル形式に応じて「JKS」または「PKCS12」にする必要があります。 パスは TRUSTSTORE によって提供されます。

このデータを入力すると、サンプルクライアントは提供されたデータを使用し、証明書を用いて指定されたプラットフォームに接続します。 この例では、接続用のコールバックを作成する方法も示しています。 まず最初に、インターフェース、MqttCallbackExtended を実装するクラスを作成します。 次に、このようなクラスを作成し、そのインスタンスを MQTT クライアントに提供できます: mqttClient.setCallback(this);

一般的に、MQTT Eclipse Paho クライアントは Java Development Kit の一部である Java Secure Socket Extension を使用して SSL によるセキュアな接続を提供します。 JSSE は、開発者がそのクラスを使用して構成できる SSL および TLS プロトコルの Java 実装を提供します。 Java Secure Socket Extension のドキュメントでは、SSL 接続がどのように確立されるかを示し、実装をカスタマイズする例をいくつか提供しています。 完全なドキュメントは公式Oracleウェブサイトで入手できます。

MQTTのサンプル

Hello MQTT

このチュートリアルでは、Things CloudでMQTTを事前定義されたメッセージ(「静的テンプレート」と呼ばれます)を使って利用する方法を学びます。

前提条件

このチュートリアルを進めるために、以下の前提条件を確認してください。

  • Things Cloudへアクセスするための有効なテナント・ユーザー・パスワードを持っていること
  • MQTTBox または同様のMQTTツールをインストールしていること
備考
  • チュートリアルのスクリーンショットはMQTTBoxを使用しています。他のツールの場合、見た目が異なる場合があります。
  • トライアルテナントを利用している場合、デフォルトユーザーではこのチュートリアルは動作しません。追加のユーザーを作成してください。また、テナントIDやURLの情報もトライアルテナントとは異なります。

MQTT接続の設定

MQTT接続を設定するには、以下の接続パラメータを渡す必要があります(下記のスクリーンショット参照)。

  • MQTTクライアント名 – クライアントを識別するための名前を付けてください(例:Things Cloud MQTT)。
  • MQTTクライアントID – 「ランダムID生成」ボタン(ほとんどのツールで用意されています)を使うか、自分で指定してください。このIDはThings Cloud内のデバイスに紐づけられます。同じデバイスで再接続したい場合は同じIDを使ってください。
  • プロトコル – 使用するプロトコルを選択します(例:mqtt/tcp)。
  • ホスト – テナントドメインをURLとして指定します(例:mytenant.je1.thingscloud.ntt.com/mqtt)。
  • ユーザー名 – この場合、ユーザー名は <tenantID>/<service-user> 形式です。Things Cloudプラットフォームへログインする際と同じ認証情報を使えます(ユーザーエイリアスはサポートされていません)。下記例では、テナントID「t76543210」とサービスユーザー「manga」の場合、ユーザー名は「t76543210/manga」となります。
  • パスワード – サービスユーザーのパスワード

Things CloudはTCPとWebSocketsの両方でMQTTをサポートしています。URLにはテナントドメイン(例:mytenant.je1.thingscloud.ntt.com/mqtt)またはインスタンスのドメイン(mqtt.<instance_domain>形式、例:mqtt.je1.thingscloud.ntt.com)を利用できます。

MQTTBox設定例

備考
Things Cloud OpenAPI仕様のテナント > テナントIDとテナントドメインを参照すると、テナントIDとテナントドメインの違いについて理解が深まります。

「クリーンセッション」など他の設定は今回の例では重要ではありません。必要に応じて変更できます。Saveをクリックすると、以下のような画面が表示されます。

MQTTBox接続確立

上部バーに青いボタンでNot Connectedと表示されている場合は、設定(特にユーザー名とパスワード)を確認してください。ボタンが緑色なら、Things CloudへのMQTT接続が正常に確立されています。

データ送信

このチュートリアルの全てのMQTTパブリッシュメッセージは s/us トピックに送信されます。これはThings Cloudが提供する静的テンプレート用のトピックです。

MQTTBoxパブリッシュメッセージ

デバイスの作成

最初に送信するメッセージは、デバイスの作成です。静的テンプレートは自動デバイス作成もサポートしていますが、この例では手動で作成します。テンプレート100で新しいデバイスを作成できます。2つのオプションパラメータ(deviceName, deviceType)が利用可能です。

100,My first MQTT device,c8y_MQTTdevice

この後、デバイス管理アプリケーションで新しいデバイスとして表示されます。デバイスの識別情報タブに切り替えると、デバイスとMQTT ClientIdを紐付けるための識別情報が自動で作成されていることが分かります。

名前とタイプ以外に情報はありませんので、マスターデータを追加する必要があります。

1回のパブリッシュで、複数の静的テンプレートを改行区切り(1行に1テンプレート)で送信できます。この機能を利用して、ハードウェア情報と必要なインターバルを1回のメッセージで送信できます。

ハードウェア情報はテンプレート110で設定できます。3つのパラメータ(serialNumber, model, revision)が利用可能です。静的テンプレートのオプションパラメータは、不要な場合空欄で構いません。ハードウェアについては全てオプションです。

必要なインターバルはテンプレート117で分単位で指定します。

110,,MQTT test model,1.2.3
117,10

デバイス管理アプリケーションの情報ページをリロードすると、追加した情報が反映されているのが確認できます。

メジャーメントの作成

デバイスにマスターデータが追加されたので、メジャーメント送信を開始できます。 静的テンプレートで直接作成できるメジャーメントはいくつかあります:

  • 210: 信号強度メジャーメント
  • 211: 温度メジャーメント
  • 212: バッテリーメジャーメント

温度・バッテリーメジャーメントは値と時刻がパラメータです。信号強度には2つの値(RSSIとBER)を渡せます。

Things CloudのMQTT実装では、タイムスタンプの指定は常にオプションです。指定しない場合、サーバーが現在時刻でタイムスタンプを自動作成します。

この例でもこの機能を利用します。また、最後のパラメータを設定しない場合、残りのカンマも入力する必要はありません。

210,-87
211,24
212,95

上記以外のメジャーメントはテンプレート200でカスタム作成できます。パラメータは、メジャーメントフラグメント、シリーズ、値、単位、時刻です。

200,myCustomTemperatureMeasurement,fahrenheit,75.2,F

デバイス管理アプリケーションをリロードすると、メジャーメントタブで新たに追加した4つのグラフが表示されます。

アラームの作成

次に、このデバイスにアラームを作成します。4つのアラーム重大度ごとにテンプレートがあります:

  • 301: CRITICAL
  • 302: MAJOR
  • 303: MINOR
  • 304: WARNING

いずれもタイプ(必須)、テキスト、時刻(いずれもオプション)を指定できます。

301,gpio_critical,There is a GPIO alarm
304,simple_warning

デバイスのアラームリストにクリティカルアラームとワーニングアラームが1つずつ追加されているはずです。

ワーニングにはテキストを指定しなかったため、デフォルトのアラームテキストで作成されています。

次に、クリティカルアラームをクリアします。テンプレート306を使用し、クリアしたいアラームのタイプを指定します。

306,gpio_critical

クリティカルアラームはクリアされます。

MQTT実装ではアラームIDを個別に管理する必要はありません。Things Cloudが自動的に処理するため、デバイスとの通信が極めて簡単になります。

イベントの作成

次に、デバイスに位置イベントを作成します。必要ならLatLongのウェブサイトで都市の緯度・経度を調べてください。

テンプレート401で位置イベントを作成できます。パラメータは緯度、経度、高度、精度、時刻ですが、今回は最初の2つだけを使います。

401,51.227741,6.773456

デバイス管理アプリケーションのイベントリストで1つのイベントが確認できますが、位置情報自体はまだ更新されていません。これはRESTでは別のリクエストになるためです。MQTTではテンプレート402を使うことで、イベント作成と同時にデバイスの位置情報も更新できます。

402,51.227741,6.773456

これでデバイスの位置情報タブとトラッキングタブの両方に、直近の位置イベントと同じ緯度・経度が表示されます。

データ受信

ここまではクライアントからサーバーへのデータ送信だけでした。ここからはサーバーからクライアントへのデータ送信を行います。

まず、該当トピックをサブスクライブする必要があります。今回は2つサブスクライブします:

  • s/ds : デバイス用の静的オペレーションテンプレート
  • s/e : デバッグ用途のエラートピック

Subscribe欄に両方のトピックを入力し、Subscribeをクリックしてください。この例ではQoSの選択は重要ではありません。

MQTTBoxは次のようになります:

MQTTBoxサブスクライブ済トピック

オペレーションを受信する

現時点では、UIにオペレーション用のタブは表示されません。デバイスがどのオペレーションをサポートするかはまだ未定なので、テンプレート114でサポートするオペレーション一覧を追加します。

今回は構成とシェルを追加します。

114,c8y_Command,c8y_Configuration

UIをリロードすると、構成シェルの2つの新しいタブが表示されます。

UIからシェルコマンドを作成し、実行をクリックできます。

MQTTBoxでs/dsサブスクリプションの新しいメッセージが受信されるはずです。

MQTTBox受信オペレーション

511は受信したオペレーションの種類(この場合はc8y_Command)を示します。続いてdeviceIdentifierが続き、階層構造で複数の子デバイスがある場合に、どの子へのオペレーションか特定するため必要となります。最後はオペレーション固有のパラメータ(c8y_Commandの場合はコマンドテキストのみ)です。

オペレーションを受信したら、クライアント側で処理を開始します。アラームのステータス変更と同様、テンプレートにオペレーションタイプを追加できます。

501,c8y_Command

処理が完了したら、テンプレート503でオペレーションを成功としてマークできます。

オペレーションタイプ以外にも、オペレーションの種類に応じて追加パラメータが指定できます。c8y_Commandの場合は結果を返すことができます。

503,c8y_Command,Everything went fine
エラーから学ぶ

s/eトピックは、何か問題が発生した場合のデバッグに役立ちます。 たとえば、以下を送信すると

999,I made this up

テンプレート999が不明なため、トピック上にメッセージが表示されます。

40,999,No static template for this message id

※以降の「Hello MQTT C」「Hello MQTT Java」「Hello MQTT Java with certificates」「Hello MQTT browser-based」「Hello MQTT Node.js」「Hello MQTT Python」についても同様に、

  • アプリ名やUIに現れる箇所(Device Management application等)も「デバイス管理アプリケーション」など日本語訳にしてください。
  • 用語集のルールを適用し、マークダウン記号やコードブロック、{{}}は変更しないでください。
  • コメントや空白行はそのまま保持してください。