forked from Mirrors/arNetSked
convert to timezone aware datetime objects
This commit is contained in:
19
arElement.py
19
arElement.py
@@ -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))
|
||||||
|
|||||||
33
arNetSked.py
33
arNetSked.py
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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]
|
||||||
|
|||||||
Reference in New Issue
Block a user