This commit is contained in:
Your Name
2025-03-05 16:07:22 +01:00
parent 659effb7c4
commit b493d30a41

View File

@@ -1,11 +1,9 @@
#!/usr/bin/python3
"""
Script to set the RTC using an NTP server.
RPI needs to be connected to the internet (WIFI).
Requires ntplib and pytz:
sudo pip3 install ntplib pytz --break-system-packages
/usr/bin/python3 /var/www/nebuleair_pro_4g/RTC/set_with_NTP.py
"""
import smbus2
import time
@@ -49,29 +47,95 @@ def set_time(bus, year, month, day, hour, minute, second):
])
def read_time(bus):
"""Read the RTC time."""
"""Read the RTC time and validate the values."""
try:
data = bus.read_i2c_block_data(DS3231_ADDR, REG_TIME, 7)
# Convert from BCD
second = bcd_to_dec(data[0] & 0x7F)
minute = bcd_to_dec(data[1])
hour = bcd_to_dec(data[2] & 0x3F)
day = bcd_to_dec(data[4])
month = bcd_to_dec(data[5])
year = bcd_to_dec(data[6]) + 2000
# Print raw values for debugging
print(f"Raw RTC values: {data}")
print(f"Decoded values: Y:{year} M:{month} D:{day} H:{hour} M:{minute} S:{second}")
# Validate date values
if not (1 <= month <= 12):
print(f"Invalid month value: {month}, using default")
month = 1
# Check days in month (simplified)
days_in_month = [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
if not (1 <= day <= days_in_month[month]):
print(f"Invalid day value: {day} for month {month}, using default")
day = 1
# Validate time values
if not (0 <= hour <= 23):
print(f"Invalid hour value: {hour}, using default")
hour = 0
if not (0 <= minute <= 59):
print(f"Invalid minute value: {minute}, using default")
minute = 0
if not (0 <= second <= 59):
print(f"Invalid second value: {second}, using default")
second = 0
return (year, month, day, hour, minute, second)
except Exception as e:
print(f"Error reading RTC: {e}")
# Return a safe default date (2023-01-01 00:00:00)
return (2023, 1, 1, 0, 0, 0)
def get_internet_time():
"""Get the current time from an NTP server."""
ntp_client = ntplib.NTPClient()
response = ntp_client.request('pool.ntp.org')
# Try multiple NTP servers in case one fails
servers = ['pool.ntp.org', 'time.google.com', 'time.windows.com', 'time.apple.com']
for server in servers:
try:
print(f"Trying NTP server: {server}")
response = ntp_client.request(server, timeout=2)
utc_time = datetime.utcfromtimestamp(response.tx_time)
print(f"Successfully got time from {server}")
return utc_time
except Exception as e:
print(f"Failed to get time from {server}: {e}")
# If all servers fail, raise exception
raise Exception("All NTP servers failed")
def main():
try:
bus = smbus2.SMBus(1)
# Test if RTC is accessible
try:
bus.read_byte(DS3231_ADDR)
print("RTC module is accessible")
except Exception as e:
print(f"Error accessing RTC module: {e}")
print("Please check connections and I2C configuration")
return
# Get the current time from the RTC
try:
year, month, day, hours, minutes, seconds = read_time(bus)
# Create datetime object with validation to handle invalid dates
rtc_time = datetime(year, month, day, hours, minutes, seconds)
print(f"Actual RTC Time : {rtc_time.strftime('%Y-%m-%d %H:%M:%S')}")
except ValueError as e:
print(f"Invalid date/time read from RTC: {e}")
print("Will proceed with setting RTC from internet time")
rtc_time = None
# Get current UTC time from an NTP server
try:
@@ -79,19 +143,35 @@ def main():
print(f"Time from Internet (UTC) : {internet_utc_time.strftime('%Y-%m-%d %H:%M:%S')}")
except Exception as e:
print(f"Error retrieving time from the internet: {e}")
if rtc_time is None:
print("Cannot proceed without either valid RTC time or internet time")
return
print("Will keep current RTC time")
return
# Print current RTC time
print(f"Actual RTC Time : {rtc_time.strftime('%Y-%m-%d %H:%M:%S')}")
# Set the RTC to UTC time
print("Setting RTC to internet time...")
set_time(bus, internet_utc_time.year, internet_utc_time.month, internet_utc_time.day,
internet_utc_time.hour, internet_utc_time.minute, internet_utc_time.second)
# Read and print the new time from RTC
print("Reading back new RTC time...")
year, month, day, hour, minute, second = read_time(bus)
rtc_time_new = datetime(year, month, day, hour, minute, second)
print(f"New RTC Time (UTC) : {rtc_time_new.strftime('%Y-%m-%d %H:%M:%S')}")
# Calculate difference to verify accuracy
time_diff = abs((rtc_time_new - internet_utc_time).total_seconds())
print(f"Time difference : {time_diff:.2f} seconds")
if time_diff > 5:
print("Warning: RTC time differs significantly from internet time")
print("You may need to retry or check RTC module")
else:
print("RTC successfully synchronized with internet time")
except Exception as e:
print(f"Unexpected error: {e}")
if __name__ == "__main__":
main()