Skip to content
This repository was archived by the owner on May 24, 2022. It is now read-only.

Commit ba6de70

Browse files
committed
Replace simpleDSTAdjust with another solution esp8266/Arduino#4637 (comment)
1 parent fdfb6a7 commit ba6de70

File tree

4 files changed

+101
-55
lines changed

4 files changed

+101
-55
lines changed

platformio.ini

-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,5 @@ lib_deps =
2121
DallasTemperature
2222
OneWire
2323
Mini Grafx
24-
simpleDSTadjust
2524
build_flags =
2625
-DPIO_FRAMEWORK_ARDUINO_LWIP2_LOW_MEMORY

src/Settings.h

+6-3
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,18 @@
22
#define OPEN_WEATHER_DISPLAYED_CITY_NAME "Vancouver"
33
#define OPEN_WEATHER_LANGUAGE "en"
44
#define OPEN_WEATHER_MAP_LOCATION_ID "6173331"
5+
#define TZ_ST "PST"
6+
#define TZ_DST "PDT"
7+
#define TZ_UTC_OFFSET "+8"
8+
#define DST_START "M3.2.0/2"
9+
#define DST_END "M11.1.0/2"
510

611
// Define data display formats
712
#define IS_METRIC true
813
#define IS_12H true
914
#define UPDATE_INTERVAL 300
1015
#define TEMPERATURE_UPDATE 10
11-
#define UTC_OFFSET -8
12-
struct dstRule startRule = {"PDT", Last, Sun, Mar, 2, 3600};
13-
struct dstRule endRule = {"PST", Last, Sun, Oct, 2, 0};
16+
uint8_t allowedHours[] = {3, 15, 21};
1417

1518
// Define pallete
1619
#define MINI_BLACK 0

src/main.cpp

+89-48
Original file line numberDiff line numberDiff line change
@@ -5,74 +5,110 @@ bool otaInitialDrawDone = false;
55
uint8_t otaState = 0;
66
uint8_t otaProgress = 0;
77

8-
float insideTemp = 0;
98
uint32_t currTempRotateTime = 0;
109

10+
// Set initially to false to wait for WiFi before attempting update
11+
// These are handled outside Homie loop to ensure it still functions
12+
// even without an MQTT connection
1113
bool initialUpdate = false;
12-
bool currentUpdate = false;
13-
bool forecastUpdate = false;
14-
bool astronomyUpdate = false;
14+
bool doCurrentUpdate = false;
15+
bool doForecastUpdate = false;
16+
bool doAstronomyUpdate = false;
17+
// Set to True inititally since sending is handled inside Homie loop
18+
// and an MQTT connection is guarenteed
19+
bool doTemperatureSend = true;
1520

16-
time_t dstOffset = 0;
1721
uint8_t moonAge = 0;
1822
String moonAgeImage = "";
1923
uint32_t lastTemperatureSent = 0;
2024

2125
HomieNode temperatureNode("temperature", "temperature");
2226
HomieSetting<const char *> owApiKey("ow_api_key", "Open Weather API Key");
27+
HomieSetting<const char *> tzUtcOffset("tz_utc_offset", "Standard time UTC offset. See https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html");
28+
HomieSetting<const char *> tzDST("tz_dst", "Timezone abbrev when in Daylight Saving Time.");
29+
HomieSetting<const char *> tzST("tz_st", "Timezone abbrev when in Standard Time.");
30+
HomieSetting<const char *> dstStart("dst_start", "When DST starts in TZ format");
31+
HomieSetting<const char *> dstEnd("dst_end", "When DST ends in TZ format");
32+
2333

2434
void initialize() {
25-
currentUpdate = true;
26-
forecastUpdate = true;
27-
astronomyUpdate = true;
28-
sensors.begin();
35+
// Setup timezone configurations
36+
// https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html
37+
String tzInfo;
38+
tzInfo.concat(tzST.get());
39+
tzInfo.concat(tzUtcOffset.get());
40+
tzInfo.concat(tzDST.get());
41+
tzInfo.concat(",M3.2.0/2,M11.1.0/2");
42+
Homie.getLogger() << F("Setting TZ info '") << tzInfo << F("'") << endl;
43+
setenv("TZ", tzInfo.c_str(), 1);
44+
tzset(); // save the TZ variable
45+
configTime(0, 0, NTP_SERVERS);
46+
47+
doCurrentUpdate = true;
48+
doForecastUpdate = true;
49+
doAstronomyUpdate = true;
2950
temperatureNode.setProperty("unit").send("c");
3051
}
3152

