101 lines
2.7 KiB
Python
101 lines
2.7 KiB
Python
import re
|
|
from aprslib import base91
|
|
from aprslib.exceptions import ParseError
|
|
from aprslib.parsing import logger
|
|
|
|
__all__ = [
|
|
'_parse_comment_telemetry',
|
|
'_parse_telemetry_config',
|
|
]
|
|
|
|
|
|
def _parse_comment_telemetry(text):
|
|
"""
|
|
Looks for base91 telemetry found in comment field
|
|
Returns [remaining_text, telemetry]
|
|
"""
|
|
parsed = {}
|
|
match = re.findall(r"^(.*?)\|([!-{]{4,14})\|(.*)$", text)
|
|
|
|
if match and len(match[0][1]) % 2 == 0:
|
|
text, telemetry, post = match[0]
|
|
text += post
|
|
|
|
temp = [0] * 7
|
|
for i in range(7):
|
|
temp[i] = base91.to_decimal(telemetry[i*2:i*2+2])
|
|
|
|
parsed.update({
|
|
'telemetry': {
|
|
'seq': temp[0],
|
|
'vals': temp[1:6]
|
|
}
|
|
})
|
|
|
|
if temp[6] != '':
|
|
parsed['telemetry'].update({
|
|
'bits': "{0:08b}".format(temp[6] & 0xFF)[::-1]
|
|
})
|
|
|
|
return (text, parsed)
|
|
|
|
|
|
def _parse_telemetry_config(body):
|
|
parsed = {}
|
|
|
|
match = re.findall(r"^(PARM|UNIT|EQNS|BITS)\.(.*)$", body)
|
|
if match:
|
|
logger.debug("Attempting to parse telemetry-message packet")
|
|
form, body = match[0]
|
|
|
|
parsed.update({'format': 'telemetry-message'})
|
|
|
|
if form in ["PARM", "UNIT"]:
|
|
vals = body.split(',')[:13]
|
|
|
|
for val in vals:
|
|
if not re.match(r"^(.{1,20}|)$", val):
|
|
raise ParseError("incorrect format of %s (name too long?)" % form)
|
|
|
|
defvals = [''] * 13
|
|
defvals[:len(vals)] = vals
|
|
|
|
parsed.update({
|
|
't%s' % form: defvals
|
|
})
|
|
elif form == "EQNS":
|
|
eqns = body.split(',')[:15]
|
|
teqns = [0, 1, 0] * 5
|
|
|
|
for idx, val in enumerate(eqns):
|
|
if not re.match(r"^([-]?\d*\.?\d+|)$", val):
|
|
raise ParseError("value at %d is not a number in %s" % (idx+1, form))
|
|
else:
|
|
try:
|
|
val = int(val)
|
|
except:
|
|
val = float(val) if val != "" else 0
|
|
|
|
teqns[idx] = val
|
|
|
|
# group values in 5 list of 3
|
|
teqns = [teqns[i*3:(i+1)*3] for i in range(5)]
|
|
|
|
parsed.update({
|
|
't%s' % form: teqns
|
|
})
|
|
elif form == "BITS":
|
|
match = re.findall(r"^([01]{8}),(.{0,23})$", body)
|
|
if not match:
|
|
raise ParseError("incorrect format of %s (title too long?)" % form)
|
|
|
|
bits, title = match[0]
|
|
|
|
parsed.update({
|
|
't%s' % form: bits,
|
|
'title': title.strip(' ')
|
|
})
|
|
|
|
return (body, parsed)
|
|
|