Getting the Weather

Ok, we don't really care about the weather. I use DarkSky to fetch the weather data for the day but ignore everything other than the sunrise and sunset times. Using that information along with the time of day from the RTC, the system can determine if it's day or night.

boolean fetch_sunrise_sunset(long *sunrise, long *sunset)
{
  if (!client.connectSSL("api.darksky.net", 443)) {
    return false;
  }

  client.print("GET /forecast/");
  client.print(DARKSKY_KEY);
  client.print("/42.9837,-81.2497?units=ca&exclude=currently,minutely,hourly,alerts,flags&language=en");
  client.println(" HTTP/1.1");

  client.print("Host: ");
  client.println("api.darksky.net");
  client.println("Connection: close");
  if (!client.println()) {
    client.stop();
    return false;
  }

  char status[32] = {0};
  client.readBytesUntil('\r', status, sizeof(status));
  if (strcmp(status, "HTTP/1.1 200 OK") != 0) {
    client.stop();
    return false;
  }

  char endOfHeaders[] = "\r\n\r\n";
  if (!client.find(endOfHeaders)) {
    client.stop();
    return false;
  }

  JsonObject& root = jsonBuffer.parseObject(client);
  client.stop();

  if (!root.success()) {
    return false;
  }

  JsonObject& data = root["daily"]["data"][0];
  long start_of_day = data["time"];
  long raw_sunrise_time = data["sunriseTime"];
  long raw_sunset_time = data["sunsetTime"];

  *sunrise = raw_sunrise_time - start_of_day;
  *sunset = raw_sunset_time - start_of_day;

  return true;
}


boolean update_sunrise_sunset()
{
  long sunrise_seconds, sunset_seconds;
  if (!fetch_sunrise_sunset(&sunrise_seconds, &sunset_seconds)) {
    return false;
  }
  
  if (sunrise) {
    delete sunrise;
  }
  sunrise = new DateTime(0, 0, 0, sunrise_seconds / 3600, (sunrise_seconds / 60) % 60, 0);

  if (sunset) {
    delete sunset;
  }
  sunset = new DateTime(0, 0, 0, sunset_seconds / 3600, (sunset_seconds / 60) % 60, 0);

  return true;
}

The Darksky api takes url arguments for the location, units, as well as data items to exclude. In this case I have it exclude as much as possible to minimize the size of the response body.

Note that fetch_sunrise_sunset returns times in seconds, be relative to the start of the day. That then gets converted to DateTime objects for use later.

This guide was first published on Feb 14, 2018. It was last updated on Feb 14, 2018. This page (Getting the Weather) was last updated on Feb 08, 2018.