This commit is contained in:
PaulVua
2025-01-30 13:46:22 +01:00
parent a689a7d2de
commit 4f59928b1e
5 changed files with 248 additions and 19 deletions

97
RTC/set_with_NTP.py Normal file
View File

@@ -0,0 +1,97 @@
"""
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()

View File

@@ -0,0 +1,47 @@
"""
Script to set the RTC using the browser time.
/usr/bin/python3 /var/www/nebuleair_pro_4g/RTC/set_with_browserTime.py '$rtc_time'
"""
import sys
from datetime import datetime
import smbus2
# DS3231 I2C address
DS3231_ADDR = 0x68
REG_TIME = 0x00
def dec_to_bcd(dec):
"""Convert decimal to BCD."""
return (dec // 10 * 16) + (dec % 10)
def set_rtc(bus, year, month, day, hour, minute, second):
"""Set the RTC time."""
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) # RTC stores years since 2000
bus.write_i2c_block_data(DS3231_ADDR, REG_TIME, [
second_bcd, minute_bcd, hour_bcd, 0x01, day_bcd, month_bcd, year_bcd
])
def main():
if len(sys.argv) != 2:
print("Usage: python3 set_rtc.py 'YYYY-MM-DD HH:MM:SS'")
sys.exit(1)
rtc_time_str = sys.argv[1]
rtc_time = datetime.strptime(rtc_time_str, '%Y-%m-%d %H:%M:%S')
bus = smbus2.SMBus(1)
set_rtc(bus, rtc_time.year, rtc_time.month, rtc_time.day,
rtc_time.hour, rtc_time.minute, rtc_time.second)
print(f"RTC updated to: {rtc_time}")
if __name__ == "__main__":
main()