8000 fix(cbio): drop the unverified mg/dL claim from the raw record by shroominic · Pull Request #168 · shroominic/OpenGlucose · GitHub
[go: up one dir, main page]

Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 17 additions & 14 deletions packages/cgm_cbio/lib/src/cbio_history_archive.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@
/// guessing when a batch is missing or out of order.
library;

/// One raw (`08`) record with derived, explicitly unverified glucose values.
/// One raw (`08`) record with an explicit, unverified engineering value.
///
/// The vendor layout is `temp LE16, dump LE16, current LE16, extra LE16`. Two
/// independent implementations of this protocol divide `current` by 10 to get
/// mmol/L and `temp` by 10 to get Celsius, and the observed live values are
/// consistent with that reading. It is still a derived value: no reference
/// measurement has confirmed it, so [isUnitVerified] stays false and callers
/// must show [rawCurrent] alongside any converted number.
/// independent implementations of this protocol divide `current` by 10, and the
/// observed live values are consistent with that reading. Nothing establishes
/// that the divisor is ten *of a particular unit*, and no reference measurement
/// exists for this sensor, so the record exposes the raw field and its scaled
/// value and no unit at all: [isUnitVerified] stays false, no accessor carries a
/// unit in its name, and callers must show [rawCurrent] alongside anything
/// scaled.
final class CbioRawGlucoseRecord {
const CbioRawGlucoseRecord({
required this.index,
Expand All @@ -39,20 +41,21 @@ final class CbioRawGlucoseRecord {
/// Raw dump field; no meaning is established.
final int rawDump;

/// Raw value field. Independent clients read this as tenths of mmol/L.
/// Raw value field. Independent clients read this as tenths of a glucose unit.
final int rawCurrent;

/// Raw trailing field; no meaning is established.
final int rawExtra;

/// Derived mmol/L, `rawCurrent / 10`. Not independently validated.
double get derivedMillimolesPerLitre => rawCurrent / 10;
/// `rawCurrent / 10`, the scale this package and the capture harness read.
///
/// This is an unverified engineering value, not mmol/L, not mg/dL, and not any
/// other unit. Rendering it with a unit suffix asserts a unit the protocol
/// does not establish, which is what the tracking issue is about. A converted
/// mg/dL accessor used to live here and was removed for that reason.
double get rawCurrentScaled => rawCurrent / 10;

/// Der 8000 ived mg/dL from the derived mmol/L. Not independently validated.
int get derivedMilligramsPerDecilitre =>
(derivedMillimolesPerLitre * 18.0182).round();

/// Always false until a reference measurement confirms the scale.
/// Always false until a reference measurement confirms the scale and unit.
bool get isUnitVerified => false;
}

Expand Down
25 changes: 23 additions & 2 deletions packages/cgm_cbio/test/cbio_history_archive_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,34 @@ void main() {
expect(first.reindex, 5000);
expect(first.rawCurrent, 78);
expect(first.rawTemperature, 320);
expect(first.derivedMillimolesPerLitre, 7.8);
expect(first.derivedMilligramsPerDecilitre, 141);
expect(first.rawCurrentScaled, 7.8);
expect(first.isUnitVerified, isFalse);
expect(archive.records.last.rawTime, 1757534220 + 180);
expect(archive.records.last.reindex, 4997);
});

test('the record carries no glucose unit in any accessor', () {
final archive = CbioHistoryArchive();
archive.ingest(_rawBatch(first: 1, count: 1, baseTime: 1000));
final record = archive.records.first;

// The scaled value is the raw field over ten and nothing more. A unit-bearing
// accessor would let a surface render a unit the protocol never established,
// which is exactly what the raw-scale issue reports.
expect(record.rawCurrentScaled, record.rawCurrent / 10);
expect(record.isUnitVerified, isFalse);
expect(
() => (record as dynamic).derivedMilligramsPerDecilitre,
throwsNoSuchMethodError,
reason: 'a derived mg/dL accessor must not come back',
);
expect(
() => (record as dynamic).derivedMillimolesPerLitre,
throwsNoSuchMethodError,
reason: 'a derived mmol/L accessor must not come back',
);
});

test('walks consecutive batches without reporting a gap', () {
final archive = CbioHistoryArchive();
expect(
Expand Down
Loading
0