In my previous post of NMEA TAG block encoded data, I discussed my
parsing of the USCG old style NMEA metadata, how to calculate NMEA
checksums, and parsing the timestamp.
Here are the complete list of codes for the TAG components:
Before, we had:
SentenceNum-TotalSentences-IntegerIdentifyingTheGroup
Letter code | NMEA Config Msg | Description | type |
c | CPC | UNIX time in sec on millisec | int |
d | CPD | Destination | string |
g | CPG | Grouping param | ? |
n | CPN | line-count | int |
r | CPR | relative time (Units?) | int |
s | CPS | Source / station | string |
t | CPT | Text string | string |
\\c:(?P<timestamp>\d{10,15})\*(?P<checksum>[0-9A-F]{2})?\\.*Now, we would like to add the rest. We start by adding a 2nd by creating a string with a destination ("d") entry. The spec says this is an alphanumeric string up to 15 charactions. What exactly can be, I'm not totally sure. I presume that it can't have either a star ('*'), comma (','), and backslash ('\'), but am unsure about characters in the ASCII printable set.
body_parts = ['c:%d' % time.time(), 'd:%s' % 'MyStation12345'] body = ','.join(body_parts); body # 'c:1372002373,d:MyStation12345' '\{body}*{checksum}\\'.format(body=body, checksum=checksum(body)) # \c:1372002373,d:MyStation12345*15\We can get the destination with theis regex string: 'd:[^*,\\]{1,15}'. It needs to be named and if we turn on "Verbose," kodos allows us to have the regular expression span multiple lines.
\\ c:(?P<timestamp>\d{10,15}), d:(?P<dest>[^*,\\]{1,15}) \*(?P<checksum>[0-9A-F]{2})?\\.*What if the order were reversed? And what if either of the two entries was missing? Please note in this next code block that I have setup the regex to take either a common or star between any parameter. This will let through '*' between parameters, which is not correct. I am sure there is a way to make the regex such that commas between elements and the start is outside of the repeated block, but I haven't figured it out yet.
\\ ( ( c:(?P<timestamp>\d{10,15}) | d:(?P<dest>[^*,\\]{1,15}) )[,*] ) (?P<checksum>[0-9A-F]{2})?\\.*Now we need to flush out for the rest of the options. Grouping has substructure to it:
SentenceNum-TotalSentences-IntegerIdentifyingTheGroup
g:(?P<group>(?P<sent_num>\d)-(?P<sent_tot>\d)-(?P<group_id>\d+))Then n for line number and r for relative time are just an integer for each.
\\ ( ( c:(?P<time>\d{10,15}) | d:(?P<dest>[^*,\\]{1,15}) | g:(?P<group>(?P<sent_num>\d)-(?P<sent_tot>\d)-(?P<group_id>\d+)) | n:(?P<line_num>\d+) | r:(?P<rel_time>\d+) | s:(?P<src>[^$*,!\\]{1,15}) | t:(?P<text>[^$*,!\\]+) )[,*] )+ (?P<checksum>[0-9A-F]{2})?\\(?P<nmea_msg>.*)At this point, we can parse any tag block in the front.