D1_mini_weather_station/D1_mini_weather_station.ino
2024-02-07 20:06:07 +01:00

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