Underwater communications codec with DCCL-inspired compact binary encoding
Project description
uwacomm
Underwater Communications Codec – DCCL-inspired compact binary encoding for Python
Inspiration & Credits
uwacomm is inspired by DCCL (Dynamic Compact Control Language) from GobySoft. DCCL is a mature, battle-tested C++ library used extensively in underwater robotics and autonomous vehicle communications.
Key differences:
- uwacomm: Python-native, Pydantic-based, designed for ease of use in Python/ROS2 ecosystems
- DCCL: C++ implementation with Protobuf integration, part of the larger Goby underwater autonomy framework
We are NOT affiliated with or claiming to replace DCCL. If you need:
- Production-grade C++ implementation
- Full Goby framework integration
- Official DCCL Python bindings
→ Use the official DCCL project: https://github.com/GobySoft/dccl
uwacomm implements similar compact encoding concepts but with a pure-Python, Pydantic-first approach for Python developers who want DCCL-inspired functionality without C++ dependencies.
Why uwacomm exists
While DCCL is excellent, Python developers often want:
- Native Pydantic integration for modern Python codebases
- Simpler installation (pip install, no compilation)
- Pythonic API design
- Easy integration with Python-based robotics stacks
Standing on the shoulders of giants: This project wouldn't exist without the pioneering work of the DCCL team at GobySoft. Thank you!
Overview
uwacomm is a Python library for schema-based compact binary encoding designed for bandwidth-constrained communications, particularly underwater acoustic modems. Inspired by DCCL from GobySoft, uwacomm uses Pydantic models for message definition and provides DCCL-style bounded field optimization to minimize transmitted bytes.
Key Features
- 🎯 Schema-first design: Define messages using Pydantic's intuitive field syntax
- 📦 Compact encoding: Bounded fields use only the minimum required bits
- 🔒 Type-safe: Full type hints and mypy strict mode compliance
- ✅ Deterministic: Platform-independent, reproducible encodings
- 🛡️ Error detection: Built-in CRC-16/CRC-32 and framing utilities
- 🔄 Protobuf interop: Generate
.protoschemas from Pydantic models - 📊 Size analysis: Calculate encoded sizes before transmission
- 🧪 Well-tested: Comprehensive unit, integration, and property-based tests
Installation
pip install uwacomm
Optional dependencies
# For Protobuf schema generation
pip install uwacomm[protobuf]
# For development (tests, docs, linting)
pip install uwacomm[dev]
# All optional dependencies
pip install uwacomm[all]
Quick Start
1. Define a Message
from pydantic import Field
from uwacomm import BaseMessage
class StatusReport(BaseMessage):
"""Underwater vehicle status report."""
vehicle_id: int = Field(ge=0, le=255) # 8 bits
depth_cm: int = Field(ge=0, le=10000) # 14 bits
battery_pct: int = Field(ge=0, le=100) # 7 bits
active: bool # 1 bit
# Optional: specify max bytes and message ID
uwacomm_max_bytes: ClassVar[Optional[int]] = 16
uwacomm_id: ClassVar[Optional[int]] = 10
2. Encode and Decode
from uwacomm import encode, decode
# Create a message
msg = StatusReport(
vehicle_id=42,
depth_cm=2500,
battery_pct=87,
active=True
)
# Encode to compact binary
data = encode(msg) # 4 bytes (30 bits rounded up)
# Decode back
decoded = decode(StatusReport, data)
assert decoded == msg
3. Add Framing for Transmission
from uwacomm import frame_with_id, unframe_with_id
# Frame with message ID and CRC-32
framed = frame_with_id(data, message_id=10, crc="crc32")
# Transmit over acoustic modem...
# Receive and unframe
msg_id, payload = unframe_with_id(framed, crc="crc32")
decoded = decode(StatusReport, payload)
4. Analyze Message Size
from uwacomm import encoded_size, field_sizes
# Get total encoded size
size = encoded_size(StatusReport) # 4 bytes
# Get per-field bit usage
sizes = field_sizes(StatusReport)
# {'vehicle_id': 8, 'depth_cm': 14, 'battery_pct': 7, 'active': 1}
CLI Tools
Message Analysis
Analyze message schemas and see field-by-field bit usage (inspired by dccl --analyze):
uwacomm --analyze message.py
Example output:
||||||| uwacomm: Underwater Communications Codec |||||||
2 messages loaded.
Field sizes are in bits unless otherwise noted.
=================== 10: StatusReport ===================
Actual maximum size of message: 4 bytes / 32 bits
uwacomm.id head........................8 (if present)
body..................................29
padding to full byte...................3
Allowed maximum size of message: 32 bytes / 256 bits
--------------------------- Header ---------------------------
uwacomm.id............................................8 bits
---------------------------- Body ----------------------------
StatusReport..........................................29 bits
1. vehicle_id...........................8 bits [0-255]
2. depth_cm..........................14 bits [0-10000]
3. battery_pct..........................7 bits [0-100]
======================== Summary ========================
Compression vs JSON: 22.2x smaller
Estimated transmission time @ 80 bps: 0.4 seconds
CLI commands:
uwacomm --analyze FILE # Analyze message schema
uwacomm --version # Show version
uwacomm --help # Show help
Why uwacomm?
Bandwidth Matters Underwater
Underwater acoustic modems typically operate at 80-5000 bits per second—orders of magnitude slower than terrestrial networks. For comparison:
| Encoding | Message Size | Transmission Time (80 bps) |
|---|---|---|
| JSON | 95 bytes | 9.5 seconds |
| Protobuf | 12 bytes | 1.2 seconds |
| uwacomm | 4 bytes | 0.4 seconds |
With limited transmission windows and high per-byte costs, every bit counts.
DCCL-Style Bounded Field Optimization
Unlike generic binary formats, uwacomm uses field constraints to minimize encoding size:
# Standard int: 32 bits
value: int
# Bounded int (0-255): only 8 bits!
value: int = Field(ge=0, le=255)
# Bounded int (0-15): only 4 bits!
value: int = Field(ge=0, le=15)
Pythonic and Type-Safe
Built on Pydantic v2, uwacomm provides:
- Automatic validation
- IDE autocomplete
- Type checking with mypy
- Clear error messages
Documentation
- User Guide: In-depth tutorials and concepts
- API Reference: Complete API documentation
- Examples: Runnable example scripts
Examples
See the examples/ directory for complete, runnable examples:
basic_usage.py- Message definition, encoding, decodingframing_example.py- Message framing with CRCprotobuf_schema.py- Generate.protoschemasunderwater_comms.py- Realistic UUV scenario
Supported Features (v0.1.0)
Field Types
- ✅ Booleans (1 bit)
- ✅ Bounded unsigned integers (minimal bits)
- ✅ Bounded signed integers (minimal bits)
- ✅ Enums (minimal bits for value count)
- ✅ Fixed-length bytes
- ✅ Fixed-length strings (UTF-8)
- ⏸️ Floats with precision (planned for v0.2.0)
- ⏸️ Nested messages (planned for v0.2.0)
- ⏸️ Variable-length arrays/strings (planned for v0.2.0)
Utilities
- ✅ CRC-16 and CRC-32 checksums
- ✅ Length-prefixed framing
- ✅ Message ID multiplexing
- ✅ Encoded size calculation
- ✅ Protobuf schema generation
- ⏸️ Fragmentation/reassembly (planned for v0.2.0)
Design Principles
- Explicit over implicit: All constraints must be declared
- Deterministic: Same message → same bytes, always
- Security-minded: Bounds checking, no unbounded recursion
- Fail-fast: Clear exceptions, not silent corruption
Comparison to Alternatives
| Feature | uwacomm | Protobuf | JSON | MessagePack |
|---|---|---|---|---|
| Schema-based | ✅ | ✅ | ❌ | ❌ |
| Bounded optimization | ✅ | ❌ | ❌ | ❌ |
| Python-native | ✅ | ❌ | ✅ | ✅ |
| Size (status msg) | 4 bytes | 12 bytes | 95 bytes | 30 bytes |
| Type safety | ✅ | ✅ | ❌ | ❌ |
Development
Setup
git clone https://github.com/patel999jay/uwacomm.git
cd uwacomm
pip install -e ".[dev]"
Run Tests
pytest
Linting
black src tests examples
ruff check src tests examples
mypy src
Contributing
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
License
MIT License - see LICENSE for details.
Acknowledgments
- Inspired by DCCL (GobySoft)
- Built on Pydantic
- Influenced by arlpy usability principles
- Extends the author's prior work: ProtocolDataUnits
Citation
If you use uwacomm in your research, please cite:
@software{uwacomm2026,
author = {Patel, Jay},
title = {uwacomm: Python DCCL-inspired compact binary encoding for underwater communications},
year = {2026},
url = {https://github.com/patel999jay/uwacomm}
}
Related Projects
Predecessor: ProtocolDataUnits
- ProtocolDataUnits: https://github.com/patel999jay/ProtocolDataUnits
- PyPI: https://pypi.org/project/ProtocolDataUnits/
- Blog: https://patel999jay.github.io/post/protocoldataunits-python-package/
uwacomm is the evolution of ProtocolDataUnits, adding:
- Pydantic v2 integration
- DCCL-inspired bounded field optimization
- Better type safety and modern Python practices
- CLI analysis tools
For new projects, use uwacomm. ProtocolDataUnits remains available for existing users.
Official DCCL Project
- DCCL (C++): https://github.com/GobySoft/dccl
- Documentation: https://libdccl.org/
- Goby Framework: https://github.com/GobySoft/goby3
Python Underwater Acoustics
- arlpy: https://github.com/org-arl/arlpy - Underwater acoustics toolbox
- UnetStack: https://unetstack.net/ - Underwater network simulator
Other Python Binary Encodings
- Protobuf: https://protobuf.dev/ - Google's binary format
- MessagePack: https://msgpack.org/ - Efficient binary serialization
- construct: https://construct.readthedocs.io/ - Binary parsing library
uwacomm complements these tools by providing DCCL-inspired compact encoding specifically optimized for bandwidth-constrained underwater communications.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file uwacomm-0.2.0.tar.gz.
File metadata
- Download URL: uwacomm-0.2.0.tar.gz
- Upload date:
- Size: 33.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e1d9094364df7c09549d35e715f88349d31be924b6d3cee0bad041189aa3fa92
|
|
| MD5 |
57f00bde4d3510643f8a4fa4bc02d745
|
|
| BLAKE2b-256 |
1a054972f0b3633286917a098f904a179fc286cda4411934146f29c3032a5bde
|
Provenance
The following attestation bundles were made for uwacomm-0.2.0.tar.gz:
Publisher:
publish.yml on patel999jay/uwacomm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
uwacomm-0.2.0.tar.gz -
Subject digest:
e1d9094364df7c09549d35e715f88349d31be924b6d3cee0bad041189aa3fa92 - Sigstore transparency entry: 939542087
- Sigstore integration time:
-
Permalink:
patel999jay/uwacomm@586ee10e5aefb51c25897d1d2aa74e95e3d1d62e -
Branch / Tag:
refs/heads/main - Owner: https://github.com/patel999jay
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@586ee10e5aefb51c25897d1d2aa74e95e3d1d62e -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file uwacomm-0.2.0-py3-none-any.whl.
File metadata
- Download URL: uwacomm-0.2.0-py3-none-any.whl
- Upload date:
- Size: 31.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
058ee83d2ee34c3ef8b55d4e307cd778fc8458194bbdf9860a12d2b707e507e8
|
|
| MD5 |
bfdf352f4a191f9e42bb1d026ee6f923
|
|
| BLAKE2b-256 |
fb2ea7b368ff35e6dd764e4c5ecab0fb36d5049a417685a77a67a4b8fccce3a0
|
Provenance
The following attestation bundles were made for uwacomm-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on patel999jay/uwacomm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
uwacomm-0.2.0-py3-none-any.whl -
Subject digest:
058ee83d2ee34c3ef8b55d4e307cd778fc8458194bbdf9860a12d2b707e507e8 - Sigstore transparency entry: 939542108
- Sigstore integration time:
-
Permalink:
patel999jay/uwacomm@586ee10e5aefb51c25897d1d2aa74e95e3d1d62e -
Branch / Tag:
refs/heads/main - Owner: https://github.com/patel999jay
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@586ee10e5aefb51c25897d1d2aa74e95e3d1d62e -
Trigger Event:
workflow_dispatch
-
Statement type: