More comments, renaming files, fixing typos, new api for hourly forecast, more descriptive instructions for wetup of examples, thicker google calendar lines, fixed google calendar time aligment and location overflow.
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
|
@ -1,353 +0,0 @@
|
||||||
// Network.cpp contains various functions and classes that enable Weather station
|
|
||||||
// They have been declared in seperate file to increase readability
|
|
||||||
#include "Network.h"
|
|
||||||
|
|
||||||
#include <WiFi.h>
|
|
||||||
#include <WiFiMulti.h>
|
|
||||||
#include <HTTPClient.h>
|
|
||||||
#include <WiFiClientSecure.h>
|
|
||||||
|
|
||||||
#include <ArduinoJson.h>
|
|
||||||
|
|
||||||
// WiFiMulti object declaration
|
|
||||||
WiFiMulti WiFiMulti;
|
|
||||||
|
|
||||||
// Static Json from ArduinoJson library
|
|
||||||
StaticJsonDocument<6000> doc;
|
|
||||||
|
|
||||||
// Declared week days
|
|
||||||
char weekDays[8][8] = {
|
|
||||||
"Mon",
|
|
||||||
"Tue",
|
|
||||||
"Wed",
|
|
||||||
"Thr",
|
|
||||||
"Fri",
|
|
||||||
"Sat",
|
|
||||||
"Sun",
|
|
||||||
};
|
|
||||||
|
|
||||||
void Network::begin(char *city)
|
|
||||||
{
|
|
||||||
// Initiating wifi, like in BasicHttpClient example
|
|
||||||
WiFi.mode(WIFI_STA);
|
|
||||||
WiFiMulti.addAP(ssid, pass);
|
|
||||||
|
|
||||||
Serial.print(F("Waiting for WiFi to connect..."));
|
|
||||||
while ((WiFiMulti.run() != WL_CONNECTED))
|
|
||||||
{
|
|
||||||
// Printing a dot to Serial monitor every second while waiting to connect
|
|
||||||
Serial.print(F("."));
|
|
||||||
delay(1000);
|
|
||||||
}
|
|
||||||
Serial.println(F(" connected"));
|
|
||||||
|
|
||||||
// Find internet time
|
|
||||||
setTime();
|
|
||||||
|
|
||||||
// Search for given cities woeid
|
|
||||||
findCity(city);
|
|
||||||
|
|
||||||
// reduce power by making WiFi module sleep
|
|
||||||
WiFi.setSleep(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gets time from ntp server
|
|
||||||
void Network::getTime(char *timeStr)
|
|
||||||
{
|
|
||||||
// Get seconds since 1.1.1970.
|
|
||||||
time_t nowSecs = time(nullptr);
|
|
||||||
|
|
||||||
// Used to store time
|
|
||||||
struct tm timeinfo;
|
|
||||||
gmtime_r(&nowSecs, &timeinfo);
|
|
||||||
|
|
||||||
//Copies time string into timeStr
|
|
||||||
strncpy(timeStr, asctime(&timeinfo) + 11, 5);
|
|
||||||
|
|
||||||
// Setting time string timezone
|
|
||||||
int hr = 10 * timeStr[0] + timeStr[1] + timeZone;
|
|
||||||
|
|
||||||
// Better defined modulo, in case timezone makes hours to go below 0
|
|
||||||
hr = (hr % 24 + 24) % 24;
|
|
||||||
|
|
||||||
// Adding time to '0' char makes it into whatever time char, for both digits
|
|
||||||
timeStr[0] = hr / 10 + '0';
|
|
||||||
timeStr[1] = hr % 10 + '0';
|
|
||||||
}
|
|
||||||
|
|
||||||
void formatTemp(char *str, float temp)
|
|
||||||
{
|
|
||||||
// Built in function for float to char* conversion
|
|
||||||
dtostrf(temp, 2, 0, str);
|
|
||||||
}
|
|
||||||
|
|
||||||
void formatWind(char *str, float wind)
|
|
||||||
{
|
|
||||||
// Built in function for float to char* conversion
|
|
||||||
dtostrf(wind, 2, 0, str);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Upgrade to our inital example, uses a different API to get current real time data
|
|
||||||
bool Network::getCurrentData(char *city, char *temp1, char *temp2, char *temp3, char *temp4, char *currentTemp, char *currentWind, char *currentTime, char *currentWeather, char *currentWeatherAbbr)
|
|
||||||
{
|
|
||||||
doc.clear();
|
|
||||||
|
|
||||||
bool f = 0;
|
|
||||||
// Return if wifi isn't connected
|
|
||||||
if (WiFi.status() != WL_CONNECTED)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
// Wake up if sleeping and save inital state
|
|
||||||
bool sleep = WiFi.getSleep();
|
|
||||||
WiFi.setSleep(false);
|
|
||||||
|
|
||||||
// Http object used to make get request
|
|
||||||
HTTPClient http;
|
|
||||||
|
|
||||||
http.getStream().setNoDelay(true);
|
|
||||||
http.getStream().setTimeout(1);
|
|
||||||
|
|
||||||
// Do another request for real-time current data
|
|
||||||
char url[256];
|
|
||||||
|
|
||||||
// Copies our api key and city into url get parameters
|
|
||||||
sprintf(url, "http://api.weatherstack.com/current?access_key=%s&query=%s", weatherStackKey, city);
|
|
||||||
|
|
||||||
http.getStream().setNoDelay(true);
|
|
||||||
http.getStream().setTimeout(1);
|
|
||||||
|
|
||||||
Serial.println(url);
|
|
||||||
|
|
||||||
// Initiate http
|
|
||||||
http.begin(url);
|
|
||||||
|
|
||||||
// Actually do request
|
|
||||||
int httpCode = http.GET();
|
|
||||||
|
|
||||||
delay(1000);
|
|
||||||
|
|
||||||
if (httpCode == 200)
|
|
||||||
{
|
|
||||||
int32_t len = http.getSize();
|
|
||||||
|
|
||||||
// Try parsing JSON object
|
|
||||||
DeserializationError error = deserializeJson(doc, http.getString());
|
|
||||||
|
|
||||||
// If an error happens print it to Serial monitor
|
|
||||||
if (error)
|
|
||||||
{
|
|
||||||
Serial.print(F("deserializeJson() failed: "));
|
|
||||||
Serial.println(error.c_str());
|
|
||||||
|
|
||||||
f = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Set all data got from internet using formatTemp and formatWind defined above
|
|
||||||
// This part relies heavily on ArduinoJson library
|
|
||||||
|
|
||||||
formatTemp(currentTemp, doc["current"]["temperature"].as<float>());
|
|
||||||
formatWind(currentWind, (float)doc["current"]["wind_speed"].as<int>());
|
|
||||||
|
|
||||||
//strcpy(city, doc["title"].as<char *>());
|
|
||||||
|
|
||||||
strcpy(currentWeather, doc["current"]["weather_descriptions"][0].as<char *>());
|
|
||||||
//strcpy(currentWeatherAbbr, doc["consolidated_weather"][0]["weather_state_abbr"].as<char *>());
|
|
||||||
|
|
||||||
// formatTemp(temp1, doc["consolidated_weather"][0][F("the_temp")].as<float>());
|
|
||||||
// formatTemp(temp2, doc["consolidated_weather"][1][F("the_temp")].as<float>());
|
|
||||||
// formatTemp(temp3, doc["consolidated_weather"][2][F("the_temp")].as<float>());
|
|
||||||
// formatTemp(temp4, doc["consolidated_weather"][3][F("the_temp")].as<float>());
|
|
||||||
|
|
||||||
f = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear document and end http
|
|
||||||
doc.clear();
|
|
||||||
http.end();
|
|
||||||
|
|
||||||
return !f;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Network::getData(char *city, char *temp1, char *temp2, char *temp3, char *temp4, char *currentTemp, char *currentWind, char *currentTime, char *currentWeather, char *currentWeatherAbbr)
|
|
||||||
{
|
|
||||||
// Return if wifi isn't connected
|
|
||||||
if (WiFi.status() != WL_CONNECTED)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Wake up if sleeping and save inital state
|
|
||||||
bool sleep = WiFi.getSleep();
|
|
||||||
WiFi.setSleep(false);
|
|
||||||
|
|
||||||
// Http object used to make get request
|
|
||||||
HTTPClient http;
|
|
||||||
|
|
||||||
http.getStream().setNoDelay(true);
|
|
||||||
http.getStream().setTimeout(1);
|
|
||||||
|
|
||||||
// Add woeid to api call
|
|
||||||
char url[256];
|
|
||||||
sprintf(url, "https://www.metaweather.com/api/location/%d/", location);
|
|
||||||
|
|
||||||
// Initiate http
|
|
||||||
http.begin(url);
|
|
||||||
|
|
||||||
// Actually do request
|
|
||||||
int httpCode = http.GET();
|
|
||||||
if (httpCode == 200)
|
|
||||||
{
|
|
||||||
int32_t len = http.getSize();
|
|
||||||
|
|
||||||
if (len > 0)
|
|
||||||
{
|
|
||||||
// Try parsing JSON object
|
|
||||||
DeserializationError error = deserializeJson(doc, http.getStream());
|
|
||||||
|
|
||||||
// If an error happens print it to Serial monitor
|
|
||||||
if (error)
|
|
||||||
{
|
|
||||||
Serial.print(F("deserializeJson() failed: "));
|
|
||||||
Serial.println(error.c_str());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Set all data got from internet using formatTemp and formatWind defined above
|
|
||||||
// This part relies heavily on ArduinoJson library
|
|
||||||
|
|
||||||
//formatTemp(currentTemp, doc["consolidated_weather"][0][F("the_temp")].as<float>());
|
|
||||||
//formatWind(currentWind, doc["consolidated_weather"][0][F("wind_speed")].as<float>());
|
|
||||||
|
|
||||||
strcpy(city, doc["title"].as<char *>());
|
|
||||||
|
|
||||||
//strcpy(currentWeather, doc["consolidated_weather"][0]["weather_state_name"].as<char *>());
|
|
||||||
strcpy(currentWeatherAbbr, doc["consolidated_weather"][0]["weather_state_abbr"].as<char *>());
|
|
||||||
|
|
||||||
formatTemp(temp1, doc["consolidated_weather"][0][F("the_temp")].as<float>());
|
|
||||||
formatTemp(temp2, doc["consolidated_weather"][1][F("the_temp")].as<float>());
|
|
||||||
formatTemp(temp3, doc["consolidated_weather"][2][F("the_temp")].as<float>());
|
|
||||||
formatTemp(temp4, doc["consolidated_weather"][3][F("the_temp")].as<float>());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop http and clear document
|
|
||||||
doc.clear();
|
|
||||||
http.end();
|
|
||||||
|
|
||||||
// Return to initial state
|
|
||||||
WiFi.setSleep(sleep);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Network::setTime()
|
|
||||||
{
|
|
||||||
// Used for setting correct time
|
|
||||||
configTime(0, 0, "pool.ntp.org", "time.nist.gov");
|
|
||||||
|
|
||||||
Serial.print(F("Waiting for NTP time sync: "));
|
|
||||||
time_t nowSecs = time(nullptr);
|
|
||||||
while (nowSecs < 8 * 3600 * 2)
|
|
||||||
{
|
|
||||||
// Print a dot every half a second while time is not set
|
|
||||||
delay(500);
|
|
||||||
Serial.print(F("."));
|
|
||||||
yield();
|
|
||||||
nowSecs = time(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
Serial.println();
|
|
||||||
|
|
||||||
// Used to store time info
|
|
||||||
struct tm timeinfo;
|
|
||||||
gmtime_r(&nowSecs, &timeinfo);
|
|
||||||
|
|
||||||
Serial.print(F("Current time: "));
|
|
||||||
Serial.print(asctime(&timeinfo));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Network::getDays(char *day, char *day1, char *day2, char *day3)
|
|
||||||
{
|
|
||||||
// Seconds since 1.1.1970.
|
|
||||||
time_t nowSecs = time(nullptr);
|
|
||||||
|
|
||||||
// Find weekday
|
|
||||||
|
|
||||||
// We get seconds since 1970, add 3600 (1 hour) times the time zone and add 3 to
|
|
||||||
// make monday the first day of the week, as 1.1.1970. was a thursday
|
|
||||||
// finally do mod 7 to insure our day is within [0, 6]
|
|
||||||
int dayWeek = ((long)((nowSecs + 3600L * timeZone) / 86400L) + 3) % 7;
|
|
||||||
|
|
||||||
// Copy day data to globals in main file
|
|
||||||
strncpy(day, weekDays[dayWeek], 3);
|
|
||||||
strncpy(day1, weekDays[(dayWeek + 1) % 7], 3);
|
|
||||||
strncpy(day2, weekDays[(dayWeek + 2) % 7], 3);
|
|
||||||
strncpy(day3, weekDays[(dayWeek + 3) % 7], 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Network::findCity(char *city)
|
|
||||||
{
|
|
||||||
// If not connected to wifi, return
|
|
||||||
if (WiFi.status() != WL_CONNECTED)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Wake wifi module and save initial state
|
|
||||||
bool sleep = WiFi.getSleep();
|
|
||||||
WiFi.setSleep(false);
|
|
||||||
|
|
||||||
// Http object
|
|
||||||
HTTPClient http;
|
|
||||||
|
|
||||||
http.getStream().setNoDelay(true);
|
|
||||||
http.getStream().setTimeout(1);
|
|
||||||
|
|
||||||
// Add query param to url
|
|
||||||
char url[256];
|
|
||||||
strcpy(url, "https://www.metaweather.com/api/location/search/?query=");
|
|
||||||
strcat(url, city);
|
|
||||||
|
|
||||||
// Initiate http
|
|
||||||
http.begin(url);
|
|
||||||
|
|
||||||
// Do get request
|
|
||||||
int httpCode = http.GET();
|
|
||||||
if (httpCode == 200) // 200: http success
|
|
||||||
{
|
|
||||||
int32_t len = http.getSize();
|
|
||||||
|
|
||||||
if (len > 0)
|
|
||||||
{
|
|
||||||
// Try to parse JSON object
|
|
||||||
DeserializationError error = deserializeJson(doc, http.getStream());
|
|
||||||
|
|
||||||
// Print error to Serial monitor if one exsists
|
|
||||||
if (error)
|
|
||||||
{
|
|
||||||
Serial.print(F("deserializeJson() failed: "));
|
|
||||||
Serial.println(error.c_str());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Empty list means no matches
|
|
||||||
if (doc.size() == 0)
|
|
||||||
{
|
|
||||||
Serial.println(F("City not found"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Woeid id used for fetching data later on
|
|
||||||
location = doc[0]["woeid"].as<int>();
|
|
||||||
|
|
||||||
Serial.println(F("Found city, woied:"));
|
|
||||||
Serial.println(location);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear document and end http
|
|
||||||
doc.clear();
|
|
||||||
http.end();
|
|
||||||
|
|
||||||
// Return module to initial state
|
|
||||||
WiFi.setSleep(sleep);
|
|
||||||
};
|
|
|
@ -1,41 +0,0 @@
|
||||||
#include "Arduino.h"
|
|
||||||
|
|
||||||
#include <WiFi.h>
|
|
||||||
|
|
||||||
#include <HTTPClient.h>
|
|
||||||
|
|
||||||
#include <WiFiClientSecure.h>
|
|
||||||
|
|
||||||
// To get timeZone from main file
|
|
||||||
extern int timeZone;
|
|
||||||
|
|
||||||
// wifi ssid and password
|
|
||||||
extern char *ssid;
|
|
||||||
extern char *pass;
|
|
||||||
extern char *weatherStackKey;
|
|
||||||
|
|
||||||
#ifndef NETWORK_H
|
|
||||||
#define NETWORK_H
|
|
||||||
|
|
||||||
// All functions defined in Network.cpp
|
|
||||||
|
|
||||||
class Network
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// Functions we can access in main file
|
|
||||||
void begin(char *city);
|
|
||||||
void getTime(char *timeStr);
|
|
||||||
bool getCurrentData(char *city, char *temp1, char *temp2, char *temp3, char *temp4, char *currentTemp, char *currentWind, char *currentTime, char *currentWeather, char *currentWeatherAbbr);
|
|
||||||
void getData(char *city, char *temp1, char *temp2, char *temp3, char *temp4, char *currentTemp, char *currentWind, char *currentTime, char *currentWeather, char *currentWeatherAbbr);
|
|
||||||
void getDays(char *day, char *day1, char *day2, char *day3);
|
|
||||||
|
|
||||||
// Used to store loaction woeid (world id), set in findCity()
|
|
||||||
int location = -1;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Functions called from within our class
|
|
||||||
void setTime();
|
|
||||||
void findCity(char *city);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,15 +0,0 @@
|
||||||
#ifndef ICONS_H
|
|
||||||
#define ICONS_H
|
|
||||||
|
|
||||||
#include "binary_icons/icon_c.h"
|
|
||||||
#include "binary_icons/icon_h.h"
|
|
||||||
#include "binary_icons/icon_hc.h"
|
|
||||||
#include "binary_icons/icon_hr.h"
|
|
||||||
#include "binary_icons/icon_lc.h"
|
|
||||||
#include "binary_icons/icon_lr.h"
|
|
||||||
#include "binary_icons/icon_s.h"
|
|
||||||
#include "binary_icons/icon_sl.h"
|
|
||||||
#include "binary_icons/icon_sn.h"
|
|
||||||
#include "binary_icons/icon_t.h"
|
|
||||||
|
|
||||||
#endif
|
|
Before Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 10 KiB |
|
@ -17,54 +17,96 @@
|
||||||
28 July 2020 by e-radionica.com
|
28 July 2020 by e-radionica.com
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// ---------- CHANGE HERE -------------:
|
//---------- CHANGE HERE -------------:
|
||||||
|
|
||||||
// Time zone for adding hours
|
//Time zone for adding hours
|
||||||
int timeZone = 2;
|
int timeZone = 2;
|
||||||
|
|
||||||
// City search query
|
//City name to de displayed on the bottom
|
||||||
char city[128] = "ZAGREB";
|
char city[128] = "OSIJEK";
|
||||||
|
|
||||||
// Change to your wifi ssid and password
|
//Coordinates sent to the api
|
||||||
|
char *lon = "45.5510548";
|
||||||
|
char *lat = "18.5947808";
|
||||||
|
|
||||||
|
//Change to your wifi ssid and password
|
||||||
char *ssid = "";
|
char *ssid = "";
|
||||||
char *pass = "";
|
char *pass = "";
|
||||||
|
|
||||||
// Change to your weatherstack api key
|
//Change to your api key, if you don't have one, head over to:
|
||||||
char *weatherStackKey = "";
|
//https://openweathermap.org/guide , register and copy the key provided
|
||||||
|
char *apiKey = "";
|
||||||
|
|
||||||
// if you don't have one, go ahead and register at their website:
|
//----------------------------------
|
||||||
// https://weatherstack.com/
|
|
||||||
|
|
||||||
// ----------------------------------
|
//Include Inkplate library to the sketch
|
||||||
|
|
||||||
// Include Inkplate library to the sketch
|
|
||||||
#include "Inkplate.h"
|
#include "Inkplate.h"
|
||||||
|
|
||||||
// Header file for easier code readability
|
//Header file for easier code readability
|
||||||
#include "Network.h"
|
#include "Network.h"
|
||||||
|
|
||||||
// Including fonts used
|
//Including fonts used
|
||||||
#include "Fonts/Roboto_Light_48.h"
|
#include "Fonts/Roboto_Light_48.h"
|
||||||
#include "Fonts/Roboto_Light_36.h"
|
#include "Fonts/Roboto_Light_36.h"
|
||||||
#include "Fonts/Roboto_Light_120.h"
|
#include "Fonts/Roboto_Light_120.h"
|
||||||
|
|
||||||
// Including icons generated by the py file
|
//Including icons generated by the py file
|
||||||
#include "icons.h"
|
#include "icons.h"
|
||||||
|
|
||||||
// Delay between API calls, about 1000 per month, which is the free tier limit
|
//Delay between API calls, about 1000 per month, which is the free tier limit
|
||||||
#define DELAY_MS 267800L
|
#define DELAY_MS 267800L
|
||||||
|
|
||||||
// Inkplate object
|
//Inkplate object
|
||||||
Inkplate display(INKPLATE_1BIT);
|
Inkplate display(INKPLATE_1BIT);
|
||||||
|
|
||||||
// All our network functions are in this object, see Network.h
|
//All our network functions are in this object, see Network.h
|
||||||
Network network;
|
Network network;
|
||||||
|
|
||||||
// Contants used for drawing icons
|
//Contants used for drawing icons
|
||||||
char abbrs[32][16] = {"sn", "sl", "h", "t", "hr", "lr", "s", "hc", "lc", "c"};
|
char abbrs[32][32] = {"01d", "02d", "03d", "04d", "09d", "10d", "11d", "13d", "50d", "01n", "02n", "03n", "04n", "09n", "10n", "11n", "13n", "50n"};
|
||||||
const uint8_t *logos[16] = {icon_sn, icon_sl, icon_h, icon_t, icon_hr, icon_lr, icon_s, icon_hc, icon_lc, icon_c};
|
const uint8_t *logos[18] = {
|
||||||
|
icon_01d,
|
||||||
|
icon_02d,
|
||||||
|
icon_03d,
|
||||||
|
icon_04d,
|
||||||
|
icon_09d,
|
||||||
|
icon_10d,
|
||||||
|
icon_11d,
|
||||||
|
icon_13d,
|
||||||
|
icon_50d,
|
||||||
|
icon_01n,
|
||||||
|
icon_02n,
|
||||||
|
icon_03n,
|
||||||
|
icon_04n,
|
||||||
|
icon_09n,
|
||||||
|
icon_10n,
|
||||||
|
icon_11n,
|
||||||
|
icon_13n,
|
||||||
|
icon_50n,
|
||||||
|
};
|
||||||
|
|
||||||
// Variables for storing temperature
|
const uint8_t *s_logos[18] = {
|
||||||
|
icon_s_01d,
|
||||||
|
icon_s_02d,
|
||||||
|
icon_s_03d,
|
||||||
|
icon_s_04d,
|
||||||
|
icon_s_09d,
|
||||||
|
icon_s_10d,
|
||||||
|
icon_s_11d,
|
||||||
|
icon_s_13d,
|
||||||
|
icon_s_50d,
|
||||||
|
icon_s_01n,
|
||||||
|
icon_s_02n,
|
||||||
|
icon_s_03n,
|
||||||
|
icon_s_04n,
|
||||||
|
icon_s_09n,
|
||||||
|
icon_s_10n,
|
||||||
|
icon_s_11n,
|
||||||
|
icon_s_13n,
|
||||||
|
icon_s_50n,
|
||||||
|
};
|
||||||
|
|
||||||
|
//Variables for storing temperature
|
||||||
char temps[8][4] = {
|
char temps[8][4] = {
|
||||||
"0F",
|
"0F",
|
||||||
"0F",
|
"0F",
|
||||||
|
@ -72,30 +114,35 @@ char temps[8][4] = {
|
||||||
"0F",
|
"0F",
|
||||||
};
|
};
|
||||||
|
|
||||||
// Variables for storing days of the week
|
//Variables for storing hour strings
|
||||||
char days[8][4] = {
|
char hours[8][4] = {
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
};
|
};
|
||||||
|
|
||||||
// Variable for counting partial refreshes
|
//Variable for counting partial refreshes
|
||||||
long refreshes = 0;
|
long refreshes = 0;
|
||||||
|
|
||||||
// Constant to determine when to full update
|
//Constant to determine when to full update
|
||||||
const int fullRefresh = 10;
|
const int fullRefresh = 10;
|
||||||
|
|
||||||
// Variables for storing current time and weather info
|
//Variables for storing current time and weather info
|
||||||
char currentTemp[16] = "0F";
|
char currentTemp[16] = "0F";
|
||||||
char currentWind[16] = "0m/s";
|
char currentWind[16] = "0m/s";
|
||||||
|
|
||||||
char currentTime[16] = "9:41";
|
char currentTime[16] = "9:41";
|
||||||
|
|
||||||
char currentWeather[32] = "-";
|
char currentWeather[32] = "-";
|
||||||
char currentWeatherAbbr[8] = "th";
|
char currentWeatherAbbr[8] = "01d";
|
||||||
|
|
||||||
// functions defined below
|
char abbr1[16];
|
||||||
|
char abbr2[16];
|
||||||
|
char abbr3[16];
|
||||||
|
char abbr4[16];
|
||||||
|
|
||||||
|
//functions defined below
|
||||||
void drawWeather();
|
void drawWeather();
|
||||||
void drawCurrent();
|
void drawCurrent();
|
||||||
void drawTemps();
|
void drawTemps();
|
||||||
|
@ -104,86 +151,75 @@ void drawTime();
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
// Begin serial and display
|
//Begin serial and display
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
display.begin();
|
display.begin();
|
||||||
|
|
||||||
// Initial cleaning of buffer and physical screen
|
//Initial cleaning of buffer and physical screen
|
||||||
display.clearDisplay();
|
display.clearDisplay();
|
||||||
display.clean();
|
display.clean();
|
||||||
|
|
||||||
// Calling our begin from network.h file
|
//Calling our begin from network.h file
|
||||||
network.begin(city);
|
network.begin(city);
|
||||||
|
|
||||||
// If city not found, do nothing
|
//Welcome screen
|
||||||
if (network.location == -1)
|
|
||||||
{
|
|
||||||
display.setCursor(50, 290);
|
|
||||||
display.setTextSize(3);
|
|
||||||
display.print(F("City not in Metaweather Database"));
|
|
||||||
display.display();
|
|
||||||
while (1)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Welcome screen
|
|
||||||
display.setCursor(50, 290);
|
display.setCursor(50, 290);
|
||||||
display.setTextSize(3);
|
display.setTextSize(3);
|
||||||
display.print(F("Welcome to Inkplate 6 weather example!"));
|
display.print(F("Welcome to Inkplate 6 weather example!"));
|
||||||
display.display();
|
display.display();
|
||||||
|
|
||||||
// Wait a bit before proceeding
|
//Wait a bit before proceeding
|
||||||
delay(5000);
|
delay(5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
{
|
{
|
||||||
// Clear display
|
//Clear display
|
||||||
display.clearDisplay();
|
display.clearDisplay();
|
||||||
|
|
||||||
// Get all relevant data, see Network.cpp for info
|
//Get all relevant data, see Network.cpp for info
|
||||||
network.getTime(currentTime);
|
network.getTime(currentTime);
|
||||||
if (refreshes % fullRefresh == 0)
|
if (refreshes % fullRefresh == 0)
|
||||||
{
|
{
|
||||||
network.getDays(days[0], days[1], days[2], days[3]);
|
while (!network.getData(city, temps[0], temps[1], temps[2], temps[3], currentTemp, currentWind, currentTime, currentWeather, currentWeatherAbbr, abbr1, abbr2, abbr3, abbr4))
|
||||||
while (!network.getCurrentData(city, temps[0], temps[1], temps[2], temps[3], currentTemp, currentWind, currentTime, currentWeather, currentWeatherAbbr))
|
|
||||||
{
|
{
|
||||||
|
Serial.println("Retrying fetching data!");
|
||||||
delay(5000);
|
delay(5000);
|
||||||
Serial.println("Retrying accessing API");
|
|
||||||
}
|
}
|
||||||
network.getData(city, temps[0], temps[1], temps[2], temps[3], currentTemp, currentWind, currentTime, currentWeather, currentWeatherAbbr);
|
network.getHours(hours[0], hours[1], hours[2], hours[3]);
|
||||||
}
|
}
|
||||||
// Draw data, see functions below for info
|
|
||||||
|
//Draw data, see functions below for info
|
||||||
drawWeather();
|
drawWeather();
|
||||||
drawCurrent();
|
drawCurrent();
|
||||||
drawTemps();
|
drawTemps();
|
||||||
drawCity();
|
drawCity();
|
||||||
drawTime();
|
drawTime();
|
||||||
|
|
||||||
// Refresh full screen every fullRefresh times, defined above
|
//Refresh full screen every fullRefresh times, defined above
|
||||||
if (refreshes % fullRefresh == 0)
|
if (refreshes % fullRefresh == 0)
|
||||||
display.display();
|
display.display();
|
||||||
else
|
else
|
||||||
display.partialUpdate();
|
display.partialUpdate();
|
||||||
|
|
||||||
// Go to sleep before checking again
|
//Go to sleep before checking again
|
||||||
esp_sleep_enable_timer_wakeup(1000L * DELAY_MS);
|
esp_sleep_enable_timer_wakeup(1000L * DELAY_MS);
|
||||||
(void)esp_light_sleep_start();
|
(void)esp_light_sleep_start();
|
||||||
++refreshes;
|
++refreshes;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function for drawing weather info
|
//Function for drawing weather info
|
||||||
void drawWeather()
|
void drawWeather()
|
||||||
{
|
{
|
||||||
// Searching for weather state abbreviation
|
//Searching for weather state abbreviation
|
||||||
for (int i = 0; i < 10; ++i)
|
for (int i = 0; i < 18; ++i)
|
||||||
{
|
{
|
||||||
// If found draw specified icon
|
//If found draw specified icon
|
||||||
if (strcmp(abbrs[i], currentWeatherAbbr) == 0)
|
if (strcmp(abbrs[i], currentWeatherAbbr) == 0)
|
||||||
display.drawBitmap(50, 50, logos[i], 152, 152, BLACK);
|
display.drawBitmap(50, 50, logos[i], 152, 152, BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw weather state
|
//Draw weather state
|
||||||
display.setTextColor(BLACK, WHITE);
|
display.setTextColor(BLACK, WHITE);
|
||||||
display.setFont(&Roboto_Light_36);
|
display.setFont(&Roboto_Light_36);
|
||||||
display.setTextSize(1);
|
display.setTextSize(1);
|
||||||
|
@ -191,10 +227,10 @@ void drawWeather()
|
||||||
display.println(currentWeather);
|
display.println(currentWeather);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function for drawing current time
|
//Function for drawing current time
|
||||||
void drawTime()
|
void drawTime()
|
||||||
{
|
{
|
||||||
// Drawing current time
|
//Drawing current time
|
||||||
display.setTextColor(BLACK, WHITE);
|
display.setTextColor(BLACK, WHITE);
|
||||||
display.setFont(&Roboto_Light_36);
|
display.setFont(&Roboto_Light_36);
|
||||||
display.setTextSize(1);
|
display.setTextSize(1);
|
||||||
|
@ -203,10 +239,10 @@ void drawTime()
|
||||||
display.println(currentTime);
|
display.println(currentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function for drawing city name
|
//Function for drawing city name
|
||||||
void drawCity()
|
void drawCity()
|
||||||
{
|
{
|
||||||
// Drawing city name
|
//Drawing city name
|
||||||
display.setTextColor(BLACK, WHITE);
|
display.setTextColor(BLACK, WHITE);
|
||||||
display.setFont(&Roboto_Light_36);
|
display.setFont(&Roboto_Light_36);
|
||||||
display.setTextSize(1);
|
display.setTextSize(1);
|
||||||
|
@ -215,10 +251,10 @@ void drawCity()
|
||||||
display.println(city);
|
display.println(city);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function for drawing temperatures
|
//Function for drawing temperatures
|
||||||
void drawTemps()
|
void drawTemps()
|
||||||
{
|
{
|
||||||
// Drawing 4 black rectangles in which temperatures will be written
|
//Drawing 4 black rectangles in which temperatures will be written
|
||||||
int rectWidth = 150;
|
int rectWidth = 150;
|
||||||
int rectSpacing = (800 - rectWidth * 4) / 5;
|
int rectSpacing = (800 - rectWidth * 4) / 5;
|
||||||
|
|
||||||
|
@ -233,46 +269,74 @@ void drawTemps()
|
||||||
display.setTextSize(1);
|
display.setTextSize(1);
|
||||||
display.setTextColor(WHITE, BLACK);
|
display.setTextColor(WHITE, BLACK);
|
||||||
|
|
||||||
display.setCursor(1 * rectSpacing + 0 * rectWidth + textMargin, 300 + textMargin + 70);
|
display.setCursor(1 * rectSpacing + 0 * rectWidth + textMargin, 300 + textMargin + 40);
|
||||||
display.println(days[0]);
|
display.println(hours[0]);
|
||||||
|
|
||||||
display.setCursor(2 * rectSpacing + 1 * rectWidth + textMargin, 300 + textMargin + 70);
|
display.setCursor(2 * rectSpacing + 1 * rectWidth + textMargin, 300 + textMargin + 40);
|
||||||
display.println(days[1]);
|
display.println(hours[1]);
|
||||||
|
|
||||||
display.setCursor(3 * rectSpacing + 2 * rectWidth + textMargin, 300 + textMargin + 70);
|
display.setCursor(3 * rectSpacing + 2 * rectWidth + textMargin, 300 + textMargin + 40);
|
||||||
display.println(days[2]);
|
display.println(hours[2]);
|
||||||
|
|
||||||
display.setCursor(4 * rectSpacing + 3 * rectWidth + textMargin, 300 + textMargin + 70);
|
display.setCursor(4 * rectSpacing + 3 * rectWidth + textMargin, 300 + textMargin + 40);
|
||||||
display.println(days[3]);
|
display.println(hours[3]);
|
||||||
|
|
||||||
// Drawing temperature values into black rectangles
|
//Drawing temperature values into black rectangles
|
||||||
display.setFont(&Roboto_Light_48);
|
display.setFont(&Roboto_Light_48);
|
||||||
display.setTextSize(1);
|
display.setTextSize(1);
|
||||||
display.setTextColor(WHITE, BLACK);
|
display.setTextColor(WHITE, BLACK);
|
||||||
|
|
||||||
display.setCursor(1 * rectSpacing + 0 * rectWidth + textMargin, 300 + textMargin + 160);
|
display.setCursor(1 * rectSpacing + 0 * rectWidth + textMargin, 300 + textMargin + 120);
|
||||||
display.print(temps[0]);
|
display.print(temps[0]);
|
||||||
display.println(F("C"));
|
display.println(F("C"));
|
||||||
|
|
||||||
display.setCursor(2 * rectSpacing + 1 * rectWidth + textMargin, 300 + textMargin + 160);
|
display.setCursor(2 * rectSpacing + 1 * rectWidth + textMargin, 300 + textMargin + 120);
|
||||||
display.print(temps[1]);
|
display.print(temps[1]);
|
||||||
display.println(F("C"));
|
display.println(F("C"));
|
||||||
|
|
||||||
display.setCursor(3 * rectSpacing + 2 * rectWidth + textMargin, 300 + textMargin + 160);
|
display.setCursor(3 * rectSpacing + 2 * rectWidth + textMargin, 300 + textMargin + 120);
|
||||||
display.print(temps[2]);
|
display.print(temps[2]);
|
||||||
display.println(F("C"));
|
display.println(F("C"));
|
||||||
|
|
||||||
display.setCursor(4 * rectSpacing + 3 * rectWidth + textMargin, 300 + textMargin + 160);
|
display.setCursor(4 * rectSpacing + 3 * rectWidth + textMargin, 300 + textMargin + 120);
|
||||||
display.print(temps[3]);
|
display.print(temps[3]);
|
||||||
display.println(F("C"));
|
display.println(F("C"));
|
||||||
|
|
||||||
|
for (int i = 0; i < 18; ++i)
|
||||||
|
{
|
||||||
|
//If found draw specified icon
|
||||||
|
if (strcmp(abbr1, abbrs[i]) == 0)
|
||||||
|
display.drawBitmap(1 * rectSpacing + 0 * rectWidth + textMargin, 300 + textMargin + 150, s_logos[i], 48, 48, WHITE, BLACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 18; ++i)
|
||||||
|
{
|
||||||
|
//If found draw specified icon
|
||||||
|
if (strcmp(abbr2, abbrs[i]) == 0)
|
||||||
|
display.drawBitmap(2 * rectSpacing + 1 * rectWidth + textMargin, 300 + textMargin + 150, s_logos[i], 48, 48, WHITE, BLACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 18; ++i)
|
||||||
|
{
|
||||||
|
//If found draw specified icon
|
||||||
|
if (strcmp(abbr3, abbrs[i]) == 0)
|
||||||
|
display.drawBitmap(3 * rectSpacing + 2 * rectWidth + textMargin, 300 + textMargin + 150, s_logos[i], 48, 48, WHITE, BLACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 18; ++i)
|
||||||
|
{
|
||||||
|
//If found draw specified icon
|
||||||
|
if (strcmp(abbr4, abbrs[i]) == 0)
|
||||||
|
display.drawBitmap(4 * rectSpacing + 3 * rectWidth + textMargin, 300 + textMargin + 150, s_logos[i], 48, 48, WHITE, BLACK);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Current weather drawing function
|
//Current weather drawing function
|
||||||
void drawCurrent()
|
void drawCurrent()
|
||||||
{
|
{
|
||||||
// Drawing current information
|
//Drawing current information
|
||||||
|
|
||||||
// Temperature:
|
//Temperature:
|
||||||
display.setFont(&Roboto_Light_120);
|
display.setFont(&Roboto_Light_120);
|
||||||
display.setTextSize(1);
|
display.setTextSize(1);
|
||||||
display.setTextColor(BLACK, WHITE);
|
display.setTextColor(BLACK, WHITE);
|
||||||
|
@ -289,7 +353,7 @@ void drawCurrent()
|
||||||
display.setCursor(x, y);
|
display.setCursor(x, y);
|
||||||
display.println(F("C"));
|
display.println(F("C"));
|
||||||
|
|
||||||
// Wind:
|
//Wind:
|
||||||
display.setFont(&Roboto_Light_120);
|
display.setFont(&Roboto_Light_120);
|
||||||
display.setTextSize(1);
|
display.setTextSize(1);
|
||||||
display.setTextColor(BLACK, WHITE);
|
display.setTextColor(BLACK, WHITE);
|
||||||
|
@ -306,7 +370,7 @@ void drawCurrent()
|
||||||
display.setCursor(x, y);
|
display.setCursor(x, y);
|
||||||
display.println(F("m/s"));
|
display.println(F("m/s"));
|
||||||
|
|
||||||
// Labels underneath
|
//Labels underneath
|
||||||
display.setFont(&Roboto_Light_36);
|
display.setFont(&Roboto_Light_36);
|
||||||
display.setTextSize(1);
|
display.setTextSize(1);
|
||||||
|
|