Does anyone know how to interface the time alarms library with the TimeZone library so that the TimeAlarms go off at the time in the timezone for the user rather than the UTC time set in the system clock, further set by the NTP library.
Anyone? Anyone?
Bueller?
#include <NTPClient.h>
// change next line to use with another board/shield
#include <ESP8266WiFi.h>
//#include <WiFi.h> // for WiFi shield
//#include <WiFi101.h> // for WiFi 101 shield or MKR1000
#include <WiFiUdp.h>
#include <Timezone.h>
const char *ssid = "***";
const char *password = "***";
WiFiUDP ntpUDP;
// You can specify the time server pool and the offset (in seconds, can be
// changed later with setTimeOffset() ). Additionaly you can specify the
// update interval (in milliseconds, can be changed using setUpdateInterval() ).
NTPClient timeClient(ntpUDP, "us.pool.ntp.org", 3600, 60000);
// US Eastern Time Zone (New York, Detroit)
TimeChangeRule myDST = {"EDT", Second, Sun, Mar, 2, -300}; // Daylight time = UTC - 4 hours
TimeChangeRule mySTD = {"EST", First, Sun, Nov, 2, -360}; // Standard time = UTC - 5 hours
Timezone myTZ(myDST, mySTD);
TimeChangeRule *tcr;
void setup(){
Serial.begin(115200);
WiFi.begin(ssid, password);
while ( WiFi.status() != WL_CONNECTED ) {
delay ( 500 );
Serial.print ( "." );
}
timeClient.begin();
}
void loop() {
timeClient.update();
setTime(timeClient.getEpochTime());
time_t utc = now();
time_t local = myTZ.toLocal(utc, &tcr);
Serial.println();
printDateTime(utc, "UTC");
printDateTime(local, tcr -> abbrev);
//Serial.println(timeClient.getFormattedTime());
delay(1000);
}
// format and print a time_t value, with a time zone appended.
void printDateTime(time_t t, const char *tz)
{
char buf[32];
char m[4]; // temporary storage for month string (DateStrings.cpp uses shared buffer)
strcpy(m, monthShortStr(month(t)));
sprintf(buf, "%.2d:%.2d:%.2d %s %.2d %s %d %s",
hour(t), minute(t), second(t), dayShortStr(weekday(t)), day(t), m, year(t), tz);
Serial.println(buf);
}
The following was extracted from TimeAlarms.cpp. Notice how it uses UTC in the now() function. Also notice how ive included the paramArgs argument into the function so it can work with arguments, rather than being a static function. There is a setter above (not in view).
void TimeAlarmsClass::serviceAlarms()
{
if (!isServicing) {
isServicing = true;
for (servicedAlarmId = 0; servicedAlarmId < dtNBR_ALARMS; servicedAlarmId++) {
if (Alarm[servicedAlarmId].Mode.isEnabled && (now() >= Alarm[servicedAlarmId].nextTrigger)) {
OnTick_t TickHandler = Alarm[servicedAlarmId].onTickHandler;
if (Alarm[servicedAlarmId].Mode.isOneShot) {
free(servicedAlarmId); // free the ID if mode is OnShot
} else {
Alarm[servicedAlarmId].updateNextTrigger();
}
if (TickHandler != NULL) {
(*TickHandler)(Alarm[servicedAlarmId].paramArgs); // call the handler
}
}
}
isServicing = false;
}
}