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.

This commit is contained in:
nitko12 2020-08-04 12:51:53 +02:00
parent 65381a7251
commit f012be658b
330 changed files with 845 additions and 804 deletions

View File

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -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);
};

View File

@ -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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

View File

@ -22,18 +22,20 @@
//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";
//Coordinates sent to the api
char *lon = "45.5510548";
char *lat = "18.5947808";
//Change to your wifi ssid and password //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/
//---------------------------------- //----------------------------------
@ -61,8 +63,48 @@ Inkplate display(INKPLATE_1BIT);
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,
};
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 //Variables for storing temperature
char temps[8][4] = { char temps[8][4] = {
@ -72,8 +114,8 @@ 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] = {
"", "",
"", "",
"", "",
@ -93,7 +135,12 @@ 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";
char abbr1[16];
char abbr2[16];
char abbr3[16];
char abbr4[16];
//functions defined below //functions defined below
void drawWeather(); void drawWeather();
@ -115,17 +162,6 @@ void setup()
//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
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 //Welcome screen
display.setCursor(50, 290); display.setCursor(50, 290);
display.setTextSize(3); display.setTextSize(3);
@ -145,14 +181,14 @@ void loop()
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();
@ -176,7 +212,7 @@ void loop()
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)
@ -233,38 +269,66 @@ 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

Some files were not shown because too many files have changed in this diff Show More