Skip to content
This repository has been archived by the owner on Apr 6, 2024. It is now read-only.

Commit

Permalink
fix: split entries and treatments loop
Browse files Browse the repository at this point in the history
- this should avoid missing out on any treatments like boli
  by not interfering with the base glucose values
  • Loading branch information
burnedikt committed Sep 25, 2022
1 parent 4123689 commit 9a111a6
Show file tree
Hide file tree
Showing 5 changed files with 258 additions and 217 deletions.
30 changes: 15 additions & 15 deletions __tests__/diasend-to-nightscout-entries.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { diasendGlucoseRecordToNightscoutEntry } from "../adapter";
import { DeviceData, GlucoseRecord } from "../diasend";
import {
DeviceData,
GlucoseRecord,
PatientRecordWithDeviceData,
} from "../diasend";
import {
ManualGlucoseValueEntry,
SensorGlucoseValueEntry,
Expand All @@ -14,7 +18,7 @@ const testDevice: DeviceData = {
describe("testing conversion of diasend patient data to nightscout entries", () => {
test("continuous reading", () => {
// given a continuous glucose reading from diasend
const glucoseReading: GlucoseRecord = {
const glucoseReading: PatientRecordWithDeviceData<GlucoseRecord> = {
type: "glucose",
created_at: "2022-08-26T16:33:44",
value: 232,
Expand All @@ -25,15 +29,13 @@ describe("testing conversion of diasend patient data to nightscout entries", ()
description: "Continous reading",
},
],
// and some device data
device: testDevice,
};
// and some device data
const device = testDevice;

// when converting the reading to a nightscout entry
const nightscoutEntry = diasendGlucoseRecordToNightscoutEntry(
glucoseReading,
device
);
const nightscoutEntry =
diasendGlucoseRecordToNightscoutEntry(glucoseReading);

// then expect it to look like this
expect(nightscoutEntry).toStrictEqual<SensorGlucoseValueEntry>({
Expand All @@ -49,7 +51,7 @@ describe("testing conversion of diasend patient data to nightscout entries", ()

test("manual blood glucose measurement", () => {
// given a manual blood glucose measurement
const glucoseReading: GlucoseRecord = {
const glucoseReading: PatientRecordWithDeviceData<GlucoseRecord> = {
type: "glucose",
created_at: "2022-08-26T16:04:37",
value: 178,
Expand All @@ -60,15 +62,13 @@ describe("testing conversion of diasend patient data to nightscout entries", ()
description: "Manual",
},
],
// and some device data
device: testDevice,
};
// and some device data
const device = testDevice;

// when converting the reading to a nightscout entry
const nightscoutEntry = diasendGlucoseRecordToNightscoutEntry(
glucoseReading,
device
);
const nightscoutEntry =
diasendGlucoseRecordToNightscoutEntry(glucoseReading);

// then expect it to look like this
expect(nightscoutEntry).toStrictEqual<ManualGlucoseValueEntry>({
Expand Down
71 changes: 37 additions & 34 deletions __tests__/diasend-to-nightscout-treatments.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { identifyTreatments } from "../index";
import { diasendRecordToNightscoutTreatment } from "../adapter";
import { BolusRecord, CarbRecord, DeviceData, PatientRecord } from "../diasend";
import {
BolusRecord,
CarbRecord,
DeviceData,
PatientRecord,
PatientRecordWithDeviceData,
} from "../diasend";
import {
CarbCorrectionTreatment,
CorrectionBolusTreatment,
Expand All @@ -16,7 +22,7 @@ const testDevice: DeviceData = {
describe("testing conversion of diasend patient data to nightscout treatments", () => {
test("meal bolus + carbs", () => {
// given a meal bolus and matching carb record
const mealBolusRecord: BolusRecord = {
const mealBolusRecord: PatientRecordWithDeviceData<BolusRecord> = {
type: "insulin_bolus",
created_at: "2022-08-26T18:20:27",
unit: "U",
Expand All @@ -33,22 +39,21 @@ describe("testing conversion of diasend patient data to nightscout treatments",
description: "Bolus type ezcarb",
},
],
device: testDevice,
};
const carbRecord: CarbRecord = {
const carbRecord: PatientRecordWithDeviceData<CarbRecord> = {
type: "carb",
created_at: "2022-08-26T18:21:05",
value: "18",
unit: "g",
flags: [],
device: testDevice,
};
// and some device data
const device = testDevice;

// when converting the reading to a nightscout entry
const nightscoutTreatment = diasendRecordToNightscoutTreatment(
mealBolusRecord,
[mealBolusRecord, carbRecord],
device
[mealBolusRecord, carbRecord]
);

// then expect it to look like this
Expand All @@ -65,7 +70,7 @@ describe("testing conversion of diasend patient data to nightscout treatments",

test("meal bolus with correction", () => {
// given a correction bolus with a meal bolus and matching carbs
const bolusRecord: BolusRecord = {
const bolusRecord: PatientRecordWithDeviceData<BolusRecord> = {
type: "insulin_bolus",
created_at: "2022-08-25T11:28:55",
unit: "U",
Expand All @@ -87,22 +92,21 @@ describe("testing conversion of diasend patient data to nightscout treatments",
description: "Bolus type ezcarb",
},
],
device: testDevice,
};
const carbRecord: CarbRecord = {
const carbRecord: PatientRecordWithDeviceData<CarbRecord> = {
type: "carb",
created_at: "2022-08-25T11:29:31",
value: "11",
unit: "g",
flags: [],
device: testDevice,
};
// and some device data
const device = testDevice;

// when converting the reading to a nightscout entry
const nightscoutTreatment = diasendRecordToNightscoutTreatment(
bolusRecord,
[bolusRecord, carbRecord],
device
[bolusRecord, carbRecord]
);

// then expect it to look like this
Expand All @@ -119,7 +123,7 @@ describe("testing conversion of diasend patient data to nightscout treatments",

test("meal bolus without maching carbs", () => {
// given a meal bolus without matching carbs
const bolusRecord: BolusRecord = {
const bolusRecord: PatientRecordWithDeviceData<BolusRecord> = {
type: "insulin_bolus",
created_at: "2022-08-25T11:28:55",
unit: "U",
Expand All @@ -141,21 +145,18 @@ describe("testing conversion of diasend patient data to nightscout treatments",
description: "Bolus type ezcarb",
},
],
device: testDevice,
};
// and some device data
const device = testDevice;

// when converting the reading to a nightscout entry
expect(() =>
diasendRecordToNightscoutTreatment(bolusRecord, [bolusRecord], device)
)
expect(() => diasendRecordToNightscoutTreatment(bolusRecord, [bolusRecord]))
// then expect to get an exception
.toThrowError("Could not find matching carb record");
});

test("correction bolus", () => {
// given a correction-only bolus
const bolusRecord: BolusRecord = {
const bolusRecord: PatientRecordWithDeviceData<BolusRecord> = {
type: "insulin_bolus",
created_at: "2022-08-25T15:42:11",
unit: "U",
Expand All @@ -172,15 +173,13 @@ describe("testing conversion of diasend patient data to nightscout treatments",
description: "Bolus type ezbg",
},
],
device: testDevice,
};
// and some device data
const device = testDevice;

// when converting the reading to a nightscout entry
const nightscoutTreatment = diasendRecordToNightscoutTreatment(
bolusRecord,
[bolusRecord],
device
[bolusRecord]
);

// then expect it to look like this
Expand All @@ -195,22 +194,19 @@ describe("testing conversion of diasend patient data to nightscout treatments",

test("convert hypoglycaemia treatment", () => {
// given a hypoglycaemia treatment (which is essentially: Just carbs without any bolus)
const records: CarbRecord[] = [
const records: PatientRecordWithDeviceData<CarbRecord>[] = [
{
type: "carb",
created_at: "2022-09-18T13:50:40",
value: "5",
unit: "g",
flags: [],
device: testDevice,
},
];

// When passing through the converter
const treatment = diasendRecordToNightscoutTreatment(
records[0],
records,
testDevice
);
const treatment = diasendRecordToNightscoutTreatment(records[0], records);

// Then expect to obtain a hypo treatment
expect(treatment).toStrictEqual<CarbCorrectionTreatment>({
Expand All @@ -224,7 +220,7 @@ describe("testing conversion of diasend patient data to nightscout treatments",

test("detect hypoglycaemia treatment with confusing meal bolus", () => {
// given a hypoglycaemia treatment (which is essentially: Just carbs without any bolus)
const records: PatientRecord[] = [
const records: PatientRecordWithDeviceData<PatientRecord>[] = [
{
type: "glucose",
created_at: "2022-09-18T13:49:30",
Expand All @@ -236,13 +232,15 @@ describe("testing conversion of diasend patient data to nightscout treatments",
description: "Continous reading",
},
],
device: testDevice,
},
{
type: "carb",
created_at: "2022-09-18T13:50:40",
value: "7",
unit: "g",
flags: [],
device: testDevice,
},
{
type: "glucose",
Expand All @@ -255,6 +253,7 @@ describe("testing conversion of diasend patient data to nightscout treatments",
description: "Continous reading",
},
],
device: testDevice,
},
// want to have a bolus here as well to ensure it's not mixed up with the hypo
{
Expand All @@ -274,18 +273,20 @@ describe("testing conversion of diasend patient data to nightscout treatments",
description: "Bolus type ezcarb",
},
],
device: testDevice,
},
{
type: "carb",
created_at: "2022-09-18T14:09:11",
value: "11",
unit: "g",
flags: [],
device: testDevice,
},
];

// When passing through the converter
const { treatments } = identifyTreatments(records, testDevice);
const { treatments } = identifyTreatments(records);

// Then expect to obtain a hypo treatment and a meal bolus
expect(treatments).toHaveLength(2);
Expand All @@ -298,7 +299,7 @@ describe("testing conversion of diasend patient data to nightscout treatments",

test("throws an error if no matching carb record for bolus", () => {
// Given a bunch of records that contain a bolus for a programmed meal but miss the corresponding carbs
const records: PatientRecord[] = [
const records: PatientRecordWithDeviceData<PatientRecord>[] = [
{
type: "glucose",
created_at: "2022-09-18T13:54:29",
Expand All @@ -310,6 +311,7 @@ describe("testing conversion of diasend patient data to nightscout treatments",
description: "Continous reading",
},
],
device: testDevice,
},
{
type: "insulin_bolus",
Expand All @@ -328,11 +330,12 @@ describe("testing conversion of diasend patient data to nightscout treatments",
description: "Bolus type ezcarb",
},
],
device: testDevice,
},
];

// When attempting to identify the treatments
const { unprocessedRecords } = identifyTreatments(records, testDevice);
const { unprocessedRecords } = identifyTreatments(records);

// Then expect the bolus record to stay unprocessed
expect(unprocessedRecords).toHaveLength(1);
Expand Down
22 changes: 11 additions & 11 deletions adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
DeviceData,
GlucoseRecord,
PatientRecord,
PatientRecordWithDeviceData,
PumpSettings,
} from "./diasend";
import {
Expand All @@ -21,8 +22,7 @@ import {
} from "./nightscout";

export function diasendGlucoseRecordToNightscoutEntry(
record: GlucoseRecord,
device: DeviceData
record: PatientRecordWithDeviceData<GlucoseRecord>
): SensorGlucoseValueEntry | ManualGlucoseValueEntry {
// FIXME: The created_at datetimes from diasend do not contain any timezone information which can be problematic
const date = new Date(record.created_at);
Expand All @@ -35,7 +35,7 @@ export function diasendGlucoseRecordToNightscoutEntry(
dateString: date.toISOString(),
date: date.getTime(),
app: "diasend",
device: `${device.model} (${device.serial})`,
device: `${record.device.model} (${record.device.serial})`,
};

if (isManualBloodGlucose) {
Expand Down Expand Up @@ -88,9 +88,8 @@ function isRecordCreatedWithinTimeSpan(
}

export function diasendRecordToNightscoutTreatment(
record: BolusRecord | CarbRecord,
allRecords: (BolusRecord | CarbRecord)[],
device: DeviceData
record: PatientRecordWithDeviceData<BolusRecord | CarbRecord>,
allRecords: PatientRecordWithDeviceData<BolusRecord | CarbRecord>[]
):
| MealBolusTreatment
| CorrectionBolusTreatment
Expand All @@ -106,7 +105,7 @@ export function diasendRecordToNightscoutTreatment(
carbs: parseInt(record.value),
app: nightscoutApp,
date: new Date(record.created_at).getTime(),
device: `${device.model} (${device.serial})`,
device: `${record.device.model} (${record.device.serial})`,
};
}

Expand All @@ -117,8 +116,9 @@ export function diasendRecordToNightscoutTreatment(
const isMealBolus = "programmed_meal" in bolusRecord;
if (isMealBolus) {
const carbRecord = allRecords
.filter<CarbRecord>(
(record): record is CarbRecord => record.type === "carb"
.filter<PatientRecordWithDeviceData<CarbRecord>>(
(record): record is PatientRecordWithDeviceData<CarbRecord> =>
record.type === "carb"
)
.find(
// carbs should have been recorded within the next minute after bolus
Expand Down Expand Up @@ -146,7 +146,7 @@ export function diasendRecordToNightscoutTreatment(
notes: notesParts.length ? notesParts.join(", ") : undefined,
app: nightscoutApp,
date: new Date(bolusRecord.created_at).getTime(),
device: `${device.model} (${device.serial})`,
device: `${bolusRecord.device.model} (${bolusRecord.device.serial})`,
};
} else {
if (bolusRecord.programmed_bg_correction) {
Expand All @@ -155,7 +155,7 @@ export function diasendRecordToNightscoutTreatment(
insulin: bolusRecord.programmed_bg_correction,
app: nightscoutApp,
date: new Date(bolusRecord.created_at).getTime(),
device: `${device.model} (${device.serial})`,
device: `${bolusRecord.device.model} (${bolusRecord.device.serial})`,
};
} else {
console.warn("Bolus record cannot be handled", bolusRecord);
Expand Down
Loading

0 comments on commit 9a111a6

Please sign in to comment.