Skip to main content

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)

Source distribution for maritime-frame 0.1.0
File Size Uploaded
maritime_frame-0.1.0.tar.gz 11.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for maritime-frame 0.1.0
File Interpreter ABI Platform
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

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page