Packet parsing ************** An overview of the parsing functionality. APRS Reference ============== The implementation follows the APRS Protocol Reference * Version 1.0: http://www.aprs.org/doc/APRS101.PDF * Version 1.1: http://www.aprs.org/aprs11.html * Version 1.2: http://www.aprs.org/aprs12.html Encodings ========= Packets can often contain characters outside of 7-bit ASCII. :py:func:`aprslib.parse` will attempt to guess the charset and return ``unicode`` strings using these steps and in that order: 1. Attempt to decode string as ``utf-8`` 2. Attempt to guess the charset using ``chardet`` module (if installed), decode if confidence factor is sufficient 3. Finally, decode as ``latin-1`` .. _sup_formats: Supported formats ================= - normal/compressed position reports - mic-e position reports - objects reports - weather reports - status reports - messages (inc. telemetry, bulletins, etc) - base91 comment telemetry extension - altitude extension - beacons Position reports ================ Normal ------ .. code:: python >>> aprslib.parse("FROMCALL>TOCALL:!4903.50N/07201.75W-Test /A=001234") {'altitude': 376.1232, 'comment': u'Test', 'format': 'uncompressed', 'from': u'FROMCALL', 'latitude': 49.05833333333333, 'longitude': -72.02916666666667, 'messagecapable': False, 'path': [], 'posambiguity': 0, 'raw': u'FROMCALL>TOCALL:!4903.50N/07201.75W-Test /A=001234', 'symbol': u'-', 'symbol_table': u'/', 'to': u'TOCALL', 'via': ''} Compressed ---------- .. code:: python >>> aprslib.parse("M0XER-4>APRS64,TF3RPF,WIDE2*,qAR,TF3SUT-2:!/.(M4I^C,O `DXa/A=040849|#B>@\"v90!+|") {'altitude': 12450.7752, 'comment': u'Xa', 'format': 'compressed', 'from': u'M0XER-4', 'gpsfixstatus': 1, 'latitude': 64.11987367625208, 'longitude': -19.070654142799384, 'messagecapable': False, 'path': [u'TF3RPF', u'WIDE2*', u'qAR', u'TF3SUT-2'], 'raw': u'M0XER-4>APRS64,TF3RPF,WIDE2*,qAR,TF3SUT-2:!/.(M4I^C,O `DXa/A=040849|#B>@"v90!+|', 'symbol': u'O', 'symbol_table': u'/', 'telemetry': {'bits': '00000000', 'seq': 215, 'vals': [2670, 176, 2199, 10, 0]}, 'to': u'APRS64', 'via': u'TF3SUT-2'} With timestamp: .. code:: python >>> aprslib.parse("FROMCALL>TOCALL:/092345z4903.50N/07201.75W>Test1234") {'comment': u'Test1234', 'format': 'uncompressed', 'from': u'FROMCALL', 'latitude': 49.05833333333333, 'longitude': -72.02916666666667, 'messagecapable': False, 'path': [], 'posambiguity': 0, 'raw': u'FROMCALL>TOCALL:/092345z4903.50N/07201.75W>Test1234', 'raw_timestamp': u'092345z', 'symbol': u'>', 'symbol_table': u'/', 'timestamp': 1452383100, 'to': u'TOCALL', 'via': ''} Mic-E ----- .. code:: python >>> aprslib.parse('FROMCALL>SUSUR1:`CF"l#![/`"3z}_ ') {'altitude': 8, 'comment': u'`_', 'course': 305, 'format': 'mic-e', 'from': u'FROMCALL', 'latitude': 35.58683333333333, 'longitude': 139.701, 'mbits': u'111', 'mtype': 'M0: Off Duty', 'path': [], 'posambiguity': 0, 'raw': u'FROMCALL>SUSUR1:`CF"l#![/`"3z}_ ', 'speed': 0.0, 'symbol': u'[', 'symbol_table': u'/', 'to': u'SUSUR1', 'via': ''} Objects ======= .. code:: python >>> aprslib.parse('FROMCALL>TOCALL:;LEADER *092345z4903.50N/07201.75W>088/036') {'alive': True, 'comment': u'', 'course': 88, 'format': 'object', 'from': u'FROMCALL', 'latitude': 49.05833333333333, 'longitude': -72.02916666666667, 'object_format': 'uncompressed', 'object_name': u'LEADER ', 'path': [], 'posambiguity': 0, 'raw': u'FROMCALL>TOCALL:;LEADER *092345z4903.50N/07201.75W>088/036', 'raw_timestamp': u'092345z', 'speed': 66.672, 'symbol': u'>', 'symbol_table': u'/', 'timestamp': 1452383100, 'to': u'TOCALL', 'via': ''} Weather ======= Positionless ------------ .. code:: python >>> aprslib.parse('FROMCALL>TOCALL:_10090556c220s004g005t077r000p000P000h50b09900wRSW') {'comment': u'wRSW', 'format': 'wx', 'from': u'FROMCALL', 'path': [], 'raw': u'FROMCALL>TOCALL:_10090556c220s004g005t077r000p000P000h50b09900wRSW', 'to': u'TOCALL', 'via': '', 'weather': {'humidity': 50, 'pressure': 990.0, 'rain_1h': 0.0, 'rain_24h': 0.0, 'rain_since_midnight': 0.0, 'temperature': 25.0, 'wind_direction': 220, 'wind_gust': 2.2352, 'wind_speed': 1.78816}, 'wx_raw_timestamp': u'10090556'} Comment field ------------- .. code:: python >>> aprslib.parse("FROMCALL>TOCALL:=4903.50N/07201.75W_225/000g000t050r000p001...h00b10138dU2k") {'comment': u'...dU2k', 'format': 'uncompressed', 'from': u'FROMCALL', 'latitude': 49.05833333333333, 'longitude': -72.02916666666667, 'messagecapable': True, 'path': [], 'posambiguity': 0, 'raw': u'FROMCALL>TOCALL:=4903.50N/07201.75W_225/000g000t050r000p001...h00b10138dU2k', 'symbol': u'_', 'symbol_table': u'/', 'to': u'TOCALL', 'via': '', 'weather': {'humidity': 0, 'pressure': 1013.8, 'rain_1h': 0.0, 'rain_24h': 0.254, 'temperature': 10.0, 'wind_direction': 225, 'wind_gust': 0.0, 'wind_speed': 0.0}} Status report ============= .. code:: python >>> aprslib.parse('FROMCALL>TOCALL:>status text') {'format': 'status', 'from': u'FROMCALL', 'path': [], 'raw': u'FROMCALL>TOCALL:>status text', 'status': u'status text', 'to': u'TOCALL', 'via': ''} Messages ======== Regular ------- .. code:: python >>> aprslib.parse('FROMCALL>TOCALL::ADDRCALL :message text') {'addresse': u'ADDRCALL', 'format': 'message', 'from': u'FROMCALL', 'message_text': u'message text', 'path': [], 'raw': u'FROMCALL>TOCALL::FROMCALL :message text', 'to': u'TOCALL', 'via': ''} Telemetry configuration ----------------------- .. code:: python >>> aprslib.parse('FROMCALL>TOCALL::FROMCALL :PARM.Vin,Rx1h,Dg1h,Eff1h,A5,O1,O2,O3,O4,I1,I2,I3,I4') {'addresse': 'FROMCALL', 'format': 'telemetry-message', 'from': 'FROMCALL', 'path': [], 'raw': 'FROMCALL>TOCALL::FROMCALL :PARM.Vin,Rx1h,Dg1h,Eff1h,A5,O1,O2,O3,O4,I1,I2,I3,I4', 'tPARM': ['Vin', 'Rx1h', 'Dg1h', 'Eff1h', 'A5', 'O1', 'O2', 'O3', 'O4', 'I1', 'I2', 'I3', 'I4'], 'to': 'TOCALL', 'via': ''} >>> aprslib.parse('FROMCALL>TOCALL::FROMCALL :UNIT.Volt,Pkt,Pkt,Pcnt,None,On,On,On,On,Hi,Hi,Hi,Hi') {'addresse': 'FROMCALL', 'format': 'telemetry-message', 'from': 'FROMCALL', 'path': [], 'raw': 'FROMCALL>TOCALL::FROMCALL :UNIT.Volt,Pkt,Pkt,Pcnt,None,On,On,On,On,Hi,Hi,Hi,Hi', 'tUNIT': ['Volt', 'Pkt', 'Pkt', 'Pcnt', 'None', 'On', 'On', 'On', 'On', 'Hi', 'Hi', 'Hi', 'Hi'], 'to': 'TOCALL', 'via': ''} >>> aprslib.parse('FROMCALL>TOCALL::FROMCALL :EQNS.0,0.075,0,0,10,0,0,10,0,0,1,0,0,0,0') {'addresse': 'FROMCALL', 'format': 'telemetry-message', 'from': 'FROMCALL', 'path': [], 'raw': 'FROMCALL>TOCALL::FROMCALL :EQNS.0,0.075,0,0,10,0,0,10,0,0,1,0,0,0,0', 'tEQNS': [[0, 0.075, 0], [0, 10, 0], [0, 10, 0], [0, 1, 0], [0, 0, 0]], 'to': 'TOCALL', 'via': ''}