add telemetry report parsing; fix #29

This commit is contained in:
Rossen Georgiev 2017-03-19 18:59:35 +02:00
parent 9c159200cd
commit 2a222e69ea
3 changed files with 50 additions and 13 deletions

View File

@ -1,14 +1,27 @@
from aprslib.packets.base import APRSPacket
class TelemetryAddon(object):
analog_values = None
_analog_values = None
_sequence_number = 0
_digital_value = 0
def __init__(self, *args, **kwargs):
self._analog_values = AnalogList()
super(TelemetryAddon, self).__init__( *args, **kwargs)
self. analog_values = AnalogList()
@property
def analog_values(self):
return self._analog_values
@analog_values.setter
def analog_values(self, v):
if not isinstance(v, list):
raise TypeError("Expected analog_values to be list, got %s" % type(v))
if len(v) != 5:
raise ValueError("Expected a list of 5 elements, got a list of %d" % len(v))
self._analog_values[:] = v
@property
def sequence_number(self):
@ -48,32 +61,30 @@ class AnalogList(list):
def __setslice__(self, i, j, v):
if i > j:
i, j = j, i
if (not 0 <= i <= 5) or (not 0 <= j <= 5):
raise IndexError("Slice outside of range [0:5], got %s" % [i, j])
for x in range(i, j):
for x in range(max(0, i), min(5, j)):
list.__setitem__(self, x, v[x])
def append(self, other):
def append(self, a):
raise NotImplementedError("not supported")
def remove(self, other):
def remove(self, a):
raise NotImplementedError("not supported")
def pop(self):
def pop(self, a):
raise NotImplementedError("not supported")
def extend(self):
def extend(self, a):
raise NotImplementedError("not supported")
def insert(self):
def insert(self, a, b):
raise NotImplementedError("not supported")
class TelemetryReport(TelemetryAddon, APRSPacket):
@property
def format(self):
return 'raw'
return 'telemetry'
_comment = ''

View File

@ -152,13 +152,12 @@ def _try_toparse_body(packet_type, body, parsed):
# . - reserved
# < - station capabilities
# ? - general query format
# T - telemetry report
# [ - maidenhead locator beacon
# \ - unused
# ] - unused
# ^ - unused
# } - 3rd party traffic
if packet_type in '#$%)*<?T[}':
if packet_type in '#$%)*<?[}':
raise UnknownFormat("format is not supported")
# user defined
@ -197,6 +196,12 @@ def _try_toparse_body(packet_type, body, parsed):
body, result = parse_weather(body)
# Telemetry Report
elif packet_type == 'T':
logger.debug("Attempting to parse as telemetry report")
body, result = parse_telemetry(body)
# postion report (regular or compressed)
elif (packet_type in '!=/@;' or
0 <= body.find('!') < 40): # page 28 of spec (PDF)

View File

@ -4,11 +4,32 @@ from aprslib.exceptions import ParseError
from aprslib.parsing import logger
__all__ = [
'parse_telemetry',
'parse_comment_telemetry',
'parse_telemetry_config',
]
def parse_telemetry(body):
parsed = {}
match = re.match(r'#(\d{3},|MIC,?)(\d{3}),(\d{3}),(\d{3}),(\d{3}),(\d{3}),([0-1]{8})(.*)', body, flags=re.I)
if not match:
raise ParseError("Invalid telemetry format")
data = match.groups()
parsed.update({
'format': 'telemetry',
'sequence_number': 0 if data[0].lower().startswith('mic') else int(data[0][:3]),
'analog_values': list(map(int, data[1:6])),
'digital_value': int(data[6], 2)
})
return '', parsed
def parse_comment_telemetry(text):
"""
Looks for base91 telemetry found in comment field