MQTTのサンプル
Hello MQTT
このチュートリアルでは、事前定義されたメッセージ(「静的テンプレート」)を使用して、Things Cloud で MQTT を使用する方法を学びます。
前提条件
このチュートリアルを進めるには、次の前提条件を確認してください。
Things Cloud にアクセスするための有効なテナント、ユーザ、パスワードがあること。
MQTTBox または同様の MQTT ツールをインストールしていること。
備考
このチュートリアルのスクリーンショットでは MQTTBox を使用しています。ほかのツールでは表示が異なる場合があります。
トライアルテナントを使用している場合、デフォルトユーザはこのチュートリアルでは使用できません。代わりに追加のユーザを作成してください。テナント ID と URL データも、トライアルテナント情報とは異なります。
MQTT 接続の設定
MQTT 接続を設定するには、次の接続パラメータを渡す必要があります(以下のスクリーンショットを参照)。
MQTT Client Name – クライアントを識別するための名前を付けます。たとえば、Things Cloud MQTT です。
MQTT Client Id – 「Generate a random ID」ボタンを使用するか(ほとんどのツールにはこのようなボタンがあります)、自分で指定します。この ID は Things Cloud 内のデバイスにリンクされます。同じデバイスに再接続するには、同じ ID を使用します。
Protocol – 使用するプロトコルを選択します。たとえば、mqtt/tcp です。
Host – URL にテナントドメインを指定します。たとえば、mytenant.je1.thingscloud.ntt.com/mqtt です。
Username – この場合、ユーザ名は <tenantID>/<service-user> の形式です。Things Cloud プラットフォームへのログインに使用するものと同じ認証情報を使用できます(ユーザエイリアスはサポートされていません)。以下の例のように、テナント ID が「t76543210」、サービスユーザが「manga」の場合、ユーザ名は「t76543210/manga」です。
Password: サービスユーザのパスワード。
Things Cloud は TCP と WebSockets の両方で MQTT をサポートしています。URL としては、テナントドメイン(たとえば mytenant.je1.thingscloud.ntt.com/mqtt )または mqtt.<instance_domain> 形式のインスタンスドメイン(たとえば mqtt.je1.thingscloud.ntt.com )を使用できます。
「clean session」などのほかの設定は、この例では重要ではありません。必要に応じて変更できます。Save をクリックすると、次のスクリーンショットのような画面が表示されます。
上部バーに Not Connected と表示された青いボタンがある場合は、設定(特にユーザ名とパスワード)を確認してください。ボタンが緑色であれば、Things Cloud への MQTT 接続は正常に確立されています。
データの送信
このチュートリアルのすべての MQTT パブリッシュメッセージは、トピック s/us に送信されます。これは、Things Cloud の事前提供された静的テンプレートに使用されるトピックです。
デバイスの作成
最初に送信するメッセージでデバイスを作成します。静的テンプレートは自動デバイス作成をサポートしていますが、この例ではデバイスを手動で作成します。テンプレート 100 は新しいデバイスを作成します。これは 2 つのオプションパラメータ(deviceName、deviceType)とともに使用できます。
100,My first MQTT device,c8y_MQTTdevice
その後、このデバイスはデバイス管理アプリケーション内で新しいデバイスとして見つかります。デバイスの Identity タブに切り替えると、デバイスを MQTT ClientId にリンクするための ID が自動的に作成されていることがわかります。
名前とタイプ以外には、このデバイスにはそれ以上の情報がないため、マスターデータを追加する必要があります。
1 回のパブリッシュで、改行区切りにより複数の静的テンプレートを使用できます(1 行につき 1 テンプレート)。この機能は、1 つのパブリッシュメッセージでハードウェア情報とデバイスに必要な間隔を設定するために使用されます。
ハードウェアはテンプレート 110 で設定できます。これは 3 つのパラメータ(serialNumber、model、revision)を取ります。静的テンプレートのオプションパラメータは、設定したくない場合は空のままにできます。ハードウェアについては、すべてのパラメータがオプションです。
必要な間隔はテンプレート 117 で設定でき、1 つのパラメータ(分単位の間隔)だけを取ります。
110,,MQTT test model,1.2.3
117,10
デバイス管理アプリケーションでデバイスの Info ページを再読み込みすると、追加した情報が表示されるはずです。
メジャーメントの作成
これでデバイスにはいくつかのマスターデータが設定され、メジャーメントの送信を開始できます。
静的テンプレートを使用して直接作成できるメジャーメントがいくつかあります。
210: 信号強度メジャーメント
211: 温度メジャーメント
212: バッテリーメジャーメント
温度メジャーメントとバッテリーメジャーメントは、値と時刻をパラメータとして取るだけです。信号強度については、2 つの値(RSSI と BER)を渡すことができます。
Things Cloud の MQTT 実装でタイムスタンプを渡すことは常にオプションです。渡さない場合、サーバは現在のサーバ時刻でタイムスタンプを自動的に作成します。
この例ではこの機能を使用します。また、最後のパラメータを設定しない場合は、残りのカンマを入力する必要もありません。
上記のメジャーメントに加えて、テンプレート 200 を使用して、よりカスタムなメジャーメントを作成することもできます。これは、メジャーメントフラグメント、series、値、単位、時刻をパラメータとして取ります。
200,myCustomTemperatureMeasurement,fahrenheit,75.2,F
デバイス管理アプリケーションで再読み込みすると、デバイスの Measurements タブに、新しく追加されたメジャーメントを含む 4 つのグラフが表示されるはずです。
アラームの作成
次に、このデバイス用にいくつかのアラームを作成します。4 つのアラーム重大度に対応するアラーム作成用テンプレートがあります。
301: CRITICAL
302: MAJOR
303: MINOR
304: WARNING
それぞれ、type(必須)、text、time(後者 2 つはオプション)を指定します。
301,gpio_critical,There is a GPIO alarm
304,simple_warning
これでデバイスのアラームリストには、critical アラーム 1 件と warning アラーム 1 件が含まれるはずです。
warning には text を設定していないため、デフォルトのアラームテキストで作成されたことに注意してください。
次に、critical アラームを再度クリアします。これを行うには、クリアするアラームの type を参照するテンプレート 306 を使用します。
その後、critical アラームはクリアされるはずです。
MQTT 実装ではアラーム ID を扱う必要がなかったことに注意してください。Things Cloud がこの部分を引き受けるため、デバイス通信をできるだけ簡単にできます。
イベントの作成
次に、デバイス用にいくつかの位置イベントを作成します。必要に応じて、都市の緯度と経度を取得するために LatLong website を使用できます。
テンプレート 401 を使用すると位置イベントを作成でき、緯度、経度、高度、精度、時刻をパラメータとして取りますが、ここでは最初の 2 つだけを使用します。
デバイス管理アプリケーションではイベントリストに 1 つのイベントが表示されますが、位置は更新されていません。これは REST ではこれらが別々のリクエストだからです。MQTT では、テンプレート 401 の代わりにテンプレート 402 を使用できます。これは 401 とまったく同じように動作しますが、さらにデバイス自体の位置も更新します。
これでデバイスに Location タブと Tracking タブの両方が表示され、Location タブには最後の位置イベントと同じ緯度と経度が表示されるはずです。
データの受信
ここまでは、MQTT を使用してクライアントからサーバへデータを送信するだけでした。次は、サーバからクライアントへデータを送信します。
これを実現するには、まず対象のトピックをサブスクライブする必要があります。ここでは 2 つのサブスクリプションを行います。
s/ds : デバイス用の静的オペレーションテンプレートをサブスクライブします
s/e : デバッグに使用できるエラートピックをサブスクライブします
Subscribe フィールドに両方のトピックを順に入力し、Subscribe をクリックできます。QoS の選択はこの例では重要ではありません。
その後、MQTTBox は次のようになります。
オペレーションの受信
現在の状態では、UI にオペレーション用のタブは表示されません。ここまでは、デバイスが正確に何をサポートしているかは不明でしたが、サポートされるオペレーションのリストはテンプレート 114 で変更できます。ここにサポートされるオペレーションのリストを追加できます。
ここでは、configuration と shell のサポートを追加します。
114,c8y_Command,c8y_Configuration
UI を再読み込みすると、2 つの新しいタブ(Configuration と Shell )が表示されます。
これで UI から shell コマンドを作成し、Execute をクリックできます。
MQTTBox では、s/ds サブスクリプションに対して新しいメッセージを受信しているはずです。
511 は受信したオペレーションの種類(この場合は c8y_Command)を示しています。続いて、専用オペレーションを持つデバイスを特定するための deviceIdentifier が続きます。これは、複数の子を持つ階層がある場合に必要です。その場合、どの子に対するオペレーションなのかを知る必要があります。最後に、オペレーション固有のパラメータがあります。c8y_Command の場合はコマンドテキストのみです。
オペレーションを受信した後、クライアントによるオペレーション処理を開始できます。アラームのステータス変更と同様に、テンプレートにオペレーションの type を追加できます。
処理が完了したら、テンプレート 503 を使用してオペレーションを successful に設定できます。
オペレーション type に加えて、このオペレーションはオペレーションの種類に応じた追加パラメータも取ることができます。c8y_Command に対して結果を返すことができます。
503,c8y_Command,Everything went fine
エラーから学ぶ
トピック s/e は、何か問題が発生した場合のデバッグに役立ちます。
たとえば、次を送信しようとすると
テンプレート 999 が不明であるため、このトピックにメッセージが表示されます。
40,999,No static template for this message id
Hello MQTT C
このチュートリアルでは、事前定義されたメッセージ(「静的テンプレート」)を使用して、Things Cloud で C の MQTT クライアントを使用する方法を学びます。
前提条件
このチュートリアルを進めるには、次の前提条件を確認してください。
Things Cloud にアクセスするための有効なテナント、ユーザ、パスワードがあること。
gcc コンパイラがインストールされていることを確認します。
$ gcc --version
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
MQTT C Paho Client をダウンロード、コンパイル、インストールします。Paho の詳細については、Paho website を参照してください。
「Hello, MQTT world!」クライアントの開発
Things Cloud 用の非常にシンプルな「Hello, world!」MQTT クライアントを開発するには、次のことを行う必要があります。
アプリケーションを作成する
アプリケーションをビルドして実行する
アプリケーションの作成
ソースファイル(たとえば hello_mqtt.c )を作成し、次の内容を記述します。
#include "stdlib.h"
#include "string.h"
#include "unistd.h"
#include "MQTTClient.h"
#define ADDRESS "<<serverUrl>>"
#define CLIENTID "<<clientId>>"
void publish (MQTTClient client, char * topic, char * payload) {
MQTTClient_message pubmsg = MQTTClient_message_initializer;
pubmsg.payload = payload;
pubmsg.payloadlen = strlen(pubmsg.payload);
pubmsg.qos = 2 ;
pubmsg.retained = 0 ;
MQTTClient_deliveryToken token;
MQTTClient_publishMessage(client, topic, &pubmsg, &token);
MQTTClient_waitForCompletion(client, token, 1000L );
printf("Message '%s' with delivery token %d delivered \n " , payload, token);
}
int on_message (void *context, char *topicName, int topicLen, MQTTClient_message *message) {
char * payload = message->payload;
printf("Received operation %s \n " , payload);
MQTTClient_freeMessage(&message);
MQTTClient_free(topicName);
return 1 ;
}
int main (int argc, char * argv[]) {
MQTTClient client;
MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL );
MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
conn_opts.username = "<<tenant_ID>>/<<username>>" ;
conn_opts.password = "<<password>>" ;
MQTTClient_setCallbacks(client, NULL , NULL , on_message, NULL );
int rc;
if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) {
printf("Failed to connect, return code %d \n " , rc);
exit(-1 );
}
//create device
publish(client, "s/us" , "100,C MQTT,c8y_MQTTDevice" );
//set hardware information
publish(client, "s/us" , "110,S123456789,MQTT test model,Rev0.1" );
//listen for operation
MQTTClient_subscribe(client, "s/ds" , 0 );
for (;;) {
//send temperature measurement
publish(client, "s/us" , "211,25" );
sleep(3 );
}
MQTTClient_disconnect(client, 1000 );
MQTTClient_destroy(&client);
return rc;
}
<<clientId>>、<<serverUrl>>、<<tenant_ID>>、<<username>>、<<password>> を自分のデータに置き換えてください。
Things Cloud MQTT プロトコルは、セキュリティ保護されていない TCP 接続と、セキュリティ保護された SSL 接続の両方をサポートしています(たとえば tcp://mqtt.je1.thingscloud.ntt.com:1883 または ssl://mqtt.je1.thingscloud.ntt.com:8883)。そのため、<<serverUrl>> には自分に合ったものを選択できます。
SSL を使用する場合は、MQTTClient_SSLOptions を設定し、それを MQTTClient_connectOptions に設定することを忘れないでください。
main のコードは何を行いますか?
MQTT 接続を設定します。
受信メッセージを出力する on_message コールバック関数を登録します。
MQTT プロトコル経由で Things Cloud に接続します。
C MQTT という名前と c8y_MQTTDevice というタイプで新しいデバイスを作成します。
"S123456789" のシリアル、"MQTT test model" のモデル、"Rev0.1" のリビジョンを設定して、デバイスのハードウェア情報を更新します。
デバイス用の静的オペレーションテンプレートをサブスクライブします。これにより、新しいオペレーションが作成されるたびに on_message メソッドが呼び出されます。
3 秒ごとに温度メジャーメントを送信します。
publish のコードは何を行いますか?
新しい MQTT メッセージを作成し、ペイロードを設定します。
MQTT プロトコル経由でメッセージをパブリッシュします。
サーバからのメッセージ配信 ACK を最大 1 秒待機します。
サブスクリプションはデバイス作成後に確立されることに注意してください。そうしないと、指定された clientId に対するデバイスが存在しない場合、サーバはそれを受け付けません。
アプリケーションのビルドと実行
アプリケーションをビルドするには、次のように入力します。
$ gcc hello_mqtt.c -o hello_mqtt -lpaho-mqtt3c
アプリケーションを実行するには、次のように入力します。
$ ./hello_mqtt
Message '100,C MQTT,c8y_MQTTDevice' with delivery token 1 delivered
...
アプリケーションを起動すると、デバイス管理アプリケーションの All devices に、新しいデバイスが表示されるはずです。
さらに、このデバイスに対して新しいオペレーション(たとえば c8y_Restart)が作成されると、その情報がコンソールに出力されます。
エージェントの改善
最初の一歩を踏み出したので、Hello MQTT セクションを参照して、Things Cloud MQTT についてさらに学び、アプリケーションを改善してください。
Hello MQTT Java
このチュートリアルでは、事前定義されたメッセージ(「静的テンプレート」)を使用して、Things Cloud で Java MQTT クライアントを使用する方法を学びます。
前提条件
このチュートリアルを進めるには、次の前提条件を確認してください。
Things Cloud にアクセスするための有効なテナント、ユーザ、パスワードがあること。
Maven 3 と少なくとも Java 7 がインストールされていることを確認します。
$ mvn -v
Maven home: /Library/Maven/apache-maven-3.6.0
Java version: 1.8.0_201, vendor: Oracle Corporation, runtime: /Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre
Default locale: en_GB, platform encoding: UTF-8
OS name: "mac os x" , version: "10.14.2" , arch: "x86_64" , family: "mac"
Maven は Maven website からダウンロードできます。
「Hello, MQTT world!」クライアントの開発
Things Cloud 用の非常にシンプルな「Hello, world!」MQTT クライアントを開発するには、次のことを行う必要があります。
Maven プロジェクトを作成する
MQTT Java クライアントライブラリへの依存関係を pom.xml に追加する(この例では Paho Java Client を使用します)
Java アプリケーションを作成する
Java アプリケーションをビルドして実行する
Maven プロジェクトの作成
Maven でプレーンな Java プロジェクトを作成するには、次のコマンドを実行します。
$ mvn archetype:generate -DgroupId=c8y.example -DartifactId=hello-mqtt-java -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
これにより、現在のディレクトリに hello-mqtt-java フォルダが作成され、プロジェクトのスケルトン構造が生成されます。
MQTT Java クライアントライブラリの追加
hello-mqtt-java フォルダ内の pom.xml を編集します。MQTT Paho Java Client への依存関係を追加します。
<dependency>
<groupId> org.eclipse.paho</groupId>
<artifactId> org.eclipse.paho.client.mqttv3</artifactId>
<version> [1.2.1,)</version>
</dependency>
Java 9 以降を使用している場合は、Apache Maven Compiler Plugin のページで説明されているように source と target を設定し、次のコードを追加する必要があります。
<properties>
<maven.compiler.source> 1.8</maven.compiler.source>
<maven.compiler.target> 1.8</maven.compiler.target>
</properties>
Java アプリケーションの作成
hello-mqtt-java/src/main/java/c8y/example フォルダにある App.java ファイルを編集し、次の内容を記述します。
package c8y.example;
import org.eclipse.paho.client.mqttv3.*;
import java.util.concurrent.*;
public class App {
public static void main (String[] args) throws Exception {
// client, user and device details
final String serverUrl = "tcp://mqtt.cumulocity.com" ; /* ssl://mqtt.je1.thingscloud.ntt.com:8883 for a secure connection */
final String clientId = "my_mqtt_java_client" ;
final String device_name = "My Java MQTT device" ;
final String tenant = "<<tenant_ID>>" ;
final String username = "<<username>>" ;
final String password = "<<password>>" ;
// MQTT connection options
final MqttConnectOptions options = new MqttConnectOptions();
options.setUserName(tenant + "/" + username);
options.setPassword(password.toCharArray());
// connect the client to Things Cloud
final MqttClient client = new MqttClient(serverUrl, clientId, null );
client.connect(options);
// register a new device
client.publish("s/us" , ("100," + device_name + ",c8y_MQTTDevice" ).getBytes(), 2, false );
// set device's hardware information
client.publish("s/us" , "110,S123456789,MQTT test model,Rev0.1" .getBytes(), 2, false );
// add restart operation
client.publish("s/us" , "114,c8y_Restart" .getBytes(), 2, false );
System.out.println("The device \"" + device_name + "\" has been registered successfully!" );
// listen for operations
client.subscribe("s/ds" , new IMqttMessageListener() {
public void messageArrived (final String topic, final MqttMessage message) throws Exception {
final String payload = new String(message.getPayload());
System.out.println("Received operation " + payload);
if (payload.startsWith("510" )) {
// execute the operation in another thread to allow the MQTT client to
// finish processing this message and acknowledge receipt to the server
Executors.newSingleThreadScheduledExecutor().execute(new Runnable() {
public void run () {
try {
System.out.println("Simulating device restart..." );
client.publish("s/us" , "501,c8y_Restart" .getBytes(), 2, false );
System.out.println("...restarting..." );
Thread.sleep(TimeUnit.SECONDS.toMillis(5));
client.publish("s/us" , "503,c8y_Restart" .getBytes(), 2, false );
System.out.println("...done..." );
} catch (MqttException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
});
// generate a random temperature (10º-20º) measurement and send it every 7 seconds
Executors.newSingleThreadScheduledExecutor().scheduleWithFixedDelay(new Runnable() {
public void run () {
try {
int temp = (int ) (Math.random() * 10 + 10);
System.out.println("Sending temperature measurement (" + temp + "º) ..." );
client.publish("s/us" , new MqttMessage(("211," + temp).getBytes()));
} catch (MqttException e) {
e.printStackTrace();
}
}
}, 1, 7, TimeUnit.SECONDS);
}
}
必要に応じて serverUrl、clientId、device_name を置き換えてください。tenant_ID、username、password の値を設定して、ユーザ認証情報を指定することを忘れないでください。
Things Cloud MQTT プロトコルは、セキュリティ保護されていない TCP 接続と、セキュリティ保護された SSL 接続の両方をサポートしています(つまり、tcp://mqtt.je1.thingscloud.ntt.com:1883 または ssl://mqtt.je1.thingscloud.ntt.com:8883)。そのため、自分に合ったものを選択して serverUrl に使用できます。
main のコードは何を行いますか?
MQTT 接続を設定します。
MQTT プロトコル経由で Things Cloud に接続します。
名前 (device_name) とタイプ (c8y_MQTTDevice) を持つ新しいデバイスを作成します。
"S123456789" のシリアル、"MQTT test model" のモデル、"Rev0.1" のリビジョンを設定して、デバイスのハードウェア情報を更新します。
デバイス用の静的オペレーションテンプレートをサブスクライブし、受信したすべてのオペレーションをコンソールに出力します。c8y_Restart オペレーションの場合は、デバイスの再起動をシミュレートします。
7 秒ごとに温度メジャーメントを送信する新しいスレッドを作成します。
サブスクリプションはデバイス作成後に確立されることに注意してください。そうしないと、指定された clientId に対するデバイスが存在しない場合、サーバはそれを受け付けません。
アプリケーションのビルドと実行
アプリケーションをビルドするには、次のコマンドを使用します。
$ cd hello-mqtt-java
$ mvn clean install
...
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ hello-mqtt-java ---
[INFO] Building jar: /home/schm/Pulpit/hello-mqtt-java/target/hello-mqtt-java-1.0-SNAPSHOT.jar
[INFO]
[INFO] --- maven-install-plugin:2.4:install (default-install) @ hello-mqtt-java ---
[INFO] Installing /home/schm/Pulpit/hello-mqtt-java/target/hello-mqtt-java-1.0-SNAPSHOT.jar to /home/schm/.m2/repository/c8y/example/hello-mqtt-java/1.0-SNAPSHOT/hello-mqtt-java-1.0-SNAPSHOT.jar
[INFO] Installing /home/schm/Pulpit/hello-mqtt-java/pom.xml to /home/schm/.m2/repository/c8y/example/hello-mqtt-java/1.0-SNAPSHOT/hello-mqtt-java-1.0-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.642 s
[INFO] Finished at: 2017-03-14T09:16:25+01:00
[INFO] Final Memory: 14M/301M
[INFO] ------------------------------------------------------------------------
実行するには、次のコマンドを使用します。
$ mvn exec:java -Dexec.mainClass="c8y.example.App"
...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building hello-mqtt-java 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- exec-maven-plugin:1.6.0:java (default-cli) @ hello-mqtt-java ---
Received operation 510,123456789
アプリケーションを起動すると、デバイス管理アプリケーションの All devices に、新しく登録されたデバイスが表示されるはずです。Measurements タブでは、クライアントから送信される温度メジャーメントを確認できます。
さらに、このデバイスに対して新しいオペレーション(たとえば c8y_Restart)が作成されると、その情報がコンソールに出力されます。
エージェントの改善
最初の一歩を踏み出したので、Hello MQTT セクションを参照して、Things Cloud MQTT についてさらに学び、アプリケーションを改善してください。
Hello MQTT Java with certificates
このチュートリアルでは、X.509 証明書を認証に使用して、Things Cloud で Java MQTT クライアントを使用する方法を学びます。
GitHub リポジトリ cumulocity-examples には、X.509 証明書を使用するサンプル Java MQTT クライアントと、このチュートリアルで使用する必要なすべてのスクリプトがあります。
前提条件
このチュートリアルを進めるには、次の前提条件を確認してください。
Hello MQTT Java チュートリアルに基づいて Java クライアントが正しく設定されていること。
Things Cloud にアクセスするための有効なテナント、ユーザ、パスワードがあること。
有効な証明書があること。ない場合は、次のセクションの手順に従って生成してください。
有効な証明書を生成するには
有効な証明書がない場合は、デバイス証明書 の手順に従って、テスト目的で生成できます。
cumulocity-examples リポジトリからスクリプトをダウンロードします。
ルート自己署名証明書を作成し(00createRootSelfSignedCertificate.sh スクリプトを実行)、それをテナントにアップロードします。これは UI のデバイス管理アプリケーション または REST で行えます。
証明書を作成して署名します(01createSignedCertificate.sh スクリプトを実行)。
証明書をキーストアに移動します(02moveCertificatesToKeystore.sh スクリプトを実行)。さらに、キーストア内でデバイスのリーフ証明書のみが必要な場合は、–leafonly オプションを使用します。
最後に、次のコマンドを実行して信頼された証明書をキーストアにインポートします。
$ keytool -importcert -file c8y-mqtt-server.cer -keystore chain-with-private-key-iot-device-0001.jks -alias "Alias"
証明書付き「Hello, MQTT world!」クライアントの開発
証明書付きで Things Cloud 用の「Hello, world!」MQTT クライアントを開発するには、次のことを行う必要があります。
証明書をコピーしてプラットフォームにアップロードする
MQTT クライアントの設定を変更する
証明書をコピーしてアップロードするには
ファイル chain-iot-device-0001.pem から証明書をコピーし、POST リクエストを使用してプラットフォームにアップロードします。
エンドポイント: /tenant/tenants/{tenantId}/trusted-certificates
認証: Basic
Content-Type: application/json
リクエスト本文:
{
"status" : "ENABLED" ,
"name" : "sampleName" ,
"autoRegistrationEnabled" : "true" ,
"certInPemFormat" : "<<certificate in pem format>>"
}
設定を変更するには
MQTT クライアントの設定を変更するには、ファイル chain-with-private-key-iot-device-0001.jks をリソースフォルダにコピーし、設定を行います。使用するスクリプト(手順 4)ではパスワード changeit を使用することに注意してください。スクリプト内で値を変更した場合は、次の例の KEYSTORE_PASSWORD と TRUSTSTORE_PASSWORD でも同様に変更してください。
// Configuration
private static final String KEYSTORE_NAME = "chain-with-private-key-iot-device-0001.jks" ;
private static final String KEYSTORE_PASSWORD = "changeit" ;
private static final String KEYSTORE_FORMAT = "jks" ;
private static final String TRUSTSTORE_NAME = "chain-with-private-key-iot-device-0001.jks" ;
private static final String TRUSTSTORE_PASSWORD = "changeit" ;
private static final String TRUSTSTORE_FORMAT = "jks" ;
private static final String CLIENT_ID = "iotdevice0001" ;
private static final String BROKER_URL = "<SSL URL of the platform>" ;
private MqttClient connect () throws MqttException {
MqttClient mqttClient = new MqttClient(BROKER_URL, "d:" + CLIENT_ID, new MemoryPersistence());
MqttConnectOptions options = new MqttConnectOptions();
options.setCleanSession(true );
Properties sslProperties = new Properties();
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);
sslProperties.put(SSLSocketFactoryFactory.CLIENTAUTH, true );
options.setSSLProperties(sslProperties);
mqttClient.setCallback(this );
System.out.println("Connecting to the broker at " + BROKER_URL);
mqttClient.connect(options);
return mqttClient;
}
デバイスは、標準デバイスとしてパブリッシュおよびサブスクライブできるようになりました。最初の接続前には、たとえばユーザの作成など、ほかの操作は不要であることに注意してください。ユーザは 自動登録 プロセス中に作成されます。
備考
証明書を使用して接続する MQTT クライアントでは、パスワード、ユーザ、テナントを設定する必要はありません。Things Cloud は、提供された証明書によってテナントとユーザを認識します。
Hello MQTT browser-based
このチュートリアルでは、事前定義されたメッセージ(「静的テンプレート」)を使用して、Things Cloud でブラウザベースの MQTT クライアントを使用する方法を学びます。
前提条件
このチュートリアルを進めるには、次の前提条件を確認してください。
Things Cloud にアクセスするための有効なテナント、ユーザ、パスワードがあること。
「Hello, MQTT world!」クライアントの開発
Things Cloud 用の非常にシンプルな「Hello, world!」MQTT クライアントを開発するには、次のことを行う必要があります。
HTML ファイルを作成し、MQTT JavaScript クライアントを含める(この例では Paho JavaScript Client を使用します)
JavaScript アプリケーションを作成する
アプリケーションを実行する
JavaScript アプリケーションの作成
HTML ファイル(たとえば hello_mqtt_js.html )を作成し、次の内容を記述します。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" >
<meta http-equiv="X-UA-Compatible" content="IE=edge" >
<title> Hello MQTT World</title>
<meta name="viewport" content="width=device-width, initial-scale=1" >
<script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.min.js" ></script>
<script src="main.js" defer></script>
</head>
<body>
<div id="logger" ></div>
</body>
</html>
JavaScript ファイル main.js を作成し、次の内容を記述します。
// client, user and device details
var serverUrl = "ws://mqtt.cumulocity.com/mqtt" ; /* wss://mqtt.je1.thingscloud.ntt.com/mqtt for a secure connection */
var clientId = "my_mqtt_js_client" ;
var device_name = "My JS MQTT device" ;
var tenant = "<<tenant_ID>>" ;
var username = "<<username>>" ;
var password = "<<password>>" ;
var undeliveredMessages = [];
var temperature = 25 ;
// configure the client to Things Cloud
var client = new Paho.MQTT.Client(serverUrl, clientId);
// display all incoming messages
client.onMessageArrived = function (message) {
log('Received operation "' + message.payloadString + '"' );
if (message.payloadString.indexOf("510" ) == 0 ) {
log("Simulating device restart..." );
publish("s/us" , "501,c8y_Restart" );
log("...restarting..." );
setTimeout(function () {
publish("s/us" , "503,c8y_Restart" );
log("...done..." );
}, 1000 );
}
};
// display all delivered messages
client.onMessageDelivered = function onMessageDelivered (message) {
log('Message "' + message.payloadString + '" delivered' );
var undeliveredMessage = undeliveredMessages.pop();
if (undeliveredMessage.onMessageDeliveredCallback) {
undeliveredMessage.onMessageDeliveredCallback();
}
};
function createDevice () {
// register a new device
publish("s/us" , "100," + device_name + ",c8y_MQTTDevice" , function () {
// set hardware information
publish("s/us" , "110,S123456789,MQTT test model,Rev0.1" , function () {
publish('s/us' , '114,c8y_Restart' , function () {
log('Enable restart operation support' );
//listen for operation
client.subscribe("s/ds" );
})
// send temperature measurement
setInterval(function () {
publish("s/us" , '211,' +temperature);
temperature += 0.5 - Math .random();
}, 3000 );
});
});
}
// send a message
function publish (topic, message, onMessageDeliveredCallback) {
message = new Paho.MQTT.Message(message);
message.destinationName = topic;
message.qos = 2 ;
undeliveredMessages.push({
message: message,
onMessageDeliveredCallback: onMessageDeliveredCallback
});
client.send(message);
}
// connect the client to Things Cloud
function init () {
client.connect({
userName: tenant + "/" + username,
password: password,
onSuccess: createDevice
});
}
// display all messages on the page
function log (message) {
document .getElementById('logger' ).insertAdjacentHTML('beforeend' , '<div>' + message + '</div>' );
}
init();
必要に応じて serverUrl、clientId、device_name を置き換えてください。tenant_ID、username、password の値を設定して、ユーザ認証情報を指定することを忘れないでください。
Things Cloud MQTT プロトコルは、セキュリティ保護されていない TCP 接続と、セキュリティ保護された SSL 接続の両方をサポートしています(つまり、ws://mqtt.je1.thingscloud.ntt.com/mqtt または wss://mqtt.je1.thingscloud.ntt.com/mqtt)。そのため、自分に合ったものを選択して serverUrl に使用できます。
このコードは何を行いますか?
MQTT 接続を設定します。
受信したすべてのメッセージを表示する onMessageArrived コールバック関数を登録します。c8y_Restart オペレーションの場合は、デバイスの再起動をシミュレートします。
パブリッシュメッセージの配信後に呼び出される onMessageDelivered コールバック関数を登録します。
ページが完全に読み込まれた後、関数 init が呼び出され、MQTT プロトコル経由で Things Cloud に接続します。
接続が確立されたら、createDevice 関数を呼び出します。
名前 (device_name) とタイプ (c8y_MQTTDevice) を持つ新しいデバイスを作成します。
"S123456789" のシリアル、"MQTT test model" のモデル、"Rev0.1" のリビジョンを設定して、デバイスのハードウェア情報を更新します。
デバイス用の静的オペレーションテンプレートをサブスクライブします。これにより、新しいオペレーションが作成されるたびに onMessageArrived メソッドが呼び出されます。
3 秒ごとに温度メジャーメントを送信します。
サブスクリプションはデバイス作成後に確立されることに注意してください。そうしないと、指定された clientId に対するデバイスが存在しない場合、サーバはそれを受け付けません。
アプリケーションの実行
ブラウザで hello_mqtt_js.html ファイルを開きます。デバイス管理アプリケーションの All devices に、新しく登録されたデバイスが表示されるはずです。Measurements タブでは、クライアントから送信される温度メジャーメントを確認できます。
さらに、このデバイスに対して新しいオペレーション(たとえば c8y_Restart)が作成されると、関連情報がブラウザページに表示されます。
エージェントの改善
最初の一歩を踏み出したので、Hello MQTT セクションを参照して、Things Cloud MQTT についてさらに学び、アプリケーションを改善してください。
Hello MQTT Node.js
このチュートリアルでは、事前定義されたメッセージ(「静的テンプレート」)を使用して、Things Cloud で Node.js MQTT クライアントを使用する方法を学びます。
前提条件
このチュートリアルを進めるには、次の前提条件を確認してください。
Node.js とパッケージマネージャ(npm)がインストールされていること。
Things Cloud にアクセスするための有効なテナント、ユーザ、パスワードがあること。
「Hello, MQTT world!」クライアントの開発
Things Cloud 用の非常にシンプルな「Hello, world!」MQTT クライアントを開発するには、次のことを行う必要があります。
Node.js アプリケーションを作成する
MQTT ミドルウェアをインストールする(この例では MQTT.js ライブラリを使用します)
アプリケーションを実行する
Node.js アプリケーションの作成
依存関係やアプリケーションに関する基本情報を一覧化するために、package.json ファイルを作成します。
{
"dependencies" : {
"mqtt" : "*"
},
"scripts" : {
"start" : "node app.js"
}
}
package.json ファイルで指定した起動スクリプト(app.js )を作成し、次の内容を記述します。
// MQTT dependency https://github.com/mqttjs/MQTT.js
const mqtt = require("mqtt" );
// client, user and device details
const serverUrl = "tcp://mqtt.cumulocity.com" ;
const clientId = "my_mqtt_nodejs_client" ;
const device_name = "My Node.js MQTT device" ;
const tenant = "<<tenant_ID>>" ;
const username = "<<username>>" ;
const password = "<<password>>" ;
var temperature = 25 ;
// connect the client to Things Cloud
const client = mqtt.connect(serverUrl, {
username: tenant + "/" + username,
password: password,
clientId: clientId
});
// once connected...
client.on("connect" , function () {
// ...register a new device with restart operation
client.publish("s/us" , "100," + device_name + ",c8y_MQTTDevice" , function () {
client.publish("s/us" , "114,c8y_Restart" , function () {
console.log("Device registered with restart operation support" );
});
// listen for operations
client.subscribe("s/ds" );
// send a temperature measurement every 3 seconds
setInterval(function () {
console.log("Sending temperature measurement: " + temperature + "º" );
client.publish("s/us" , "211," + temperature);
temperature += 0.5 - Math .random();
}, 3000 );
});
console.log("\nUpdating hardware information..." );
client.publish("s/us" , "110,S123456789,MQTT test model,Rev0.1" );
});
// display all incoming messages
client.on("message" , function (topic, message) {
console.log('Received operation "' + message + '"' );
if (message.toString().indexOf("510" ) == 0 ) {
console.log("Simulating device restart..." );
client.publish("s/us" , "501,c8y_Restart" );
console.log("...restarting..." );
setTimeout(function () {
client.publish("s/us" , "503,c8y_Restart" );
console.log("...done..." );
}, 1000 );
}
});
必要に応じて serverUrl、clientId、device_name を置き換えてください。tenant_ID、username、password の値を設定して、ユーザ認証情報を指定することを忘れないでください。
Things Cloud MQTT プロトコルは、セキュリティ保護されていない TCP 接続と、セキュリティ保護された SSL 接続の両方をサポートしています。どちらの接続タイプを選択しても、serverUrl は同じままにする必要があります(mqtt.je1.thingscloud.ntt.com のように)。
このコードは何を行いますか?
MQTT 接続を設定します。
接続が確立されると、名前 (device_name) とタイプ (c8y_MQTTDevice) を持つ新しいデバイスを登録します。
デバイスに再起動機能を追加します。
オペレーションを受信するためにサブスクライブします。
3 秒ごとにランダムな温度メジャーメントを送信します。
"S123456789" のシリアル、"MQTT test model" のモデル、"Rev0.1" のリビジョンを設定して、デバイスのハードウェア情報を更新します。
受信したすべてのメッセージを監視します。c8y_Restart オペレーションの場合は、デバイスの再起動をシミュレートします。
サブスクリプションはデバイス作成後に確立されることに注意してください。そうしないと、指定された clientId に対するデバイスが存在しない場合、サーバはそれを受け付けません。
アプリケーションの実行
アプリケーションを実行する前に、MQTT ミドルウェアをインストールする必要があります。これを行うには、次のコマンドを実行します。
インストールは 1 回だけ行えば十分です。その後は、次のコマンドを実行するだけです。
デバイス管理アプリケーションの All devices に、新しく登録されたデバイスが表示されるはずです。Measurements タブでは、クライアントから送信される温度メジャーメントを確認できます。
さらに、このデバイスに対して新しいオペレーション(たとえば c8y_Restart)が作成されると、その関連情報がコンソールに出力されます。
エージェントの改善
最初の一歩を踏み出したので、Hello MQTT セクションを参照して、Things Cloud MQTT についてさらに学び、アプリケーションを改善してください。
Hello MQTT Python
このチュートリアルでは、事前定義されたメッセージ(「静的テンプレート」)を使用して、Things Cloud で Python MQTT クライアントを使用する方法を学びます。
前提条件
このチュートリアルを進めるには、次の前提条件を確認してください。
Things Cloud にアクセスするための有効なテナント、ユーザ、パスワードがあること。
Python 3 がインストールされていることを確認します。
$ python3 --version
Python 3.8.5
Python は www.python.org からダウンロードできます。
システムのパッケージマネージャまたは pip を使用して Python Paho クライアントをインストールします。
備考
上記コマンドはシステムに Paho をインストールします。この例のためだけにインストールするには、
virtualenv の使用を検討してください。
備考
macOS では、pip コマンドが見つからない場合に sudo easy_install pip を実行する必要があることがあります。
「Hello, MQTT world!」クライアントの開発
Things Cloud 用の非常にシンプルな「Hello, world!」MQTT クライアントを開発するには、次のことを行う必要があります。
Python スクリプトを作成する
スクリプトを実行する
Python スクリプトの作成
スクリプトファイル(たとえば hello_mqtt.py )を作成し、次の内容を記述します。
# /usr/bin/env python3
# -*- coding: utf-8 -*-
import paho.mqtt.client as mqtt
import time, random, threading
import multiprocessing as mp
# client, user and device details
serverUrl = "mqtt.cumulocity.com"
clientId = "my_mqtt_python_client"
device_name = "My Python MQTT device"
tenant = "<<tenant_ID>>"
username = "<<username>>"
password = "<<password>>"
# task queue to overcome issue with paho when using multiple threads:
# https://github.com/eclipse/paho.mqtt.python/issues/354
task_queue = mp.Queue()
# display all incoming messages
def on_message (client, userdata, message):
payload = message.payload.decode("utf-8" )
print (" < received message " + payload)
if payload.startswith("510" ):
task_queue.put(perform_restart)
# simulate restart
def perform_restart ():
print ("Simulating device restart..." )
publish("s/us" , "501,c8y_Restart" , wait_for_ack = True );
print ("...restarting..." )
time.sleep(1 )
publish("s/us" , "503,c8y_Restart" , wait_for_ack = True );
print ("...restart completed" )
# send temperature measurement
def send_measurement ():
print ("Sending temperature measurement..." )
temperature = random.randint(10 , 20 )
publish("s/us" , "211, {} " .format(temperature))
# publish a message
def publish (topic, message, wait_for_ack = False ):
QoS = 2 if wait_for_ack else 0
message_info = client.publish(topic, message, QoS)
if wait_for_ack:
print (" > awaiting ACK for {} " .format(message_info.mid))
message_info.wait_for_publish()
print (" < received ACK for {} " .format(message_info.mid))
# display all outgoing messages
def on_publish (client, userdata, mid):
print (" > published message: {} " .format(mid))
# main device loop
def device_loop ():
while True :
task_queue.put(send_measurement)
time.sleep(7 )
# connect the client to Things Cloud and register a device
client = mqtt.Client(clientId)
client.username_pw_set(tenant + "/" + username, password)
client.on_message = on_message
client.on_publish = on_publish
client.connect(serverUrl)
client.loop_start()
publish("s/us" , "100," + device_name + ",c8y_MQTTDevice" , wait_for_ack = True )
publish("s/us" , "110,S123456789,MQTT test model,Rev0.1" )
publish("s/us" , "114,c8y_Restart" )
print ("Device registered successfully!" )
client.subscribe("s/ds" )
device_loop_thread = threading.Thread(target = device_loop)
device_loop_thread.daemon = True
device_loop_thread.start()
# process all tasks on queue
try :
while True :
task = task_queue.get()
task()
except (KeyboardInterrupt , SystemExit ):
print ("Received keyboard interrupt, quitting ..." )
exit(0 )
必要に応じて serverUrl、clientId、device_name を置き換えてください。tenant_ID、username、password の値を設定して、ユーザ認証情報を指定することを忘れないでください。
Things Cloud MQTT プロトコルは、セキュリティ保護されていない TCP 接続と、セキュリティ保護された SSL 接続の両方をサポートしています。そのため、ポートを設定する際は正しいものを使用することを忘れないでください。どちらの接続タイプを選択しても、serverUrl は同じままにする必要があります(mqtt.je1.thingscloud.ntt.com のように)。
上記の例では TCP 接続を使用しています。SSL 接続を使用する場合は、Paho MQTT クライアントの適切な設定を使用することを忘れないでください。詳細は www.eclipse.org を参照してください。
このスクリプトは何を行いますか?
MQTT 接続を設定します。
受信メッセージを出力する on_message コールバック関数を登録します。c8y_Restart オペレーションの場合は、デバイスの再起動をシミュレートします。
パブリッシュメッセージの配信後に呼び出される on_publish コールバック関数を登録します。
MQTT プロトコルを介して Things Cloud に接続します。
名前 (device_name) とタイプ (c8y_MQTTDevice) を持つ新しいデバイスを作成します。
"S123456789" のシリアル、"MQTT test model" のモデル、"Rev0.1" のリビジョンを設定して、デバイスのハードウェア情報を更新します。
デバイス用の静的オペレーションテンプレートをサブスクライブします。これにより、新しいオペレーションが作成されるたびに on_message メソッドが呼び出されます。
7 秒ごとに温度メジャーメントを送信する device_loop_thread を開始します。
すべてのタスクを 1 つずつ実行する task_queue を準備します。
publish メッセージは何を行いますか?
指定されたトピックについて、指定されたメッセージを MQTT 経由でパブリッシュします。
メッセージをパブリッシュするときに QoS 2 を使用します。そのため、メッセージが配信されたことを確実にするために、サーバ ACK を待機します(対応するメッセージ ID で on_publish メソッドが呼び出されるまで)。
サブスクリプションはデバイス作成後に確立されることに注意してください。そうしないと、指定された clientId に対するデバイスが存在しない場合、サーバはそれを受け付けません。
スクリプトの実行
スクリプトを実行するには、次のコマンドを使用します。
アプリケーションを起動すると、デバイス管理アプリケーションの All devices に、新しく登録されたデバイスが表示されるはずです。Measurements タブでは、クライアントから送信される温度メジャーメントを確認できます。
さらに、このデバイスに対して新しいオペレーション(たとえば c8y_Restart)が作成されると、その情報がコンソールに出力されます。
エージェントの改善
最初の一歩を踏み出したので、Hello MQTT セクションを参照して、Things Cloud MQTT についてさらに学び、アプリケーションを改善してください。