 
 	void configure(JsonObject &o);
 } cfg;
+
+struct Conditions {
+	char icon[20];
+	char weather[32];
+	int temp, feelslike;
+	int humidity;
+	int wind;
+	int atmos_pressure;
+	int pressure_trend;
+	char wind_dir[10];
+	int sunrise_hour;
+	char sunrise_minute[3];
+	int sunset_hour;
+	char sunset_minute[3];
+	char moonrise_hour[3];
+	char moonrise_minute[3];
+	char moonset_hour[3];
+	char moonset_minute[3];
+	char moon_phase[16];
+	char age_of_moon[3];
+	time_t epoch;
+	char city[48];
+	int wind_degrees;
+} conditions;
+
+struct Forecast {
+	time_t epoch;
+	char day[4];
+	int temp_high;
+	int temp_low;
+	int max_wind;
+	int ave_wind;
+	char wind_dir[8];
+	int wind_degrees;
+	int ave_humidity;
+	char conditions[32];
+	char icon[20];
+} forecasts[4];
+
+struct Statistics {
+	time_t last_age, min_age, max_age, total;
+	uint32_t last_fetch_conditions, last_fetch_forecasts;
+	unsigned num_updates;
+	unsigned connect_failures;
+	unsigned parse_failures;
+	unsigned mem_failures;
+} stats;
 
 void config::configure(JsonObject &o) {
 	strlcpy(ssid, o[F("ssid")] | "", sizeof(ssid));

		tft.print(WiFi.localIP());
		tft.println('/');

		last_fetch_conditions = -cfg.conditions_interval;
		last_fetch_forecasts = -cfg.forecasts_interval;
	}
	attachInterrupt(SWITCH, []() { swtch=true; }, FALLING);
}

struct Conditions {
	char icon[20];
	char weather[32];
	int temp, feelslike;
	int humidity;
	int wind;
	int atmos_pressure;
	int pressure_trend;
	char wind_dir[10];
	int sunrise_hour;
	char sunrise_minute[3];
	int sunset_hour;
	char sunset_minute[3];
	char moonrise_hour[3];
	char moonrise_minute[3];
	char moonset_hour[3];
	char moonset_minute[3];
	char moon_phase[16];
	char age_of_moon[3];
	time_t epoch;
	char city[48];
	int wind_degrees;
} conditions;

struct Statistics {
	unsigned last_connect;
	unsigned last_update, max_update, num_updates;
	unsigned connect_failures;
	unsigned parse_failures;
	unsigned mem_failures;
} stats;

bool update_conditions(JsonObject &root, struct Conditions &c) {
	JsonObject &current_observation = root[F("current_observation")];
	if (!current_observation.success())
		return false;
	time_t epoch = (time_t)atoi(current_observation[F("observation_epoch")] | "0");
	if (epoch <= c.epoch)
		return false;	    

	unsigned last = stats.last_update, now = millis(), update = now - last;
	stats.num_updates++;
	stats.last_update = now;
	if (update > stats.max_update)
		stats.max_update = update;

	c.epoch = epoch;
	strlcpy(c.weather, current_observation[F("weather")] | "", sizeof(c.weather));

ESP8266WebServer server(80);
ESP8266HTTPUpdateServer httpUpdater;

uint32_t display_on;
uint8_t fade;
bool connected, debug;
