Module lib.server.timesetting

Function which sets the internal clock of the card based on an ntp server

Expand source code
# Distributed under Pycameresp License
# Copyright (c) 2023 Remi BERTHOLET
# pylint:disable=consider-using-f-string
""" Function which sets the internal clock of the card based on an ntp server """
import tools.logger
import tools.date

def get_ntp_time():
        """ Return the time from a NTP server """
        try:
                import socket
                import struct
                ntp_query = bytearray(48)
                ntp_query[0] = 0x1B
                addr = socket.getaddrinfo("pool.ntp.org", 123)[0][-1]
                s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
                try:
                        s.settimeout(2)
                        res = s.sendto(ntp_query, addr)
                        msg = s.recv(48)
                finally:
                        s.close()
                val = struct.unpack("!I", msg[40:44])[0]
                # (date(2000, 1, 1) - date(1900, 1, 1)).days * 24*60*60
                return val - 3155673600
        except:
                return 0

def set_time(current_time):
        """ Change the current time """
        try:
                newtime = tools.date.local_time(current_time)
                year,month,day,hour,minute,second,weekday,yearday = newtime[:8]

                import machine
                machine.RTC().datetime((year, month, day, weekday + 1, hour, minute, second, 0))
        except Exception as exc:
                tools.logger.syslog("Cannot set time '%s'"%exc)

def calc_local_time(current_time, offset_time=+1, dst=True):
        """ Calculate the local time """
        year,month,day,hour,minute,second,weekday,yearday = tools.date.local_time(current_time)[:8]

        # Get the day of the last sunday of march
        march_end_weekday = tools.date.local_time(tools.date.mktime((year, 3, 31, 0, 0, 0, 0, 0)))[6]
        start_day_dst = 31-((1+march_end_weekday)%7)

        # Get the day of the last sunday of october
        october_end_weekday = tools.date.local_time(tools.date.mktime((year,10, 30, 0, 0, 0, 0, 0)))[6]
        end_day_dst = 30-((1+october_end_weekday)%7)

        start_dst = tools.date.mktime((year,3 ,start_day_dst,1,0,0,0,0))
        end_dst   = tools.date.mktime((year,10,end_day_dst  ,1,0,0,0,0))

        now = tools.date.mktime((year,month,day,hour,minute,second,weekday,yearday))

        if dst and now > start_dst and now < end_dst : # we are before last sunday of october
                return now+(offset_time*3600)+3600 # DST: UTC+dst*H + 1
        else:
                return now+(offset_time*3600) # EST: UTC+dst*H

def set_date(offset_time=+1, dst=True, display=False):
        """ Set the date """
        current_time = get_ntp_time()
        if current_time > 0:
                current_time = calc_local_time(current_time, offset_time, dst)
                if current_time > 0:
                        set_time(current_time)
                        if display:
                                tools.logger.syslog("Date updated : %s"%(tools.date.date_to_string()))
                        return current_time
        return 0

Functions

def calc_local_time(current_time, offset_time=1, dst=True)

Calculate the local time

Expand source code
def calc_local_time(current_time, offset_time=+1, dst=True):
        """ Calculate the local time """
        year,month,day,hour,minute,second,weekday,yearday = tools.date.local_time(current_time)[:8]

        # Get the day of the last sunday of march
        march_end_weekday = tools.date.local_time(tools.date.mktime((year, 3, 31, 0, 0, 0, 0, 0)))[6]
        start_day_dst = 31-((1+march_end_weekday)%7)

        # Get the day of the last sunday of october
        october_end_weekday = tools.date.local_time(tools.date.mktime((year,10, 30, 0, 0, 0, 0, 0)))[6]
        end_day_dst = 30-((1+october_end_weekday)%7)

        start_dst = tools.date.mktime((year,3 ,start_day_dst,1,0,0,0,0))
        end_dst   = tools.date.mktime((year,10,end_day_dst  ,1,0,0,0,0))

        now = tools.date.mktime((year,month,day,hour,minute,second,weekday,yearday))

        if dst and now > start_dst and now < end_dst : # we are before last sunday of october
                return now+(offset_time*3600)+3600 # DST: UTC+dst*H + 1
        else:
                return now+(offset_time*3600) # EST: UTC+dst*H
def get_ntp_time()

Return the time from a NTP server

Expand source code
def get_ntp_time():
        """ Return the time from a NTP server """
        try:
                import socket
                import struct
                ntp_query = bytearray(48)
                ntp_query[0] = 0x1B
                addr = socket.getaddrinfo("pool.ntp.org", 123)[0][-1]
                s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
                try:
                        s.settimeout(2)
                        res = s.sendto(ntp_query, addr)
                        msg = s.recv(48)
                finally:
                        s.close()
                val = struct.unpack("!I", msg[40:44])[0]
                # (date(2000, 1, 1) - date(1900, 1, 1)).days * 24*60*60
                return val - 3155673600
        except:
                return 0
def set_date(offset_time=1, dst=True, display=False)

Set the date

Expand source code
def set_date(offset_time=+1, dst=True, display=False):
        """ Set the date """
        current_time = get_ntp_time()
        if current_time > 0:
                current_time = calc_local_time(current_time, offset_time, dst)
                if current_time > 0:
                        set_time(current_time)
                        if display:
                                tools.logger.syslog("Date updated : %s"%(tools.date.date_to_string()))
                        return current_time
        return 0
def set_time(current_time)

Change the current time

Expand source code
def set_time(current_time):
        """ Change the current time """
        try:
                newtime = tools.date.local_time(current_time)
                year,month,day,hour,minute,second,weekday,yearday = newtime[:8]

                import machine
                machine.RTC().datetime((year, month, day, weekday + 1, hour, minute, second, 0))
        except Exception as exc:
                tools.logger.syslog("Cannot set time '%s'"%exc)