pnf
A pure-Python decoder for Shearwater's Petrel Native Format (PNF), the on-device log format used by Shearwater's Petrel-family dive computers (Petrel, Perdix, Teric, Nerd, Peregrine, and successors).
Shearwater Cloud can export your dives to XML, CSV, or its own SQLite database.
The XML and CSV are lossy: they drop channels the computer actually recorded,
including GF99, the deco ceiling, per-sample battery voltage and percentage, and
the "@+5" prediction. The SQLite export keeps the real thing: each dive is
stored as a compressed native-format blob. pnf decodes those blobs.
No dependencies, standard library only, Python 3.9+.
pip install pnf
Usage
Point it at a Shearwater Cloud "Export Database" file (dive_data.db):
import pnf
for log_id, dive in pnf.decode_database("dive_data.db"):
h = dive.header
print(f"{h['computer_model']} #{h['computer_serial']:X} dive {h['dive_number']}: "
f"{h['max_depth_m']} m, {len(dive.samples)} samples")
for s in dive.samples:
if s.gf99 is not None:
print(f" t={s.t_s:.0f}s depth={s.depth_m}m gf99={s.gf99} "
f"ceiling={s.ceiling_m}m battery={s.battery_v}V")
Or decode a single sw-pnf blob you already have:
dive = pnf.decode(blob)
What you get
decode() returns a Dive with:
header: a dict with the dive number and start time, and the dive configuration: gases, gradient factors, deco model, water density, atmospheric pressure, sample interval, computer serial, model, and firmware, the GNSS entry and exit fix (on computers that log it), and verbatim copies of the raw config records.start_timeis seconds since 1970 on the local wall clock with no time zone, sodatetime.fromtimestamp(t, timezone.utc)gives the local time the computer showed.samples: a list ofSample, one per log interval (typically every 10 s), each with depth, temperature, TTS, next-stop depth and time, NDL, average and per-cell ppO2, CNS, GF99, deco ceiling, battery voltage and percentage, gas fractions, setpoint, wireless-air-integration tank pressures, SAC, the decoded status/mode bits (including CCR solenoid-fired count), and the "@+5" prediction. Channels the computer did not record areNone. Depths are in metres even on an imperial-units log.gases: the ten programmed gases (O2/He, open- vs closed-circuit, enabled).events: info-event records.unknown_records: every record type this decoder does not interpret, kept verbatim as(type_key, seq, raw_bytes). Shearwater's own desktop parser also leaves several record types (tissue snapshots, validity maps, surface ppO2, button pushes, DiveCAN events) undecoded;pnfpreserves them rather than discarding them, so a future decoder can revisit them.
Under the DCIEM deco model, sample bytes 24-25 encode a safe-ascent depth
instead of a ceiling / GF99 pair; pnf decodes them to safe_ascent_depth_m
and leaves ceiling_m / gf99 as None. See SPEC.md for details.
The format
SPEC.md documents the container, the record types, and every byte of the dive-sample record, with the provenance of each field.
Provenance and scope
This is independent reverse engineering for interoperability: reading dive
logs you own, in Python, without going through Shearwater Cloud. The documented
sample fields follow the layout in
libdivecomputer's
shearwater_predator_parser.c. The remaining fields were identified by
observation across real dives and cross-checked against Shearwater Cloud's own
outputs (its XML export and its per-dive EndGF99 summary), then reconciled for
naming and edge cases such as the DCIEM branch.
pnf is not affiliated with or endorsed by Shearwater Research, contains no
Shearwater code, and does not redistribute any Shearwater software. Format facts
(byte offsets and field meanings) are not code. If you want a maintained,
officially-supported path, Shearwater offers a developer program.
Validated against Perdix 2 and Petrel 3 logs. The sample record layout is stable across native-format versions, but other models may populate fields this decoder has not seen. If a dive decodes wrong, open an issue with the blob; that is exactly the data that improves the decoder.
License
MIT. See LICENSE.
Metadata
Release files for pnf 0.2.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 | Provenance | Actions |
|---|---|---|---|---|
| pnf-0.2.0.tar.gz | 18.0 kB | Without provenance | Details for pnf-0.2.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pnf-0.2.0-py3-none-any.whl | Python 3 | none | any | Details for pnf-0.2.0-py3-none-any.whl |
Total release size: 30.0 kB
Release files / pnf-0.2.0.tar.gz
| Download URL | pnf-0.2.0.tar.gz |
|---|---|
| Size | 18.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2f8ce2ba39fbbe6e1f6859ed7d059fe16560f2dd8f834d14e77fa03e18e27c39
|
|
BLAKE2b-256 checksum How to use checksums |
e3741d0a31762711785970743bca1367bf4bb5b203aa07d11cc31fc625938764
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.5
|
Release files / pnf-0.2.0-py3-none-any.whl
| Download URL | pnf-0.2.0-py3-none-any.whl |
|---|---|
| Size | 12.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
efad5aad24b0da65c8afbecb209688df230e816f3ac793aaf6e1906fb61744e7
|
|
BLAKE2b-256 checksum How to use checksums |
14ce2ab5d0f48793f0fa8b30f3b93f61df1630ff7fbeac47b6d936a2cd14f965
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.5
|
Security for pnf 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.