Skip to content

Commit 9163b68

Browse files
committed
open meteo weather app for the inkplate 2
upload
1 parent 8097846 commit 9163b68

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+11371
-0
lines changed
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/*
2+
Inkplate2 OpenMeteo Weather Station Example
3+
Compatible with Soldered Inkplate 2
4+
5+
Getting Started:
6+
For setup and documentation, visit: https://inkplate.readthedocs.io/en/latest/
7+
8+
Overview:
9+
This example demonstrates how to fetch and display weather data from the OpenMeteo API
10+
using the Inkplate 10 e-paper display.
11+
12+
Before You Start:
13+
- Enter your WiFi credentials carefully (they are case-sensitive).
14+
- Update the following variables for accurate local weather data:
15+
• timeZone
16+
• latitude
17+
• longitude
18+
Set your username and city with `myUsername` and `myCity` (for display only, not essential for the API).
19+
20+
Units:
21+
By default, the app uses the metric system.
22+
To switch to Imperial units, change the metricUnits to "bool metricUnits = false;"
23+
*/
24+
#include "src/includes.h" // Include necessary libraries and dependencies for Inkplate and networking
25+
26+
// --- WiFi Configuration ---
27+
const char *ssid = "Soldered-testingPurposes";
28+
const char *password = "Testing443";
29+
30+
// --- User and Location Info ---
31+
String myUsername = "Username"; // User's name to be displayed on screen
32+
String myCity = "Osijek"; // City name for weather data
33+
int timeZone =
34+
2; // timeZone is the number in (UTC + number) in your time zone UTC + 2 for Osijek, UTC - 4 for New York City
35+
float latitude = 45.5550; // Latitude of the city
36+
float longitude = 18.6955; // Longitude of the city
37+
38+
bool metricUnits = true; // set this to false if you wish to use Imperial units
39+
40+
const char* ntpServer = "pool.ntp.org"; // in case you want to use a different one
41+
42+
// --- Device and Data Objects ---
43+
Inkplate inkplate;
44+
Network network; // Network utility for weather fetching
45+
Network::UserInfo userInfo; // Structure to hold user and device info (battery, last updated, etc.)
46+
WeatherData weatherData; // Structure to hold fetched weather data
47+
Gui gui(inkplate); // Drawing visuals and info
48+
49+
// --- Deep Sleep Configuration ---
50+
#define uS_TO_S_FACTOR 1000000 // Convert microseconds to seconds
51+
#define TIME_TO_SLEEP 120 // Sleep time: 1800 seconds = 30 minutes
52+
53+
// Add this above setup()
54+
RTC_DATA_ATTR int bootCount = 0; // This variable persists across deep sleep resets
55+
56+
// --- Main Setup: Runs Once on Boot ---
57+
void setup()
58+
{
59+
Serial.begin(115200); // Initialize serial monitor for debugging
60+
inkplate.begin(); // Start the Inkplate display
61+
inkplate.clearDisplay(); // Clear the screen
62+
63+
// Attempt to connect to WiFi
64+
const unsigned long timeout = 30000;
65+
unsigned long startTime = millis();
66+
bool connected = false;
67+
68+
while (!connected && (millis() - startTime) < timeout)
69+
{
70+
connected = inkplate.connectWiFi(ssid, password, 10, true);
71+
}
72+
73+
// If WiFi failed, display error message
74+
if (!connected)
75+
{
76+
gui.wifiError();
77+
}
78+
else
79+
{
80+
configTime(timeZone * 3600, 0, ntpServer); // Set local time via NTP server
81+
// Gather battery and city info
82+
// userInfo.voltage = inkplate.readBattery();
83+
userInfo.city = myCity;
84+
userInfo.username = myUsername;
85+
userInfo.useMetric = metricUnits;
86+
87+
// Fetch weather data for specified coordinates
88+
network.fetchWeatherData(&weatherData, &userInfo, &latitude, &longitude);
89+
90+
// Display if weather API call fails
91+
if (userInfo.apiError)
92+
{
93+
gui.apiError();
94+
}
95+
else
96+
{
97+
if (bootCount % 2 == 1)
98+
{
99+
gui.displayWeatherData(&weatherData, &userInfo); // Odd boots
100+
bootCount++;
101+
}
102+
else
103+
{
104+
gui.displayWeatherData2(&weatherData, &userInfo);// Even boots
105+
bootCount++;
106+
}
107+
}
108+
}
109+
110+
// Sleep to save power; wakes every 30 minutes
111+
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP *
112+
uS_TO_S_FACTOR); // Activate wake-up timer -- wake up after 30mins here
113+
esp_deep_sleep_start(); // Put ESP32 into deep sleep.
114+
}
115+
116+
void loop()
117+
{
118+
// Nothing to do here - main logic runs once in setup()
119+
}
120+
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
#include "Gui.h"
2+
#include "Network.h"
3+
#include "WeatherData.h"
4+
#include <Arduino.h>
5+
#include <Inkplate.h>
6+
7+
// all the weather icons
8+
#include "binary_Icons/icon_s_clear_sky.h"
9+
#include "binary_Icons/icon_s_fog.h"
10+
#include "binary_Icons/icon_s_gray.h"
11+
#include "binary_Icons/icon_s_moon.h"
12+
#include "binary_Icons/icon_s_partly_cloudy.h"
13+
#include "binary_Icons/icon_s_rain.h"
14+
#include "binary_Icons/icon_s_snow.h"
15+
#include "binary_Icons/icon_s_storm.h"
16+
#include "binary_Icons/icon_s_thermometer.h"
17+
18+
// font
19+
#include "fonts/FreeSans12pt7b.h"
20+
#include "fonts/FreeSans18pt7b.h"
21+
#include "fonts/FreeSans9pt7b.h"
22+
#include "fonts/FreeSans6pt7b.h"
23+
#include "fonts/FreeSansBold24pt7b.h"
24+
25+
Gui::Gui(Inkplate &inkplate) : inkplate(inkplate)
26+
{
27+
}
28+
29+
void Gui::drawBackground()
30+
{
31+
}
32+
33+
void Gui::wifiError()
34+
{
35+
inkplate.clearDisplay();
36+
inkplate.setTextColor(INKPLATE2_BLACK);
37+
inkplate.setFont(&FreeSans9pt7b);
38+
inkplate.setCursor(10, 30);
39+
inkplate.print("WiFi connection failed.");
40+
inkplate.setCursor(10, 80);
41+
inkplate.print("Check credentials or try again.");
42+
inkplate.display();
43+
}
44+
45+
void Gui::apiError()
46+
{
47+
inkplate.clearDisplay();
48+
inkplate.setTextColor(INKPLATE2_BLACK);
49+
inkplate.setFont(&FreeSans9pt7b);
50+
inkplate.setCursor(10, 30);
51+
inkplate.print("HTTP request failed.");
52+
inkplate.setCursor(10, 80);
53+
inkplate.print("Check API URL or try again.");
54+
inkplate.display();
55+
}
56+
57+
// Weather Icons based on open-meteo api code
58+
const uint8_t *Gui::getWeatherIcon(int code)
59+
{
60+
switch (code)
61+
{
62+
case 0:
63+
return icon_s_clear_sky;
64+
case 1:
65+
case 2:
66+
case 3:
67+
return icon_s_partly_cloudy;
68+
case 45:
69+
case 48:
70+
return icon_s_fog;
71+
case 51:
72+
case 53:
73+
case 55:
74+
case 56:
75+
case 57:
76+
case 61:
77+
case 63:
78+
case 65:
79+
case 66:
80+
case 67:
81+
case 80:
82+
case 81:
83+
case 82:
84+
return icon_s_rain;
85+
case 71:
86+
case 73:
87+
case 75:
88+
case 77:
89+
case 85:
90+
case 86:
91+
return icon_s_snow;
92+
case 95:
93+
case 96:
94+
case 99:
95+
return icon_s_storm;
96+
default:
97+
return icon_s_gray;
98+
}
99+
}
100+
101+
102+
// --- Display All Weather Data ---
103+
void Gui::displayWeatherData(WeatherData *weatherData, Network::UserInfo *userInfo)
104+
{
105+
inkplate.setTextColor(INKPLATE2_BLACK);
106+
int startX = 10; // Starting x-position for the weekly forecast
107+
int startY = 15; // Starting y-position for the weekly forecast
108+
int iconSize = 48; // Size of the icon
109+
int margin = 5; // Margin between elements
110+
int dayWidth = iconSize + margin + 15; // Space for icon + margin + text width
111+
// Loop through the 7-day forecast and display each day
112+
for (int i = 0; i < 3; i++)
113+
{
114+
inkplate.setFont(&FreeSans6pt7b);
115+
int xPos = startX + i * dayWidth;
116+
// Day name
117+
inkplate.setCursor(xPos + 15, startY);
118+
inkplate.print(weatherData->dailyNames[i]);
119+
// Weather icon
120+
inkplate.setFont(&FreeSans6pt7b);
121+
inkplate.drawBitmap(xPos + 5, startY + 8, getWeatherIcon(weatherData->dailyWeatherCodes[i]), iconSize,
122+
iconSize, INKPLATE2_BLACK);
123+
int tempYStart = startY + iconSize + margin;
124+
// === Max Temp - Up Arrow Triangle ===
125+
int arrowX = xPos;
126+
int arrowY = tempYStart + 15;
127+
// Triangle pointing up
128+
inkplate.fillTriangle(arrowX, arrowY, // bottom center
129+
arrowX - 4, arrowY + 6, // bottom left
130+
arrowX + 4, arrowY + 6, // bottom right
131+
INKPLATE2_RED // white color
132+
);
133+
// Max temp text next to it
134+
inkplate.setCursor(arrowX + 10, arrowY + 6);
135+
inkplate.print(weatherData->dailyMaxTemp[i]);
136+
inkplate.print(userInfo->temperatureLabel);
137+
// === Min Temp - Down Arrow Triangle ===
138+
arrowY += 10;
139+
// Triangle pointing down
140+
inkplate.fillTriangle(arrowX, arrowY + 6, // top center
141+
arrowX - 4, arrowY, // bottom left
142+
arrowX + 4, arrowY, // bottom right
143+
INKPLATE2_BLACK // white color
144+
);
145+
// Min temp text next to it
146+
inkplate.setCursor(arrowX + 10, arrowY + 6);
147+
inkplate.print(weatherData->dailyMinTemp[i]);
148+
inkplate.print(userInfo->temperatureLabel);
149+
}
150+
151+
// Finalize drawing
152+
inkplate.display();
153+
}
154+
155+
// --- Display All Weather Data ---
156+
void Gui::displayWeatherData2(WeatherData *weatherData, Network::UserInfo *userInfo)
157+
{
158+
// Section 1: Main info
159+
inkplate.setFont(&FreeSans12pt7b);
160+
inkplate.setTextColor(INKPLATE2_BLACK);
161+
inkplate.drawBitmap(0, 5, icon_s_gray, 48, 48, INKPLATE2_RED);
162+
inkplate.setCursor(55, 35);
163+
inkplate.print(userInfo->city);
164+
inkplate.setFont(&FreeSans9pt7b);
165+
//inkplate.drawBitmap(0, 50, icon_s_thermometer, 24, 24, INKPLATE2_BLACK);
166+
inkplate.setCursor(55, 75);
167+
inkplate.print(weatherData->currentTemp);
168+
inkplate.print(userInfo->temperatureLabel);
169+
inkplate.drawBitmap(0, 55, getWeatherIcon(weatherData->weatherCode), 48, 48, INKPLATE2_BLACK);
170+
inkplate.setCursor(55, 95);
171+
inkplate.println(weatherData->weatherDescription);
172+
173+
174+
// Finalize drawing
175+
inkplate.display();
176+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#ifndef GUI_H
2+
#define GUI_H
3+
4+
#include "Inkplate.h"
5+
#include "Network.h"
6+
#include "WeatherData.h"
7+
#include <Arduino.h>
8+
9+
class Gui
10+
{
11+
12+
public:
13+
Gui(Inkplate &inkplate);
14+
void drawBackground();
15+
void displayWeatherData(WeatherData *weatherData, Network::UserInfo *userInfo);
16+
void displayWeatherData2(WeatherData *weatherData, Network::UserInfo *userInfo);
17+
void wifiError();
18+
void apiError();
19+
20+
private:
21+
Inkplate &inkplate;
22+
void drawTemperaturePrecipGraph(WeatherData *weatherData, Network::UserInfo *userInfo);
23+
const uint8_t* getWeatherIcon(int code);
24+
const uint8_t* getBatteryIcon(int percentage);
25+
26+
};
27+
28+
#endif

0 commit comments

Comments
 (0)