てきとうなさいと べぇたばん

ESP8266(Arduino)でJSONを取得して、パースする

ESP8266の写真 ArduinoJson使って、インターネットからJSONを取得する

ArduinoでJSONをパースをするのに、いくらかライブラリがあって、そのうちArduinoJsonを使った。

また、HTTPでJSONを取得したくても、Arduinoではインターネットに繋ぐのが日本では結構難しいので、ESP8266を使った。

天気予報を取得できるhttp://weather.livedoor.com/weather_hacks/webserviceを使ったけども、これ今年の7月末で終了してしまうのか…

コード

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266WiFiMulti.h>
#define ARDUINOJSON_DECODE_UNICODE 1
#include <ArduinoJson.h>

char ssid[] = "SSID"; // SSID
char password[] = "password"; // パスワード

ESP8266WiFiMulti WiFiMulti;

void setup() {
  Serial.begin(115200);

  for (uint8_t t = 4; t > 0; t--) {
    Serial.printf("[SETUP] WAIT %d...\n", t);
    Serial.flush();
    delay(1000);
  }
  WiFi.mode(WIFI_STA);
  WiFiMulti.addAP(ssid, password);

  while (WiFiMulti.run() != WL_CONNECTED) {
    delay(1000);
  }
  WiFiClient client;
  HTTPClient http;

  Serial.print("[HTTP] begin...\n");
  if (http.begin(client, "http://weather.livedoor.com/forecast/webservice/json/v1?city=110010")) {
    Serial.printf("[HTTP] GET...\n");
    int httpCode = http.GET();

    if (httpCode > 0) {
      Serial.printf("[HTTP] GET... code: %d\n", httpCode);

      if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
        String payload = http.getString();
        const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_ARRAY_SIZE(2) + JSON_ARRAY_SIZE(38) + 44 * JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + 3 * JSON_OBJECT_SIZE(4) + 3 * JSON_OBJECT_SIZE(5) + JSON_OBJECT_SIZE(8) + 3850; // 
        DynamicJsonDocument doc(capacity);
        StaticJsonDocument<64> filter;
        filter["forecasts"][0]["date"] = true;
        filter["forecasts"][0]["telop"] = true;

        DeserializationError error = deserializeJson(doc, payload, DeserializationOption::Filter(filter));

        if (error) {
          Serial.print(F("deserializeJson() failed: "));
          Serial.println(error.c_str());
          return;
        }

        const char *date = doc["forecasts"][0]["date"];
        const char *telop = doc["forecasts"][0]["telop"];

        Serial.printf(
          "%sの天気: %s\n",
          date,
          telop
        );
      }
    } else {
      Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
    }

    http.end();
  } else {
    Serial.printf("[HTTP] Unable to connect\n");
  }
}

void loop() {
  Serial.println("loop");
  delay(1000);
}

なにか気をつけるべき事があるかというと、次の2点だろうか。