98 lines
2.9 KiB
Python
98 lines
2.9 KiB
Python
"""
|
|
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()
|