クリスマスにSORACOMからジェイソンを呼び出した話(メタデータサービスは使える)


なんの話?

SORACOM Air メタデータサービスに感動して、やってみた話です。
SORACOMのTechnology Campのmaxさんのセッションで紹介されていました。

何それ?

  • SORACOMのユーザーコンソールを開いて
  • SIMのチェックを入れて
  • 「詳細」を押して
  • 「タグ」のタブを開いて
  • こんな風に設定したら

  • Air SIMを挿した端末からこのURLでJSONが呼び出せる。
    http://metadata.soracom.io/v1/subscriber.tags.conf

何が便利なの?

端末に設定するコードを統一できる。

もう一回言います。

端末に設定するコードを統一できる!!!!!

いちいち端末側で定数をdefineしなくても、
SORACOMのコンソール側から自由に値を変更できる。
これがかなり使える。

サンプルコード

WioLTEで定数として設定していた値を、メタデータサービスで取得した値に書き換えます。
超音波センサーの値をHarvestにアップロードする間隔を、20秒から5秒に変更します。
SORACOMからジェイソンを呼び出します、クリスマスに。

usrtosoracom.ino
#include <WioLTEforArduino.h>
#include <ArduinoJson.h>
#include <Ultrasonic.h>
#include <stdio.h>

#define ULTRASONIC_PIN (WIOLTE_D38)

Ultrasonic UltrasonicRanger(ULTRASONIC_PIN);
WioLTE Wio;

int interval_sec=20000;
int receive_timeout_sec=10000;

void setup() {
  delay(200);

  SerialUSB.println("");
  SerialUSB.println("--- START ---------------------------------------------------");

  SerialUSB.println("### I/O Initialize.");
  Wio.Init();

  SerialUSB.println("### Power supply ON.");
  Wio.PowerSupplyLTE(true);
  delay(500);

  SerialUSB.println("### Turn on or reset.");
  if (!Wio.TurnOnOrReset()) {
    SerialUSB.println("### ERROR! ###");
    return;
  }

  SerialUSB.println("### Connecting to \"soracom.io\".");
  if (!Wio.Activate("soracom.io","sora","sora")) {
    SerialUSB.println("### ERROR! ###");
    return;
  }

  SerialUSB.println("### Setup completed.");

  SerialUSB.println("### Get Interval...");
  char metadata[2048];

  if (Wio.HttpGet("http://metadata.soracom.io/v1/subscriber.tags.conf", metadata, sizeof(metadata))<0) {
    SerialUSB.println("### ERROR! ###");
    return;
  }

  SerialUSB.println("### Metadata:");
  SerialUSB.println(metadata);

  StaticJsonBuffer<2048> jsonBuffer;
  JsonObject& root = jsonBuffer.parseObject(metadata);

  if (!root.success()) {
    SerialUSB.println("parseObject() failed");
    return;
  }else{
    SerialUSB.println("parseObject() success");

    interval_sec=atoi(root["interval_sec"]);
    receive_timeout_sec=atoi(root["receive_timeout_sec"]);

    SerialUSB.print("interval_sec:");
    SerialUSB.println(interval_sec);
    SerialUSB.print("receive_timeout_sec:");
    SerialUSB.println(receive_timeout_sec);
  }
}

void loop() {
  char data[100];
  long distance;

  distance = UltrasonicRanger.MeasureInCentimeters();

  SerialUSB.println("### Open.");
  int connectId;
  connectId = Wio.SocketOpen("harvest.soracom.io", 8514, WIOLTE_UDP);
  if (connectId < 0) {
    SerialUSB.println("### ERROR! ###");
    goto err;
  }

  SerialUSB.println("### Send.");
  sprintf(data, "{\"distance\":%ld}", distance);
  SerialUSB.print("Send:");
  SerialUSB.print(data);
  SerialUSB.println("");

  if (!Wio.SocketSend(connectId, data)) {
    SerialUSB.println("### ERROR! ###");
    goto err_close;
  }

  SerialUSB.println("### Receive.");
  int length;
  length = Wio.SocketReceive(connectId, data, sizeof (data), receive_timeout_sec);
  if (length < 0) {
    SerialUSB.println("### ERROR! ###");
    goto err_close;
  }
  if (length == 0) {
    SerialUSB.println("### RECEIVE TIMEOUT! ###");
    goto err_close;
  }
  SerialUSB.print("Receive:");
  SerialUSB.print(data);
  SerialUSB.println("");

err_close:
  SerialUSB.println("### Close.");
  if (!Wio.SocketClose(connectId)) {
    SerialUSB.println("### ERROR! ###");
    goto err;
  }

err:
  SerialUSB.println("### Wait.");
  delay(interval_sec);
}

ちなみに

SIMグループ全体に設定することもできる

「ユーザーデータ」という仕組み:下記のURLで取得できる。
http://metadata.soracom.io/v1/userdata

→SIMグループ全体の接続先をメタデータに仕込んでおけば、端末で設定を変える必要がない。
例)
{"host":"funnel.soracom.io", "port":23080, "type":"WIOLTE_UDP"}

さいごに

無事、アップロード間隔が自動的に変わり、
Harvestにアップロードできました。

メリークリスマス!

参考(にさせていただきました)