とりちらかったもろもろの言葉たち

ちょっと大きめのつぶやきにすぎない戯言をとりあえず書いてみました

月別アーカイブ: 12月 2018

Machinistにデータを送ってみるテスト

某紙のコラムのネタにするので、IIJの「Machinist」をちょいと使ってみた。データロガー的な使い方が簡単にできるサービスだ。

簡単に言ってしまえば、IoTデバイスなどのデータをJSONのパケットに組み立てて、Machinistに対してHTTPSでPOSTしてやればずんずん積もっていくというもの。基本は時間ごとのデータしか取れないのでまあ何でも格納できるというわけではないが、センサーが発したデータや機器のステータスなどを放り込んでおくにはいいのではないかと思う。

普通ならまあ、ラズパイあたりを使うところなのだろうが、これくらい単純なものならむしろESP32を使うくらいのほうがリアルだし実践的だろうと思ったので試してみた(あ、そもそもWindows 10のbashからは試していたんだった)。

用意したのは適当にAliExpressかeBayかで購入した、Node-32コンパチの安物。今はArduinoで使えるようにしているので、そのままArduinoでスクリプトを組むことにした。一応ESP32には内蔵の温度センサーがあるらしいので、これを送ればそれなりになるかという目論見で本体のみである。

まず調べるのは温度のとり方だが、どうやら怪しいようではあるがこういうところがあったのでそれを使って動かしてみた。OK。値はベロベロでようわからんが、まあ動いている。

次はそれをJSONのパケットにするのだが、ヒアドキュメントが使えないのでだるい‥と思って一瞬microPythonに乗り換えようかとも思ったが、考えてみればJSONくらいArduinoでも扱う方法があるだろうと探したら、やっぱりあった。いくつかあるようだが、とりあえず今回使ったのはArduinoJsonである。

これでゴリゴリ組み立ててシリアライズすればいいわけだが、意外と面倒なのが本当に正しくできているのかの検証。ArduinoJsonの場合、いろいろと見ていたらAssistantというページがあって、サンプルのJSONを放り込んだらシリアライズするプログラムを自動生成してくれる。これがありがたかった。

おかげで温度チェックのあと、HTTPとJSONを入れ込んだスクリプトが一発で動いた。正確にはArduinoJsonのページで警告しているように、標準のライブラリアンでデフォルトを使うとベータ版が入ってしまうこと。Assitantのページで生成するのはその前の安定版用なので、ライブラリの入れ替えは必要だった。あと相変わらずプログラムの転送が安定していないので3回くらいやり直したのが面倒だった。

というわけでコードはこんな感じ。なんかインデントが変だけどわかるでしょ。

#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>

const char SSID[] = “<Your Wi-Fi SSID>”;
const char PASSWORD[] = “Wi-Fi PWD”;
const char URL[] = “https://gw.machinist.iij.jp/endpoint&#8221;;

extern “C” {
uint8_t temprature_sens_read();
}

void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT);
WiFi.begin(SSID, PASSWORD);
Serial.print(“WiFi connecting”);

while (WiFi.status() != WL_CONNECTED) {
Serial.print(“.”);
delay(100);
}
Serial.println(” connected”);
}

void loop() {
if(WiFi.status()== WL_CONNECTED){ //Check WiFi connection status

HTTPClient http;

http.begin(URL); //Specify destination for HTTP request
http.addHeader(“Content-Type”, “application/json”); //Specify content-type header
http.addHeader(“Authorization”, “Bearer <Your API Key>”);

char buffer[256];
const size_t bufferSize = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + 2*JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(4);
DynamicJsonBuffer jsonBuffer(bufferSize);

JsonObject& root = jsonBuffer.createObject();
root[“agent”] = “ESP32”;

JsonArray& metrics = root.createNestedArray(“metrics”);

JsonObject& metrics_0 = metrics.createNestedObject();
metrics_0[“name”] = “temperature”;
metrics_0[“namespace”] = “Environment Sensor”;
JsonObject& metrics_0_tags = metrics_0.createNestedObject(“tags”);
metrics_0_tags[“FLOOR”] = “1F”;

JsonObject& metrics_0_data_point = metrics_0.createNestedObject(“data_point”);
metrics_0_data_point[“value”] = temperatureRead();

root.printTo(buffer, sizeof(buffer));
Serial.println(buffer);

int httpResponseCode = http.POST(buffer); //Send the actual POST request

if(httpResponseCode>0){
String response = http.getString(); //Get the response to the request
Serial.println(httpResponseCode); //Print return code
Serial.println(response); //Print request answer
}else{
Serial.print(“Error on sending POST: “);
Serial.println(httpResponseCode);
}
http.end(); //Free resources

}else{
Serial.println(“Error in WiFi connection”);

}
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(500);
digitalWrite(LED_BUILTIN, LOW); // turn the LED on (HIGH is the voltage level)

delay(1000);
}