ESP32 Arduinoで Ambientからデータを取得して得られたJSONをパースして値を抽出する方法

Ambientからデータを取得する

Ambientは、ネットワークにつながったセンサ端末からの情報を受けとり、グラフ化してくれるクラウドサービスです。

見守りをするため、M5StickCでベッドの重量を測定し、Ambientに送信するハードとソフトを作りました。

次のステップに進むために、逆にAmbientにあるデータを端末側から参照したくなったので、Arduinoでプログラムを作ってみました。

仕組み

ambientからデータを取得するには、次のURLをambientのサーバに送ります。するとデータがJSON形式で返ってきます。

http://ambidata.io/api/v2/channels/チャネルID/data?&readKey=リードキー&n=行数

「チャネルID」と「リードキー」はMyチャネルのページで確認できます。

行数は1以上の数字を指定します。1を指定すると直近のデータが1セット、nを指定すると直近から過去へn番目までデータ、nセット分が返ってきます。

ちなみに、上記のURLをブラウザで開くと、データが返ってくることが事前にわかります。

上記はn=1とした場合の結果です。直近のデータが1つ表示されます。

n=2にすると、以下のように2セットデータが返ってきます。

さて、仕組みがわかったところで、これをコードにします。

データを取得するプログラム

...
#include <HTTPClient.h>
const unsigned int channelId = xxxxx; // AmbientのチャネルID
const char* readKey = "xxxxxxxxxxxxx"; // リードキー
...

void setup() {
  ...
  Serial.begin(115200);
  ...
  // ...WiFiに接続する...

}

void loop() {
  ...
  String response = readFromAmbient( channelId, readKey, 1 );
  delay(10000);
  ...
}

//Ambientからデータを受信する
String readFromAmbient( unsigned int channelId, const char* readKey, int n )
{
  const String host ="ambidata.io";

  String url = "http://";
  url += host;
  url += "/api/v2/channels/";
  url += channelId;
  url += "/data?&readKey=";
  url += readKey;
  url += "&n=";
  url += n;
  Serial.print("Requesting URL ");
  Serial.println(url);

  HTTPClient httpClient;
  httpClient.begin(url);
  int httpCode = httpClient.GET();
  String httpResponse = httpClient.getString();
  httpClient.end();

  Serial.printf("httpCode:%d\n",httpCode);
  Serial.println(httpResponse);

  return httpResponse;
}

上記は、必要な部分を抜き出したコードです。これの他に、WiFiにつなぐコードが必要です。

Ambientのサーバからデータを受信するための、readFromAmbient()という関数を作りました。チャンネルIDとリードキー、行数nを指定すると、JSON形式のStringが得られます。

M5StickCで受信してみる

サンプルプログラム

先ほどのコードを、M5SticCで動くようプログラムしました。こちら↓↓がそのプログラムです。

m5stick_readDataFromAmbient

//Wifi
const char* WifiSSID = "SSID"; //アクセスポイントのSSID
const char* WifiPassword = "POSSWORD"; //アクセスポイントのパスワード
WiFiClient client;

//Ambient
unsigned int channelId = CHANNEL_ID; // AmbientのチャネルID
const char* writeKey = "WRITE_KEY"; // ライトキー
const char* readKey = "READ_KEY"; // リードキー
Ambient ambient;

上記の部分の、WifiSSID、WifiPasswordに、ご自宅のWiFiのSSIDとパスワードを指定し、channelId、writeKey、readKeyはAmbientのそれぞれのID、キーを指定します。

コンパイルしてM5StickCに書き込むと、プログラムが実行されます。Aボタンを押すと、Ambientからデータを受信し、ボタンBを押すと、Ambientに予め設定されているValue1,2,3のデータが送信されるようになっています。

実行結果

WiFiに接続された後に、Aボタンを押すとシリアルモニタに結果が表示されます。

[{“d1″:1,”d2″:2,”d3″:10,”created”:”2019-10-09T04:52:08.689Z”}]

n=1としたので、1行分のデータが返ってきました。

M5Stickの画面にも、シリアルで出力したデータが表示されます。

ArduinoJSONでパース

Ambientからデータを受信できるようになりました。この結果をArduinoJSONを使ってパースして、パラメータを取り出してみたいと思います。

ArduinoJSONは、ライブラリマネージャで検索すると出てきます。これをインストールしておきます。

私が使ったのは現時点で最新のバージョン6.12.0です。

先ほどのコードに、ArduinoJSONでパースして、値を取り出すコードを追加します。

...
#include <ArduinoJson.h>
...

void setup() {
  ...
}

void loop() {
  ...
  //Aボタンを押されたら
  ...
    String response = readFromAmbient( channelId, readKey, 1 );
  
    //jsonドキュメントの作成 make JSON document
    const size_t capacity = 500;
    DynamicJsonDocument doc(capacity);
    DeserializationError err = deserializeJson(doc, response);
    Serial.printf("DeserializationError:%s\n",err.c_str());
  
    //抽出
    int value[3] = { 0, 0 ,0 };
    value[0] = doc[0]["d1"];
    value[1] = doc[0]["d2"];
    value[2] = doc[0]["d3"];
  
    //結果を出力
    Serial.printf("Result:%d, %d, %d\n",value[0],value[1],value[2]);
    M5.Lcd.print("Value1:"); M5.Lcd.println(value[0]);
    M5.Lcd.print("Value2:"); M5.Lcd.println(value[1]);
    M5.Lcd.print("Value3:"); M5.Lcd.println(value[2]);    
  ...
}

JSONドキュメントを作るときのcapacityは、ArduinoJson Assistantに受信したJSONのデータ列をペーストして、計算された容量を使用します。

今回はn=2の受信結果で244だったので、さらに余裕をみて500にしてみました。

M5Stickで実行してみましょう。

Value1:1
Value2:2
Value10:10

と、JSONフォーマットから正しく値が抽出できています。

プログラムはこちらm5stick_readDataFromAmbient2にあります。

まとめ

M5StickCでAmbientからデータを取得できるようになりました。取得したJSONフォーマットから、データを抽出できるようになりました。

これで、センサ端末からでもデータにアクセスできるようになりました。

つづく

2019.10.10 追加 つづきはこちらです↓↓

追加終わり

コメント

  1. こんにちは。いつも読ん勉強しているものです。なかなか勉強しても自分なりのアイデアを
    プログラムに展開して、実用的な活用までには、まだまだ時間がかかりそうです、そこで先生にアイデアをm5stickc用にプログラム書いてもらいたい。その様な事は、可能でしょうか?内容はえぶちゃんわんちゃんの記述とほぼ同じです。可能でしたら、料金はどの位になるのでしょうか?
    宜しくお願い申し上げます。

    • 市村様 ブログを読んで頂き、またありがたいコメントを頂きましてありがとうございます。しかしながら、ただいま立て込んでおりまして、しっかりとシステムを構築するお時間を割くことが難しい状況です。もしよろしければ今回のM5StickCのプログラムを、無保証ですがお渡しすることができます。また、これをベースに多少修正することであれば、有償でお手伝いすることは可能です。少しでもお役に立てれれば幸いです。
      今後ともよろしくお願いいたします。