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