Skip to content

Instantly share code, notes, and snippets.

@lukicdarkoo
Created August 20, 2019 12:07
Show Gist options
  • Save lukicdarkoo/4c98e799f1e117d1af5771c87b4bdf75 to your computer and use it in GitHub Desktop.
Save lukicdarkoo/4c98e799f1e117d1af5771c87b4bdf75 to your computer and use it in GitHub Desktop.
NMEА0183 sentence parser
import re
from functools import reduce
def nmea0183_create(arguments, proprietary='P', manufacturer_identifier='UWV'):
"""
Create NMEА0183 sentence
Parameters
----------
arguments: array
List of arguments where the first element is sentence identifier
Returns
-------
sentence: bytearray
Sentence ready to be transmitted through e.g. serial port
"""
arguments = [ str(x) for x in arguments ]
pmi = '{}{}'.format(proprietary, manufacturer_identifier)
data = '{}{}'.format(pmi, ','.join(arguments))
# Generate checksum
checksum = reduce(lambda acc, byte: ord(byte) ^ acc, data, 0)
checksum_hex = hex(checksum).lstrip('0x').upper()
# Generate sentence
sentence = '${}*{}\r\n'.format(data, checksum_hex)
return sentence.encode()
def nmea0183_parse(sentence, proprietary='P', manufacturer_identifier='UWV', ignore_checksum=False):
"""
Parse NMEА0183 sentence
Parameters
----------
sentence: bytearray
Sentence received from e.g. serial port
Returns
-------
arguments: array
List of arguments where the first element is sentence identifier
"""
sentence = sentence.decode()
pmi = '{}{}'.format(proprietary, manufacturer_identifier)
rexp = re.compile(r'\$(' + pmi + r'.*)\*([0-9A-F]{2})')
data, checksum = re.findall(rexp, sentence).pop()
# Verify checksum
checksum_ref = reduce(lambda acc, byte: ord(byte) ^ acc, data, 0)
checksum_ref_hex = hex(checksum_ref).lstrip('0x')
assert(ignore_checksum or checksum == checksum_ref_hex)
# Export arguments
arguments = data.replace(pmi, '').split(',')
return arguments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment