Skip to content

Commit ae91866

Browse files
committed
Add first version of weather & moon
1 parent 301b3e7 commit ae91866

File tree

149 files changed

+291
-17
lines changed

Some content is hidden

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

149 files changed

+291
-17
lines changed

assets/moon/_README.txt

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Source: https://lunaf.com/lunar-calendar/
2+
3+
Convert to BMP
4+
for f in *.png ; do convert "$f" -background black -alpha remove -flatten -alpha off -resize 75x75 -type truecolor "../../data/moon/${f%.png}.bmp" ; done
5+

assets/moon/m-phase-0.png

348 KB

assets/moon/m-phase-1.png

262 KB

assets/moon/m-phase-10.png

420 KB

assets/moon/m-phase-11.png

430 KB

assets/moon/m-phase-12.png

441 KB

assets/moon/m-phase-13.png

452 KB

assets/moon/m-phase-14.png

464 KB

assets/moon/m-phase-15.png

469 KB

assets/moon/m-phase-16.png

491 KB

assets/moon/m-phase-17.png

491 KB

assets/moon/m-phase-18.png

480 KB

assets/moon/m-phase-19.png

37.4 KB

assets/moon/m-phase-2.png

287 KB

assets/moon/m-phase-20.png

457 KB

assets/moon/m-phase-21.png

442 KB

assets/moon/m-phase-22.png

428 KB

assets/moon/m-phase-23.png

410 KB

assets/moon/m-phase-24.png

386 KB

assets/moon/m-phase-25.png

371 KB

assets/moon/m-phase-26.png

353 KB

assets/moon/m-phase-27.png

334 KB

assets/moon/m-phase-28.png

318 KB

assets/moon/m-phase-29.png

301 KB

assets/moon/m-phase-3.png

304 KB

assets/moon/m-phase-30.png

6.96 KB

assets/moon/m-phase-31.png

262 KB

assets/moon/m-phase-4.png

323 KB

assets/moon/m-phase-5.png

348 KB

assets/moon/m-phase-6.png

363 KB

assets/moon/m-phase-7.png

376 KB

assets/moon/m-phase-8.png

390 KB

assets/moon/m-phase-9.png

404 KB

assets/weather/_README.txt

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
Source: https://bas.dev/work/meteocons
2+
3+
How to convert large PNGs to small BMPs
4+
=======================================
5+
6+
-> use ImageMagick
7+
8+
Due to a ton of unbalanced withspace around the original images I manually cropped them first!
9+
10+
- crop
11+
- remove background and make black instead
12+
- convert to true-color BMP
13+
14+
for f in *.png ; do convert "$f" -gravity Center -crop '100x100+0+0' +repage -background black -alpha remove -flatten -alpha off -type truecolor "../../data/weather/${f%.png}.bmp" ; done
15+

assets/weather/clear-day.png

1.78 KB

assets/weather/clear-night.png

7.2 KB

assets/weather/cloudy.png

5.27 KB

assets/weather/drizzle.png

6.16 KB

assets/weather/extreme-rain.png

7.03 KB

assets/weather/fog.png

6.6 KB

assets/weather/light-rain.png

6.25 KB

assets/weather/n_a.png

592 Bytes

assets/weather/partly-cloudy-day.png

2.16 KB
2.29 KB

assets/weather/rain.png

6.65 KB

assets/weather/sleet.png

8.02 KB

assets/weather/snow.png

7.21 KB

assets/weather/thunderstorm.png

7.05 KB

assets/weather/unknown.png

5.46 KB

assets/wind/E.png

3.11 KB

assets/wind/E.svg

+10

assets/wind/N.png

4.99 KB

assets/wind/N.svg

+10

assets/wind/NE.png

4.95 KB

assets/wind/NE.svg

+10

assets/wind/NW.png

4.95 KB

assets/wind/NW.svg

+10

assets/wind/S.png

4.97 KB

assets/wind/S.svg

+10

assets/wind/SE.png

4.96 KB

assets/wind/SE.svg

+10

assets/wind/SW.png

5 KB

assets/wind/SW.svg

+10

assets/wind/W.png

3.09 KB

assets/wind/W.svg

+10

