Reports and formatters

Dive report: everything about a computed dive, ready for presentation.

DiveReport is pure data assembled from a Dive — the schedule rows plus derived figures (gas consumption, CNS/OTU, rock bottom, TTS variations). Formatters (diveplan.dive.formatters) turn a report into console text, JSON, or a Subsurface dive log; they never touch models or profiles directly, so a new output format is a single class.

class diveplan.dive.dive_report.DiveReport(*, profile, model_name, rows, runtime, max_depth, consumption_l, cns, otus, rock_bottom_l, sac_bottom, sac_deco, sac_factor, tts_variations)[source]

Bases: object

Immutable summary of a computed dive.

Build via from_dive(). Holds the schedule and the derived numbers; formatting belongs to diveplan.dive.formatters.

Parameters:
classmethod from_dive(dive, *, gas_plan=None, tts_variations=None)[source]

Assemble a report from a computed dive.

Parameters:
  • dive (Dive[DecoState]) – The computed dive (normally the full dive, bottom plus planned ascent — see Dive.with_ascent()).

  • gas_plan (GasPlan | None) – Unused for consumption (which follows the profile’s own gases) — reserved for future reserve summaries.

  • tts_variations (TtsVariations | None) – The “+1 m / +1 min” figures. They are meaningful for a bottom-phase dive, so compute them on the bottom dive (bottom.tts_variations()) and pass them here; a report over a full dive cannot derive them itself.

Return type:

DiveReport

class diveplan.dive.dive_report.ReportRow(runtime, start_depth_m, end_depth_m, duration, gas, kind)[source]

Bases: NamedTuple

One schedule line: a segment with its cumulative runtime at the end.

Parameters:
runtime: timedelta

Alias for field number 0

start_depth_m: float

Alias for field number 1

end_depth_m: float

Alias for field number 2

duration: timedelta

Alias for field number 3

gas: Gas

Alias for field number 4

kind: str

Alias for field number 5

Formatters

Report formatters: turn a DiveReport into an output document.

A formatter is a class with a NAME and a format(report) -> str method — stateless, presentation only. Third-party formatters can register under the diveplan.formatters entry-point group.

class diveplan.dive.formatters.BaseFormatter(**options)[source]

Bases: ABC

Base class for all report formatters.

Parameters:

options (Any)

abstractmethod format(report)[source]

Render the report as a string in this formatter’s output format.

Parameters:

report (DiveReport)

Return type:

str

write(report, path)[source]

Render the report and write it to path (UTF-8, LF endings).

Parameters:
Return type:

None

print(report)[source]

Render the report and print it to stdout.

Formatters with terminal-aware rendering (rich) override this.

Parameters:

report (DiveReport)

Return type:

None

class diveplan.dive.formatters.ConsoleFormatter(**options)[source]

Bases: BaseFormatter

Human-readable dive plan table with a summary block.

Parameters:

options (Any)

static format_schedule(segments)[source]

Render any segment sequence (a profile’s or an ascent plan) as a runtime table — reusable outside full reports.

Parameters:

segments (Iterable[DiveSegment])

Return type:

str

format(report)[source]

Render the full report: header, schedule table, totals block.

Parameters:

report (DiveReport)

Return type:

str

class diveplan.dive.formatters.JsonFormatter(*, indent=2)[source]

Bases: BaseFormatter

Serialize the whole report to a JSON document.

Depths in metres, durations in seconds, gases by name with exact fractions alongside.

Parameters:

indent (int | None)

format(report)[source]

Render the report as a JSON document string.

Parameters:

report (DiveReport)

Return type:

str

class diveplan.dive.formatters.RichConsoleFormatter(*, styled=True, width=72)[source]

Bases: BaseFormatter

Styled terminal rendering of a dive report.

Parameters:
  • styled (bool) – Keep ANSI color codes in the string returned by format(). Set False for plain (but still box-drawn) text, e.g. for logs.

  • width (int) – Render width in characters.

print(report, console=None)[source]

Render the report directly to a terminal (auto-detected styling).

Parameters:
Return type:

None

format(report)[source]

Render the report to a string (ANSI-styled when styled=True).

