IoT向け簡易データ収集サービスを作った

概要

上記で書いてあったデータ収集用の無償サービスを作ってみました。今どきのサービスはすべてHTTPSで動いていますが、あえてHTTPで動くように作ってあります。認証も登録も必要ないのでIoTの勉強などの取っ掛かりに使ってもらえればと思います。

サービス

Lang-ship DataStore - データ保存とグラフ化

上記のサイトとなります。サイト自体はHTTPSとHTTPの両対応になります。データは登録時間とともに10個まで保存できます。データ自体は文字列でも数値でも保存可能ですが、グラフ化は数値のみに対応しています。

いまのところあまり制限等はいれていませんが、長過ぎる文字列やhtmlタグ周りはサニタイズしてあります。データ保存間隔も当初制限無しの予定ですが、一日以上のデータをグラフ化する場合には1分間隔だとデータが多すぎてグラフが重くなるので、もう少し広い間隔が好ましいと思います。

短期間で超大量にも登録可能ですが、重くなりすぎるとこのサービス自体が閉鎖する可能性があるので適度に使ってもらえればと思います。

データ保存用URLの生成

今すぐ始めるボタンを押すことでURLが生成されます。生成されるURLはランダムの英数8桁のIDとなります。同じIDが生成される可能性もありますのでご注意ください。

  • https://datastore.lang-ship.com/d072e587/
  • https://datastore.lang-ship.com/0b659772/
  • https://datastore.lang-ship.com/09281636/

たとえばですが手元では上記のようなURLが生成されました。

生成されたURLを開く

いますぐ始めるボタンからであれば生成されたURLが開けたはずです。このURLに対してデータを保存したり、閲覧や削除などすべての権限を持ちますのでこのURLは基本的には公開しないでください。

データの追加

上記のようなフォームが表示されますので、最初は手で適当なデータを保存してみてください。

curl 'https://datastore.lang-ship.com/TEST/save?d0=83&d1=149&d2=140&d3=157'

Saveボタンで追加されますが、フォームの上に表示されているURLでも追加可能です。このURLをブラウザで開いても良いのですが、上記のように実行することでデータが追加されます。

curl 'http://datastore.lang-ship.com/TEST/save?d0=83&d1=149&d2=140&d3=157'

特徴として上記のようにHTTPでアクセス可能です。認証もないサイトなので暗号化も必要ありませんね。どうしてもHTTPS通信をする場合には証明書の管理や、暗号化通信自体が重かったりするので機密性がない情報であればHTTPの方が手軽に試せると思います。

データの確認

生成されたURLでは簡易的な表とグラフで登録されたデータを確認可能です。表では直近10件、グラフでは100件を表示する設定になっています。

「詳細データ表示」では期間や条件を指定してデータを表示することが可能です。表示形式をhtmlから他のものに変更することでデータをダウンロードすることができます。

「詳細グラフ表示」では同じように期間を指定してグラフを確認することが可能です。

データの削除

データを削除するボタンを押すことでデータがすべて消えます。まずテストでぽちぽち追加したデータがある場合には削除してから、また新しいまっさらな状態にしてIoT端末で追加してみるのがよいと思います。

ESP32端末から登録テスト

#include <Arduino.h>
#include <WiFi.h>
#include <WiFiMulti.h>
#include <HTTPClient.h>

WiFiMulti wifiMulti;

#define DATASTORE_ID  "TEST"
#define SSID1_SSID    "SSID"
#define SSID1_KEY     "KEY"

RTC_DATA_ATTR int bootCount = 0;

String urlEncode(const String &str) {
    String encodedString = "";
    char c;
    char buf[4] = {};
    for (int i = 0; i < str.length(); i++) {
        c = str.charAt(i);
        if (isalnum(c)) {
            encodedString += c; // アルファベットや数字はそのまま
        } else {
            sprintf(buf, "%%%02X", c); // 特殊文字は%XX形式に変換
            encodedString += buf;
        }
    }
    return encodedString;
}

void setup() {
  Serial.begin(115200);
  bootCount++;
  wifiMulti.addAP(SSID1_SSID, SSID1_KEY);
}

void loop() {
  if ((wifiMulti.run() == WL_CONNECTED)) {
    HTTPClient http;

    String url = "http://datastore.lang-ship.com/" DATASTORE_ID "/save";
    url += "?d0=" + String(bootCount);
    url += "&d1=" + String(random(100));
    url += "&d2=" + urlEncode(String(temperatureRead()));
    Serial.println("URL:" + url);

    http.begin(url);
    http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
    Serial.println("GET Start");
    int httpCode = http.GET();
    Serial.println("GET End(" + String(httpCode) + ")");

    if (httpCode > 0) {
      if (httpCode == HTTP_CODE_OK) {
        String payload = http.getString();
        Serial.println(payload);
      }
    } else {
      Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
    }

    http.end();

    uint64_t time_ms = 20 * 1000; // 20s
    time_ms -= millis();
    esp_sleep_enable_timer_wakeup(time_ms * 1000);
    esp_deep_sleep_start();
  }

  delay(1);
}

シンプルな例ですが、生成されたURLからデータストアのID部分を取り出してTESTの部分に設定します。Wi-Fiに接続するための情報をSSIDとKEYに設定することで動作します。

保存されるデータは起動して送信した回数と、ランダムな数字、ESP32コアの温度になります。気をつけないといけないのはデータを送信するときにURLエンコードが必要となります。数字以外の文字列なども保存できますが、送信するデータに英数以外の文字が含まれる場合にはURLエンコードをする必要があります。

ちょっとこのへんはもう少しかんたんに遅れるようなヘルパー関数などを準備予定です。

まとめ

必要最低限の機能のみを実装することで、シンプルなデータ保存サービスになったと思います。もうちょっと実装したいことはあるのですが、まずは公開してみます。

なんとなく作ってみたので、いろいろ足りていない機能や考慮不足があると思いますが実験的な意味合いがあるので、今後もいろいろなものをプロトタイプ的に作って公開していければと思っています。

コメント