convert to timezone aware datetime objects

This commit is contained in:
Rich Ferguson
2020-05-13 19:24:02 -04:00
parent 634d0d9b0a
commit 0fa97562ea
3 changed files with 42 additions and 14 deletions

View File

@@ -17,13 +17,16 @@
# along with this program; if not, write to the Free Software # along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
# #
import datetime as dt
import pytz
from tzlocal import get_localzone
import threading import threading
class arElement(): class arElement():
def __init__(self): def __init__(self):
self._arName = "%s" % (self.__class__.__name__) self._arName = "%s" % (self.__class__.__name__)
self._arTz = get_localzone()
self._arPrintLock = threading.Lock() self._arPrintLock = threading.Lock()
@property @property
@@ -34,6 +37,20 @@ class arElement():
def arName(self, v): def arName(self, v):
self._arName = "%s:%s" % (self.__class__.__name__, v) self._arName = "%s:%s" % (self.__class__.__name__, v)
@property
def arTz(self):
return self._arTz
@arTz.setter
def arTz(self, v):
self._arTz = v
def arGetLocalTime(self):
return self._arTz.localize(dt.datetime.now())
def arGetUTCTime(self):
return pytz.utc.localize(dt.datetime.utcnow())
def arPrint(self, message): def arPrint(self, message):
self._arPrintLock.acquire() self._arPrintLock.acquire()
print("[%s] %s" % (self._arName, message)) print("[%s] %s" % (self._arName, message))

View File