Parameters:

report (DiveReport)

Return type:

str

class diveplan.dive.formatters.RuntimeFormatter(**options)[source]

Bases: BaseFormatter

Printable runtime sheet: depth / duration / runtime / gas.

Parameters:

options (Any)

format(report)[source]

Render the runtime sheet as plain ASCII text.

Parameters:

report (DiveReport)

Return type:

str

class diveplan.dive.formatters.SubsurfaceXmlFormatter(*, planned_at=None)[source]

Bases: BaseFormatter

Render the report as a Subsurface dive-log XML document.

Parameters:

planned_at (datetime | None)

format(report)[source]

Render the report as a Subsurface dive-log XML string.

Parameters:

report (DiveReport)

Return type:

str

Plain-text report formatter for terminals and logs.

class diveplan.dive.formatters.console.ConsoleFormatter(**options)[source]

Bases: BaseFormatter

Human-readable dive plan table with a summary block.

Parameters:

options (Any)

static format_schedule(segments)[source]

Render any segment sequence (a profile’s or an ascent plan) as a runtime table — reusable outside full reports.

Parameters:

segments (Iterable[DiveSegment])

Return type:

str

format(report)[source]

Render the full report: header, schedule table, totals block.

Parameters:

report (DiveReport)

Return type:

str

JSON report formatter — machine-readable dive plan document.

class diveplan.dive.formatters.json.JsonFormatter(*, indent=2)[source]

Bases: BaseFormatter

Serialize the whole report to a JSON document.

Depths in metres, durations in seconds, gases by name with exact fractions alongside.

Parameters:

indent (int | None)

format(report)[source]

Render the report as a JSON document string.

Parameters:

report (DiveReport)

Return type:

str

Rich terminal formatter: the report as styled tables.

Same content as ConsoleFormatter, rendered with rich — colored segment kinds, box-drawn tables, a summary panel. format() honors the formatter contract by exporting the rendering to a string (ANSI-styled when styled=True); print() renders straight to a live terminal, which is what you want interactively.

class diveplan.dive.formatters.rich_console.RichConsoleFormatter(*, styled=True, width=72)[source]

Bases: BaseFormatter

Styled terminal rendering of a dive report.

Parameters:
  • styled (bool) – Keep ANSI color codes in the string returned by format(). Set False for plain (but still box-drawn) text, e.g. for logs.

  • width (int) – Render width in characters.

print(report, console=None)[source]

Render the report directly to a terminal (auto-detected styling).

Parameters:
Return type:

None

format(report)[source]

Render the report to a string (ANSI-styled when styled=True).

Parameters:

report (DiveReport)

Return type:

str

Runtime-table formatter: the plan as a diver would write it on a slate.

Follows the dive-table convention (matching Subsurface’s plan details with “display transitions in deco” off): travel between deco stops is folded into the following stop’s row — its duration includes the ascent, its runtime is the departure time. The ascent from the bottom to the first stop and the final surfacing keep their own rows. Whole minutes throughout. Plain ASCII, so the output pastes anywhere and prints from any encoding.

Use write() to save the sheet as a .txt.

class diveplan.dive.formatters.runtime.RuntimeFormatter(**options)[source]

Bases: BaseFormatter

Printable runtime sheet: depth / duration / runtime / gas.

Parameters:

options (Any)

format(report)[source]

Render the runtime sheet as plain ASCII text.

Parameters:

report (DiveReport)

Return type:

str

Subsurface dive-log XML formatter.

Emits a minimal Subsurface-compatible dive log: one dive with cylinders (one per gas), a planned-dive computer with depth samples and gas-change events. Written against Subsurface’s XML dive-log format and verified by importing into Subsurface 6.0; the format is theirs, not a public standard, so re-verify after major Subsurface releases.

class diveplan.dive.formatters.subsurface.SubsurfaceXmlFormatter(*, planned_at=None)[source]

Bases: BaseFormatter

Render the report as a Subsurface dive-log XML document.

Parameters:

planned_at (datetime | None)

format(report)[source]

Render the report as a Subsurface dive-log XML string.

Parameters:

report (DiveReport)

Return type:

str