diff --git a/CHANGES b/CHANGES index 72c6e1e..e74afa1 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,8 @@ CHANGES # 0.6.42 +- added util submodule containing various helper functions +- added objects for creating packets (PositionReport, APRSPacket in packets submodule) - added DAO parsing - added parsing for invalid & user-defined formats - split parsing module into submodules diff --git a/aprslib/packets/__init__.py b/aprslib/packets/__init__.py new file mode 100644 index 0000000..19914e5 --- /dev/null +++ b/aprslib/packets/__init__.py @@ -0,0 +1 @@ +from aprslib.packets.position import PositionReport diff --git a/aprslib/packets/base.py b/aprslib/packets/base.py new file mode 100644 index 0000000..b04a9fd --- /dev/null +++ b/aprslib/packets/base.py @@ -0,0 +1,31 @@ + + +class APRSPacket(object): + def __init__(self, fromcall, tocall, path=[]): + self.fromcall = fromcall + self.tocall = tocall + self.path = path + + def __repr__(self): + return "<%s(%s)>" % ( + self.__class__.__name__, + repr(str(self)), + ) + + def _serialize_header(self): + header = "%s>%s" % (self.fromcall, self.tocall) + + if self.path: + header += "," + ",".join(self.path) + + return header + + def _serialize_body(self): + return getattr(self, 'body', '') + + def __str__(self): + return "%s:%s" % ( + self._serialize_header(), + self._serialize_body(), + ) + diff --git a/aprslib/packets/position.py b/aprslib/packets/position.py new file mode 100644 index 0000000..275e6d3 --- /dev/null +++ b/aprslib/packets/position.py @@ -0,0 +1,38 @@ +from datetime import datetime +from aprslib.packets.base import APRSPacket +from aprslib.util import latitude_to_ddm, longitude_to_ddm, comment_altitude + + +class PositionReport(APRSPacket): + latitude = 0 + longitude = 0 + symbol_table = '/' + symbol = 'l' + altitude = None + timestamp = None + comment = '' + + def _serialize_body(self): + + if self.timestamp is None: + timestamp = '' + elif isinstance(self.timestamp, str): + timestamp = self.timestamp + else: + timestamp = datetime.utcfromtimestamp(self.timestamp).strftime("%d%H%M") + 'z' + + body = [ + '/' if self.timestamp else '!', # packet type + timestamp, + latitude_to_ddm(self.latitude), + self.symbol_table, + longitude_to_ddm(self.longitude), + self.symbol, + comment_altitude(self.altitude) if self.altitude is not None else '', + self.comment, + ] + + return "".join(body) + + + diff --git a/aprslib/util/__init__.py b/aprslib/util/__init__.py new file mode 100644 index 0000000..df8a9a4 --- /dev/null +++ b/aprslib/util/__init__.py @@ -0,0 +1,36 @@ +from math import floor + + +def degrees_to_ddm(dd): + degrees = int(floor(dd)) + minutes = (dd - degrees) * 60 + return (degrees, minutes) + + +def latitude_to_ddm(dd): + direction = "S" if dd < 0 else "N" + degrees, minutes = degrees_to_ddm(abs(dd)) + + return "{0:02d}{1:05.2f}{2}".format( + degrees, + minutes, + direction, + ) + +def longitude_to_ddm(dd): + direction = "W" if dd < 0 else "E" + degrees, minutes = degrees_to_ddm(abs(dd)) + + return "{0:03d}{1:05.2f}{2}".format( + degrees, + minutes, + direction, + ) + +def comment_altitude(altitude): + altitude /= 0.3048 # to feet + altitude = min(999999, altitude) + altitude = max(-99999, altitude) + return "/A={0:06.0f}".format(altitude) + +