208 lines
6.4 KiB
C++
208 lines
6.4 KiB
C++
#include <ESP8266WiFi.h>
|
|
#include <ESP8266HTTPClient.h>
|
|
#include <ArduinoJson.h>
|
|
#include <Wire.h>
|
|
#include <NTPClient.h>
|
|
#include <WiFiUdp.h>
|
|
#include <Adafruit_GFX.h>
|
|
#include <Adafruit_SSD1306.h>
|
|
#include "bitmaps.h"
|
|
#define SCREEN_WIDTH 128
|
|
#define SCREEN_HEIGHT 64
|
|
#define OLED_RESET -1
|
|
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
|
|
WiFiClient client;
|
|
|
|
// set Wi-Fi SSID and password
|
|
const char *ssid = "wifinetwork";
|
|
const char *password = "12345678";
|
|
|
|
// Define NTP Client to get time
|
|
WiFiUDP ntpUDP;
|
|
NTPClient timeClient(ntpUDP, "pool.ntp.org");
|
|
|
|
// set location and API key
|
|
const String Location = "Osijek";
|
|
const String API_Key = "someapikey";
|
|
int icon = 0;
|
|
|
|
void capitalizeFirstLetter(char* str) {
|
|
if (str != nullptr && *str != '\0') {
|
|
// Create a copy of the string
|
|
char temp[48];
|
|
strcpy(temp, str);
|
|
|
|
// Capitalize the first letter
|
|
temp[0] = toupper(temp[0]);
|
|
|
|
// Copy the modified string back to the original pointer
|
|
strcpy(str, temp);
|
|
}
|
|
}
|
|
|
|
void setup(void)
|
|
{
|
|
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3D (for the 128x64)
|
|
delay(1000);
|
|
display.clearDisplay(); // clear the display buffer
|
|
display.display();
|
|
display.setTextColor(WHITE, BLACK);
|
|
display.setTextSize(1);
|
|
WiFi.mode(WIFI_STA);
|
|
WiFi.disconnect();
|
|
WiFi.begin(ssid, password);
|
|
display.setCursor(0, 0);
|
|
display.print("Connecting");
|
|
display.display();
|
|
int cnt = 0;
|
|
while ( WiFi.status() != WL_CONNECTED )
|
|
{
|
|
if (cnt == 3) {
|
|
cnt = 0;
|
|
display.clearDisplay();
|
|
display.setCursor(0, 0);
|
|
display.print("Connecting");
|
|
display.display();
|
|
} else {
|
|
display.print(".");
|
|
display.display();
|
|
cnt++;
|
|
}
|
|
delay(1000);
|
|
}
|
|
WiFi.setAutoReconnect(true);
|
|
WiFi.persistent(true);
|
|
display.print("\nconnected");
|
|
display.display();
|
|
timeClient.begin();
|
|
delay(500);
|
|
timeClient.setTimeOffset(3600);
|
|
}
|
|
|
|
void loop()
|
|
{
|
|
if (WiFi.status() == WL_CONNECTED) {
|
|
|
|
timeClient.update();
|
|
// PowerSave
|
|
int currentHour = timeClient.getHours();
|
|
if (currentHour >= 23 || currentHour < 6) {
|
|
display.clearDisplay();
|
|
display.display();
|
|
display.ssd1306_command(SSD1306_DISPLAYOFF);
|
|
delay(300000);
|
|
return;
|
|
}
|
|
else {
|
|
display.ssd1306_command(SSD1306_DISPLAYON);
|
|
}
|
|
//Get a time structure
|
|
time_t epochTime = timeClient.getEpochTime();
|
|
struct tm *ptm = gmtime ((time_t *)&epochTime);
|
|
int currentDay = ptm->tm_mday;
|
|
int currentMonth = ptm->tm_mon + 1;
|
|
int currentYear = ptm->tm_year + 1900;
|
|
HTTPClient http; //Declare an object of class HTTPClient
|
|
|
|
// specify request destination
|
|
http.begin(client, "http://api.openweathermap.org/data/2.5/weather?q=" + Location + "&APPID=" + API_Key); // !!
|
|
int httpCode = http.GET(); // send the request
|
|
if (httpCode > 0) {
|
|
String payload = http.getString(); //Get the request response payload
|
|
|
|
DynamicJsonBuffer jsonBuffer(1024);
|
|
|
|
// Parse JSON object
|
|
JsonObject& root = jsonBuffer.parseObject(payload);
|
|
if (!root.success()) {
|
|
return;
|
|
}
|
|
http.end(); //Close connection
|
|
const char* state = root["weather"][0]["description"]; // get status as string
|
|
capitalizeFirstLetter(const_cast<char*>(state)); // Capitalize the first letter
|
|
float temp = (float)(root["main"]["temp"]) - 273.15; // get temperature in °C
|
|
int humidity = root["main"]["humidity"]; // get humidity in %
|
|
float pressure = (float)(root["main"]["pressure"]) / 1000; // get pressure in bar
|
|
float wind_speed = root["wind"]["speed"]; // get wind speed in m/s
|
|
int statusSize = 2;
|
|
if (strlen(state) > 12) {
|
|
statusSize = 1;
|
|
}
|
|
// print data
|
|
display.clearDisplay(); // clear the display buffer
|
|
display.setTextSize(1);
|
|
display.setCursor(0, 0);
|
|
display.printf("%d-%d-%d\r\n", currentYear, currentMonth, currentDay);
|
|
display.setCursor(0, 9);
|
|
display.printf("%s",Location);
|
|
display.setTextSize(statusSize);
|
|
display.setCursor(0, 21);
|
|
display.printf("%s\r\n", state);
|
|
display.setCursor(0, 39);
|
|
display.setTextSize(1);
|
|
display.printf(" %5.2f C %d%%\r\n", temp, humidity);
|
|
display.drawRect(43, 39, 3, 3, WHITE); // put degree symbol ( ° )
|
|
display.setCursor(0, 52);
|
|
display.printf(" %.3fbar %.1fm/s \r\n", pressure, wind_speed);
|
|
display.drawLine(0, 18, 127, 18, 1);
|
|
display.drawLine(65, 18, 65, 0, 1);
|
|
display.drawBitmap(0, 38, temperature_icon, 10, 10, WHITE);
|
|
display.drawBitmap(74, 38, humidity_icon, 10, 10, WHITE);
|
|
display.drawBitmap(0, 51, pressure_icon, 10, 10, WHITE);
|
|
display.drawBitmap(74, 51, wind_icon, 10, 10, WHITE);
|
|
display.display();
|
|
}
|
|
|
|
// specify request destination
|
|
http.begin(client, "http://api.openweathermap.org/data/2.5/forecast?q=" + Location + "&APPID=" + API_Key + "&cnt=3"); // !!
|
|
httpCode = http.GET(); // send the request
|
|
if (httpCode > 0) {
|
|
String payload = http.getString(); //Get the request response payload
|
|
DynamicJsonBuffer jsonBuffer(1024);
|
|
|
|
// Parse JSON object
|
|
JsonObject& forecast = jsonBuffer.parseObject(payload);
|
|
if (!forecast.success()) {
|
|
return;
|
|
}
|
|
http.end(); //Close connection
|
|
|
|
// State id info
|
|
// 200-232 Thunderstorm
|
|
// 300-321 Drizzle
|
|
// 500-531 Rain
|
|
// 600-622 Snow
|
|
// 701-781 Mist
|
|
// 800 Clear
|
|
// 801-804 Clouds
|
|
int pos = 69;
|
|
for (int day = 0; day <= 2; day++) {
|
|
int state = forecast["list"][day]["weather"][0]["id"]; // get state id
|
|
// Display bitmap based on state_id
|
|
if (state >= 200 && state <= 232) {
|
|
icon = 6; // Thunderstorm
|
|
} else if (state >= 300 && state <= 321) {
|
|
icon = 5; // Drizzle
|
|
} else if (state >= 500 && state <= 531) {
|
|
icon = 3; // Rain
|
|
} else if (state >= 600 && state <= 622) {
|
|
icon = 4; // Snow
|
|
} else if (state >= 701 && state <= 781) {
|
|
icon = 2; // Mist
|
|
} else if (state == 800) {
|
|
icon = 0; // Clear
|
|
} else if (state >= 801 && state <= 804) {
|
|
icon = 1; // Clouds
|
|
} else {
|
|
// Handle unknown state_id
|
|
icon = 0; // Default to Clear icon
|
|
}
|
|
display.drawBitmap(pos, 0, bitmap_icons[icon], 16, 16, WHITE);
|
|
pos = pos + 20;
|
|
display.display();
|
|
}
|
|
}
|
|
}
|
|
delay(1800000);
|
|
}
|