From 1308c39f3b817667e8e3219674ddc5aa8cc76604 Mon Sep 17 00:00:00 2001 From: rpwils Date: Sat, 8 Jun 2019 20:42:07 -0500 Subject: [PATCH 01/15] added override_units --- projects/parsers/loop_report.py | 23 +++++++++++++++++- projects/parsers/loop_report_parser.py | 14 +++++++++++ projects/tests/parsers/files/LoopReport.md | 28 ++++++++++++++++++++++ projects/tests/parsers/test_loop_report.py | 2 ++ 4 files changed, 66 insertions(+), 1 deletion(-) diff --git a/projects/parsers/loop_report.py b/projects/parsers/loop_report.py index 01c4d7ed..76311f41 100644 --- a/projects/parsers/loop_report.py +++ b/projects/parsers/loop_report.py @@ -7,7 +7,7 @@ license: BSD-2-Clause """ -from loop_report_parser import parse_loop_report, Sections +from loop_report_parser import parse_loop_report, Sections import os import re import json @@ -518,6 +518,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("preMeal is not in loop data") + logger.debug(e) + + except Exception as e: logger.debug("handled error loop data manager") logger.debug(e) diff --git a/projects/parsers/loop_report_parser.py b/projects/parsers/loop_report_parser.py index 8ae79a48..96234ffc 100644 --- a/projects/parsers/loop_report_parser.py +++ b/projects/parsers/loop_report_parser.py @@ -48,6 +48,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 = "IntegralRetrospectiveCorrection" + G4_CGM_MANAGER = "G4CGMManager" """ #not sure this one is used @@ -323,6 +325,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" diff --git a/projects/tests/parsers/files/LoopReport.md b/projects/tests/parsers/files/LoopReport.md index 727cad61..93dc3809 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)) diff --git a/projects/tests/parsers/test_loop_report.py b/projects/tests/parsers/test_loop_report.py index 55db049a..aeebb698 100644 --- a/projects/tests/parsers/test_loop_report.py +++ b/projects/tests/parsers/test_loop_report.py @@ -57,6 +57,8 @@ 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"] From a1947b813fdc15d846039f2eb45ef378c844d001 Mon Sep 17 00:00:00 2001 From: rpwils Date: Sun, 9 Jun 2019 12:45:19 -0500 Subject: [PATCH 02/15] added override_units --- projects/parsers/loop_report.py | 22 ++++++++++++++++++++-- projects/parsers/loop_report_parser.py | 4 ++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/projects/parsers/loop_report.py b/projects/parsers/loop_report.py index 76311f41..f0383c82 100644 --- a/projects/parsers/loop_report.py +++ b/projects/parsers/loop_report.py @@ -7,7 +7,7 @@ license: BSD-2-Clause """ -from loop_report_parser import parse_loop_report, Sections +from loop_report_parser import parse_loop_report, Sections import os import re import json @@ -535,7 +535,7 @@ def __parse(self, path, file_name) -> dict: loop_report_dict["override_units"] = override_units except Exception as e: - logger.debug("preMeal is not in loop data") + logger.debug("override_units is not in loop data") logger.debug(e) @@ -1359,6 +1359,24 @@ 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: + local_list = dict[Sections.G4_CGM_MANAGER] + # todo: implemement parser + + 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] + #todo: implemement parser + 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 96234ffc..291b99e7 100644 --- a/projects/parsers/loop_report_parser.py +++ b/projects/parsers/loop_report_parser.py @@ -48,8 +48,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 = "IntegralRetrospectiveCorrection" - G4_CGM_MANAGER = "G4CGMManager" + INTEGRAL_RETROSPECTIVE_CORRECTION = "integral_retrospective_correction" + G4_CGM_MANAGER = "g4_cgm_manager" """ #not sure this one is used From a73355f17461ffdaac08d655b219560768f82c3a Mon Sep 17 00:00:00 2001 From: rpwils Date: Sun, 9 Jun 2019 14:30:42 -0500 Subject: [PATCH 03/15] added g4 reading --- projects/parsers/loop_report.py | 55 +++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/projects/parsers/loop_report.py b/projects/parsers/loop_report.py index f0383c82..bfbd48f7 100644 --- a/projects/parsers/loop_report.py +++ b/projects/parsers/loop_report.py @@ -1361,8 +1361,59 @@ def __parse(self, path, file_name) -> dict: if Sections.G4_CGM_MANAGER in dict: try: - local_list = dict[Sections.G4_CGM_MANAGER] - # todo: implemement parser + + temp_dict = dict[Sections.G4_CGM_MANAGER] + dictionary_complete = {} + cgmblekit = temp_dict["latestReading"] + 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") From 233e0dbe8f0e7fe0ab16ad43ad958b2242b4b46d Mon Sep 17 00:00:00 2001 From: rpwils Date: Mon, 10 Jun 2019 08:30:00 -0500 Subject: [PATCH 04/15] added integral_retrospective_correction section --- projects/parsers/loop_report.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/projects/parsers/loop_report.py b/projects/parsers/loop_report.py index bfbd48f7..6ad6354f 100644 --- a/projects/parsers/loop_report.py +++ b/projects/parsers/loop_report.py @@ -1361,10 +1361,8 @@ def __parse(self, path, file_name) -> dict: if Sections.G4_CGM_MANAGER in dict: try: - temp_dict = dict[Sections.G4_CGM_MANAGER] dictionary_complete = {} - cgmblekit = temp_dict["latestReading"] if "receiver" in temp_dict: dictionary_complete["receiver"] = temp_dict["receiver"] @@ -1422,7 +1420,7 @@ def __parse(self, path, file_name) -> dict: if Sections.INTEGRAL_RETROSPECTIVE_CORRECTION in dict: try: local_list = dict[Sections.INTEGRAL_RETROSPECTIVE_CORRECTION] - #todo: implemement parser + loop_report_dict["integral_retrospective_correction"] = local_list except Exception as e: logger.debug("handled error G4_CGM_MANAGER") logger.debug(e) From 5b3dc9037c4b8c3286394dc98dc98cc3b2b42ee1 Mon Sep 17 00:00:00 2001 From: rpwils Date: Mon, 10 Jun 2019 08:49:24 -0500 Subject: [PATCH 05/15] added unit test for parser changes --- projects/tests/parsers/test_loop_report.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/projects/tests/parsers/test_loop_report.py b/projects/tests/parsers/test_loop_report.py index aeebb698..271c24c7 100644 --- a/projects/tests/parsers/test_loop_report.py +++ b/projects/tests/parsers/test_loop_report.py @@ -113,7 +113,19 @@ 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() + ) + +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 { From 8803cc4a4304b79214c8a0a1f511b23a4129df26 Mon Sep 17 00:00:00 2001 From: rpwils Date: Mon, 10 Jun 2019 08:50:18 -0500 Subject: [PATCH 06/15] added unit test for parser changes --- projects/tests/parsers/test_loop_report.py | 1 - 1 file changed, 1 deletion(-) diff --git a/projects/tests/parsers/test_loop_report.py b/projects/tests/parsers/test_loop_report.py index 271c24c7..09601834 100644 --- a/projects/tests/parsers/test_loop_report.py +++ b/projects/tests/parsers/test_loop_report.py @@ -59,7 +59,6 @@ def test_parse_by_file(): assert loop_dict["override_range_premeal_maximum"] == 80.0 assert loop_dict["override_units"] == 'mg/dL' - assert ( loop_dict["retrospective_glucose_discrepancies_summed"] == get_retrospective_glucose_discrepancies_summed() From 79329cfc4195310a62509a9ace16f5054c954378 Mon Sep 17 00:00:00 2001 From: rpwils Date: Tue, 30 Jul 2019 19:35:32 -0500 Subject: [PATCH 07/15] added fix for the loopcore.glucose threshold values. --- projects/parsers/loop_report.py | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/projects/parsers/loop_report.py b/projects/parsers/loop_report.py index 6ad6354f..d3c23a18 100644 --- a/projects/parsers/loop_report.py +++ b/projects/parsers/loop_report.py @@ -411,12 +411,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) From 6de24116501b21ec8da6eb0259b0a86e0c53696c Mon Sep 17 00:00:00 2001 From: rpwils Date: Fri, 2 Aug 2019 22:29:55 -0500 Subject: [PATCH 08/15] =?UTF-8?q?added=20=E2=80=9CcarbRatioScheduleApplyin?= =?UTF-8?q?gOverrideHistory=E2=80=9D,=20=E2=80=9CinsulinSensitivitySchedul?= =?UTF-8?q?eApplyingOverrideHistory=E2=80=9D,=20and=20=E2=80=9CbasalProfil?= =?UTF-8?q?eApplyingOverrideHistory=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- projects/parsers/loop_report.py | 58 ++++++++++++++++++++++ projects/parsers/loop_report_parser.py | 8 ++- projects/tests/parsers/files/LoopReport.md | 8 +++ projects/tests/parsers/test_loop_report.py | 14 ++++++ 4 files changed, 87 insertions(+), 1 deletion(-) diff --git a/projects/parsers/loop_report.py b/projects/parsers/loop_report.py index d3c23a18..46e9b2c5 100644 --- a/projects/parsers/loop_report.py +++ b/projects/parsers/loop_report.py @@ -173,6 +173,62 @@ def __parse(self, path, file_name) -> dict: ).group(1) ) + print("stop") #NEW ADD + basalProfileApplyingOverrideHistory = json.loads( + dose_store["basalProfileApplyingOverrideHistory"] + .replace("[", "{") + .replace("]", "}") + .replace("{{", "{") + .replace("}}", "}") + .replace(": {", ": [{") + .replace("}}", "}]}") + .replace('}, "timeZone"', '}], "timeZone"') + ) + loop_report_dict["basalProfileApplyingOverrideHistory_timeZone"] = basalProfileApplyingOverrideHistory["timeZone"] + loop_report_dict["basalProfileApplyingOverrideHistory_schedule"] = basalProfileApplyingOverrideHistory["items"] + + + + #{'timeZone': -25200, 'items': [{'startTime': 0.0, 'value': 0.85}, {'value': 0.85, 'startTime': 10800.0}, {'startTime': 43200.0, 'value': 0.5}]} + + except: + logger.debug("handled error dose store") + + if Sections.CARB_STORE in dict: + try: + carb_store = dict[Sections.CARB_STORE] + print("stop") #NEW ADD + basalProfileApplyingOverrideHistory = json.loads( + carb_store["insulinSensitivityScheduleApplyingOverrideHistory"] + .replace("[", "{") + .replace("]", "}") + .replace("{{", "{") + .replace("}}", "}") + .replace(": {", ": [{") + .replace("}}", "}]}") + .replace('}, "timeZone"', '}], "timeZone"') + ) + loop_report_dict["basalProfileApplyingOverrideHistory_timeZone"] = basalProfileApplyingOverrideHistory["timeZone"] + loop_report_dict["basalProfileApplyingOverrideHistory_schedule"] = basalProfileApplyingOverrideHistory["items"] + loop_report_dict["basalProfileApplyingOverrideHistory_units"] = basalProfileApplyingOverrideHistory["unit"] + + carbRatioScheduleApplyingOverrideHistory = json.loads( + carb_store["carbRatioScheduleApplyingOverrideHistory"] + .replace("[", "{") + .replace("]", "}") + .replace("{{", "{") + .replace("}}", "}") + .replace(": {", ": [{") + .replace("}}", "}]}") + .replace('}, "timeZone"', '}], "timeZone"') + ) + loop_report_dict["carbRatioScheduleApplyingOverrideHistory_timeZone"] = carbRatioScheduleApplyingOverrideHistory[ + "timeZone"] + loop_report_dict["carbRatioScheduleApplyingOverrideHistory_schedule"] = carbRatioScheduleApplyingOverrideHistory[ + "items"] + loop_report_dict["carbRatioScheduleApplyingOverrideHistory_units"] = carbRatioScheduleApplyingOverrideHistory[ + "unit"] + except: logger.debug("handled error dose store") @@ -1444,6 +1500,8 @@ def __parse(self, path, file_name) -> dict: 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 291b99e7..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" @@ -421,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] @@ -440,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 93dc3809..22e8f082 100644 --- a/projects/tests/parsers/files/LoopReport.md +++ b/projects/tests/parsers/files/LoopReport.md @@ -275,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) @@ -292,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 09601834..d40e13bb 100644 --- a/projects/tests/parsers/test_loop_report.py +++ b/projects/tests/parsers/test_loop_report.py @@ -120,6 +120,20 @@ def test_parse_by_file(): loop_dict["integral_retrospective_correction"] == get_integral_retrospective_correction() ) + assert(loop_dict["carbRatioScheduleApplyingOverrideHistory_timeZone"], -25200) + + assert (loop_dict["carbRatioScheduleApplyingOverrideHistory_schedule"], "[{'value': 8.0, 'startTime': 0.0}]") + + assert (loop_dict["carbRatioScheduleApplyingOverrideHistory_units"], 'g') + + assert (loop_dict["basalProfileApplyingOverrideHistory_timeZone"], -25200) + assert (loop_dict["basalProfileApplyingOverrideHistory_schedule"], "[{'startTime': 0.0, 'value': 45.0}, {'startTime': 16200.0, 'value': 45.0}, {'value': 55.0, 'startTime': 32400.0}]") + assert (loop_dict["basalProfileApplyingOverrideHistory_units"], 'mg/dL') + + assert (loop_dict["basalProfileApplyingOverrideHistory_timeZone"], -25200) + assert (loop_dict["basalProfileApplyingOverrideHistory_schedule"], "[{'startTime': 0.0, 'value': 45.0}, {'startTime': 16200.0, 'value': 45.0}, {'value': 55.0, 'startTime': 32400.0}]") + + 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)'} From 83aecdd3412bf6387ff3a76ca9400552f02e96c5 Mon Sep 17 00:00:00 2001 From: rpwils Date: Thu, 8 Aug 2019 07:51:28 -0500 Subject: [PATCH 09/15] fixed insulinSensitivityScheduleApplyingOverrideHistory output --- projects/parsers/loop_report.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/projects/parsers/loop_report.py b/projects/parsers/loop_report.py index 46e9b2c5..5f270466 100644 --- a/projects/parsers/loop_report.py +++ b/projects/parsers/loop_report.py @@ -198,7 +198,7 @@ def __parse(self, path, file_name) -> dict: try: carb_store = dict[Sections.CARB_STORE] print("stop") #NEW ADD - basalProfileApplyingOverrideHistory = json.loads( + insulinSensitivityScheduleApplyingOverrideHistory = json.loads( carb_store["insulinSensitivityScheduleApplyingOverrideHistory"] .replace("[", "{") .replace("]", "}") @@ -208,9 +208,9 @@ def __parse(self, path, file_name) -> dict: .replace("}}", "}]}") .replace('}, "timeZone"', '}], "timeZone"') ) - loop_report_dict["basalProfileApplyingOverrideHistory_timeZone"] = basalProfileApplyingOverrideHistory["timeZone"] - loop_report_dict["basalProfileApplyingOverrideHistory_schedule"] = basalProfileApplyingOverrideHistory["items"] - loop_report_dict["basalProfileApplyingOverrideHistory_units"] = basalProfileApplyingOverrideHistory["unit"] + loop_report_dict["insulinSensitivityScheduleApplyingOverrideHistory_timeZone"] = insulinSensitivityScheduleApplyingOverrideHistory["timeZone"] + loop_report_dict["insulinSensitivityScheduleApplyingOverrideHistory_schedule"] = insulinSensitivityScheduleApplyingOverrideHistory["items"] + loop_report_dict["insulinSensitivityScheduleApplyingOverrideHistory_units"] = insulinSensitivityScheduleApplyingOverrideHistory["unit"] carbRatioScheduleApplyingOverrideHistory = json.loads( carb_store["carbRatioScheduleApplyingOverrideHistory"] From db5f03108160998256ab650c31bdca72dc5ddbee Mon Sep 17 00:00:00 2001 From: rpwils Date: Thu, 8 Aug 2019 07:56:25 -0500 Subject: [PATCH 10/15] fixed test --- projects/tests/parsers/test_loop_report.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/projects/tests/parsers/test_loop_report.py b/projects/tests/parsers/test_loop_report.py index d40e13bb..ad31eeef 100644 --- a/projects/tests/parsers/test_loop_report.py +++ b/projects/tests/parsers/test_loop_report.py @@ -126,12 +126,14 @@ def test_parse_by_file(): assert (loop_dict["carbRatioScheduleApplyingOverrideHistory_units"], 'g') - assert (loop_dict["basalProfileApplyingOverrideHistory_timeZone"], -25200) - assert (loop_dict["basalProfileApplyingOverrideHistory_schedule"], "[{'startTime': 0.0, 'value': 45.0}, {'startTime': 16200.0, 'value': 45.0}, {'value': 55.0, 'startTime': 32400.0}]") - assert (loop_dict["basalProfileApplyingOverrideHistory_units"], 'mg/dL') + + + assert (loop_dict["insulinSensitivityScheduleApplyingOverrideHistory_timeZone"], -25200) + assert (loop_dict["insulinSensitivityScheduleApplyingOverrideHistory_schedule"], "[{'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_schedule"], "[{'startTime': 0.0, 'value': 45.0}, {'startTime': 16200.0, 'value': 45.0}, {'value': 55.0, 'startTime': 32400.0}]") + assert (loop_dict["basalProfileApplyingOverrideHistory_schedule"], "[{'startTime': 0.0, 'value': 0.85}, {'value': 0.85, 'startTime': 10800.0}, {'startTime': 43200.0, 'value': 0.5}]") def get_integral_retrospective_correction(): From 8b25a277b02d03132480a21e3f22ccfe5324ff8f Mon Sep 17 00:00:00 2001 From: rpwils Date: Sun, 11 Aug 2019 17:33:19 -0500 Subject: [PATCH 11/15] fixed parsing --- projects/parsers/loop_report.py | 155 ++++++++++++++++++++++---------- 1 file changed, 106 insertions(+), 49 deletions(-) diff --git a/projects/parsers/loop_report.py b/projects/parsers/loop_report.py index 5f270466..d6322b8c 100644 --- a/projects/parsers/loop_report.py +++ b/projects/parsers/loop_report.py @@ -173,63 +173,120 @@ def __parse(self, path, file_name) -> dict: ).group(1) ) - print("stop") #NEW ADD - basalProfileApplyingOverrideHistory = json.loads( - dose_store["basalProfileApplyingOverrideHistory"] - .replace("[", "{") - .replace("]", "}") - .replace("{{", "{") - .replace("}}", "}") - .replace(": {", ": [{") - .replace("}}", "}]}") - .replace('}, "timeZone"', '}], "timeZone"') - ) - loop_report_dict["basalProfileApplyingOverrideHistory_timeZone"] = basalProfileApplyingOverrideHistory["timeZone"] - loop_report_dict["basalProfileApplyingOverrideHistory_schedule"] = basalProfileApplyingOverrideHistory["items"] - - - - #{'timeZone': -25200, 'items': [{'startTime': 0.0, 'value': 0.85}, {'value': 0.85, 'startTime': 10800.0}, {'startTime': 43200.0, 'value': 0.5}]} + ####carbRatioScheduleApplyingOverrideHistory### + substr = carb_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 = carb_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] - print("stop") #NEW ADD - insulinSensitivityScheduleApplyingOverrideHistory = json.loads( - carb_store["insulinSensitivityScheduleApplyingOverrideHistory"] - .replace("[", "{") - .replace("]", "}") - .replace("{{", "{") - .replace("}}", "}") - .replace(": {", ": [{") - .replace("}}", "}]}") - .replace('}, "timeZone"', '}], "timeZone"') - ) - loop_report_dict["insulinSensitivityScheduleApplyingOverrideHistory_timeZone"] = insulinSensitivityScheduleApplyingOverrideHistory["timeZone"] - loop_report_dict["insulinSensitivityScheduleApplyingOverrideHistory_schedule"] = insulinSensitivityScheduleApplyingOverrideHistory["items"] - loop_report_dict["insulinSensitivityScheduleApplyingOverrideHistory_units"] = insulinSensitivityScheduleApplyingOverrideHistory["unit"] - - carbRatioScheduleApplyingOverrideHistory = json.loads( - carb_store["carbRatioScheduleApplyingOverrideHistory"] - .replace("[", "{") - .replace("]", "}") - .replace("{{", "{") - .replace("}}", "}") - .replace(": {", ": [{") - .replace("}}", "}]}") - .replace('}, "timeZone"', '}], "timeZone"') - ) - loop_report_dict["carbRatioScheduleApplyingOverrideHistory_timeZone"] = carbRatioScheduleApplyingOverrideHistory[ - "timeZone"] - loop_report_dict["carbRatioScheduleApplyingOverrideHistory_schedule"] = carbRatioScheduleApplyingOverrideHistory[ + ###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"] - loop_report_dict["carbRatioScheduleApplyingOverrideHistory_units"] = carbRatioScheduleApplyingOverrideHistory[ - "unit"] - except: + + + except Exception as error: + logger.debug("handled error dose store") minimed_pump_manager = None From a9b220ad1b87520c4171af54f1be79e8567b64ca Mon Sep 17 00:00:00 2001 From: rpwils Date: Mon, 12 Aug 2019 11:33:14 -0500 Subject: [PATCH 12/15] fixed parsing --- projects/parsers/loop_report.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/projects/parsers/loop_report.py b/projects/parsers/loop_report.py index d6322b8c..bb90fe7c 100644 --- a/projects/parsers/loop_report.py +++ b/projects/parsers/loop_report.py @@ -7,7 +7,7 @@ license: BSD-2-Clause """ -from loop_report_parser import parse_loop_report, Sections +from .loop_report_parser import parse_loop_report, Sections import os import re import json @@ -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,8 @@ def __parse(self, path, file_name) -> dict: ).group(1) ) - ####carbRatioScheduleApplyingOverrideHistory### - substr = carb_store["basalProfileApplyingOverrideHistory"] + + substr = dose_store["basalProfileApplyingOverrideHistory"] value = "timeZone"; start_index = substr.index(value) value_temp = substr[start_index:] @@ -188,8 +190,9 @@ def __parse(self, path, file_name) -> dict: value) + 1:last_index] + value = "items"; - substr = carb_store["basalProfileApplyingOverrideHistory"] + substr = dose_store["basalProfileApplyingOverrideHistory"] start_index = substr.index(value) value_temp = substr[start_index:] last_index = value_temp.index("]]") @@ -198,6 +201,8 @@ def __parse(self, path, file_name) -> dict: loop_report_dict["basalProfileApplyingOverrideHistory_items"] = json.loads(items_val)[ "items"] + print("test") + except: logger.debug("handled error dose store") if Sections.CARB_STORE in dict: From a99e083b29a46efb0f38a36f29800cbb88771ea9 Mon Sep 17 00:00:00 2001 From: rpwils Date: Mon, 12 Aug 2019 11:35:50 -0500 Subject: [PATCH 13/15] fixed parsing --- projects/parsers/loop_report.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/parsers/loop_report.py b/projects/parsers/loop_report.py index bb90fe7c..6f499c8e 100644 --- a/projects/parsers/loop_report.py +++ b/projects/parsers/loop_report.py @@ -7,7 +7,7 @@ license: BSD-2-Clause """ -from .loop_report_parser import parse_loop_report, Sections +from loop_report_parser import parse_loop_report, Sections import os import re import json From 61be9d4fa41e1e4abc041742a07a63f1d58093af Mon Sep 17 00:00:00 2001 From: rpwils Date: Fri, 16 Aug 2019 13:48:08 -0500 Subject: [PATCH 14/15] fixed parsing --- projects/parsers/loop_report.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/parsers/loop_report.py b/projects/parsers/loop_report.py index 6f499c8e..f1917e12 100644 --- a/projects/parsers/loop_report.py +++ b/projects/parsers/loop_report.py @@ -201,7 +201,7 @@ def __parse(self, path, file_name) -> dict: loop_report_dict["basalProfileApplyingOverrideHistory_items"] = json.loads(items_val)[ "items"] - print("test") + except: logger.debug("handled error dose store") From a9deeb61d5aa69317d195ec376275baf48d0deb0 Mon Sep 17 00:00:00 2001 From: rpwils Date: Fri, 16 Aug 2019 13:48:27 -0500 Subject: [PATCH 15/15] fixed parsing --- projects/tests/parsers/test_loop_report.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/projects/tests/parsers/test_loop_report.py b/projects/tests/parsers/test_loop_report.py index ad31eeef..98082154 100644 --- a/projects/tests/parsers/test_loop_report.py +++ b/projects/tests/parsers/test_loop_report.py @@ -121,19 +121,15 @@ def test_parse_by_file(): ) assert(loop_dict["carbRatioScheduleApplyingOverrideHistory_timeZone"], -25200) - - assert (loop_dict["carbRatioScheduleApplyingOverrideHistory_schedule"], "[{'value': 8.0, 'startTime': 0.0}]") - + 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_schedule"], "[{'startTime': 0.0, 'value': 45.0}, {'startTime': 16200.0, 'value': 45.0}, {'value': 55.0, 'startTime': 32400.0}]") + 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_schedule"], "[{'startTime': 0.0, 'value': 0.85}, {'value': 0.85, 'startTime': 10800.0}, {'startTime': 43200.0, 'value': 0.5}]") + 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():