feat: Implement watchdog timer and enhance NTP time synchronization with retry logic
This commit is contained in:
parent
9fda192f0b
commit
f4c9e20836
61
main.py
61
main.py
@ -1,9 +1,13 @@
|
|||||||
from machine import Pin
|
from machine import Pin, WDT
|
||||||
import time
|
import time
|
||||||
import network
|
import network
|
||||||
import json
|
import json
|
||||||
import gc # ADD THIS - for garbage collection
|
import gc # ADD THIS - for garbage collection
|
||||||
|
|
||||||
|
# Enable watchdog (8 seconds timeout - auto-reboot if frozen)
|
||||||
|
wdt = WDT(timeout=60000)
|
||||||
|
print("Watchdog enabled (60s timeout)")
|
||||||
|
|
||||||
# Initialize pins (LED light onboard)
|
# Initialize pins (LED light onboard)
|
||||||
led = Pin("LED", Pin.OUT)
|
led = Pin("LED", Pin.OUT)
|
||||||
led.low()
|
led.low()
|
||||||
@ -124,16 +128,20 @@ if wifi and wifi.isconnected():
|
|||||||
# Send startup notification to Discord
|
# Send startup notification to Discord
|
||||||
send_discord_message(f"Pico W online at http://{ifconfig[0]} ✅")
|
send_discord_message(f"Pico W online at http://{ifconfig[0]} ✅")
|
||||||
|
|
||||||
# ===== START: NTP Time Sync =====
|
# Start web server early so page can load even if time sync is slow
|
||||||
# Sync time with internet time server (required for schedules to work correctly)
|
web_server = TempWebServer(port=80)
|
||||||
# Without this, the Pico's clock starts at 2021 on every reboot
|
web_server.start()
|
||||||
|
|
||||||
|
# Attempt time sync non-blocking (short timeout + retry flag)
|
||||||
|
ntp_synced = False
|
||||||
try:
|
try:
|
||||||
import ntptime
|
import ntptime
|
||||||
ntptime.settime() # Downloads current time from pool.ntp.org
|
ntptime.settime()
|
||||||
|
ntp_synced = True
|
||||||
print("Time synced with NTP server")
|
print("Time synced with NTP server")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("Failed to sync time: {}".format(e))
|
print("Initial NTP sync failed: {}".format(e))
|
||||||
# ===== END: NTP Time Sync =====
|
# Will retry later in loop
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# WiFi connection failed
|
# WiFi connection failed
|
||||||
@ -142,12 +150,6 @@ else:
|
|||||||
print("="*50 + "\n")
|
print("="*50 + "\n")
|
||||||
# ===== END: WiFi Connection =====
|
# ===== END: WiFi Connection =====
|
||||||
|
|
||||||
# ===== START: Web Server Setup =====
|
|
||||||
# Start web server for monitoring and control (accessible at http://192.168.86.43)
|
|
||||||
web_server = TempWebServer(port=80)
|
|
||||||
web_server.start()
|
|
||||||
# ===== END: Web Server Setup =====
|
|
||||||
|
|
||||||
# ===== START: Sensor Configuration =====
|
# ===== START: Sensor Configuration =====
|
||||||
# Define all temperature sensors and their alert thresholds
|
# Define all temperature sensors and their alert thresholds
|
||||||
SENSOR_CONFIG = {
|
SENSOR_CONFIG = {
|
||||||
@ -285,21 +287,36 @@ monitors = [
|
|||||||
print("Starting monitoring loop...")
|
print("Starting monitoring loop...")
|
||||||
print("Press Ctrl+C to stop\n")
|
print("Press Ctrl+C to stop\n")
|
||||||
|
|
||||||
|
# Add NTP retry flags (before main loop)
|
||||||
|
retry_ntp_attempts = 0
|
||||||
|
max_ntp_attempts = 5 # Try up to 5 times after initial failure
|
||||||
|
|
||||||
|
|
||||||
# ===== START: Main Loop =====
|
# ===== START: Main Loop =====
|
||||||
# Main monitoring loop (runs forever until Ctrl+C)
|
# Main monitoring loop (runs forever until Ctrl+C)
|
||||||
while True:
|
while True:
|
||||||
# Run all monitors (each checks if it's time to run via should_run())
|
# Run all monitors (each checks if it's time to run via should_run())
|
||||||
run_monitors(monitors)
|
run_monitors(monitors)
|
||||||
|
|
||||||
# Check for incoming web requests (non-blocking)
|
# Web requests
|
||||||
# Pass schedule_monitor so web interface can reload config when schedules change
|
|
||||||
web_server.check_requests(sensors, ac_monitor, heater_monitor, schedule_monitor)
|
web_server.check_requests(sensors, ac_monitor, heater_monitor, schedule_monitor)
|
||||||
|
|
||||||
# ===== START: Garbage Collection =====
|
# Retry NTP sync every ~10s if not yet synced
|
||||||
# Free up unused memory to prevent fragmentation
|
if not ntp_synced and retry_ntp_attempts < max_ntp_attempts:
|
||||||
|
# Try once immediately, then whenever (time.time() % 10) < 1 (rough 10s window)
|
||||||
|
try:
|
||||||
|
import ntptime
|
||||||
|
if retry_ntp_attempts == 0 or (time.time() % 10) < 1:
|
||||||
|
ntptime.settime()
|
||||||
|
ntp_synced = True
|
||||||
|
print("NTP sync succeeded on retry #{}".format(retry_ntp_attempts + 1))
|
||||||
|
except Exception as e:
|
||||||
|
# Increment only when an actual attempt was made
|
||||||
|
if retry_ntp_attempts == 0 or (time.time() % 10) < 1:
|
||||||
|
retry_ntp_attempts += 1
|
||||||
|
print("NTP retry {} failed: {}".format(retry_ntp_attempts, e))
|
||||||
|
|
||||||
gc.collect()
|
gc.collect()
|
||||||
# ===== END: Garbage Collection =====
|
wdt.feed() # Reset watchdog timer (prevent auto-reboot)
|
||||||
|
|
||||||
# Small delay to prevent CPU overload (0.1 seconds = 10 loops per second)
|
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
# ===== END: Main Loop =====
|
# ===== END: Main Loop =====
|
||||||
Loading…
x
Reference in New Issue
Block a user