Skip to content

Commit d1d0bb0

Browse files
committed
refactored to use fruitjam network module
Refactored and "works for me". I'll ask @b-blake to confirm functionality as well. • Added Network.sync_time() method in network.py • Uses adafruit_ntp + adafruit_connection_manager. • Reads optional NTP_* keys from settings.toml. • Sets rtc.RTC().datetime • Added example examples/fruitjam_time_sync.py (sync once, print localtime). • Added example examples/fruitjam_ntp_settings.toml
1 parent 544adaa commit d1d0bb0

File tree

6 files changed

+139
-192
lines changed

6 files changed

+139
-192
lines changed

adafruit_fruitjam/__init__.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,23 @@ def __init__( # noqa: PLR0912,PLR0913,Too many branches,Too many arguments in f
245245

246246
gc.collect()
247247

248+
def sync_time(self, **kwargs):
249+
"""Set the system RTC via NTP using this FruitJam's Network.
250+
251+
This is a convenience wrapper for ``self.network.sync_time(...)`` so
252+
user code can simply call ``fruitjam.sync_time()``.
253+
254+
Keyword args are passed through to ``Network.sync_time``:
255+
- server (str) : NTP host (default from NTP_SERVER or pool.ntp.org)
256+
- tz_offset (float) : hours from UTC (default from NTP_TZ + NTP_DST)
257+
- timeout (float) : socket timeout seconds (default from NTP_TIMEOUT or 5.0)
258+
- cache_seconds (int) : NTP cache seconds (default from NTP_CACHE_SECONDS or 0)
259+
- require_year (int) : sanity check lower bound (default 2022)
260+
Returns:
261+
time.struct_time
262+
"""
263+
return self.network.sync_time(**kwargs)
264+
248265
def set_caption(self, caption_text, caption_position, caption_color):
249266
"""A caption. Requires setting ``caption_font`` in init!
250267

adafruit_fruitjam/network.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,13 @@
2525
"""
2626

2727
import gc
28+
import os
2829

30+
import adafruit_connection_manager as acm
31+
import adafruit_ntp
2932
import microcontroller
3033
import neopixel
34+
import rtc
3135
from adafruit_portalbase.network import (
3236
CONTENT_IMAGE,
3337
CONTENT_JSON,
@@ -209,3 +213,86 @@ def process_image(self, json_data, sd_card=False): # noqa: PLR0912 Too many bra
209213
gc.collect()
210214

211215
return filename, position
216+
217+
def sync_time(self, server=None, tz_offset=None, tuning=None):
218+
"""
219+
Set the system RTC via NTP using this Network's Wi-Fi connection.
220+
221+
Reads optional settings from settings.toml:
222+
NTP_SERVER (default "pool.ntp.org")
223+
NTP_TZ (float hours from UTC, default 0)
224+
NTP_DST (additional offset, usually 0 or 1)
225+
NTP_TIMEOUT (seconds, default 5.0)
226+
NTP_CACHE_SECONDS (default 0 = always fetch fresh)
227+
NTP_REQUIRE_YEAR (minimum acceptable year, default 2022)
228+
229+
Keyword args:
230+
server (str) – override NTP_SERVER
231+
tz_offset (float) – override NTP_TZ (+ NTP_DST still applied)
232+
tuning (dict) – override other knobs:
233+
{"timeout": 5.0,
234+
"cache_seconds": 0,
235+
"require_year": 2022}
236+
237+
Returns:
238+
time.struct_time
239+
"""
240+
# Bring up Wi-Fi using the existing flow.
241+
self.connect()
242+
243+
# Build a socket pool from the existing ESP interface.
244+
pool = acm.get_radio_socketpool(self._wifi.esp)
245+
246+
# Settings with environment fallbacks.
247+
server = server or os.getenv("NTP_SERVER") or "pool.ntp.org"
248+
249+
if tz_offset is None:
250+
tz_env = os.getenv("NTP_TZ")
251+
try:
252+
tz_offset = float(tz_env) if tz_env not in {None, ""} else 0.0
253+
except Exception:
254+
tz_offset = 0.0
255+
256+
# Simple DST additive offset (no IANA time zone logic).
257+
try:
258+
dst = float(os.getenv("NTP_DST") or 0)
259+
except Exception:
260+
dst = 0.0
261+
tz_offset += dst
262+
263+
# Optional tuning (env can override passed defaults).
264+
t = tuning or {}
265+
266+
def _f(name, default):
267+
v = os.getenv(name)
268+
try:
269+
return float(v) if v not in {None, ""} else float(default)
270+
except Exception:
271+
return float(default)
272+
273+
def _i(name, default):
274+
v = os.getenv(name)
275+
try:
276+
return int(v) if v not in {None, ""} else int(default)
277+
except Exception:
278+
return int(default)
279+
280+
timeout = float(t.get("timeout", _f("NTP_TIMEOUT", 5.0)))
281+
cache_seconds = int(t.get("cache_seconds", _i("NTP_CACHE_SECONDS", 0)))
282+
require_year = int(t.get("require_year", _i("NTP_REQUIRE_YEAR", 2022)))
283+
284+
# Query NTP and set the system RTC.
285+
ntp = adafruit_ntp.NTP(
286+
pool,
287+
server=server,
288+
tz_offset=tz_offset,
289+
socket_timeout=timeout,
290+
cache_seconds=cache_seconds,
291+
)
292+
now = ntp.datetime # struct_time
293+
294+
if now.tm_year < require_year:
295+
raise RuntimeError("NTP returned an unexpected year; not setting RTC")
296+
297+
rtc.RTC().datetime = now
298+
return now

adafruit_fruitjam/ntp.py

Lines changed: 0 additions & 164 deletions
This file was deleted.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2025 Tim Cocks for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
# Wi-Fi credentials
5+
CIRCUITPY_WIFI_SSID = "YourSSID"
6+
CIRCUITPY_WIFI_PASSWORD = "YourPassword"
7+
8+
# NTP settings
9+
# Common UTC offsets (hours):
10+
# 0 UTC / Zulu
11+
# 1 CET (Central Europe)
12+
# 2 EET (Eastern Europe)
13+
# 3 FET (Further Eastern Europe)
14+
# -5 EST (Eastern US)
15+
# -6 CST (Central US)
16+
# -7 MST (Mountain US)
17+
# -8 PST (Pacific US)
18+
# -9 AKST (Alaska)
19+
# -10 HST (Hawaii, no DST)
20+
21+
NTP_SERVER = "pool.ntp.org" # NTP host (default pool.ntp.org)
22+
NTP_TZ = -5 # timezone offset in hours
23+
NTP_DST = 1 # daylight saving (0=no, 1=yes)
24+
NTP_INTERVAL = 3600 # re-sync interval (seconds)
25+
26+
# Optional tuning
27+
NTP_TIMEOUT = 5 # socket timeout in seconds
28+
NTP_CACHE_SECONDS = 0 # cache results (0 = always fetch)
29+
NTP_REQUIRE_YEAR = 2022 # sanity check minimum year
Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
# SPDX-FileCopyrightText: Copyright (c) 2025 Tim Cocks for Adafruit Industries
22
#
33
# SPDX-License-Identifier: MIT
4-
#
5-
# see examples/settings.toml for NTP_ options
6-
#
7-
from adafruit_fruitjam.ntp import sync_time
4+
import time
5+
6+
from adafruit_fruitjam import FruitJam
87

9-
now, next_sync = sync_time()
8+
fj = FruitJam()
9+
now = fj.sync_time()
1010
print("RTC set:", now)
11+
print("Localtime:", time.localtime())

examples/settings.toml

Lines changed: 0 additions & 23 deletions
This file was deleted.

0 commit comments

Comments
 (0)