assets/wind/_README.txt

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Origin of the wind-rose design
2+
==============================
3+
4+
-> the wind-rose's mother is https://github.com/basmilius/weather-icons/blob/dev/production/line/svg-static/compass.svg
5+
6+
7+
How to convert large PNGs to small BMPs
8+
=======================================
9+
10+
-> use ImageMagick
11+
12+
- crop
13+
- remove background and make black instead
14+
- resize
15+
- convert to true-color BMP
16+
17+
for f in *.png ; do convert "$f" -gravity Center -crop '160x160+0+0' +repage -background black -alpha remove -flatten -alpha off -resize 50x50 -type truecolor "../../data/wind/${f%.png}.bmp" ; done
18+

data/moon/m-phase-0.bmp

16.8 KB
Binary file not shown.

data/moon/m-phase-1.bmp

16.8 KB
Binary file not shown.

data/moon/m-phase-10.bmp

16.8 KB
Binary file not shown.

data/moon/m-phase-11.bmp

16.8 KB
Binary file not shown.

data/moon/m-phase-12.bmp

16.8 KB
Binary file not shown.

data/moon/m-phase-13.bmp

16.8 KB
Binary file not shown.

data/moon/m-phase-14.bmp

16.8 KB
Binary file not shown.

data/moon/m-phase-15.bmp

16.8 KB
Binary file not shown.

data/moon/m-phase-16.bmp

16.8 KB
Binary file not shown.

data/moon/m-phase-17.bmp

16.8 KB
Binary file not shown.

data/moon/m-phase-18.bmp

16.8 KB
Binary file not shown.

data/moon/m-phase-19.bmp

16.8 KB
Binary file not shown.

data/moon/m-phase-2.bmp

16.8 KB
Binary file not shown.

data/moon/m-phase-20.bmp

16.8 KB
Binary file not shown.

data/moon/m-phase-21.bmp

16.8 KB
Binary file not shown.

data/moon/m-phase-22.bmp

16.8 KB
Binary file not shown.

data/moon/m-phase-23.bmp

16.8 KB
Binary file not shown.

data/moon/m-phase-24.bmp

16.8 KB
Binary file not shown.

data/moon/m-phase-25.bmp

16.8 KB
Binary file not shown.

data/moon/m-phase-26.bmp

16.8 KB
Binary file not shown.

data/moon/m-phase-27.bmp

16.8 KB
Binary file not shown.

data/moon/m-phase-28.bmp

16.8 KB
Binary file not shown.

data/moon/m-phase-29.bmp

16.8 KB
Binary file not shown.

data/moon/m-phase-3.bmp

16.8 KB
Binary file not shown.

data/moon/m-phase-30.bmp

16.8 KB
Binary file not shown.

data/moon/m-phase-31.bmp

16.8 KB
Binary file not shown.

data/moon/m-phase-4.bmp

16.8 KB
Binary file not shown.

data/moon/m-phase-5.bmp

16.8 KB
Binary file not shown.

data/moon/m-phase-6.bmp

16.8 KB
Binary file not shown.

data/moon/m-phase-7.bmp

16.8 KB
Binary file not shown.

data/moon/m-phase-8.bmp

16.8 KB
Binary file not shown.

data/moon/m-phase-9.bmp

16.8 KB
Binary file not shown.

data/moon/moonphase_L0.bmp

-10.7 KB
Binary file not shown.

data/moon/moonphase_L1.bmp

-10.7 KB
Binary file not shown.

data/moon/moonphase_L10.bmp

-10.7 KB
Binary file not shown.

data/moon/moonphase_L11.bmp

-10.7 KB
Binary file not shown.

data/moon/moonphase_L12.bmp

-10.7 KB
Binary file not shown.

data/moon/moonphase_L13.bmp

-10.7 KB
Binary file not shown.

data/moon/moonphase_L14.bmp

-10.7 KB
Binary file not shown.

data/moon/moonphase_L15.bmp

-10.7 KB
Binary file not shown.

data/moon/moonphase_L16.bmp

-10.7 KB
Binary file not shown.

data/moon/moonphase_L17.bmp

-10.7 KB
Binary file not shown.

data/moon/moonphase_L18.bmp

-10.7 KB
Binary file not shown.

data/moon/moonphase_L19.bmp

-10.7 KB
Binary file not shown.

