Skip to content

Commit

Permalink
Update SystemClock_NTP sample and Timezone library
Browse files Browse the repository at this point in the history
Add to Windows CI builds
  • Loading branch information
mikee47 authored and mikee47 committed Jun 17, 2024
1 parent 11afd4e commit 7d0c23f
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 21 deletions.
2 changes: 2 additions & 0 deletions Tools/ci/build.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ REM HostTests must build for all architectures
REM Building Bear SSL library causes memory issues with CI builds in Windows, so avoid for now
%MAKE_PARALLEL% -C "%SMING_PROJECTS_DIR%/tests/HostTests" %TEST_FLAGS% || goto :error

%MAKE_PARALLEL% -C "%SMING_HOME%" SystemClock_NTP || goto :error

REM Start Arch-specific tests
cd /d %SMING_HOME%
call Arch\%SMING_ARCH%\Tools\ci\build.run.cmd || goto :error
Expand Down
79 changes: 61 additions & 18 deletions samples/SystemClock_NTP/app/NtpClientDemo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,69 @@
#include <SystemClock.h>
#include <HardwareSerial.h>
#include <SolarCalculator.h>
#include <Timezone.h>

namespace
namespace MyZone
{
using namespace TZ;
/*
* For handling local/UTC time conversions
* This is for the UK, amend as required
*/
const TimeChangeRule dstStart{"BST", Last, Sun, Mar, 1, 60};
const TimeChangeRule stdStart{"GMT", Last, Sun, Oct, 2, 0};
Timezone tz(dstStart, stdStart);
const Rule dstStart{"BST", Last, Sun, Mar, 1, 60};
const Rule stdStart{"GMT", Last, Sun, Oct, 2, 0};

// Posix rule string
DEFINE_FSTR_LOCAL(tzstr, "GMT0BST,M3.5.0/1,M10.5.0")

// Sunrise/sunset requires co-ordinates
SolarRef solarRef = {51.4769, 0.0005}; // Greenwich, London

} // namespace MyZone

namespace
{
// We can initialise timezone in various ways
Timezone tz = Timezone::fromPosix(MyZone::tzstr);
// Timezone tz(MyZone::dstStart, MyZone::stdStart);

/*
* We use the y/m/d from local time for sunrise/sunset calculations, and the solar calculator
* returns the time from midnight in UTC for that day. We therefore need to adjust this
* to account for timezone and daylight savings.
*/
time_t getNextSunriseSet(bool isSunrise)
ZonedTime getNextSunriseSet(bool isSunrise)
{
auto timeNow = SystemClock.now(eTZ_Local);
DateTime dt(timeNow);
auto utcNow = SystemClock.now(eTZ_UTC);
DateTime dt(tz.toLocal(utcNow));
dt.Hour = 0;
dt.Minute = 0;
dt.Second = 0;
SolarCalculator calc;
SolarCalculator calc(MyZone::solarRef);
int offset_secs = SECS_PER_MIN * calc.sunRiseSet(isSunrise, dt.Year, dt.Month + 1, dt.Day);

time_t t = tz.toLocal(dt + offset_secs);
time_t utcNext = dt + offset_secs;

// If time has already passed, then make it tomorrow
if(t < timeNow) {
t = tz.toLocal(dt + offset_secs + SECS_PER_DAY);
if(utcNext < utcNow) {
utcNext += SECS_PER_DAY;
}

return t;
return tz.makeZoned(utcNext);
}

void checkTimeZoneOffset(time_t systemTime)
{
static ZonedTime nextChange{TZ::invalidTime};

if(nextChange == TZ::invalidTime) {
nextChange = tz.makeZoned(systemTime);
} else if(systemTime < nextChange) {
return;
}

SystemClock.setTimeZone(nextChange.getZoneInfo());
nextChange = tz.getNextChange(systemTime);
}

} // namespace
Expand All @@ -46,9 +75,10 @@ void NtpClientDemo::ntpResult(NtpClient& client, time_t ntpTime)
* Update the system clock and calculate the correct time offset,
* accounting for time zone and daylight savings.
*/
auto localTime = tz.toLocal(ntpTime);
SystemClock.setTime(ntpTime, eTZ_UTC);
SystemClock.setTimeZoneOffset(localTime - ntpTime);

// Now we've set the clock, we can determine the initial active timezone and maintain the offset
SystemClock.onCheckTimeZoneOffset([this](time_t systemTime) { checkTimeZoneOffset(systemTime); });

/*
* Display the new time
Expand All @@ -60,8 +90,21 @@ void NtpClientDemo::ntpResult(NtpClient& client, time_t ntpTime)
/*
* Display times of next sunrise and sunset
*/
DateTime sunrise = getNextSunriseSet(true);
DateTime sunset = getNextSunriseSet(false);
Serial << _F("Next sunrise at ") << sunrise.toShortTimeString() << _F(", sunset at ") << sunset.toShortTimeString()
<< endl;
ZonedTime sunrise = getNextSunriseSet(true);
ZonedTime sunset = getNextSunriseSet(false);
Serial << _F("Next sunrise ") << sunrise.toString() << _F(", sunset ") << sunset.toString() << endl;

/*
* Display points at which daylight savings changes.
*/
DateTime dt(ntpTime);

ZonedTime dst = tz.getTransition(dt.Year, true);
Serial << dst.tag() << _F(" starts ") << dst.toUtc().toString() << endl;

ZonedTime std = tz.getTransition(dt.Year, false);
Serial << std.tag() << _F(" starts ") << std.toUtc().toString() << endl;

ZonedTime nextChange = tz.getNextChange(ntpTime);
Serial << _F("Next change to ") << nextChange.tag() << _F(" on ") << nextChange.toUtc().toString() << endl;
}
2 changes: 0 additions & 2 deletions samples/SystemClock_NTP/include/NtpClientDemo.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#pragma once

#include <Network/NtpClient.h>
#include <SystemClock.h>
#include <Timezone.h>

class NtpClientDemo
{
Expand Down

0 comments on commit 7d0c23f

Please sign in to comment.