Skip to content

Commit

Permalink
Merge pull request #49 from techniccontroller/dev_automatic_timezone
Browse files Browse the repository at this point in the history
automatically set timezone via API request
  • Loading branch information
techniccontroller authored Feb 15, 2025
2 parents 238322f + 4343490 commit f111059
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 31 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,11 @@ Please download all these libraries as ZIP from GitHub, and extract them in the
- https://github.com/adafruit/Adafruit_NeoPixel
- https://github.com/tzapu/WiFiManager
- https://github.com/adafruit/Adafruit_BusIO
- https://github.com/bxparks/AceTime

folder structure should look like this:
You can als install these libraries via the library manager in the Arduino IDE.

The folder structure should look like this:

```
MySketchbookLocation
Expand Down
32 changes: 10 additions & 22 deletions ntp_client_plus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ NTPClientPlus::NTPClientPlus(UDP &udp, const char *poolServerName, int utcx, boo
{
this->_udp = &udp;
this->_utcx = utcx;
this->_timeOffset = this->secondperhour * this->_utcx;
this->_poolServerName = poolServerName;
this->_swChange = _swChange;
}
Expand Down Expand Up @@ -104,18 +103,13 @@ void NTPClientPlus::end()
}

/**
* @brief Setter TimeOffset
* @brief Setter UTC offset
*
* @param timeOffset offset from UTC in seconds
* @param utcOffset offset from UTC in minutes
*/
void NTPClientPlus::setTimeOffset(int timeOffset)
void NTPClientPlus::setUTCOffset(int utcOffset)
{
this->_timeOffset = timeOffset;
}

long NTPClientPlus::getTimeOffset()
{
return this->_timeOffset;
this->_utcx = utcOffset;
}

/**
Expand All @@ -135,9 +129,10 @@ void NTPClientPlus::setPoolServerName(const char *poolServerName)
*/
unsigned long NTPClientPlus::getSecsSince1900() const
{
return this->_timeOffset + // User offset
this->_secsSince1900 + // seconds returned by the NTP server
((millis() - this->_lastUpdate) / 1000); // Time since last update
return this->_utcx * this->secondperminute + // UTC offset
this->_summertime * this->secondperhour + // Summer time offset
this->_secsSince1900 + // seconds returned by the NTP server
((millis() - this->_lastUpdate) / 1000); // Time since last update
}

/**
Expand Down Expand Up @@ -556,18 +551,11 @@ void NTPClientPlus::sendNTPPacket()
*/
void NTPClientPlus::setSummertime(bool summertime)
{
if (summertime)
{
this->_timeOffset = this->secondperhour * (this->_utcx + 1);
}
else
{
this->_timeOffset = this->secondperhour * (this->_utcx);
}
this->_summertime = summertime;
}

/**
* @brief (private) Update Summer/Winter time change
* @brief Update Summer/Winter time change
*
* @returns bool summertime active
*/
Expand Down
7 changes: 3 additions & 4 deletions ntp_client_plus.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class NTPClientPlus{
void setupNTPClient();
int updateNTP();
void end();
void setTimeOffset(int timeOffset);
void setUTCOffset(int utcOffset);
void setPoolServerName(const char* poolServerName);
unsigned long getSecsSince1900() const;
unsigned long getEpochTime() const;
Expand All @@ -36,7 +36,6 @@ class NTPClientPlus{
unsigned int getYear();
bool isLeapYear(unsigned int year);
int getMonth(int dayOfYear);
long getTimeOffset();
bool updateSWChange();


Expand All @@ -47,9 +46,9 @@ class NTPClientPlus{
const char* _poolServerName = "pool.ntp.org"; // Default time server
IPAddress _poolServerIP;
unsigned int _port = NTP_DEFAULT_LOCAL_PORT;
long _timeOffset = 0;
int _utcx = 0;
bool _swChange = 1;
bool _swChange = 1;
bool _summertime = false;

unsigned long _updateInterval = 60000; // In ms

Expand Down
74 changes: 74 additions & 0 deletions timezonefunctions.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include <ESP8266HTTPClient.h>
#include <AceTime.h> // https://github.com/bxparks/AceTime
#include "ntp_client_plus.h"
#include "udplogger.h"

using namespace ace_time;

static const int CACHE_SIZE = 1;
static ExtendedZoneProcessorCache<CACHE_SIZE> zoneProcessorCache;
static ExtendedZoneManager manager(
zonedbx::kZoneAndLinkRegistrySize,
zonedbx::kZoneAndLinkRegistry,
zoneProcessorCache);

/**
* @brief Request the timezone as string from the IP-API
*
* @param logger UDPLogger object to log messages
* @return String timezone string
*/
String getTimeZoneString(UDPLogger &logger) {
WiFiClient client;
HTTPClient http;
logger.logString("[HTTP] Requesting timezone from IP-API");
if (http.begin(client, "http://ip-api.com/json/")) {
int httpCode = http.GET();

if (httpCode > 0) {
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
String payload = http.getString();

int tzIndex = payload.indexOf("\"timezone\":\"");
if (tzIndex != -1) {
int tzStart = tzIndex + 12;
int tzEnd = payload.indexOf("\"", tzStart);
String timezone = payload.substring(tzStart, tzEnd);
logger.logString("[HTTP] Received timezone: " + timezone);
return timezone;
}
}
}
else {
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end(); // Close connection
}
else {
logger.logString("[HTTP] Unable to connect");
}
return "";
}

/**
* @brief Update the UTC offset from the timezone string obtained from the IP-API
*
* @param logger UDPLogger object to log messages
* @param ntp NTPClientPlus object to set the UTC offset
* @return int
*/
void updateUTCOffsetFromTimezoneAPI(UDPLogger &logger, NTPClientPlus &ntp) {
String timezone = getTimeZoneString(logger);
if (timezone.length() > 0) {
uint16_t zone_index = manager.indexForZoneName(timezone.c_str());
if (zone_index != ZoneManager::kInvalidIndex) {
ExtendedZone zone = manager.getZoneForIndex(zone_index);
int offset = zone.stdOffset().toMinutes();
logger.logString("[ZoneManager] Timezone offset (min): " + String(offset));
ntp.setUTCOffset(offset);
}
else {
logger.logString("[ZoneManager] Error: Could not find time_zone value in DB. Use hardcoded UTC offset.");
}
}
}
8 changes: 4 additions & 4 deletions wordclock_esp8266.ino
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ const String hostname = "wordclock";
// URL DNS server
const char WebserverURL[] = "www.wordclock.local";

int utcOffset = 60; // UTC offset in minutes

// ----------------------------------------------------------------------------------
// GLOBAL VARIABLES
// ----------------------------------------------------------------------------------
Expand Down Expand Up @@ -174,7 +176,7 @@ uint16_t behaviorUpdatePeriod = PERIOD_TIMEVISUUPDATE; // holdes the period in w
// Create necessary global objects
UDPLogger logger;
WiFiUDP NTPUDP;
NTPClientPlus ntp = NTPClientPlus(NTPUDP, "pool.ntp.org", 1, true);
NTPClientPlus ntp = NTPClientPlus(NTPUDP, "pool.ntp.org", utcOffset, true);
LEDMatrix ledmatrix = LEDMatrix(&matrix, brightness, &logger);
Tetris mytetris = Tetris(&ledmatrix, &logger);
Snake mysnake = Snake(&ledmatrix, &logger);
Expand Down Expand Up @@ -343,10 +345,10 @@ void setup() {
logger.logString("Reset Reason: " + ESP.getResetReason());

// setup NTP
updateUTCOffsetFromTimezoneAPI(logger, ntp);
ntp.setupNTPClient();
logger.logString("NTP running");
logger.logString("Time: " + ntp.getFormattedTime());
logger.logString("TimeOffset (seconds): " + String(ntp.getTimeOffset()));

// load persistent variables from EEPROM
loadMainColorFromEEPROM();
Expand Down Expand Up @@ -457,7 +459,6 @@ void loop() {
logger.logString("Time: " + ntp.getFormattedTime());
logger.logString("Date: " + ntp.getFormattedDate());
logger.logString("Day of Week (Mon=1, Sun=7): " + String(ntp.getDayOfWeek()));
logger.logString("TimeOffset (seconds): " + String(ntp.getTimeOffset()));
logger.logString("Summertime: " + String(ntp.updateSWChange()));
lastNTPUpdate = millis();
watchdogCounter = 30;
Expand All @@ -480,7 +481,6 @@ void loop() {
logger.logString("Time: " + ntp.getFormattedTime());
logger.logString("Date: " + ntp.getFormattedDate());
logger.logString("Day of Week (Mon=1, Sun=7): " + ntp.getDayOfWeek());
logger.logString("TimeOffset (seconds): " + String(ntp.getTimeOffset()));
logger.logString("Summertime: " + String(ntp.updateSWChange()));
lastNTPUpdate += 10000;
watchdogCounter--;
Expand Down

0 comments on commit f111059

Please sign in to comment.