diff --git a/projects/parsers/loop_report.py b/projects/parsers/loop_report.py index 01c4d7ed..f1917e12 100644 --- a/projects/parsers/loop_report.py +++ b/projects/parsers/loop_report.py @@ -150,6 +150,8 @@ def __parse(self, path, file_name) -> dict: if Sections.DOSE_STORE in dict: try: dose_store = dict[Sections.DOSE_STORE] + + basal_profile = json.loads( dose_store["basalProfile"] .replace("[", "{") @@ -173,8 +175,124 @@ def __parse(self, path, file_name) -> dict: ).group(1) ) + + substr = dose_store["basalProfileApplyingOverrideHistory"] + value = "timeZone"; + start_index = substr.index(value) + value_temp = substr[start_index:] + value_temp = value_temp.replace('"', '') + last_index = 0 + if value_temp.find(",") == -1: + last_index = value_temp.index("]") + else: + last_index = value_temp.find(",") + loop_report_dict["basalProfileApplyingOverrideHistory_timeZone"] = value_temp[len( + value) + 1:last_index] + + + + value = "items"; + substr = dose_store["basalProfileApplyingOverrideHistory"] + start_index = substr.index(value) + value_temp = substr[start_index:] + last_index = value_temp.index("]]") + items_val = '{"items": [' + value_temp[len(value) + 2:last_index + 2].replace(" ", "") \ + .replace("(", "{").replace("]", "}").replace("[", "{").replace("{{", "{").replace("}}", "}") + ']}' + loop_report_dict["basalProfileApplyingOverrideHistory_items"] = json.loads(items_val)[ + "items"] + + + except: logger.debug("handled error dose store") + if Sections.CARB_STORE in dict: + try: + """ + ["timeZone": -25200, "items": [["startTime": 0.0, "value": 60.0], [ + "startTime": 23400.0, "value": 40.0], [ + "value": 66.66666666666667, "startTime": 28369.19808101654], [ + "startTime": 35569.19808101654, "value": 40.0], [ + "value": 80.0, "startTime": 50400.0]], "unit": "mg/dL"] + + ["timeZone": -25200, "unit": "mg/dL", + "items": [["startTime": 0.0, "value": 45.0], ["value": 45.0, "startTime": 16200.0], [ + "startTime": 32400.0, "value": 55.0]]] + """ + + carb_store = dict[Sections.CARB_STORE] + ###insulinSensitivityScheduleApplyingOverrideHistory### + substr = carb_store["insulinSensitivityScheduleApplyingOverrideHistory"] + value = "timeZone"; + start_index = substr.index(value) + value_temp = substr[start_index:] + value_temp = value_temp.replace('"', '') + last_index = 0 + if value_temp.find(",") == -1: + last_index = value_temp.index("]") + else: + last_index = value_temp.find(",") + + loop_report_dict["insulinSensitivityScheduleApplyingOverrideHistory_timeZone"] = value_temp[len(value) + 1:last_index] + + value = "unit"; + substr = carb_store["insulinSensitivityScheduleApplyingOverrideHistory"] + start_index = substr.index(value) + value_temp = substr[start_index:] + value_temp = value_temp.replace('"', '') + last_index = value_temp.index("]") + if last_index > 12: + last_index = value_temp.index(",") + loop_report_dict["insulinSensitivityScheduleApplyingOverrideHistory_units"] = value_temp[len(value) + 1:last_index] + + value = "items"; + start_index = substr.index(value) + value_temp = substr[start_index:] + last_index = value_temp.index("]]") + items_val = '{"items": [' + value_temp[len(value) + 2:last_index+2].replace(" ", "")\ + .replace("(", "{").replace("]", "}").replace("[", "{").replace("{{", "{").replace("}}", "}") + ']}' + loop_report_dict["insulinSensitivityScheduleApplyingOverrideHistory_items"] =json.loads(items_val)["items"] + + + ####carbRatioScheduleApplyingOverrideHistory### + substr = carb_store["carbRatioScheduleApplyingOverrideHistory"] + value = "timeZone"; + start_index = substr.index(value) + value_temp = substr[start_index:] + value_temp = value_temp.replace('"', '') + last_index = 0 + if value_temp.find(",") == -1: + last_index = value_temp.index("]") + else: + last_index = value_temp.find(",") + + loop_report_dict["carbRatioScheduleApplyingOverrideHistory_timeZone"] = value_temp[len( + value) + 1:last_index] + + value = "unit"; + substr = carb_store["carbRatioScheduleApplyingOverrideHistory"] + start_index = substr.index(value) + value_temp = substr[start_index:] + value_temp = value_temp.replace('"', '') + last_index = value_temp.index("]") + if last_index > 12: + last_index = value_temp.index(",") + loop_report_dict["carbRatioScheduleApplyingOverrideHistory_units"] = value_temp[len(value) + 1:last_index] + + value = "items"; + substr = carb_store["carbRatioScheduleApplyingOverrideHistory"] + start_index = substr.index(value) + value_temp = substr[start_index:] + last_index = value_temp.index("]]") + items_val = '{"items": [' + value_temp[len(value) + 2:last_index + 2].replace(" ", "") \ + .replace("(", "{").replace("]", "}").replace("[", "{").replace("{{", "{").replace("}}", "}") + ']}' + loop_report_dict["carbRatioScheduleApplyingOverrideHistory_items"] = json.loads(items_val)[ + "items"] + + + + except Exception as error: + + logger.debug("handled error dose store") minimed_pump_manager = None omnipod_pump_manager = None @@ -411,12 +529,30 @@ def __parse(self, path, file_name) -> dict: if temp: loop_report_dict["retrospective_correction_enabled"] = temp.group(1) - loop_report_dict["suspend_threshold"] = float( - re.search( - r"Loop.GlucoseThreshold\(value: (.+?), unit", - loop_data_manager["settings"], - ).group(1) - ) + try: + loop_report_dict["suspend_threshold"] = float( + re.search( + r"Loop.GlucoseThreshold\(value: (.+?), unit", + loop_data_manager["settings"], + ).group(1) + + ) + except Exception as e: + logger.debug("handled error LOOP_DATA_MANAGER - suspend_threshold_unit - Loop.GlucoseThreshold miss") + logger.debug(e) + + try: + + if "suspend_threshold" not in loop_report_dict or loop_report_dict["suspend_threshold"] is None or loop_report_dict["suspend_threshold"] == "": + loop_report_dict["suspend_threshold"] = float( + re.search( + r"LoopCore.GlucoseThreshold\(value: (.+?), unit", + loop_data_manager["settings"], + ).group(1) + ) + except Exception as e: + logger.debug("handled error LOOP_DATA_MANAGER - suspend_threshold_unit - LoopCore.GlucoseThreshold miss") + logger.debug(e) except Exception as e: logger.debug("handled error LOOP_DATA_MANAGER - retrospective_correction_enabled") logger.debug(e) @@ -518,6 +654,27 @@ def __parse(self, path, file_name) -> dict: logger.debug("preMeal is not in loop data") logger.debug(e) + + try: + unit = substr.index("unit") + + start_index = unit + 8 + end_index = start_index + check = "" + + while check != '"': + end_index += 1 + check = substr[end_index] + + override_units = substr[start_index : end_index] + + loop_report_dict["override_units"] = override_units + + except Exception as e: + logger.debug("override_units is not in loop data") + logger.debug(e) + + except Exception as e: logger.debug("handled error loop data manager") logger.debug(e) @@ -1338,6 +1495,75 @@ def __parse(self, path, file_name) -> dict: logger.debug("handled error CACHED_GLUCOSE_SAMPLES") logger.debug(e) + if Sections.G4_CGM_MANAGER in dict: + try: + temp_dict = dict[Sections.G4_CGM_MANAGER] + dictionary_complete = {} + if "receiver" in temp_dict: + dictionary_complete["receiver"] = temp_dict["receiver"] + + if "providesBLEHeartbeat" in temp_dict: + dictionary_complete["providesBLEHeartbeat"] = temp_dict["providesBLEHeartbeat"] + + if "latestBackfill" in temp_dict: + dictionary_complete["latestBackfill"] = temp_dict["latestBackfill"] + + latestReading_dict = temp_dict["latestReading"] + latestReading_dict = latestReading_dict.replace( + "Optional(G4ShareSpy.GlucoseG4(", + "", + ) + latestReading_dict = latestReading_dict.replace("))", "") + split_list = latestReading_dict.split(",") + dictionary = {} + latestReading = {} + for item in split_list: + item = item.replace(")", "") + keyvalue = item.split(":") + m = keyvalue[0].strip("'") + m = m.replace('"', "").strip() + dictionary[m] = keyvalue[1].strip("\"'") + + if "sequence" in dictionary: + latestReading["sequence"] = dictionary["sequence"] + + if "glucose" in dictionary: + latestReading["glucose"] = dictionary["glucose"] + + if "isDisplayOnly" in dictionary: + latestReading["isDisplayOnly"] = dictionary["isDisplayOnly"] + + if "trend" in dictionary: + latestReading["trend"] = dictionary["trend"] + + if "time" in dictionary: + latestReading["time"] = dictionary["time"] + + if "wallTime" in dictionary: + latestReading["wallTime"] = dictionary["wallTime"] + + if "systemTime" in dictionary: + latestReading["systemTime"] = dictionary["systemTime"] + + dictionary_complete["latestReading"] = latestReading + + loop_report_dict["g4_cgm_manager"] = dictionary_complete + + except Exception as e: + logger.debug("handled error G4_CGM_MANAGER") + logger.debug(e) + + if Sections.INTEGRAL_RETROSPECTIVE_CORRECTION in dict: + try: + local_list = dict[Sections.INTEGRAL_RETROSPECTIVE_CORRECTION] + loop_report_dict["integral_retrospective_correction"] = local_list + except Exception as e: + logger.debug("handled error G4_CGM_MANAGER") + logger.debug(e) + + + + return loop_report_dict def add_to_dictionary(self, dictionary, item): diff --git a/projects/parsers/loop_report_parser.py b/projects/parsers/loop_report_parser.py index 8ae79a48..bd21cd01 100644 --- a/projects/parsers/loop_report_parser.py +++ b/projects/parsers/loop_report_parser.py @@ -9,7 +9,6 @@ """ import os - class Sections: G5_CGM_MANAGER = "g5_cgm_manager" DEX_CGM_MANAGER = "dex_cgm_manager" @@ -48,6 +47,8 @@ class Sections: GET_NORMALIZED_DOSE_ENTRIES = "get_normalized_dose_entries" CACHED_DOSE_ENTRIES = "cached_dose_entries" STATUS_EXTENSION_DATA_MANAGER = "status_extension_data_manager" + INTEGRAL_RETROSPECTIVE_CORRECTION = "integral_retrospective_correction" + G4_CGM_MANAGER = "g4_cgm_manager" """ #not sure this one is used @@ -323,6 +324,18 @@ def parse_loop_report(path: str, file_name: str): all_sections["g6_cgm_manager"] = g6_cgm_manager new_line = False + elif line.startswith("## G4CGMManager"): + g4_cgm_manager = {} + current_section = "g4_cgm_manager" + all_sections["g4_cgm_manager"] = g4_cgm_manager + new_line = False + + elif line.startswith("## IntegralRetrospectiveCorrection"): + integral_retrospective_correction = {} + current_section = "integral_retrospective_correction" + all_sections["integral_retrospective_correction"] = integral_retrospective_correction + new_line = False + elif line.startswith("## ShareClientManager"): share_client_manager = {} current_section = "share_client_manager" @@ -407,6 +420,10 @@ def parse_loop_report(path: str, file_name: str): and current_section == Sections.LOOP_DATA_MANAGER ): one = "one" + elif(line.startswith("* basalProfileApplyingOverrideHistory")): + dict = all_sections[current_section] + dict["basalProfileApplyingOverrideHistory"] = line.replace("* basalProfileApplyingOverrideHistory", "") + elif current_section: new_line = False dict = all_sections[current_section] @@ -426,6 +443,9 @@ def parse_loop_report(path: str, file_name: str): return all_sections + + + def parse_key_value(all_sections, line): dict = all_sections["loop_data_manager"] key, value = _split_key_value(line, ":") diff --git a/projects/tests/parsers/files/LoopReport.md b/projects/tests/parsers/files/LoopReport.md index 727cad61..22e8f082 100644 --- a/projects/tests/parsers/files/LoopReport.md +++ b/projects/tests/parsers/files/LoopReport.md @@ -16,6 +16,34 @@ sensorInfo: Optional(CGMBLEKit.Glucose(glucoseMessage: CGMBLEKit.GlucoseSubMessa latestReading: Optional(CGMBLEKit.Glucose(glucoseMessage: CGMBLEKit.GlucoseSubMessage(timestamp: 2596408, glucoseIsDisplayOnly: false, glucose: 85, state: 6, trend: -1), timeMessage: CGMBLEKit.TransmitterTimeRxMessage(status: 0, currentTime: 2596413, sessionStartTime: 1820222), transmitterID: "00AA0A", status: CGMBLEKit.TransmitterStatus.ok, sessionStartDate: 2019-01-19 15:39:54 +0000, lastCalibration: nil, readDate: 2019-01-28 15:16:20 +0000)) transmitter: Optional(CGMBLEKit.Transmitter) providesBLEHeartbeat: true + +## G4CGMManager +shareManager: ## ShareClientManager +latestBackfill: nil + +latestReading: Optional(G4ShareSpy.GlucoseG4(sequence: 335096, glucose: 75, isDisplayOnly: false, trend: 4, time: 2019-01-14 22:21:27 +0000, wallTime: 2019-01-14 23:20:12 +0000, systemTime: 316739656)) +receiver: G4ShareSpy.Receiver +providesBLEHeartbeat: true + +## IntegralRetrospectiveCorrection + +Enabled: true +Last updated: 2019-01-14 22:22:41 +0000 +Status: effect computed successfully. +currentDiscrepancyGain: 1.0 +persistentDiscrepancyGain: 5.0 +correctionTimeConstant [min]: 90.0 +proportionalGain: 0.7714890209590539 +integralForget: 0.9459594689067654 +integralGain: 0.22851097904094608 +differentialGain: 2.0 +Integration performed over 2 most recent discrepancies having the same sign as the latest discrepancy value. Earliest-to-most-recent recentDiscrepancyValues [mg/dL]: [-2.4322013873640103, -13.183917919339311] +proportionalCorrection [mg/dL]: -10.171247927995612 +integralCorrection [mg/dL]: -3.5384198101391116 +differentialCorrection [mg/dL]: -21.503433063950602 +totalGlucoseCorrectionEffect: Optional(-35.2131 mg/dL) +integralCorrectionEffectDuration [min]: Optional(70.0) + ## DexCGMManager shareManager: Optional(## ShareClientManager latestBackfill: Optional(ShareClient.ShareGlucose(glucose: 98, trend: 5, timestamp: 2018-12-13 21:55:17 +0000)) @@ -247,6 +275,13 @@ StoredGlucoseSample(sampleUUID: AFCF551E-BA6D-45A3-9507-18ADCC1F41EB, syncIdenti * observationStart: 2019-01-28 00:20:09 +0000 * observationEnabled: true * authorizationRequired: false +* carbRatioScheduleApplyingOverrideHistory: ["unit": "g", "items": [["value": 8.0, "startTime": 0.0]], "timeZone": -25200] +* insulinSensitivityScheduleApplyingOverrideHistory: ["unit": "mg/dL", "items": [["startTime": 0.0, "value": 45.0], ["startTime": 16200.0, "value": 45.0], ["value": 55.0, "startTime": 32400.0]], "timeZone": -25200] +* basalProfileApplyingOverrideHistory ["timeZone": -25200, "items": [["startTime": 0.0, "value": 0.85], ["value": 0.85, "startTime": 10800.0], ["startTime": 43200.0, "value": 0.5]]] + + +* overrideHistory: TemporaryScheduleOverrideHistory(recentEvents: [LoopKit.(unknown context at $105ce28d0).OverrideEvent(override: LoopKit.TemporaryScheduleOverride(context: LoopKit.TemporaryScheduleOverride.Context.preset(LoopKit.TemporaryScheduleOverridePreset(symbol: "πŸ•πŸŒ›", name: "Late Dinner", settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 80.0, maxValue: 110.0)), insulinNeedsScaleFactor: Optional(1.5)), duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite)), settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 80.0, maxValue: 110.0)), insulinNeedsScaleFactor: Optional(1.5)), startDate: 2019-04-29 05:56:50 +0000, duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite), end: LoopKit.(unknown context at $105ce28d0).OverrideEvent.End.early(2019-04-29 05:56:53 +0000)), LoopKit.(unknown context at $105ce28d0).OverrideEvent(override: LoopKit.TemporaryScheduleOverride(context: LoopKit.TemporaryScheduleOverride.Context.preset(LoopKit.TemporaryScheduleOverridePreset(symbol: "πŸšΆβ€β™‚οΈ", name: "Walking", settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 130.0, maxValue: 170.0)), insulinNeedsScaleFactor: Optional(0.5)), duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite)), settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 130.0, maxValue: 170.0)), insulinNeedsScaleFactor: Optional(0.5)), startDate: 2019-04-29 05:56:55 +0000, duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite), end: LoopKit.(unknown context at $105ce28d0).OverrideEvent.End.early(2019-04-29 05:56:59 +0000)), LoopKit.(unknown context at $105ce28d0).OverrideEvent(override: LoopKit.TemporaryScheduleOverride(context: LoopKit.TemporaryScheduleOverride.Context.preset(LoopKit.TemporaryScheduleOverridePreset(symbol: "πŸšΆβ€β™‚οΈ", name: "Walking", settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 130.0, maxValue: 170.0)), insulinNeedsScaleFactor: Optional(0.5)), duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite)), settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 130.0, maxValue: 170.0)), insulinNeedsScaleFactor: Optional(0.5)), startDate: 2019-04-29 05:57:01 +0000, duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite), end: LoopKit.(unknown context at $105ce28d0).OverrideEvent.End.early(2019-04-29 05:57:02 +0000)), LoopKit.(unknown context at $105ce28d0).OverrideEvent(override: LoopKit.TemporaryScheduleOverride(context: LoopKit.TemporaryScheduleOverride.Context.preset(LoopKit.TemporaryScheduleOverridePreset(symbol: "πŸ•πŸŒ›", name: "Late Dinner", settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 80.0, maxValue: 110.0)), insulinNeedsScaleFactor: Optional(1.5)), duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite)), settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 80.0, maxValue: 110.0)), insulinNeedsScaleFactor: Optional(1.5)), startDate: 2019-04-29 06:29:10 +0000, duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite), end: LoopKit.(unknown context at $105ce28d0).OverrideEvent.End.early(2019-04-29 06:29:17 +0000)), LoopKit.(unknown context at $105ce28d0).OverrideEvent(override: LoopKit.TemporaryScheduleOverride(context: LoopKit.TemporaryScheduleOverride.Context.preset(LoopKit.TemporaryScheduleOverridePreset(symbol: "πŸ•πŸŒ›", name: "Late Dinner", settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 80.0, maxValue: 110.0)), insulinNeedsScaleFactor: Optional(1.5)), duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite)), settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 80.0, maxValue: 110.0)), insulinNeedsScaleFactor: Optional(1.5)), startDate: 2019-04-29 06:29:19 +0000, duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite), end: LoopKit.(unknown context at $105ce28d0).OverrideEvent.End.early(2019-04-29 06:30:08 +0000)), LoopKit.(unknown context at $105ce28d0).OverrideEvent(override: LoopKit.TemporaryScheduleOverride(context: LoopKit.TemporaryScheduleOverride.Context.preset(LoopKit.TemporaryScheduleOverridePreset(symbol: "πŸ•πŸŒ›", name: "Late Dinner", settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 80.0, maxValue: 110.0)), insulinNeedsScaleFactor: Optional(1.5)), duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite)), settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 80.0, maxValue: 110.0)), insulinNeedsScaleFactor: Optional(1.5)), startDate: 2019-04-29 06:30:21 +0000, duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite), end: LoopKit.(unknown context at $105ce28d0).OverrideEvent.End.early(2019-04-29 06:30:34 +0000)), LoopKit.(unknown context at $105ce28d0).OverrideEvent(override: LoopKit.TemporaryScheduleOverride(context: LoopKit.TemporaryScheduleOverride.Context.preset(LoopKit.TemporaryScheduleOverridePreset(symbol: "πŸ•πŸŒ›", name: "Late Dinner", settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 80.0, maxValue: 110.0)), insulinNeedsScaleFactor: Optional(1.5)), duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite)), settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 80.0, maxValue: 110.0)), insulinNeedsScaleFactor: Optional(1.5)), startDate: 2019-04-29 06:30:34 +0000, duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite), end: LoopKit.(unknown context at $105ce28d0).OverrideEvent.End.early(2019-04-29 07:13:52 +0000)), LoopKit.(unknown context at $105ce28d0).OverrideEvent(override: LoopKit.TemporaryScheduleOverride(context: LoopKit.TemporaryScheduleOverride.Context.preset(LoopKit.TemporaryScheduleOverridePreset(symbol: "πŸ•πŸŒ›", name: "Late Dinner", settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 80.0, maxValue: 110.0)), insulinNeedsScaleFactor: Optional(1.5)), duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite)), settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 80.0, maxValue: 110.0)), insulinNeedsScaleFactor: Optional(1.5)), startDate: 2019-04-30 06:42:39 +0000, duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite), end: LoopKit.(unknown context at $105ce28d0).OverrideEvent.End.early(2019-04-30 07:54:51 +0000)), LoopKit.(unknown context at $105ce28d0).OverrideEvent(override: LoopKit.TemporaryScheduleOverride(context: LoopKit.TemporaryScheduleOverride.Context.preset(LoopKit.TemporaryScheduleOverridePreset(symbol: "πŸ•πŸŒ›", name: "Late Dinner", settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 80.0, maxValue: 110.0)), insulinNeedsScaleFactor: Optional(1.5)), duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite)), settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 80.0, maxValue: 110.0)), insulinNeedsScaleFactor: Optional(1.5)), startDate: 2019-05-02 02:49:54 +0000, duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite), end: LoopKit.(unknown context at $105ce28d0).OverrideEvent.End.early(2019-05-02 06:12:43 +0000)), LoopKit.(unknown context at $105ce28d0).OverrideEvent(override: LoopKit.TemporaryScheduleOverride(context: LoopKit.TemporaryScheduleOverride.Context.preset(LoopKit.TemporaryScheduleOverridePreset(symbol: "πŸšΆβ€β™‚οΈ", name: "Walking", settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 130.0, maxValue: 170.0)), insulinNeedsScaleFactor: Optional(0.5)), duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite)), settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 130.0, maxValue: 170.0)), insulinNeedsScaleFactor: Optional(0.5)), startDate: 2019-05-03 01:35:33 +0000, duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite), end: LoopKit.(unknown context at $105ce28d0).OverrideEvent.End.early(2019-05-03 01:40:59 +0000)), LoopKit.(unknown context at $105ce28d0).OverrideEvent(override: LoopKit.TemporaryScheduleOverride(context: LoopKit.TemporaryScheduleOverride.Context.preset(LoopKit.TemporaryScheduleOverridePreset(symbol: "πŸšΆβ€β™‚οΈ", name: "Walking", settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 130.0, maxValue: 170.0)), insulinNeedsScaleFactor: Optional(0.5)), duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite)), settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 130.0, maxValue: 170.0)), insulinNeedsScaleFactor: Optional(0.5)), startDate: 2019-05-03 01:41:01 +0000, duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite), end: LoopKit.(unknown context at $105ce28d0).OverrideEvent.End.early(2019-05-03 02:24:36 +0000)), LoopKit.(unknown context at $105ce28d0).OverrideEvent(override: LoopKit.TemporaryScheduleOverride(context: LoopKit.TemporaryScheduleOverride.Context.preset(LoopKit.TemporaryScheduleOverridePreset(symbol: "πŸ•πŸŒ›", name: "Late Dinner", settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 80.0, maxValue: 110.0)), insulinNeedsScaleFactor: Optional(1.5)), duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite)), settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 80.0, maxValue: 110.0)), insulinNeedsScaleFactor: Optional(1.5)), startDate: 2019-05-09 21:54:17 +0000, duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite), end: LoopKit.(unknown context at $105ce28d0).OverrideEvent.End.early(2019-05-09 21:54:20 +0000)), LoopKit.(unknown context at $105ce28d0).OverrideEvent(override: LoopKit.TemporaryScheduleOverride(context: LoopKit.TemporaryScheduleOverride.Context.preset(LoopKit.TemporaryScheduleOverridePreset(symbol: "πŸ•πŸŒ›", name: "Late Dinner", settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 80.0, maxValue: 110.0)), insulinNeedsScaleFactor: Optional(1.5)), duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite)), settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 80.0, maxValue: 110.0)), insulinNeedsScaleFactor: Optional(1.5)), startDate: 2019-05-24 02:39:36 +0000, duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite), end: LoopKit.(unknown context at $105ce28d0).OverrideEvent.End.early(2019-05-24 03:23:28 +0000)), LoopKit.(unknown context at $105ce28d0).OverrideEvent(override: LoopKit.TemporaryScheduleOverride(context: LoopKit.TemporaryScheduleOverride.Context.preset(LoopKit.TemporaryScheduleOverridePreset(symbol: "πŸ•πŸŒ›", name: "Late Dinner", settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 80.0, maxValue: 110.0)), insulinNeedsScaleFactor: Optional(1.5)), duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite)), settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 80.0, maxValue: 110.0)), insulinNeedsScaleFactor: Optional(1.5)), startDate: 2019-06-04 20:53:41 +0000, duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite), end: LoopKit.(unknown context at $105ce28d0).OverrideEvent.End.early(2019-06-04 21:56:07 +0000)), LoopKit.(unknown context at $105ce28d0).OverrideEvent(override: LoopKit.TemporaryScheduleOverride(context: LoopKit.TemporaryScheduleOverride.Context.preset(LoopKit.TemporaryScheduleOverridePreset(symbol: "πŸšΆβ€β™‚οΈ", name: "Walking", settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 130.0, maxValue: 170.0)), insulinNeedsScaleFactor: Optional(0.5)), duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite)), settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 130.0, maxValue: 170.0)), insulinNeedsScaleFactor: Optional(0.5)), startDate: 2019-06-07 03:39:51 +0000, duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite), end: LoopKit.(unknown context at $105ce28d0).OverrideEvent.End.early(2019-06-07 03:40:02 +0000)), LoopKit.(unknown context at $105ce28d0).OverrideEvent(override: LoopKit.TemporaryScheduleOverride(context: LoopKit.TemporaryScheduleOverride.Context.preset(LoopKit.TemporaryScheduleOverridePreset(symbol: "πŸ•πŸŒ›", name: "Late Dinner", settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 80.0, maxValue: 110.0)), insulinNeedsScaleFactor: Optional(1.5)), duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite)), settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 80.0, maxValue: 110.0)), insulinNeedsScaleFactor: Optional(1.5)), startDate: 2019-06-12 02:35:28 +0000, duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite), end: LoopKit.(unknown context at $105ce28d0).OverrideEvent.End.early(2019-06-12 04:45:52 +0000)), LoopKit.(unknown context at $105ce28d0).OverrideEvent(override: LoopKit.TemporaryScheduleOverride(context: LoopKit.TemporaryScheduleOverride.Context.preset(LoopKit.TemporaryScheduleOverridePreset(symbol: "πŸ•πŸŒ›", name: "Late Dinner", settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 80.0, maxValue: 110.0)), insulinNeedsScaleFactor: Optional(1.5)), duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite)), settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 80.0, maxValue: 110.0)), insulinNeedsScaleFactor: Optional(1.5)), startDate: 2019-06-12 13:29:04 +0000, duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite), end: LoopKit.(unknown context at $105ce28d0).OverrideEvent.End.early(2019-06-12 15:11:28 +0000)), LoopKit.(unknown context at $105ce28d0).OverrideEvent(override: LoopKit.TemporaryScheduleOverride(context: LoopKit.TemporaryScheduleOverride.Context.preset(LoopKit.TemporaryScheduleOverridePreset(symbol: "πŸ•πŸŒ›", name: "Late Dinner", settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 100.0, maxValue: 100.0)), insulinNeedsScaleFactor: Optional(1.5)), duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite)), settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 100.0, maxValue: 100.0)), insulinNeedsScaleFactor: Optional(1.5)), startDate: 2019-06-15 04:50:34 +0000, duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite), end: LoopKit.(unknown context at $105ce28d0).OverrideEvent.End.early(2019-06-15 15:48:20 +0000)), LoopKit.(unknown context at $105ce28d0).OverrideEvent(override: LoopKit.TemporaryScheduleOverride(context: LoopKit.TemporaryScheduleOverride.Context.preset(LoopKit.TemporaryScheduleOverridePreset(symbol: "πŸ•πŸŒ›", name: "Late Dinner", settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 80.0, maxValue: 110.0)), insulinNeedsScaleFactor: Optional(1.5)), duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite)), settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 80.0, maxValue: 110.0)), insulinNeedsScaleFactor: Optional(1.5)), startDate: 2019-06-29 03:25:48 +0000, duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite), end: LoopKit.(unknown context at $105ce28d0).OverrideEvent.End.early(2019-06-29 04:39:39 +0000)), LoopKit.(unknown context at $105ce28d0).OverrideEvent(override: LoopKit.TemporaryScheduleOverride(context: LoopKit.TemporaryScheduleOverride.Context.preset(LoopKit.TemporaryScheduleOverridePreset(symbol: "πŸšΆβ€β™‚οΈ", name: "Walking", settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 130.0, maxValue: 170.0)), insulinNeedsScaleFactor: Optional(0.5)), duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite)), settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 130.0, maxValue: 170.0)), insulinNeedsScaleFactor: Optional(0.5)), startDate: 2019-06-29 17:14:45 +0000, duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite), end: LoopKit.(unknown context at $105ce28d0).OverrideEvent.End.early(2019-06-29 17:29:39 +0000)), LoopKit.(unknown context at $105ce28d0).OverrideEvent(override: LoopKit.TemporaryScheduleOverride(context: LoopKit.TemporaryScheduleOverride.Context.preset(LoopKit.TemporaryScheduleOverridePreset(symbol: "πŸ•πŸŒ›", name: "Late Dinner", settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 80.0, maxValue: 110.0)), insulinNeedsScaleFactor: Optional(1.5)), duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite)), settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 80.0, maxValue: 110.0)), insulinNeedsScaleFactor: Optional(1.5)), startDate: 2019-07-01 04:25:25 +0000, duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite), end: LoopKit.(unknown context at $105ce28d0).OverrideEvent.End.early(2019-07-01 04:37:03 +0000)), LoopKit.(unknown context at $105ce28d0).OverrideEvent(override: LoopKit.TemporaryScheduleOverride(context: LoopKit.TemporaryScheduleOverride.Context.preset(LoopKit.TemporaryScheduleOverridePreset(symbol: "πŸ•πŸŒ›", name: "Late Dinner", settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 80.0, maxValue: 110.0)), insulinNeedsScaleFactor: Optional(1.5)), duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite)), settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 80.0, maxValue: 110.0)), insulinNeedsScaleFactor: Optional(1.5)), startDate: 2019-07-05 15:23:29 +0000, duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite), end: LoopKit.(unknown context at $105ce28d0).OverrideEvent.End.early(2019-07-05 16:15:28 +0000)), LoopKit.(unknown context at $105ce28d0).OverrideEvent(override: LoopKit.TemporaryScheduleOverride(context: LoopKit.TemporaryScheduleOverride.Context.preset(LoopKit.TemporaryScheduleOverridePreset(symbol: "πŸšΆβ€β™‚οΈ", name: "Walking", settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 130.0, maxValue: 170.0)), insulinNeedsScaleFactor: Optional(0.5)), duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite)), settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 130.0, maxValue: 170.0)), insulinNeedsScaleFactor: Optional(0.5)), startDate: 2019-07-16 23:58:22 +0000, duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite), end: LoopKit.(unknown context at $105ce28d0).OverrideEvent.End.early(2019-07-17 00:52:06 +0000)), LoopKit.(unknown context at $105ce28d0).OverrideEvent(override: LoopKit.TemporaryScheduleOverride(context: LoopKit.TemporaryScheduleOverride.Context.preset(LoopKit.TemporaryScheduleOverridePreset(symbol: "πŸ•πŸŒ›", name: "Late Dinner", settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 80.0, maxValue: 110.0)), insulinNeedsScaleFactor: Optional(1.5)), duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite)), settings: LoopKit.TemporaryScheduleOverrideSettings(targetRange: Optional(LoopKit.DoubleRange(minValue: 80.0, maxValue: 110.0)), insulinNeedsScaleFactor: Optional(1.5)), startDate: 2019-07-26 02:26:12 +0000, duration: LoopKit.TemporaryScheduleOverride.Duration.indefinite), end: LoopKit.(unknown context at $105ce28d0).OverrideEvent.End.early(2019-07-26 03:47:15 +0000))]) +* carbSensitivitySchedule: ["unit": "mg/gΒ·dL", "items": [["value": 5.625, "startTime": 0.0], ["value": 5.625, "startTime": 16200.0], ["startTime": 32400.0, "value": 6.875]], "timeZone": -25200] cachedCarbEntries: [ StoredCarbEntry(sampleUUID, syncIdentifier, syncVersion, startDate, quantity, foodType, absorptionTime, createdByCurrentApp, externalID, isUploaded) @@ -264,6 +299,7 @@ deletedCarbEntries: [ * insulinModel: Optional(humalogNovologAdult(ExponentialInsulinModel(actionDuration: 21600.0, peakActivityTime: 4500.0)) * basalProfile: ["timeZone": -28800, "items": [["startTime": 0.0, "value": 0.8], ["startTime": 23400.0, "value": 0.8], ["startTime": 72000.0, "value": 0.6]]] +* basalProfileApplyingOverrideHistory ["timeZone": -25200, "items": [["startTime": 0.0, "value": 0.85], ["value": 0.85, "startTime": 10800.0], ["startTime": 43200.0, "value": 0.5]]] * insulinSensitivitySchedule: ["timeZone": -28800, "unit": "mg/dL", "items": [["startTime": 0.0, "value": 20.0], ["startTime": 9000.0, "value": 40.0], ["startTime": 82800.0, "value": 35.0]]] * areReservoirValuesValid: true * isUploadRequestPending: false diff --git a/projects/tests/parsers/test_loop_report.py b/projects/tests/parsers/test_loop_report.py index 55db049a..98082154 100644 --- a/projects/tests/parsers/test_loop_report.py +++ b/projects/tests/parsers/test_loop_report.py @@ -57,6 +57,7 @@ def test_parse_by_file(): assert loop_dict["override_range_premeal_minimum"] == 70.0 assert loop_dict["override_range_premeal_maximum"] == 80.0 + assert loop_dict["override_units"] == 'mg/dL' assert ( loop_dict["retrospective_glucose_discrepancies_summed"] @@ -111,7 +112,31 @@ def test_parse_by_file(): loop_dict["retrospective_predicted_glucose"] == get_retrospective_predicted_glucose() ) + assert ( + loop_dict["g4_cgm_manager"] == get_g4_cgm_manager() + ) + + assert ( + loop_dict["integral_retrospective_correction"] == get_integral_retrospective_correction() + ) + + assert(loop_dict["carbRatioScheduleApplyingOverrideHistory_timeZone"], -25200) + assert (loop_dict["carbRatioScheduleApplyingOverrideHistory_items"], "[{'value': 8.0, 'startTime': 0.0}]") + assert (loop_dict["carbRatioScheduleApplyingOverrideHistory_units"], 'g') + + assert (loop_dict["insulinSensitivityScheduleApplyingOverrideHistory_timeZone"], -25200) + assert (loop_dict["insulinSensitivityScheduleApplyingOverrideHistory_items"], "[{'startTime': 0.0, 'value': 45.0}, {'startTime': 16200.0, 'value': 45.0}, {'value': 55.0, 'startTime': 32400.0}]") + assert (loop_dict["insulinSensitivityScheduleApplyingOverrideHistory_units"], 'mg/dL') + + assert (loop_dict["basalProfileApplyingOverrideHistory_timeZone"], -25200) + assert (loop_dict["basalProfileApplyingOverrideHistory_items"], "[{'startTime': 0.0, 'value': 0.85}, {'value': 0.85, 'startTime': 10800.0}, {'startTime': 43200.0, 'value': 0.5}]") + + +def get_integral_retrospective_correction(): + return {'Enabled': ' true', 'Last updated': ' 2019-01-14 22:22:41 +0000', 'Status': ' effect computed successfully.', 'currentDiscrepancyGain': ' 1.0', 'persistentDiscrepancyGain': ' 5.0', 'correctionTimeConstant [min]': ' 90.0', 'proportionalGain': ' 0.7714890209590539', 'integralForget': ' 0.9459594689067654', 'integralGain': ' 0.22851097904094608', 'differentialGain': ' 2.0', 'Integration performed over 2 most recent discrepancies having the same sign as the latest discrepancy value. Earliest-to-most-recent recentDiscrepancyValues [mg/dL]': ' [-2.4322013873640103, -13.183917919339311]', 'proportionalCorrection [mg/dL]': ' -10.171247927995612', 'integralCorrection [mg/dL]': ' -3.5384198101391116', 'differentialCorrection [mg/dL]': ' -21.503433063950602', 'totalGlucoseCorrectionEffect': ' Optional(-35.2131 mg/dL)', 'integralCorrectionEffectDuration [min]': ' Optional(70.0)'} +def get_g4_cgm_manager(): + return {'receiver': ' G4ShareSpy.Receiver', 'providesBLEHeartbeat': ' true', 'latestBackfill': ' nil', 'latestReading': {'sequence': ' 335096', 'glucose': ' 75', 'isDisplayOnly': ' false', 'trend': ' 4', 'time': ' 2019-01-14 22', 'wallTime': ' 2019-01-14 23', 'systemTime': ' 316739656'}} def get_status_extension_data_manager(): return {