@@ -22,6 +22,7 @@ import os
import sys import sys
import re import re
import datetime as dt import datetime as dt
from pytz import timezone
import click import click
import math import math
import threading import threading
@@ -41,6 +42,8 @@ def td2min(td):
class arNet(arElement, threading.Thread): class arNet(arElement, threading.Thread):
def __init__(self, call, txCB): def __init__(self, call, txCB):
arElement.__init__(self)
self._day = 0 # sunday self._day = 0 # sunday
# self._repeat = 7 # weekly # self._repeat = 7 # weekly
self._timeofday = 20 * 60 # 8pm self._timeofday = 20 * 60 # 8pm
@@ -55,7 +58,7 @@ class arNet(arElement, threading.Thread):
self._lon = "00000.00W" # longitude self._lon = "00000.00W" # longitude
self._comment = "" # comment self._comment = "" # comment
self._dt = dt.datetime.now() self._dt = self.arGetLocalTime()
self._stopped = threading.Event() self._stopped = threading.Event()
self.opcall = call self.opcall = call
@@ -69,7 +72,7 @@ class arNet(arElement, threading.Thread):
self.objmode = 0 self.objmode = 0
threading.Thread.__init__(self) threading.Thread.__init__(self)
arElement.__init__(self)
@property @property
def day(self): def day(self):
@@ -289,7 +292,7 @@ class arNet(arElement, threading.Thread):
self._dt = self._dt.replace(hour=hrs, minute=mins, second=0) + \ self._dt = self._dt.replace(hour=hrs, minute=mins, second=0) + \
dt.timedelta(days=dayshift) dt.timedelta(days=dayshift)
if td2min(self._dt - dt.datetime.now()) + self._duration < 0: if td2min(self._dt - self.arGetLocalTime()) + self._duration < 0:
self._dt += dt.timedelta(days = 7) self._dt += dt.timedelta(days = 7)
self.arPrint("Time initialized, next NET starts at %s" % self._dt.strftime("%c")) self.arPrint("Time initialized, next NET starts at %s" % self._dt.strftime("%c"))
@@ -301,7 +304,7 @@ class arNet(arElement, threading.Thread):
# for duration, beacon 3 times after to kill every 3 minutes # for duration, beacon 3 times after to kill every 3 minutes
# calc delta time in minutes, negative after net start # calc delta time in minutes, negative after net start
dMin = td2min(self._dt - dt.datetime.now()) dMin = td2min(self._dt - self.arGetLocalTime())
self.arPrint("Minutes until NET start: %d" % dMin) self.arPrint("Minutes until NET start: %d" % dMin)
retVal = 604800 # 1week retVal = 604800 # 1week
if dMin > 30: if dMin > 30:
@@ -331,7 +334,7 @@ class arNet(arElement, threading.Thread):
#update _dt for next net beacon time #update _dt for next net beacon time
self.objmode = 0 self.objmode = 0
self._dt += dt.timedelta(days=7) self._dt += dt.timedelta(days=7)
dMin = td2min(self._dt - dt.datetime.now()) dMin = td2min(self._dt - self.arGetLocalTime())
retVal = (dMin - 30) * 60 retVal = (dMin - 30) * 60
# safety net to not rapid fire network # safety net to not rapid fire network
@@ -352,7 +355,7 @@ class arNet(arElement, threading.Thread):
self.txCB(self.buildPacket()) self.txCB(self.buildPacket())
while not self._stopped.wait(wt): while not self._stopped.wait(wt):
self.arPrint("Delay complete at %s" % dt.datetime.now()) self.arPrint("Delay complete at %s" % arGetLocalTime())
wt = self.calcWaitTime() wt = self.calcWaitTime()
if not self._stopped.is_set() and self.objmode > 0: if not self._stopped.is_set() and self.objmode > 0:
self.txCB(self.buildPacket()) self.txCB(self.buildPacket())
@@ -416,7 +419,7 @@ class arNet(arElement, threading.Thread):
objs = 'E' if self.objmode < 3 else '.' # switch to X when killing object objs = 'E' if self.objmode < 3 else '.' # switch to X when killing object
objstr = ";%s%c%s%s/%s%c" % \ objstr = ";%s%c%s%s/%s%c" % \
(self._objname, objc, \ (self._objname, objc, \
dt.datetime.utcnow().strftime("%d%H%Mz"), \ self.arGetUTCTime().strftime("%d%H%Mz"), \
self._latitude, \ self._latitude, \
self._longitude, \ self._longitude, \
objs ) objs )
@@ -446,16 +449,20 @@ class arNet(arElement, threading.Thread):
return bstr+objstr.encode('UTF-8') return bstr+objstr.encode('UTF-8')
class arNetSked(arElement): class arNetSked(arElement):
def __init__(self, call, skedfile, host, port, verbose): def __init__(self, call, skedfile, host, port, tz, verbose):
arElement.__init__(self)
self._objlist = [] self._objlist = []
self.call = call self.call = call
self.skedfile = skedfile self.skedfile = skedfile
self.tnchost = host self.tnchost = host
self.tncport = port self.tncport = port
if tz is not None:
self.arTz = tz
self.verbose = verbose self.verbose = verbose
arElement.__init__(self)
def abortSignal(self, signum, frame): def abortSignal(self, signum, frame):
self.abort() self.abort()
@@ -540,6 +547,7 @@ class arNetSked(arElement):
break break
self._objlist.append(objn) self._objlist.append(objn)
objn.arTz = self.arTz
objn.initTime() objn.initTime()
objn.start() objn.start()
@@ -595,13 +603,16 @@ class arNetSked(arElement):
@click.option("--port", "-p", "port", default=8001, @click.option("--port", "-p", "port", default=8001,
help="TNC network port or bluetooth channel", help="TNC network port or bluetooth channel",
) )
@click.option("--timezone", "-t", "tz", required=False,
help="Timezone of schedule information",
)
@click.option("--verbose", is_flag=True, help="Verbose output") @click.option("--verbose", is_flag=True, help="Verbose output")
def main(sfile, call, host, port, verbose): def main(sfile, call, host, port, tz, verbose):
"""Process schedule for APRS NetSked beacons and """Process schedule for APRS NetSked beacons and
transmit over network TNC KISS server. transmit over network TNC KISS server.
""" """
netsked = arNetSked(call, sfile, host, port, verbose) netsked = arNetSked(call, sfile, host, port, tz, verbose)
signal.signal(signal.SIGINT, netsked.abortSignal) signal.signal(signal.SIGINT, netsked.abortSignal)
# signal.signal(signal.SIGTERM, netsked.abort) # signal.signal(signal.SIGTERM, netsked.abort)

View File

@@ -52,12 +52,12 @@ ST_ESC = 3
class arTNCKiss(arElement): class arTNCKiss(arElement):
def __init__(self, packet_cb): def __init__(self, packet_cb):
arElement.__init__(self)
self._packet_cb = packet_cb self._packet_cb = packet_cb
self._rx_state = ST_IDL self._rx_state = ST_IDL
self._rx_buf = bytearray(0) self._rx_buf = bytearray(0)
arElement.__init__(self)
# byte in, bytearray out # byte in, bytearray out
def recvChar(self,c): def recvChar(self,c):
hc = struct.unpack("B",c)[0] hc = struct.unpack("B",c)[0]