3253
void temperatureLoop() {
33-
if (millis() - lastTemperatureSent >= TEMPERATURE_UPDATE * 1000 ||
34-
lastTemperatureSent == 0) {
54+
if (doTemperatureSend) {
3555
sensors.requestTemperatures();
36-
insideTemp = sensors.getTempCByIndex(0);
56+
float insideTemp = sensors.getTempCByIndex(0);
3757
Homie.getLogger() << F("Temperature: ") << insideTemp << endl;
3858
temperatureNode.setProperty("degrees").send(String(insideTemp));
39-
lastTemperatureSent = millis();
59+
doTemperatureSend = false;
4060
}
4161
}
4262

4363
void setup() {
4464
Serial.begin(115200);
4565

66+
time_t rtc_time_t = 1543819410; // fake RTC time for now
67+
timezone tz_ = { 0, 0};
68+
timeval tv_ = { rtc_time_t, 0};
69+
settimeofday(&tv_, &tz_);
70+
71+
// Setup pins
4672
pinMode(TFT_LED, OUTPUT);
4773
digitalWrite(TFT_LED, HIGH);
4874
pinMode(TEMP_PIN, INPUT);
75+
sensors.begin();
4976

50-
gfx.init();
51-
gfx.fillBuffer(MINI_BLACK);
52-
gfx.commit();
53-
77+
// Setup tickers
5478
updateCurrentTicker.attach(5 * 60 * 1000, []() {
55-
if (WiFi.status() == WL_CONNECTED) currentUpdate = true;
79+
if (WiFi.status() == WL_CONNECTED) doCurrentUpdate = true;
5680
});
5781
updateForecastTicker.attach(20 * 60 * 1000, []() {
58-
if (WiFi.status() == WL_CONNECTED) forecastUpdate = true;
82+
if (WiFi.status() == WL_CONNECTED) doForecastUpdate = true;
5983
});
6084
updateAstronomyTicker.attach(60 * 60 * 1000, []() {
61-
if (WiFi.status() == WL_CONNECTED) astronomyUpdate = true;
85+
if (WiFi.status() == WL_CONNECTED) doAstronomyUpdate = true;
6286
});
87+
sendTemperatureTicker.attach(60 * 1000, []() { doTemperatureSend = true; });
6388

89+
// setup graphics driver
90+
gfx.init();
91+
gfx.fillBuffer(MINI_BLACK);
92+
gfx.commit();
6493
carousel.setFrames(frames, frameCount);
6594
carousel.disableAllIndicators();
6695
carousel.setTargetFPS(3);
6796

97+
// Setup HTTP clients
6898
currentWeatherClient.setMetric(IS_METRIC);
6999
currentWeatherClient.setLanguage(OPEN_WEATHER_LANGUAGE);
70100
forecastClient.setMetric(IS_METRIC);
71101
forecastClient.setLanguage(OPEN_WEATHER_LANGUAGE);
72102
forecastClient.setAllowedHours(allowedHours, sizeof(allowedHours));
73103

104+
// Setup Homie
74105
Homie_setFirmware("weather-station", "0.0.1");
75106
Homie_setBrand("IoT");
107+
tzUtcOffset.setDefaultValue(TZ_UTC_OFFSET);
108+
tzST.setDefaultValue(TZ_ST);
109+
tzDST.setDefaultValue(TZ_DST);
110+
dstStart.setDefaultValue(DST_START);
111+
dstEnd.setDefaultValue(DST_END);
76112
Homie.onEvent(onHomieEvent);
77113
Homie.setSetupFunction(initialize);
78114
Homie.setLoopFunction(temperatureLoop);
@@ -131,7 +167,7 @@ void loop() {
131167
switch (bootMode) {
132168
case HomieBootMode::NORMAL:
133169
// Only update data if WiFi connected and interval passed
134-
if (currentUpdate || forecastUpdate || astronomyUpdate) {
170+
if (doCurrentUpdate || doForecastUpdate || doAstronomyUpdate) {
135171
updateData();
136172
return;
137173
}
@@ -172,9 +208,9 @@ void drawWifiQuality() {
172208

173209
void drawTime() {
174210
char time_str[11];
175-
char *dstAbbrev;
176-
time_t now = dstAdjusted.time(&dstAbbrev);
177-
struct tm *timeinfo = localtime(&now);
211+
212+
time_t tnow = time(nullptr);
213+
struct tm *timeinfo = localtime(&tnow);
178214

179215
gfx.setTextAlignment(TEXT_ALIGN_CENTER);
180216
gfx.setFont(ArialRoundedMTBold_14);
@@ -202,11 +238,11 @@ void drawTime() {
202238
gfx.setFont(ArialMT_Plain_10);
203239
gfx.setColor(MINI_BLUE);
204240
if (IS_12H) {
205-
sprintf(time_str, "%s\n%s", dstAbbrev,
241+
sprintf(time_str, "%s\n%s", getTimezone(timeinfo),
206242
timeinfo->tm_hour >= 12 ? "PM" : "AM");
207243
gfx.drawString(195, 27, time_str);
208244
} else {
209-
sprintf(time_str, "%s", dstAbbrev);
245+
sprintf(time_str, "%s", getTimezone(timeinfo));
210246
gfx.drawString(195, 27, time_str); // Known bug: Cuts off 4th character of
211247
// timezone abbreviation
212248
}
@@ -247,9 +283,14 @@ void drawCurrentWeather() {
247283
gfx.setColor(MINI_WHITE);
248284
gfx.setTextAlignment(TEXT_ALIGN_RIGHT);
249285

250-
gfx.drawString(220, 78,
251-
String(displayCurrent ? currentWeather.temp : insideTemp, 1) +
252-
(IS_METRIC ? "°C" : "°F"));
286+
if (!displayCurrent) {
287+
sensors.requestTemperatures();
288+
float insideTemp = sensors.getTempCByIndex(0);
289+
gfx.drawString(220, 78, String(insideTemp, 1) + (IS_METRIC ? "°C" : "°F"));
290+
} else {
291+
gfx.drawString(220, 78,
292+
String(currentWeather.temp, 1) + (IS_METRIC ? "°C" : "°F"));
293+
}
253294

254295
if (displayCurrent) {
255296
gfx.setFont(ArialRoundedMTBold_14);
@@ -284,7 +325,7 @@ void drawForecastDetail(uint16_t x, uint16_t y, uint8_t dayIndex) {
284325
gfx.setColor(MINI_YELLOW);
285326
gfx.setFont(ArialRoundedMTBold_14);
286327
gfx.setTextAlignment(TEXT_ALIGN_CENTER);
287-
time_t time = forecasts[dayIndex].observationTime + dstOffset;
328+
time_t time = forecasts[dayIndex].observationTime;
288329
struct tm *timeinfo = localtime(&time);
289330
gfx.drawString(
290331
x + 25, y - 15,
@@ -319,10 +360,10 @@ void drawAstronomy() {
319360
gfx.setColor(MINI_YELLOW);
320361
gfx.drawString(5, 250, SUN_MOON_TEXT[0]);
321362
gfx.setColor(MINI_WHITE);
322-
time_t time = currentWeather.sunrise + dstOffset;
363+
time_t time = currentWeather.sunrise;
323364
gfx.drawString(5, 276, SUN_MOON_TEXT[1] + ":");
324365
gfx.drawString(45, 276, getTime(&time));
325-
time = currentWeather.sunset + dstOffset;
366+
time = currentWeather.sunset;
326367
gfx.drawString(5, 291, SUN_MOON_TEXT[2] + ":");
327368
gfx.drawString(45, 291, getTime(&time));
328369

@@ -351,43 +392,43 @@ void updateData() {
351392
gfx.fillBuffer(MINI_BLACK);
352393
gfx.setFont(ArialRoundedMTBold_14);
353394

354-
configTime(UTC_OFFSET * 3600, 0, NTP_SERVERS);
355-
while (!time(nullptr)) {
356-
Serial.print("#");
357-
delay(10);
358-
}
359-
// calculate for time calculation how much the dst class adds.
360-
dstOffset = UTC_OFFSET * 3600 + dstAdjusted.time(nullptr) - time(nullptr);
361-
362-
if (currentUpdate) {
395+
if (doCurrentUpdate) {
363396
drawProgress(50, F("Updating conditions..."));
364-
currentUpdate = !currentWeatherClient.updateCurrentById(
397+
doCurrentUpdate = !currentWeatherClient.updateCurrentById(
365398
&currentWeather, owApiKey.get(), OPEN_WEATHER_MAP_LOCATION_ID);
366399
Homie.getLogger() << F("Current Forecast Successful? ")
367-
<< (currentUpdate ? F("False") : F("True")) << endl;
400+
<< (doCurrentUpdate ? F("False") : F("True")) << endl;
368401
}
369402

370-
if (forecastUpdate) {
403+
if (doForecastUpdate) {
371404
drawProgress(70, F("Updating forecasts..."));
372-
forecastUpdate = !forecastClient.updateForecastsById(
405+
doForecastUpdate = !forecastClient.updateForecastsById(
373406
forecasts, owApiKey.get(), OPEN_WEATHER_MAP_LOCATION_ID, MAX_FORECASTS);
374407
Homie.getLogger() << F("Forcast Update Successful? ")
375-
<< (forecastUpdate ? F("False") : F("True")) << endl;
408+
<< (doForecastUpdate ? F("False") : F("True")) << endl;
376409
}
377410

378-
if (astronomyUpdate) {
411+
if (doAstronomyUpdate) {
379412
drawProgress(80, F("Updating astronomy..."));
380413
moonData = astronomy.calculateMoonData(time(nullptr));
381414
float lunarMonth = 29.53;
382415
moonAge = moonData.phase <= 4
383416
? lunarMonth * moonData.illumination / 2
384417
: lunarMonth - moonData.illumination * lunarMonth / 2;
385418
moonAgeImage = String((char)(65 + ((uint8_t)((26 * moonAge / 30) % 26))));
386-
astronomyUpdate = false;
419+
doAstronomyUpdate = false;
387420
}
388421
initialUpdate = true;
389422
}
390423

424+
const char* getTimezone(tm *timeInfo) {
425+
if (timeInfo->tm_isdst) {
426+
return tzDST.get();
427+
} else {
428+
return tzST.get();
429+
}
430+
}
431+
391432
String getTime(time_t *timestamp) {
392433
struct tm *timeInfo = gmtime(timestamp);
393434

src/main.hpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
#include <Arduino.h>
2+
#include <time.h>
3+
#include <sys/time.h>
4+
#include <coredecls.h>
25

36
#include <Carousel.h>
47
#include <ILI9341_SPI.h>
@@ -9,7 +12,6 @@
912
#include <Astronomy.h>
1013
#include <OpenWeatherMapCurrent.h>
1114
#include <OpenWeatherMapForecast.h>
12-
#include <simpleDSTadjust.h>
1315

1416
#include <DallasTemperature.h>
1517
#include <OneWire.h>
@@ -38,7 +40,6 @@ String SUN_MOON_TEXT[] = {"Sun", "Rise", "Set", "Moon", "Age", "Illum"};
3840
String MOON_PHASES[] = {"New Moon", "Waxing Crescent", "First Quarter",
3941
"Waxing Gibbous", "Full Moon", "Waning Gibbous",
4042
"Third quarter", "Waning Crescent"};
41-
simpleDSTadjust dstAdjusted(startRule, endRule);
4243

4344
ILI9341_SPI tft = ILI9341_SPI(TFT_CS, TFT_DC);
4445
MiniGrafx gfx = MiniGrafx(&tft, BITS_PER_PIXEL, palette);
@@ -50,19 +51,21 @@ OpenWeatherMapCurrent currentWeatherClient;
5051
OpenWeatherMapForecast forecastClient;
5152
Astronomy astronomy;
5253
Astronomy::MoonData moonData;
53-
uint8_t allowedHours[] = {12, 0};
5454

5555
OneWire oneWire(TEMP_PIN);
5656
DallasTemperature sensors(&oneWire);
5757
Ticker updateCurrentTicker;
5858
Ticker updateForecastTicker;
5959
Ticker updateAstronomyTicker;
60+
Ticker sendTemperatureTicker;
6061

6162
const char *getMeteoconIconFromProgmem(String iconText);
6263
int8_t getWifiQuality();
6364
String getTime(time_t *timestamp);
65+
const char* getTimezone(tm *timeInfo);
6466
void onHomieEvent(const HomieEvent &event);
6567
void updateData();
68+
void updateTemperatureSensor();
6669

6770
void drawWifiQuality();
6871
void drawMQTTConnection();

0 commit comments

Comments
 (0)