""" 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 from datetime import datetime import ntplib import pytz # For timezone handling # DS3231 I2C address DS3231_ADDR = 0x68 # Registers for DS3231 REG_TIME = 0x00 def bcd_to_dec(bcd): """Convert BCD to decimal.""" return (bcd // 16 * 10) + (bcd % 16) def dec_to_bcd(dec): """Convert decimal to BCD.""" return (dec // 10 * 16) + (dec % 10) def set_time(bus, year, month, day, hour, minute, second): """Set the RTC time.""" # Convert the time to BCD format second_bcd = dec_to_bcd(second) minute_bcd = dec_to_bcd(minute) hour_bcd = dec_to_bcd(hour) day_bcd = dec_to_bcd(day) month_bcd = dec_to_bcd(month) year_bcd = dec_to_bcd(year - 2000) # DS3231 uses year from 2000 # Write time to DS3231 bus.write_i2c_block_data(DS3231_ADDR, REG_TIME, [ second_bcd, minute_bcd, hour_bcd, 0x01, # Day of the week (1=Monday, etc.) day_bcd, month_bcd, year_bcd ]) 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) 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 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')}") 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')}") if __name__ == "__main__": main()