update
This commit is contained in:
@@ -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,49 +47,131 @@ def set_time(bus, year, month, day, hour, minute, second):
|
||||
])
|
||||
|
||||
def read_time(bus):
|
||||
"""Read the RTC time."""
|
||||
data = bus.read_i2c_block_data(DS3231_ADDR, REG_TIME, 7)
|
||||
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
|
||||
return (year, month, day, hour, minute, second)
|
||||
"""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')
|
||||
utc_time = datetime.utcfromtimestamp(response.tx_time)
|
||||
return utc_time
|
||||
# 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():
|
||||
bus = smbus2.SMBus(1)
|
||||
|
||||
# Get the current time from the RTC
|
||||
year, month, day, hours, minutes, seconds = read_time(bus)
|
||||
rtc_time = datetime(year, month, day, hours, minutes, seconds)
|
||||
|
||||
# Get current UTC time from an NTP server
|
||||
try:
|
||||
internet_utc_time = get_internet_time()
|
||||
print(f"Time from Internet (UTC) : {internet_utc_time.strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
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:
|
||||
internet_utc_time = get_internet_time()
|
||||
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
|
||||
|
||||
# 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"Error retrieving time from the internet: {e}")
|
||||
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
|
||||
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
|
||||
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')}")
|
||||
print(f"Unexpected error: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
main()
|
||||
Reference in New Issue
Block a user