Ambientからデータを取得する
Ambientは、ネットワークにつながったセンサ端末からの情報を受けとり、グラフ化してくれるクラウドサービスです。
見守りをするため、M5StickCでベッドの重量を測定し、Ambientに送信するハードとソフトを作りました。
次のステップに進むために、逆にAmbientにあるデータを端末側から参照したくなったので、Arduinoでプログラムを作ってみました。
仕組み
ambientからデータを取得するには、次のURLをambientのサーバに送ります。するとデータがJSON形式で返ってきます。
「チャネル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で動くようプログラムしました。こちら↓↓がそのプログラムです。
//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ボタンを押すとシリアルモニタに結果が表示されます。
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で実行してみましょう。
Value2:2
Value10:10
と、JSONフォーマットから正しく値が抽出できています。
プログラムはこちらm5stick_readDataFromAmbient2にあります。
まとめ
M5StickCでAmbientからデータを取得できるようになりました。取得したJSONフォーマットから、データを抽出できるようになりました。
これで、センサ端末からでもデータにアクセスできるようになりました。
つづく
2019.10.10 追加 つづきはこちらです↓↓
追加終わり