NervesTime
keeps the system clock on Nerves
devices in sync when connected to the network and close to in sync when
disconnected. It's especially useful for devices lacking a Battery-backed
real-time clock and will advance
the clock at startup to a reasonable guess.
First add nerves_time
to your project's dependencies:
def deps do
[
{:nerves_time, "~> 0.4.2"}
]
end
Ensure that your vm.args
allows for
timewarps.
If it doesn't, nerves_time
will update the OS system time, but Erlang's system
time will lag. The following line should be in the beginning or middle of the
vm.args
file:
+C multi_time_warp
If you're using one of the official Nerves Systems, then this is all that's
needed. nerves_time
requires Busybox's ntpd
and date
applets to be
enabled. If you haven't explicitly disabled the, they're probably enabled.
nerves_time
uses ntp.pool.org for time
synchronization. Please see their terms of
use before tweaking nerves_time
.
Alternative NTP servers can be specified using the config.exs
:
# config/config.exs
config :nerves_time, :servers, [
"0.pool.ntp.org",
"1.pool.ntp.org",
"2.pool.ntp.org",
"3.pool.ntp.org"
]
It's also possible to configure NTP servers at runtime. See
NervesTime.set_ntp_servers/1
.
nerves_time
also has a concept of a valid time range. This minimizes time
errors on systems without clocks or Internet connections or that may have some
issue that causes a very wrong time value. The default valid time range is
hardcoded and moves forward each release. It is not the build timestamp since
that results in non-reproducible builds.
Applications can override the valid range via the application config:
# config/config.exs
config :nerves_time, earliest_time: ~N[2019-10-04 00:00:00], latest_time: ~N[2022-01-01 00:00:00]
Here's the basic idea behind nerves_time
:
- If the clock hasn't been set or is invalid, set it to the earliest valid
time known to
nerves_time
. This is either set in the application config or defaulted to a reasonable value that likely moves forward a little eachnerves_time
release. - check for time via a Real Time Clock
- Run Busybox
ntpd
to synchronize time using the NTP protocol. - Update Real Time Clock periodically and on graceful power downs. This is currently only done at around 11 minute intervals.
To check the NTP synchronization status, call NervesTime.synchronized?/0
.
A hardware based real time clock can be configured by added a config.exs entry:
config :nerves_time, rtc: {SomeImplementingModule, [some: :initialization_opt]}
By default Nerves Time is configured to use NervesTime.FileTime
which will
Check for ~/.nerves_time
. If it exists, advance the clock to it's last
modification time.
See the documentation for NervesTime.RealTimeClock
to implement your own
real time clock.
This project started as a fork of nerves_ntp by Marcin Operacz and Wojciech Mandrysz. It has quite a few changes from since when they worked on the project, but some of their code still exists. Both their project and this one are covered by the Apache-2.0 license.