diff --git a/changes.md b/changes.md index 2978539..43cf82e 100644 --- a/changes.md +++ b/changes.md @@ -6,9 +6,13 @@ This document outlines the changes made between versions of the **Goat - Pico Ne ### New Features +#### Instantiation + +When instantiating the `NetworkManager` class, you can now specify a `time_sync` Boolean property to enable/disable time synchronisation. + #### Date And Time Synchronisation -When connected to a wireless network, the system date and time is now synchronised from a well known NTP time provider. The **World Time API** is used for date and time retrieval. +When connected to a wireless network, the system date and time can now be synchronised from a well known NTP time provider. The **World Time API** is used for date and time retrieval. ### Bug Fixes diff --git a/readme.md b/readme.md index 5b34403..d6e23e9 100644 --- a/readme.md +++ b/readme.md @@ -59,7 +59,7 @@ Pico Network Manager comes packed with the following features: Configure a web interface for your firmware to be used when connected to a network. - **Time Synchronisation** - Automatic time synchronisation from World Time API when connected to wi-fi. + Enable automatic time synchronisation from World Time API when connected to wi-fi. --- @@ -122,6 +122,7 @@ The library is easy to integrate into your existing project. ap_password="MyPassword", ap_dns_server=True, hostname="MyPicoW", + time_sync=True, sta_web_server=web_server ) ``` @@ -137,6 +138,7 @@ The library is easy to integrate into your existing project. ap_password="MyPassword", ap_dns_server=True, hostname="MyPicoW", + time_sync=True, sta_web_server=web_server ) @@ -155,6 +157,9 @@ The library is easy to integrate into your existing project. # DHCP settings network_manager.hostname = "PicoW" + + # Time synchronisation + network_manager.time_sync = time_sync ``` - Your optional web server must implement `run()` and `stop_server()` methods which the Network Manager will use. diff --git a/src/NetworkManager.py b/src/NetworkManager.py index 07c4e89..d6fdded 100644 --- a/src/NetworkManager.py +++ b/src/NetworkManager.py @@ -25,7 +25,7 @@ class NetworkManager: Responsible for maintaining network state and managing connection lifetime. """ # Class constructor - def __init__(self, ap_ssid="Goat - Captive Portal", ap_password="password", ap_dns_server=True, hostname="PicoW", sta_web_server=None): + def __init__(self, ap_ssid="Goat - Captive Portal", ap_password="password", ap_dns_server=True, hostname="PicoW", time_sync=True, sta_web_server=None): """Constructs the class and exposes properties.""" # Network configuration self.config_directory = "/config" @@ -60,6 +60,9 @@ def __init__(self, ap_ssid="Goat - Captive Portal", ap_password="password", ap_d # Captive portal DNS server self.dns_server = NetworkManagerDNS(portal_ip=self.ap_ip_address) + # Time synchronisation + self.time_sync = time_sync + # STA web server configuration self.sta_web_server = sta_web_server @@ -91,8 +94,10 @@ async def load_config(self): if self.sta_if.isconnected(): self.ip_address = self.sta_if.ifconfig()[0] print(f"Connected to {ssid}. IP: {self.ip_address}") + # Set system date/time try: - await self.get_ntp_time() + if self.time_sync: + await self.get_ntp_time() except Exception as e: print(f"Unable to set the system date and time: {e}") if self.sta_web_server: @@ -170,6 +175,33 @@ async def stop_ap(self): except Exception as e: print(f"Error stopping Access point: {e}") + async def start_captive_portal_server(self): + """Starts the captive portal HTTP server asynchronously.""" + if not self.ip_address: + print("AP IP address not assigned. Cannot start server.") + return + + try: + self.server = await asyncio.start_server(self.handle_request, self.ip_address, self.captive_portal_http_port) + print(f"Serving on {self.ip_address}:{self.captive_portal_http_port}") + + while True: + await asyncio.sleep(1) # Keep the server running + except Exception as e: + print(f"Error starting the captive portal server: {e}") + + async def stop_captive_portal_server(self): + """Stops the captive portal HTTP server.""" + try: + if self.server: + self.server.close() + await self.server.wait_closed() + print("Server stopped.") + else: + print("Server already stopped.") + except Exception as e: + print(f"Error stopping server: {e}") + async def handle_request(self, reader, writer): """Handles incoming HTTP requests for the captive portal.""" try: @@ -316,7 +348,8 @@ async def connect_to_wifi(self, request): # Set system date/time try: - await self.get_ntp_time() + if self.time_sync: + await self.get_ntp_time() except Exception as e: print(f"Unable to set the system date and time: {e}") @@ -364,7 +397,8 @@ async def reconnect_to_wifi(self, request): # Set system date/time try: - await self.get_ntp_time() + if self.time_sync: + await self.get_ntp_time() except Exception as e: print(f"Unable to set the system date and time: {e}") @@ -406,33 +440,6 @@ def serve_index(self):

Start Scan

""" return self.html_template("Goat - Captive Portal", body) - async def start_captive_portal_server(self): - """Starts the captive portal HTTP server asynchronously.""" - if not self.ip_address: - print("AP IP address not assigned. Cannot start server.") - return - - try: - self.server = await asyncio.start_server(self.handle_request, self.ip_address, self.captive_portal_http_port) - print(f"Serving on {self.ip_address}:{self.captive_portal_http_port}") - - while True: - await asyncio.sleep(1) # Keep the server running - except Exception as e: - print(f"Error starting the captive portal server: {e}") - - async def stop_captive_portal_server(self): - """Stops the captive portal HTTP server.""" - try: - if self.server: - self.server.close() - await self.server.wait_closed() - print("Server stopped.") - else: - print("Server already stopped.") - except Exception as e: - print(f"Error stopping server: {e}") - async def get_ntp_time(self): """Fetches the current date and time from an NTP server or time API and sets the system time.""" url = "http://worldtimeapi.org/api/ip"