diff --git a/README.rst b/README.rst index 671ca15..d1d7bbd 100644 --- a/README.rst +++ b/README.rst @@ -59,21 +59,17 @@ Usage Example .. code-block:: python + import adafruit_connection_manager import adafruit_ntp - import socketpool + import os import time import wifi - # Get wifi details and more from a secrets.py file - try: - from secrets import secrets - except ImportError: - print("WiFi secrets are kept in secrets.py, please add them there!") - raise + wifi_ssid = os.getenv("CIRCUITPY_WIFI_SSID") + wifi_password = os.getenv("CIRCUITPY_WIFI_PASSWORD") + wifi.radio.connect(wifi_ssid, wifi_password) - wifi.radio.connect(secrets["ssid"], secrets["password"]) - - pool = socketpool.SocketPool(wifi.radio) + pool = adafruit_connection_manager.get_radio_socketpool(wifi.radio) ntp = adafruit_ntp.NTP(pool, tz_offset=0) while True: diff --git a/adafruit_ntp.py b/adafruit_ntp.py index b405402..5e9c790 100644 --- a/adafruit_ntp.py +++ b/adafruit_ntp.py @@ -22,10 +22,14 @@ import struct import time +from micropython import const + + __version__ = "0.0.0+auto.0" __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_NTP.git" NTP_TO_UNIX_EPOCH = 2208988800 # 1970-01-01 00:00:00 +PACKET_SIZE = const(48) class NTP: @@ -55,7 +59,8 @@ def __init__( self._pool = socketpool self._server = server self._port = port - self._packet = bytearray(48) + self._socket_address = None + self._packet = bytearray(PACKET_SIZE) self._tz_offset = int(tz_offset * 60 * 60) self._socket_timeout = socket_timeout @@ -71,21 +76,27 @@ def datetime(self) -> time.struct_time: unless there has already been a recent request. Raises OSError exception if no response is received within socket_timeout seconds""" if time.monotonic_ns() > self.next_sync: + if self._socket_address is None: + self._socket_address = self._pool.getaddrinfo(self._server, self._port)[ + 0 + ][4] + self._packet[0] = 0b00100011 # Not leap second, NTP version 4, Client mode - for i in range(1, len(self._packet)): + for i in range(1, PACKET_SIZE): self._packet[i] = 0 with self._pool.socket(self._pool.AF_INET, self._pool.SOCK_DGRAM) as sock: + # Since the ESP32SPI doesn't support sendto, we are using + # connect + send to standardize code sock.settimeout(self._socket_timeout) - sock.sendto(self._packet, (self._server, self._port)) - sock.recvfrom_into(self._packet) + sock.connect(self._socket_address) + sock.send(self._packet) + sock.recv_into(self._packet) # Get the time in the context to minimize the difference between it and receiving # the packet. destination = time.monotonic_ns() poll = struct.unpack_from("!B", self._packet, offset=2)[0] self.next_sync = destination + (2**poll) * 1_000_000_000 - seconds = struct.unpack_from( - "!I", self._packet, offset=len(self._packet) - 8 - )[0] + seconds = struct.unpack_from("!I", self._packet, offset=PACKET_SIZE - 8)[0] self._monotonic_start = ( seconds + self._tz_offset