maritime-frame
maritime-frame is a zero-runtime-dependency Python library for incremental NMEA and marine telemetry decoding. It is designed for applications that receive arbitrary serial, TCP, UDP, or CAN fragments and cannot assume that one read equals one frame.
Install and test
python -m pip install .
python -m unittest discover -s tests -v
Streaming NMEA-0183 and AIS
from maritime_frame import StreamParser, Status
parser = StreamParser(max_sentence=1024)
for chunk in serial_port:
for event in parser.feed(chunk):
if event.status is Status.VALID_FRAME:
print(event.protocol, event.message)
elif event.status is Status.CORRUPTED_FRAME:
logger.warning("discarded frame: %s", event.error)
feed() accepts str or ASCII bytes, retains incomplete lines, rejects overlong input, validates the optional two-digit XOR checksum, and recognizes $ and ! prefixes. ddm_to_decimal("4807.038", "N") returns 48.1173. AIS !AIVDM and !AIVDO payloads are 6-bit unarmored into a bit string; message types 1, 2, 3, and 5 expose MMSI, position, speed, course, heading, identity, and ship dimensions. Multi-sentence AIS messages are reassembled by sequence ID.
NMEA-2000 CAN and Fast Packet
A 29-bit CAN identifier is mapped as follows:
28 26 25 24 23 16 15 8 7 0
+----------+--+--+-----------+------------+---------+
| priority |R |DP| PDU format|PDU specific| source |
+----------+--+--+-----------+------------+---------+
from maritime_frame import StreamParser
parser = StreamParser(n2k_timeout=1.0)
first = parser.feed_can(0x0CF00501, bytes([0, 10, 1, 2, 3, 4, 5, 6]), 100.0)
second = parser.feed_can(0x0CF00501, bytes([1, 7, 8, 9, 10, 0, 0, 0]), 100.1)
assert second.message.payload == bytes(range(1, 11))
The assembler enforces frame number order, a maximum payload of 223 bytes, exact eight-byte CAN data frames, and timeout purging before each frame. Dropped or late follow-up frames never remain in memory indefinitely.
OneNet, legacy, and proprietary layers
from maritime_frame.onenet import parse_datagram
from maritime_frame.proprietary import ProprietaryRegistry
network = parse_datagram(b"UdPBc $GPRMC,...")
registry = ProprietaryRegistry()
registry.register("PGR", lambda sentence: {"vendor": "Garmin", "fields": sentence.fields})
parse_datagram validates the UdP*/TcP* transport token and preserves the payload for the normal stream parser. legacy.parse_0180 and legacy.parse_0182 decode steering and bearing flags. The proprietary registry is intentionally open-ended so vendor payload schemas remain application-owned.
Status contract
Every chunk or CAN frame yields one deterministic status: VALID_FRAME, PARTIAL_STREAM, or CORRUPTED_FRAME. A partial NMEA line produces a partial event while its bytes remain buffered. Invalid checksums, invalid AIS armor, overflows, malformed transport headers, and N2K sequencing errors produce corrupted events without exposing unsafe indexes or unbounded allocations.
Scope and transport boundary
The package parses frames; it does not open sockets, configure serial ports, or control a CAN adapter. That keeps it portable and lets downstream systems choose their I/O, scheduling, timestamp, and multicast policy. All runtime code uses only the Python standard library.
Release files for maritime-frame 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| maritime_frame-0.1.0.tar.gz | 11.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| maritime_frame-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size:22.4 kB
Release files / maritime_frame-0.1.0.tar.gz
| Download URL | maritime_frame-0.1.0.tar.gz |
|---|---|
| Size | 11.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
562721836daca25d5aefe39788a38a8fa8e260ff84df5d2629103a0c39700346
|
|
BLAKE2b-256 checksum How to use checksums |
ca082bb3e88b987ef9280ca7170a31edc22f29064c2e78708b691533a24743ec
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / maritime_frame-0.1.0-py3-none-any.whl
| Download URL | maritime_frame-0.1.0-py3-none-any.whl |
|---|---|
| Size | 11.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
49d33600555aff3c50d031fa159b4838402ba82cdbbe06e6a1794a46c8754bd1
|
|
BLAKE2b-256 checksum How to use checksums |
d78e6887f70eab6d27b1b9cdfff9d7c2329d21c27fcfb834bde055ec57562c78
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|