data/moon/moonphase_L2.bmp

-10.7 KB
Binary file not shown.

data/moon/moonphase_L20.bmp

-10.7 KB
Binary file not shown.

data/moon/moonphase_L21.bmp

-10.7 KB
Binary file not shown.

data/moon/moonphase_L22.bmp

-10.7 KB
Binary file not shown.

data/moon/moonphase_L23.bmp

-10.7 KB
Binary file not shown.

data/moon/moonphase_L3.bmp

-10.7 KB
Binary file not shown.

data/moon/moonphase_L4.bmp

-10.7 KB
Binary file not shown.

data/moon/moonphase_L5.bmp

-10.7 KB
Binary file not shown.

data/moon/moonphase_L6.bmp

-10.7 KB
Binary file not shown.

data/moon/moonphase_L7.bmp

-10.7 KB
Binary file not shown.

data/moon/moonphase_L8.bmp

-10.7 KB
Binary file not shown.

data/moon/moonphase_L9.bmp

-10.7 KB
Binary file not shown.

data/weather/clear-day.bmp

29.4 KB
Binary file not shown.

data/weather/clear-night.bmp

29.4 KB
Binary file not shown.

data/weather/cloudy.bmp

29.4 KB
Binary file not shown.

data/weather/drizzle.bmp

29.4 KB
Binary file not shown.

data/weather/extreme-rain.bmp

29.4 KB
Binary file not shown.

data/weather/fog.bmp

29.4 KB
Binary file not shown.

data/weather/light-rain.bmp

29.4 KB
Binary file not shown.

data/weather/n_a.bmp

29.4 KB
Binary file not shown.

data/weather/partly-cloudy-day.bmp

29.4 KB
Binary file not shown.

data/weather/partly-cloudy-night.bmp

29.4 KB
Binary file not shown.

data/weather/rain.bmp

29.4 KB
Binary file not shown.

data/weather/sleet.bmp

29.4 KB
Binary file not shown.

data/weather/snow.bmp

29.4 KB
Binary file not shown.

data/weather/thunderstorm.bmp

29.4 KB
Binary file not shown.

data/weather/unknown.bmp

29.4 KB
Binary file not shown.

data/wind/E.bmp

16.8 KB
Binary file not shown.

data/wind/N.bmp

16.8 KB
Binary file not shown.

data/wind/NE.bmp

16.8 KB
Binary file not shown.

data/wind/NW.bmp

16.8 KB
Binary file not shown.

data/wind/S.bmp

16.8 KB
Binary file not shown.

data/wind/SE.bmp

16.8 KB
Binary file not shown.

data/wind/SW.bmp

16.8 KB
Binary file not shown.

data/wind/W.bmp

16.8 KB
Binary file not shown.

platformio.ini

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,5 +53,5 @@ lib_deps =
5353
bodmer/TFT_eSPI@~2.5.30
5454
bodmer/TJpg_Decoder@~1.0.8
5555
bodmer/JSON_Decoder@~0.0.7
56-
https://github.com/Bodmer/OpenFontRender#96a29bc ; no tags or releases to reference :( -> pin to Git revision
56+
https://github.com/Bodmer/OpenFontRender#f163cc6 ; no tags or releases to reference :( -> pin to Git revision
5757
thingpulse/ESP8266 Weather Station@~2.2.0

src/main.cpp

+127-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <JsonListener.h>
1313
#include <OpenWeatherMapCurrent.h>
1414
#include <OpenWeatherMapForecast.h>
15+
#include <SunMoonCalc.h>
1516

