Skip to content

Feature/shearwater cloud import#96

Merged
ericgriffin merged 12 commits into
mainfrom
feature/shearwater-cloud-import
Mar 28, 2026
Merged

Feature/shearwater cloud import#96
ericgriffin merged 12 commits into
mainfrom
feature/shearwater-cloud-import

Conversation

@ericgriffin

@ericgriffin ericgriffin commented Mar 28, 2026

Copy link
Copy Markdown
Member

Summary

Add native import support for Shearwater Cloud SQLite database (.db) files. Users can now import directly from their Shearwater Cloud desktop export without needing to convert to UDDF first. The parser extracts full dive profile data (depth, temperature, ppO2, CNS, NDL, ceiling, tank pressure, heart rate, deco model) via libdivecomputer's FFI bridge, plus rich metadata from the Shearwater Cloud database (location, site, buddy, notes, conditions, weather, tank info, gas mixes).

Resolves the shearwaterDb placeholder in the universal import system -- previously this format showed "not yet supported" with instructions to export as UDDF.

Changes

  • Add libdc_parse_raw_dive() C function exposing dc_parser_new2() for standalone binary parsing without a live device connection
  • Add parseRawDiveData() Pigeon API method with full implementation on macOS/iOS and stubs on Android/Windows/Linux
  • Add ShearwaterCloudParser implementing ImportParser -- orchestrates DB reading, FFI profile parsing, and metadata mapping into standard ImportPayload
  • Add ShearwaterDbReader -- opens SQLite .db files, queries dive_details + log_data tables, decompresses gzip BLOBs (with raw deflate fallback for zeroed CRC trailers), parses embedded JSON fields
  • Add ShearwaterFilenameParser -- extracts dive computer model/serial from log_data filenames (e.g., Teric[8629AC48]#1...)
  • Add ShearwaterValueMapper -- unit conversions (PSI to bar, F to C, lbs to kg, ft to m) and Shearwater condition enum mapping (environment, weather, visibility, current)
  • Add ShearwaterDiveMapper -- merges libdivecomputer parsed profile data with Shearwater Cloud metadata into entity maps matching the existing import pipeline conventions
  • Wire ShearwaterCloudParser into the import wizard: mark shearwaterDb as supported, add SQLite pre-validation to detect Shearwater Cloud databases, route to parser in provider
  • Treat model=0 as wildcard in find_descriptor() so vendor+product name lookup works without hardcoded model IDs
  • Handle Shearwater gzip streams with zeroed-out CRC32/ISIZE trailers via raw deflate fallback

Test Plan

  • flutter test passes (3159 tests, 0 failures)
  • flutter analyze passes (0 warnings/errors)
  • Manual testing on: macOS (import .db file, verify dive profiles render)
  • 90%+ unit test coverage on all new files (97.9% mapper, 100% parser/filename/value mapper, 94.9% DB reader)

Screenshots

Screenshot 2026-03-28 at 1 29 08 AM Screenshot 2026-03-28 at 1 29 53 AM

Extract field extraction logic from parse_dive() into a shared
extract_dive_fields() function, then add libdc_parse_raw_dive()
which uses dc_parser_new2() to parse raw binary dive data without
requiring a device connection. This enables parsing Shearwater
Cloud database exports offline.
Expose libdc_parse_raw_dive() to Dart through Pigeon so the Shearwater
Cloud import pipeline can parse raw dive data without a live device
connection. Full implementation on Darwin (macOS/iOS); Android, Windows,
and Linux return UNSUPPORTED stubs for now.
- Mark ImportFormat.shearwaterDb as supported in isSupported getter
- Set SourceApp.shearwater exportInstructions to null (native .db import supported)
- Remove shearwaterDb from PlaceholderParser supportedFormats
- Add shearwaterDb case in _parserFor() routing to ShearwaterCloudParser
- Add SQLite pre-validation in pickFile() to detect Shearwater Cloud databases
- Update tests to reflect new shearwaterDb supported status
…lue mapper

- ShearwaterCloudParser: orchestrates DB reading, FFI profile parsing,
  and metadata mapping into standard ImportPayload
- ShearwaterDbReader: opens SQLite, queries dive_details + log_data,
  decompresses binary BLOBs, parses JSON fields
- ShearwaterFilenameParser: extracts model/serial from log_data filenames
- ShearwaterValueMapper: unit conversions (PSI->bar, F->C, etc.) and
  condition enum mapping
- Full TDD test coverage (54 tests)
…amples

Two issues preventing dive profile import from Shearwater Cloud DBs:

1. find_descriptor() required exact model match. Passing model=0 from
   Dart caused descriptor lookup to fail silently. Now treats model=0
   as wildcard, matching by vendor+product only.

2. Profile samples only included depth/temp/pressure. Now includes all
   available sensor data: ppO2, setpoint, heartRate, CNS, RBT, TTS,
   decoType, ceiling (decoDepth), NDL (decoTime). Also overrides
   diveMode from parsed data instead of guessing from apparatus string.
Make mergeWithParsedDive @VisibleForTesting and add 16 new tests
covering: profile merge with all sensor fields, deco model/GF,
dive mode mapping, water temp extraction, unknown model fallback,
brackish water type, gasNotes/issueNotes in buildExtraNotes.
Some Shearwater Cloud databases produce gzip streams where the CRC32
and ISIZE trailer fields are zeroed out. Dart's GZipCodec validates
these and rejects the data, while Python's gzip is lenient.

Fix: try GZipCodec first, then fall back to raw deflate decompression
by parsing the gzip header manually and using ZLibDecoder(raw: true).
This bypasses trailer validation.

Also adds debug logging for FFI parse attempts and decompression.
Remove unnecessary dart:typed_data imports (redundant with
flutter/foundation.dart), add const to ShearwaterRawDive
constructors in tests where all fields are compile-time constants.
@ericgriffin
ericgriffin marked this pull request as ready for review March 28, 2026 05:33
Copilot AI review requested due to automatic review settings March 28, 2026 05:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds native import support for Shearwater Cloud SQLite (.db) exports to the universal import pipeline, including profile parsing via libdivecomputer and metadata mapping into the existing import entity conventions.

Changes:

  • Introduces ShearwaterCloudParser + supporting DB reader/filename/value/dive mappers and wires the format into import detection + parser selection.
  • Extends libdivecomputer plugin APIs with parseRawDiveData and adds a new C entrypoint (libdc_parse_raw_dive) for offline binary parsing.
  • Updates enums/placeholder behavior and adds unit/integration-style tests for the new import flow.

Reviewed changes

Copilot reviewed 31 out of 32 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
test/features/universal_import/data/services/shearwater_value_mapper_test.dart Unit tests for Shearwater value conversions and condition mapping.
test/features/universal_import/data/services/shearwater_filename_parser_test.dart Unit tests for filename parsing + vendor/product mapping.
test/features/universal_import/data/services/shearwater_dive_mapper_test.dart Mapper tests for metadata/profile merge behavior and warnings.
test/features/universal_import/data/services/shearwater_db_reader_test.dart DB reader tests using a fixture .db.
test/features/universal_import/data/parsers/shearwater_cloud_parser_test.dart Parser-level tests producing an ImportPayload from .db.
test/features/universal_import/data/parsers/placeholder_parser_test.dart Updates placeholder supported-format expectations.
test/features/universal_import/data/models/import_enums_test.dart Updates supported-format + export-instructions expectations.
test/features/universal_import/data/models/detection_result_test.dart Adjusts “unsupported formats” test case after adding support.
packages/libdivecomputer_plugin/windows/dive_computer_host_api_impl.h Adds ParseRawDiveData host API method declaration (Windows).
packages/libdivecomputer_plugin/windows/dive_computer_host_api_impl.cc Implements Windows stub returning UNSUPPORTED.
packages/libdivecomputer_plugin/windows/dive_computer_api.g.h Pigeon-generated Windows header updated for new method.
packages/libdivecomputer_plugin/windows/dive_computer_api.g.cc Pigeon-generated Windows channel wiring for new method.
packages/libdivecomputer_plugin/pigeons/dive_computer_api.dart Pigeon definition adds async parseRawDiveData.
packages/libdivecomputer_plugin/macos/Classes/libdc_wrapper.h Declares new C function libdc_parse_raw_dive.
packages/libdivecomputer_plugin/macos/Classes/libdc_download.c Adds standalone raw parsing + descriptor wildcard support.
packages/libdivecomputer_plugin/macos/Classes/DiveComputerApi.g.swift Pigeon-generated macOS Swift API updated for new method.
packages/libdivecomputer_plugin/linux/dive_computer_host_api_impl.cc Implements Linux stub returning UNSUPPORTED.
packages/libdivecomputer_plugin/linux/dive_computer_api.g.h Pigeon-generated Linux header updated for new method.
packages/libdivecomputer_plugin/linux/dive_computer_api.g.cc Pigeon-generated Linux channel wiring + response helpers.
packages/libdivecomputer_plugin/lib/src/generated/dive_computer_api.g.dart Dart host API wrapper adds parseRawDiveData.
packages/libdivecomputer_plugin/ios/Classes/DiveComputerApi.g.swift Pigeon-generated iOS Swift API updated for new method.
packages/libdivecomputer_plugin/darwin/Sources/LibDCDarwin/DiveComputerHostApiImpl.swift Implements Darwin raw dive parsing via libdc_parse_raw_dive.
packages/libdivecomputer_plugin/android/src/main/kotlin/com/submersion/libdivecomputer/DiveComputerHostApiImpl.kt Implements Android stub returning UNSUPPORTED.
packages/libdivecomputer_plugin/android/src/main/kotlin/com/submersion/libdivecomputer/DiveComputerApi.g.kt Pigeon-generated Android wiring for new method.
lib/features/universal_import/presentation/providers/universal_import_providers.dart Detects Shearwater DBs and routes to the new parser.
lib/features/universal_import/data/services/shearwater_value_mapper.dart Adds unit conversions + condition/visibility mapping + extra-notes builder.
lib/features/universal_import/data/services/shearwater_filename_parser.dart Parses Shearwater log filenames and maps known models to vendor/product.
lib/features/universal_import/data/services/shearwater_dive_mapper.dart Maps raw DB rows to import entities and optionally merges FFI-parsed profile data.
lib/features/universal_import/data/services/shearwater_db_reader.dart Reads Shearwater SQLite schema, decompresses log blobs, parses embedded JSON.
lib/features/universal_import/data/parsers/shearwater_cloud_parser.dart Orchestrates validation, DB read, mapping, and payload assembly.
lib/features/universal_import/data/parsers/placeholder_parser.dart Removes shearwaterDb from placeholder-supported formats.
lib/features/universal_import/data/models/import_enums.dart Marks shearwaterDb as supported and removes Shearwater UDDF instructions.

Comment thread lib/features/universal_import/data/services/shearwater_dive_mapper.dart Outdated
Comment thread lib/features/universal_import/data/services/shearwater_dive_mapper.dart Outdated
Comment thread lib/features/universal_import/data/parsers/shearwater_cloud_parser.dart Outdated
Comment thread test/features/universal_import/data/services/shearwater_dive_mapper_test.dart Outdated
Comment thread lib/features/universal_import/data/services/shearwater_dive_mapper.dart Outdated
Comment thread lib/features/universal_import/data/services/shearwater_db_reader.dart Outdated
Comment thread test/features/universal_import/data/services/shearwater_dive_mapper_test.dart Outdated
@codecov

codecov Bot commented Mar 28, 2026

Copy link
Copy Markdown

Cover LoggerService, debug log providers with filtering logic, DebugLogViewerPage, LogEntryTile, LogFilterBar, and ProviderContainer-based debug mode integration tests. Update DiveComputerService mock for logEvents stream.
Comment thread lib/features/universal_import/data/parsers/shearwater_cloud_parser.dart Outdated
Catch MissingPluginException and PlatformException separately in the parser and mapper so platform-level FFI failures cleanly fall back to metadata-only import without per-dive warning noise. Wrap DB read in try/catch to surface database errors as import warnings.
Comment thread lib/features/universal_import/data/services/shearwater_dive_mapper.dart Outdated
…pping

Only emit ceiling when the sample represents a deco stop (decoType != 0) and ndl when in no-deco mode (decoType == 0). Previously both fields could appear in samples where they had no semantic meaning.
@claude

claude Bot commented Mar 28, 2026

Copy link
Copy Markdown

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

@ericgriffin
ericgriffin merged commit 3d38625 into main Mar 28, 2026
19 checks passed
@ericgriffin
ericgriffin deleted the feature/shearwater-cloud-import branch March 28, 2026 21:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants