IoTサービスのラベル取得 (Spresense)
サンプルソースコード
概要
IIJ IoTの「ラベル機能」を使用してみます。
前回のサンプル に対して、ラベル機能を使用するような機能追加をしています。
特定のラベルが設定されていた場合は、そのラベルの値を取得し、その数値を使ってデータ送信間隔を変更します。
つまり、ラベル機能を使ってサーバーからクライアント側に向けて指示を出すようなイメージです。
ソースコード
spresense_iijiot_label.ino
#include <LTE.h> #include <LTEClient.h> #include <ArduinoHttpClient.h> #include <Arduino_JSON.h> //--- TODO: 使用するSIMのAPN情報に書き換えてください。 const char apn[] = "iot.iijmobile.jp"; // "h.iijmobile.biz"; const char lte_user[] = "mobile@iot"; const char lte_pass[] = "iot"; //--- int delay_sec = 60; const char* iij_iot_host = "gw.iot.iij.jp"; const int iij_iot_port = 80; const char* iij_iot_path = "/v1"; const char* iij_iot_label_path = "/v1/dvc-state/json/label-contents"; const char* sec_label_name = "delay_sec"; LTE lteAccess; LTEClient client; /* setup関数 */ void setup() { Serial.begin(115200); Serial.println("\nstart."); delay(3000); while (true) { if (lteAccess.begin() == LTE_SEARCHING) { if (lteAccess.attach(apn, lte_user, lte_pass) == LTE_READY) { Serial.println("attach succeeded."); break; } Serial.println("An error occurred, shutdown and try again."); lteAccess.shutdown(); sleep(1); } } randomSeed(lteAccess.getTime()); } /* IIJ IoTサービスにデータ送信する 引数 const char* ns : 送信する namespace値 const char* name : 送信する name値 const double value : 送信する value値 戻り値 bool true:送信成功 false:送信失敗 */ bool send_data(const char* ns, const char* name, const double value) { //JSONオブジェクトを作成 JSONVar body; if (ns != nullptr && strlen(ns) > 0) { body["namespace"] = ns; } body["name"] = name; body["value"] = value; //JSONを文字列に変換 String body_string = JSON.stringify(body); Serial.println("POST: " + body_string); //JSON文字列をIIJ IoTサービスにPOST HttpClient http(client, iij_iot_host, iij_iot_port); http.beginRequest(); http.post(iij_iot_path); http.sendHeader("Content-type", "application/json"); http.sendHeader("Content-length", body_string.length()); http.beginBody(); http.print(body_string); http.endRequest(); int status_code = http.responseStatusCode(); return status_code >= 200 && status_code < 300; } /* IIJ IoTサービスに設定されているラベルのJSON文字列を取得する 引数 String& labels : 取得したラベル文字列を格納するString参照 戻り値 String labelsを返す */ String get_label_string(String& labels) { HttpClient http(client, iij_iot_host, iij_iot_port); http.get(iij_iot_label_path); int status_code = http.responseStatusCode(); if(status_code == 200) { labels = http.responseBody(); } else { labels = "{}"; } return labels; } /* ラベルJSON文字列内から、keyに対応する値を返す 引数 const String& labels : 取得したラベル文字列を格納するString参照 const char* key : 値を取得するkey char* value : 取得した値(文字列)を格納する変数 size_t size : value配列のサイズ 戻り値 char* valueを返す */ char* get_label(const String& labels, const char* key, char* value, size_t size) { //ラベルのJSON文字列を解析する JSONVar root = JSON.parse(labels); //ラベルJSON内から、keyの値を取得する(keyが存在しない場合は空文字列) const char* src = root[key]; memset(value, '\0', size); if(src != nullptr) { strncpy(value, src, size-1); } //value値を返す return value; } /* IIJ IoTからラベルを取得し、keyに対応する値を返す 引数 const char* key : 値を取得するkey char* value : 取得した値(文字列)を格納する変数 size_t size : value配列のサイズ 戻り値 char* valueを返す */ char* get_label(const char* key, char* value, size_t size) { // IIJ IoTからラベルを取得する String labels; get_label_string(labels); // 値を取得する return get_label(labels, key, value, size); } /* loop関数 */ void loop() { //乱数を生成する int value = random(10000); //データ送信する bool ok = send_data("spresense", "test", value); Serial.println(ok ? "OK" : "NG"); //ラベル取得 char label_value[32]; get_label(sec_label_name, label_value, sizeof(label_value)); int sec = String(label_value).toInt(); //"delay_sec"のラベルが存在したら、送信間隔の時間をそのラベル値の数値に変更する if (sec > 0 && sec != delay_sec ) { delay_sec = sec; Serial.printf("update delay sec: %d sec.\n", delay_sec); } //待つ delay(delay_sec * 1000L); }
実行結果
IoTサービスのコントロールパネルから、ラベルを設定することで、送信間隔を変更することができます。
コントロールパネルの左側メニューから「デバイス」を選択し、続いて一覧の中から使用しているSIMを選択し、画面上の「編集」ボタンをクリックします。
表示された画面から、ラベル名に delay_sec
、値に適当な数値を入力し、保存します。
Spresense側で、設定したラベル値が読み込まれ、送信間隔が変更されます。
ラベル値に 30 と設定した場合は、下記の通りシリアルモニタに「update delay sec: 30 sec」と表示され、次回以降は30秒間隔でデータ送信されます。
start. attach succeeded. POST: {"namespace":"spresense","name":"test","value":8745} OK update delay sec: 30 sec. POST: {"namespace":"spresense","name":"test","value":5573} OK
各種情報へのリンク
IIJ IoTサービスマニュアル
Spresense
Arduino_JSON
ArduinoHttpClient