1617
#include "connectivity.h"
1718
#include "display.h"
@@ -45,8 +46,11 @@ OpenWeatherMapForecastData forecasts[MAX_FORECASTS];
4546
// ----------------------------------------------------------------------------
4647
// Function prototypes (declarations)
4748
// ----------------------------------------------------------------------------
49+
void drawAstro();
50+
void drawCurrentWeather();
4851
void drawProgress(const char *text, int8_t percentage);
4952
void drawTime();
53+
String getWeatherIconName(uint16_t id, bool today);
5054
void initJpegDecoder();
5155
void initOpenFontRender();
5256
bool pushImageToTft(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t *bitmap);
@@ -95,6 +99,82 @@ void loop(void) {
9599
// ----------------------------------------------------------------------------
96100
// Functions
97101
// ----------------------------------------------------------------------------
102+
void drawAstro() {
103+
time_t tnow = time(nullptr);
104+
struct tm *nowUtc = gmtime(&tnow);
105+
106+
SunMoonCalc smCalc = SunMoonCalc(mkgmtime(nowUtc), currentWeather.lat, currentWeather.lon);
107+
const SunMoonCalc::Result result = smCalc.calculateSunAndMoonData();
108+
109+
ofr.setFontSize(24);
110+
ofr.cdrawString(SUN_MOON_LABEL[0].c_str(), 60, 365);
111+
ofr.cdrawString(SUN_MOON_LABEL[1].c_str(), tft.width() - 60, 365);
112+
113+
ofr.setFontSize(18);
114+
// Sun
115+
strftime(timestampBuffer, 26, UI_TIME_FORMAT_NO_SECONDS, localtime(&result.sun.rise));
116+
ofr.cdrawString(timestampBuffer, 60, 400);
117+
strftime(timestampBuffer, 26, UI_TIME_FORMAT_NO_SECONDS, localtime(&result.sun.set));
118+
ofr.cdrawString(timestampBuffer, 60, 425);
119+
120+
// Moon
121+
strftime(timestampBuffer, 26, UI_TIME_FORMAT_NO_SECONDS, localtime(&result.moon.rise));
122+
ofr.cdrawString(timestampBuffer, tft.width() - 60, 400);
123+
strftime(timestampBuffer, 26, UI_TIME_FORMAT_NO_SECONDS, localtime(&result.moon.set));
124+
ofr.cdrawString(timestampBuffer, tft.width() - 60, 425);
125+
126+
// Moon icon
127+
int imageIndex = round(result.moon.age * NUMBER_OF_MOON_IMAGES / LUNAR_MONTH);
128+
if (imageIndex == NUMBER_OF_MOON_IMAGES) imageIndex = NUMBER_OF_MOON_IMAGES - 1;
129+
ui.drawBmp("/moon/m-phase-" + String(imageIndex) + ".bmp", tft.width() / 2 - 37, 365);
130+
131+
ofr.setFontSize(14);
132+
ofr.cdrawString(MOON_PHASES[result.moon.phase.index].c_str(), tft.width() / 2, 455);
133+
134+
log_i("Moon phase: %s, illumination: %f, age: %f -> image index: %d",
135+
result.moon.phase.name.c_str(), result.moon.illumination, result.moon.age, imageIndex);
136+
}
137+
138+
void drawCurrentWeather() {
139+
// re-use variable throughout function
140+
String text = "";
141+
142+
// icon
143+
String weatherIcon = getWeatherIconName(currentWeather.weatherId, true);
144+
ui.drawBmp("/weather/" + weatherIcon + ".bmp", 5, 125);
145+
// tft.drawRect(5, 125, 100, 100, 0x4228);
146+
147+
// condition string
148+
ofr.setFontSize(24);
149+
ofr.cdrawString(currentWeather.main.c_str(), tft.width() / 2, 95);
150+
151+
// temperature incl. symbol, slightly shifted to the right to find better balance due to the ° symbol
152+
ofr.setFontSize(48);
153+
text = String(currentWeather.temp, 1) + "°";
154+
ofr.cdrawString(text.c_str(), (tft.width() / 2) + 10, 120);
155+
156+
ofr.setFontSize(18);
157+
158+
// humidity
159+
text = String(currentWeather.humidity) + " %";
160+
ofr.cdrawString(text.c_str(), tft.width() / 2, 178);
161+
162+
// pressure
163+
text = String(currentWeather.pressure) + " hPa";
164+
ofr.cdrawString(text.c_str(), tft.width() / 2, 200);
165+
166+
// wind rose icon
167+
int windAngleIndex = round(currentWeather.windDeg * 8 / 360);
168+
if (windAngleIndex > 7) windAngleIndex = 0;
169+
ui.drawBmp("/wind/" + WIND_ICON_NAMES[windAngleIndex] + ".bmp", tft.width() - 80, 125);
170+
// tft.drawRect(tft.width() - 80, 125, 75, 75, 0x4228);
171+
172+
// wind speed
173+
text = String(currentWeather.windSpeed, 0);
174+
if (IS_METRIC) text += " m/s";
175+
else text += " mph";
176+
ofr.cdrawString(text.c_str(), tft.width() - 43, 200);
177+
}
98178

99179
void drawProgress(const char *text, int8_t percentage) {
100180
ofr.setFontSize(24);
@@ -108,6 +188,10 @@ void drawProgress(const char *text, int8_t percentage) {
108188
ui.drawProgressBar(pbX, pbY, pbWidth, 15, percentage, TFT_WHITE, TFT_TP_BLUE);
109189
}
110190

191+
void drawSeparator(uint16_t y) {
192+
tft.drawFastHLine(10, y, tft.width() - 2 * 15, 0x4228);
193+
}
194+
111195
void drawTime() {
112196
timeSprite.fillSprite(TFT_BLACK);
113197
ofr.setFontSize(48);
@@ -118,6 +202,41 @@ void drawTime() {
118202
ofr.setDrawer(tft);
119203
}
120204

205+
String getWeatherIconName(uint16_t id, bool today) {
206+
// Weather condition codes: https://openweathermap.org/weather-conditions#Weather-Condition-Codes-2
207+
208+
// For the 8xx group we also have night versions of the icons.
209+
// Switch to night icons? This could be written w/o if-else but it'd be less legible.
210+
if ( today && id/100 == 8) {
211+
if (today && (currentWeather.observationTime < currentWeather.sunrise ||
212+
currentWeather.observationTime > currentWeather.sunset)) {
213+
id += 1000;
214+
} else if(!today && false) {
215+
//forecast->dt[0] < forecast->sunrise || forecast->dt[0] > forecast->sunset
216+
id += 1000;
217+
}
218+
}
219+
220+
if (id/100 == 2) return "thunderstorm";
221+
if (id/100 == 3) return "drizzle";
222+
if (id == 500) return "light-rain";
223+
if (id == 504) return "extrem-rain";
224+
else if (id == 511) return "sleet";
225+
else if (id/100 == 5) return "rain";
226+
if (id >= 611 && id <= 616) return "sleet";
227+
else if (id/100 == 6) return "snow";
228+
if (id/100 == 7) return "fog";
229+
if (id == 800) return "clear-day";
230+
if (id == 801) return "partly-cloudy-day";
231+
else if (id/100 == 8) return "cloudy";
232+
// night icons
233+
if (id == 1800) return "clear-night";
234+
if (id == 1801) return "partly-cloudy-night";
235+
else if (id/100 == 18) return "cloudy";
236+
237+
return "unknown";
238+
}
239+
121240
void initJpegDecoder() {
122241
// The JPEG image can be scaled by a factor of 1, 2, 4, or 8 (default: 0)
123242
TJpgDec.setJpgScale(1);
@@ -181,6 +300,13 @@ void update() {
181300
ofr.setFontSize(16);
182301
ofr.cdrawString(String("Last weather update: " + getCurrentTimestamp(UI_TIME_FORMAT_NO_SECONDS)).c_str(), tft.width() / 2, 10);
183302
drawTime();
303+
drawSeparator(90);
304+
305+
drawCurrentWeather();
306+
drawSeparator(230);
307+
308+
drawSeparator(350);
309+
drawAstro();
184310
}
185311

186312
void updateData(boolean updateProgressBar) {
@@ -191,7 +317,7 @@ void updateData(boolean updateProgressBar) {
191317
currentWeatherClient->updateCurrentById(&currentWeather, OPEN_WEATHER_MAP_API_KEY, OPEN_WEATHER_MAP_LOCATION_ID);
192318
delete currentWeatherClient;
193319
currentWeatherClient = nullptr;
194-
log_i("Current weather in %s: %s, %.1fC°", currentWeather.cityName, currentWeather.description.c_str(), currentWeather.feelsLike);
320+
log_i("Current weather in %s: %s, %.1f°", currentWeather.cityName, currentWeather.description.c_str(), currentWeather.feelsLike);
195321

196322
if(updateProgressBar) drawProgress("Updating forecast...", 90);
197323
OpenWeatherMapForecast *forecastClient = new OpenWeatherMapForecast();

0 commit comments

Comments
 (0)