From 163ded5291974cadbeec998c555bf28437024f1e Mon Sep 17 00:00:00 2001 From: Rossen Georgiev Date: Wed, 31 Dec 2014 21:17:13 +0000 Subject: [PATCH] updated README; bump v0.6.32 --- CHANGES | 13 +++ MANIFEST.in | 2 +- README.rst | 242 +++++++++++++++++++++++++++----------------- aprslib/__init__.py | 2 +- 4 files changed, 165 insertions(+), 94 deletions(-) create mode 100644 CHANGES diff --git a/CHANGES b/CHANGES new file mode 100644 index 0000000..fa9b14c --- /dev/null +++ b/CHANGES @@ -0,0 +1,13 @@ +CHANGES +------- + +# v0.6.32 + +- sendall() method to IS, allows sending of packets +- corrently parsing beacon packets +- changed default port to full feed, instead of bi-directional filter +- added passcode() to generate passcode for a given callsign +- moved exception logging logic from exceptions.py to IS.py + Should work the same as before +- reload(aprslib) should now work +- various bug fixes diff --git a/MANIFEST.in b/MANIFEST.in index 624fcb9..31714a9 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1 +1 @@ -include LICENSE *.rst +include LICENSE CHANGES *.rst diff --git a/README.rst b/README.rst index b8d655f..73c81c1 100644 --- a/README.rst +++ b/README.rst @@ -1,92 +1,150 @@ -APRS lib for Python -~~~~~~~~~~~~~~~~~~~ - -|Build Status| |Coverage Status| - -A tiny library for dealing with APRS. It can be used to connect and listen to the aprs-is feed as well as parse packets. -The following packet formats are supported: - -- normal/compressed position reports -- mic-e -- messages (inc. telemetry, bulletins, etc) -- base91 comment telemetry - -Install ------------ - -You can grab the latest release from https://pypi.python.org/pypi/aprslib or via ``pip`` - -.. code:: bash - - pip install aprslib - -Examples ------------ - -Parsing -^^^^^^^ - -.. code:: python - - import aprslib - packet = aprslib.parse("M0XER-4>APRS64,TF3RPF,WIDE2*,qAR,TF3SUT-2:!/.(M4I^C,O `DXa/A=040849|#B>@\"v90!+|") - -.. code:: python - - {'altitude': 12450.7752, - 'comment': 'Xa', - 'format': 'compressed', - 'from': 'M0XER-4', - 'gpsfixstatus': 1, - 'latitude': 64.11987367625208, - 'longitude': -19.070654142799384, - 'messagecapable': False, - 'path': ['TF3RPF', 'WIDE2*', 'qAR', 'TF3SUT-2'], - 'raw': 'M0XER-4>APRS64,TF3RPF,WIDE2*,qAR,TF3SUT-2:!/.(M4I^C,O `DXa/A=040849|#B>@"v90!+|', - 'symbol': 'O', - 'symbol_table': '/', - 'telemetry': {'bits': '00000000', - 'seq': 215, - 'vals': [2670, 176, 2199, 10, 0]}, - 'to': 'APRS64', - 'via': 'TF3SUT-2'} - -APRS-IS -^^^^^^^ - -.. code:: python - - import aprslib - - def callback(packet): - print packet - - AIS = aprslib.IS("LZ1DEV") - AIS.connect() - # by default `raw` is False, then each line is ran through aprslib.parse() - AIS.consumer(callback, raw=True) - -.. code:: text - - VK2TRL>APU25N,qAR,VK3KAW:;AWARC *270052z3602.24S/14656.26E-Albury/Wodonga A.R.C. see www.awarc.org - DL1TMF-1>APRS,TCPIP*,qAS,DL1TMF:!5022.38N/01146.58E- http://www.dl1tmf.de - KF4HFE-1>S3SX9S,K4TQR-1,WIDE1,AB4KN-2*,WIDE2,qAR,W4GR-10:`r,^l\Lk/"5h} - ON0WTO-2>APNU19-3,WIDE,qAR,ON4AVM-11:!5037.46NL00423.37E# UIDIGI 1.9 B3 W3 NEW Paradigm sysop ON5YN - PD2RLD-12>APJI41,TCPIP*,qAC,PD2RLD-JS:!5314.20NI00542.26E&- Roland - Bitgummole - www.PD2RLD.nl - - N3BJY-C>APDG02,TCPIP*,qAC,N3BJY-CS:!4027.00ND08018.00W&RNG0000 2m Voice 146.49375MHz +0.0000MHz - DO9ST-10>AP4R10,TCPIP*,qAC,T2LEIPZIG:!4900.24N/00940.81E&PHG4240 APRS4R IGATE - ... - -Docs -^^^^ - -.. code:: bash - - $ python -m pydoc aprslib - -.. |Build Status| image:: https://travis-ci.org/rossengeorgiev/aprs-python.svg?branch=master - :target: https://travis-ci.org/rossengeorgiev/aprs-python -.. |Coverage Status| image:: https://coveralls.io/repos/rossengeorgiev/aprs-python/badge.png?branch=master - :target: https://coveralls.io/r/rossengeorgiev/aprs-python?branch=master - - +APRS library for Python +~~~~~~~~~~~~~~~~~~~~~~~ + +|Build Status| |Coverage Status| + +A tiny library for dealing with APRS. It can be used to connect and listen to the APRS-IS feed as well as upload. +Parsing of packets is also possible, but the entire spec is not fully implemeneted yet. +The following is supported: + +- normal/compressed position reports +- mic-e position report +- messages (inc. telemetry, bulletins, etc) +- base91 comment telemetry extention +- altitude extention +- beacons + +Install +----------- + +You can grab the latest release from https://pypi.python.org/pypi/aprslib or via ``pip`` + +.. code:: bash + + pip install aprslib + +Examples +----------- + +Parsing +^^^^^^^ + +.. code:: python + + import aprslib + packet = aprslib.parse("M0XER-4>APRS64,TF3RPF,WIDE2*,qAR,TF3SUT-2:!/.(M4I^C,O `DXa/A=040849|#B>@\"v90!+|") + +.. code:: python + + {'altitude': 12450.7752, + 'comment': 'Xa', + 'format': 'compressed', + 'from': 'M0XER-4', + 'gpsfixstatus': 1, + 'latitude': 64.11987367625208, + 'longitude': -19.070654142799384, + 'messagecapable': False, + 'path': ['TF3RPF', 'WIDE2*', 'qAR', 'TF3SUT-2'], + 'raw': 'M0XER-4>APRS64,TF3RPF,WIDE2*,qAR,TF3SUT-2:!/.(M4I^C,O `DXa/A=040849|#B>@"v90!+|', + 'symbol': 'O', + 'symbol_table': '/', + 'telemetry': {'bits': '00000000', + 'seq': 215, + 'vals': [2670, 176, 2199, 10, 0]}, + 'to': 'APRS64', + 'via': 'TF3SUT-2'} + +Keep in mind that this function raises exceptions if the packet format is invalid or not supported. + +.. code:: python + + try: + packet = aprslib.parse("M0XER-4>APRS64,TF3RPF,WIDE2*,qAR,TF3SUT-2:!/.(M4I^C,O `DXa/A=040849|#B>@\"v90!+|") + except (aprslib.ParseError, aprslib.UnknownFormat) as exp: + pass + + +APRS-IS +^^^^^^^ + +.. code:: python + + import aprslib + + def callback(packet): + print packet + + AIS = aprslib.IS("N0CALL") + AIS.connect() + # by default `raw` is False, then each line is ran through aprslib.parse() + AIS.consumer(callback, raw=True) + +.. code:: text + + VK2TRL>APU25N,qAR,VK3KAW:;AWARC *270052z3602.24S/14656.26E-Albury/Wodonga A.R.C. see www.awarc.org + DL1TMF-1>APRS,TCPIP*,qAS,DL1TMF:!5022.38N/01146.58E- http://www.dl1tmf.de + KF4HFE-1>S3SX9S,K4TQR-1,WIDE1,AB4KN-2*,WIDE2,qAR,W4GR-10:`r,^l\Lk/"5h} + ... + +The ``IS`` class makes use of the ``logging`` module. +There are various levels of verbosity available for ``IS``. +The only non-standard levels are 9 (unknown format errors) and 11 (parse errors). +Here is a simple example: + +.. code:: python + + import aprslib + import logging + + logging.basicConfig(level=logging.DEBUG) # level=10 + + AIS = aprslib.IS("N0CALL") + AIS.connect() + AIS.consumer(lambda x: None, raw=True) + +.. code:: text + + INFO:aprslib.IS:Attempting connection to rotate.aprs.net:10152 + INFO:aprslib.IS:Connected to 205.233.35.52:10152 + DEBUG:aprslib.IS:Banner: # aprsc 2.0.14-g28c5a6a + INFO:aprslib.IS:Sending login information + DEBUG:aprslib.IS:Server: # logresp N0CALL unverified, server EIGHTH + INFO:aprslib.IS:Login successful (receive only) + DEBUG:aprslib.parse:Parsing: PY4MM-15>Q8U11W,PU4YRM-15*,WIDE3-2,qAR,PP2MD-1:'L.Kl #/"=h}APRS DIGI - Uberlandia - MG + DEBUG:aprslib.parse:Attempting to parse as mic-e packet + DEBUG:aprslib.parse:Parsed ok. + ... + +Uploading packets to APRS-IS is posible through the ``sendall()`` method in ``IS``. +The method assumes a single line/packet per call. The parameters may end with ``\r\n``, but it's not required. + +.. code:: python + + import aprslib + + # a valid passcode for the callsign is required in order to send + AIS = aprslib.IS("N0CALL", passcode="123456", port=14580) + AIS.connect() + # send a single status message + AIS.sendall("N0CALL>APRS,TCPIP*:>status text") + +A passcode generation function is also provided. + +CHANGES +^^^^^^^ + +You can find the latest changes between versions in the CHANGES file. + +Docs +^^^^ + +.. code:: bash + + $ python -m pydoc aprslib + +.. |Build Status| image:: https://travis-ci.org/rossengeorgiev/aprs-python.svg?branch=master + :target: https://travis-ci.org/rossengeorgiev/aprs-python +.. |Coverage Status| image:: https://coveralls.io/repos/rossengeorgiev/aprs-python/badge.png?branch=master + :target: https://coveralls.io/r/rossengeorgiev/aprs-python?branch=master + + diff --git a/aprslib/__init__.py b/aprslib/__init__.py index 7ffce1c..168b9f3 100644 --- a/aprslib/__init__.py +++ b/aprslib/__init__.py @@ -34,7 +34,7 @@ from datetime import date as _date __date__ = str(_date.today()) del _date -__version__ = "0.6.31" +__version__ = "0.6.32" __author__ = "Rossen Georgiev" __all__ = ['IS', 'parse', 'passcode']