Bluenet  5.7.0
Bluenet, firmware for nRF52 smart home devices
Loading...
Searching...
No Matches
SystemTime Class Reference

Author: Crownstone Team Copyright: Crownstone (https://crownstone.rocks) Date: Sep 24, 2019 License: LGPLv3+, Apache License 2.0, and/or MIT (triple-licensed) More...

#include <cs_SystemTime.h>

Inheritance diagram for SystemTime:
Collaboration diagram for SystemTime:

Public Member Functions

void init ()
 Creates and starts the first tick timer. More...
 
virtual void handleEvent (event_t &event)
 Handle events. More...
 
virtual ~SystemTime ()=default
 
- Public Member Functions inherited from EventListener
 EventListener ()
 
virtual ~EventListener ()
 unregisters the listener. More...
 
virtual void handleEvent (event_t &event)=0
 Handle events. More...
 
void listen ()
 Registers this with the EventDispatcher. More...
 

Static Public Member Functions

static uint32_t posix ()
 Get the current time as posix timestamp in seconds. More...
 
static Time now ()
 Get the current time as Time object. More...
 
static DayOfWeek day ()
 Get the current weekday. More...
 
static uint32_t up ()
 Uptime in seconds. More...
 
static high_resolution_time_stamp_t getSynchronizedStamp ()
 Get the synchronized timestamp, updated to current time. More...
 
static cs_ret_code_t setTime (uint32_t time, bool throttled, bool sendToMesh)
 Set the system wide time to given posix timestamp. More...
 
static cs_ret_code_t setSunTimes (const sun_time_t &sunTimes, bool throttled=true)
 Set the sunrise and sunset times. More...
 

Private Member Functions

bool isOnlyReceiveByThisDevice (cmd_source_with_counter_t counted_source)
 Returns true if the command source is uart or ble through connection. More...
 

Static Private Member Functions

static void scheduleNextTick ()
 
static void tick (void *unused)
 Must be called at least once per second to update upTimeSec. More...
 
static constexpr uint32_t reboot_sync_timeout_ms ()
 Timeout period before considering this stone to be root clock. More...
 
static constexpr uint32_t root_clock_update_period_ms ()
 Time between sync messages from the root clock. More...
 
static constexpr uint32_t root_clock_reelection_timeout_ms ()
 If no sync message has been received from the root clock for this time, a new root clock will be selected. More...
 
static constexpr stone_id_t stone_id_init ()
 Stone id to use for initialization. More...
 
static constexpr uint8_t timestamp_version_lollipop_max ()
 The time version is lollipop versioned. More...
 
static constexpr uint8_t timestamp_version_min_valid ()
 Lowest time version at which a valid posix time is set. More...
 
static uint32_t syncTimeCoroutineAction ()
 
static uint8_t timeStampVersion ()
 
static void onTimeSyncMessageReceive (time_sync_message_t syncmessage)
 
static void setRootTimeStamp (high_resolution_time_stamp_t stamp, stone_id_t id, uint32_t rtcCount)
 
static void updateRootTimeStamp (uint32_t rtcCount)
 Keep up the root clock time. More...
 
static void sendTimeSyncMessage (high_resolution_time_stamp_t stamp, stone_id_t id, bool reliable=false)
 Send a sync message for given stamp/id combo to the mesh. More...
 
static bool meIsRootClock ()
 Returns true if the id of this stone can considered to be root clock. More...
 
static bool isRootClock (stone_id_t candidate)
 Returns true if the candidate can considered to be root clock. More...
 
static bool reelectionPeriodTimedOut ()
 Returns true if onTimeSyncMessageReceive hasn't received any sync messages from a clock authority in the last root_clock_reelection_timeout_ms milliseconds. More...
 
static bool rebootTimedOut ()
 Returns true when reboot period is passed. More...
 
static constexpr uint32_t debugSyncTimeMessagePeriodMs ()
 
static void initDebug ()
 Sets up the debug symc time coroutine when DEBUG_SYSTEM_TIME is defined in order to broadcast sync messages to the mesh regardless of being root clock or not. More...
 
static void publishSyncMessageForTesting ()
 
static void pushSyncMessageToTestSuite (time_sync_message_t &syncmessage)
 

Static Private Attributes

static uint32_t upTimeSec
 
static uint16_t throttleSetTimeCountdownTicks
 
static uint16_t throttleSetSunTimesCountdownTicks
 
static constexpr auto TICK_TIME_MS = 500
 
static constexpr uint16_t TIME_UPDATE_PERIOD_MS = (60 * 1000)
 
static constexpr uint16_t THROTTLE_SET_TIME_TICKS = (60 * 1000 / TICK_TIME_MS)
 
static constexpr uint16_t THROTTLE_SET_SUN_TIMES_TICKS = (30 * 60 * 1000 / TICK_TIME_MS)
 
static app_timer_t appTimerData
 
static app_timer_id_t appTimerId
 
static uint32_t rtcCountOfLastSecondIncrement
 RTC count of last time a second had passed. More...
 
static stone_id_t myId
 Cached ID of this stone. More...
 
static high_resolution_time_stamp_t rootTime
 Root clock. More...
 
static uint32_t rtcCountOfLastRootTimeUpdate
 RTC count of last time the root clock was set. More...
 
static uint32_t uptimeOfLastTimeSyncMessage
 Uptime of last time a sync message was received. More...
 
static stone_id_t rootClockId
 Stone ID of the root clock. More...
 
static Coroutine syncTimeCoroutine
 
static Coroutine debugSyncTimeCoroutine
 

Friends

class TestAccess< SystemTime >
 

Detailed Description

Author: Crownstone Team Copyright: Crownstone (https://crownstone.rocks) Date: Sep 24, 2019 License: LGPLv3+, Apache License 2.0, and/or MIT (triple-licensed)

This class keeps track of the real time in the current time zone. It may obtain its data through the mesh, or some other way and try to keep up to date using on board timing functionality.

This class also synchronizes time with other nodes in the mesh. The node with the lowest ID is considered to be the root clock. Other nodes will update their time on receival of time sync messages from the root clock.

There are some scenarios to consider here:

  1. No node knows the actual posix time: in this case we still want a synchronized clock.
  2. Nodes are all just booted, but not at the same time: they should still synchronize quickly.
  3. Nodes are all booted at the same time.
  4. A node that's not the root clock receives a set time command, this time should overrule the root clock time.

This is solved by:

  1. Update the clock even when no posix time is known, but mark it to be invalid with a low version.
  2. Only consider ourselves to be root ID after the first time sync message is received.
  1. On boot, each node will request to be synchronized (a mechanism already in the mesh). Every other node that considers themselves to be in sync, will send their clock. It's up to the receiving node to device which clock to use. Nodes will consider themselves to be in sync after hearing 1 time sync message, or after boot timeout.
  2. In this case we expect all nodes to be waiting for the first message to be sent.
  3. Add a lollipop version to the clock: a newer version will always be accepted, even if it's not the root ID.

For robustness, not only the root clock node, but all nodes will regularly send a time sync message. It's up to the receiving node to device which clock is the root clock. Not sure if this is necessary.

Constructor & Destructor Documentation

◆ ~SystemTime()

virtual SystemTime::~SystemTime ( )
virtualdefault

Member Function Documentation

◆ day()

static DayOfWeek SystemTime::day ( )
static

Get the current weekday.

◆ debugSyncTimeMessagePeriodMs()

static constexpr uint32_t SystemTime::debugSyncTimeMessagePeriodMs ( )
staticconstexprprivate

◆ getSynchronizedStamp()

static high_resolution_time_stamp_t SystemTime::getSynchronizedStamp ( )
static

Get the synchronized timestamp, updated to current time.

When version == 0, the timestamp is not posix based.

◆ handleEvent()

virtual void SystemTime::handleEvent ( event_t event)
virtual

Handle events.

This method is overloaded by all classes that derive from EventListener. They can receive an event_t struct and act upon it. These events are dispatched by the EventDispatcher.

Implements EventListener.

◆ init()

void SystemTime::init ( )

Creates and starts the first tick timer.

◆ initDebug()

static void SystemTime::initDebug ( )
staticprivate

Sets up the debug symc time coroutine when DEBUG_SYSTEM_TIME is defined in order to broadcast sync messages to the mesh regardless of being root clock or not.

◆ isOnlyReceiveByThisDevice()

bool SystemTime::isOnlyReceiveByThisDevice ( cmd_source_with_counter_t  counted_source)
private

Returns true if the command source is uart or ble through connection.

◆ isRootClock()

static bool SystemTime::isRootClock ( stone_id_t  candidate)
staticprivate

Returns true if the candidate can considered to be root clock.

◆ meIsRootClock()

static bool SystemTime::meIsRootClock ( )
staticprivate

Returns true if the id of this stone can considered to be root clock.

◆ now()

static Time SystemTime::now ( )
static

Get the current time as Time object.

◆ onTimeSyncMessageReceive()

static void SystemTime::onTimeSyncMessageReceive ( time_sync_message_t  syncmessage)
staticprivate

◆ posix()

static uint32_t SystemTime::posix ( )
static

Get the current time as posix timestamp in seconds.

Returns 0 if no valid posix time is set.

◆ publishSyncMessageForTesting()

static void SystemTime::publishSyncMessageForTesting ( )
staticprivate

◆ pushSyncMessageToTestSuite()

static void SystemTime::pushSyncMessageToTestSuite ( time_sync_message_t syncmessage)
staticprivate

◆ reboot_sync_timeout_ms()

static constexpr uint32_t SystemTime::reboot_sync_timeout_ms ( )
staticconstexprprivate

Timeout period before considering this stone to be root clock.

◆ rebootTimedOut()

static bool SystemTime::rebootTimedOut ( )
staticprivate

Returns true when reboot period is passed.

◆ reelectionPeriodTimedOut()

static bool SystemTime::reelectionPeriodTimedOut ( )
staticprivate

Returns true if onTimeSyncMessageReceive hasn't received any sync messages from a clock authority in the last root_clock_reelection_timeout_ms milliseconds.

◆ root_clock_reelection_timeout_ms()

static constexpr uint32_t SystemTime::root_clock_reelection_timeout_ms ( )
staticconstexprprivate

If no sync message has been received from the root clock for this time, a new root clock will be selected.

◆ root_clock_update_period_ms()

static constexpr uint32_t SystemTime::root_clock_update_period_ms ( )
staticconstexprprivate

Time between sync messages from the root clock.

◆ scheduleNextTick()

static void SystemTime::scheduleNextTick ( )
staticprivate

◆ sendTimeSyncMessage()

static void SystemTime::sendTimeSyncMessage ( high_resolution_time_stamp_t  stamp,
stone_id_t  id,
bool  reliable = false 
)
staticprivate

Send a sync message for given stamp/id combo to the mesh.

◆ setRootTimeStamp()

static void SystemTime::setRootTimeStamp ( high_resolution_time_stamp_t  stamp,
stone_id_t  id,
uint32_t  rtcCount 
)
staticprivate

◆ setSunTimes()

static cs_ret_code_t SystemTime::setSunTimes ( const sun_time_t sunTimes,
bool  throttled = true 
)
static

Set the sunrise and sunset times.

Also sets it to state.

Parameters
[in]sunTimesSun rise and set times.
[in]throttledWhen true, a new suntime won't be allowed to be set for a while. Unless it's set with throttled false.

◆ setTime()

static cs_ret_code_t SystemTime::setTime ( uint32_t  time,
bool  throttled,
bool  sendToMesh 
)
static

Set the system wide time to given posix timestamp.

Dispatches EVT_TIME_SET. Also sets it to state.

Parameters
[in]timePosix time in seconds.
[in]throttledWhen true, a new suntime won't be allowed to be set for a while. Unless it's set with throttled false.
[in]sendToMeshSetting this to false will prevent updating other mesh nodes
Returns
ERR_SUCCESS When time is set successfully.
ERR_BUSY When set time is throttled, try again later.
ERR_WRONG_PARAMETER When trying to set time to 0.

◆ stone_id_init()

static constexpr stone_id_t SystemTime::stone_id_init ( )
staticconstexprprivate

Stone id to use for initialization.

◆ syncTimeCoroutineAction()

static uint32_t SystemTime::syncTimeCoroutineAction ( )
staticprivate

◆ tick()

static void SystemTime::tick ( void *  unused)
staticprivate

Must be called at least once per second to update upTimeSec.

◆ timestamp_version_lollipop_max()

static constexpr uint8_t SystemTime::timestamp_version_lollipop_max ( )
staticconstexprprivate

The time version is lollipop versioned.

This constant defines its roll over point.

◆ timestamp_version_min_valid()

static constexpr uint8_t SystemTime::timestamp_version_min_valid ( )
staticconstexprprivate

Lowest time version at which a valid posix time is set.

◆ timeStampVersion()

static uint8_t SystemTime::timeStampVersion ( )
staticprivate

◆ up()

static uint32_t SystemTime::up ( )
static

Uptime in seconds.

◆ updateRootTimeStamp()

static void SystemTime::updateRootTimeStamp ( uint32_t  rtcCount)
staticprivate

Keep up the root clock time.

Should be called at least every second. But it currently looses some precision, so don't call it too often.

Friends And Related Function Documentation

◆ TestAccess< SystemTime >

friend class TestAccess< SystemTime >
friend

Member Data Documentation

◆ appTimerData

app_timer_t SystemTime::appTimerData
staticprivate

◆ appTimerId

app_timer_id_t SystemTime::appTimerId
staticprivate

◆ debugSyncTimeCoroutine

Coroutine SystemTime::debugSyncTimeCoroutine
staticprivate

◆ myId

stone_id_t SystemTime::myId
staticprivate

Cached ID of this stone.

◆ rootClockId

stone_id_t SystemTime::rootClockId
staticprivate

Stone ID of the root clock.

◆ rootTime

high_resolution_time_stamp_t SystemTime::rootTime
staticprivate

Root clock.

Updated at a low rate, use a function to get an up to date timestamp.

◆ rtcCountOfLastRootTimeUpdate

uint32_t SystemTime::rtcCountOfLastRootTimeUpdate
staticprivate

RTC count of last time the root clock was set.

◆ rtcCountOfLastSecondIncrement

uint32_t SystemTime::rtcCountOfLastSecondIncrement
staticprivate

RTC count of last time a second had passed.

◆ syncTimeCoroutine

Coroutine SystemTime::syncTimeCoroutine
staticprivate

◆ THROTTLE_SET_SUN_TIMES_TICKS

constexpr uint16_t SystemTime::THROTTLE_SET_SUN_TIMES_TICKS = (30 * 60 * 1000 / TICK_TIME_MS)
staticconstexprprivate

◆ THROTTLE_SET_TIME_TICKS

constexpr uint16_t SystemTime::THROTTLE_SET_TIME_TICKS = (60 * 1000 / TICK_TIME_MS)
staticconstexprprivate

◆ throttleSetSunTimesCountdownTicks

uint16_t SystemTime::throttleSetSunTimesCountdownTicks
staticprivate

◆ throttleSetTimeCountdownTicks

uint16_t SystemTime::throttleSetTimeCountdownTicks
staticprivate

◆ TICK_TIME_MS

constexpr auto SystemTime::TICK_TIME_MS = 500
staticconstexprprivate

◆ TIME_UPDATE_PERIOD_MS

constexpr uint16_t SystemTime::TIME_UPDATE_PERIOD_MS = (60 * 1000)
staticconstexprprivate

◆ uptimeOfLastTimeSyncMessage

uint32_t SystemTime::uptimeOfLastTimeSyncMessage
staticprivate

Uptime of last time a sync message was received.

◆ upTimeSec

uint32_t SystemTime::upTimeSec
staticprivate

The documentation for this class was generated from the following file: