From 02148023fc900761860c6460bed6f5bd2b8f90fd Mon Sep 17 00:00:00 2001 From: Andries Smit Date: Tue, 7 Jun 2022 09:03:47 +0200 Subject: [PATCH 1/5] fix: rounding rate in SMB, AMA, Dyn ISF reason --- app/src/main/assets/OpenAPSAMA/determine-basal.js | 14 +++++++------- app/src/main/assets/OpenAPSSMB/determine-basal.js | 12 ++++++------ .../assets/OpenAPSSMBDynamicISF/determine-basal.js | 12 ++++++------ 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/app/src/main/assets/OpenAPSAMA/determine-basal.js b/app/src/main/assets/OpenAPSAMA/determine-basal.js index 4e052e8e01..e31fb90a28 100644 --- a/app/src/main/assets/OpenAPSAMA/determine-basal.js +++ b/app/src/main/assets/OpenAPSAMA/determine-basal.js @@ -324,7 +324,7 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_ rT.reason += ", but Min. Delta " + minDelta.toFixed(2) + " > Exp. Delta " + expectedDelta; } if (currenttemp.duration > 15 && (round_basal(basal, profile) === round_basal(currenttemp.rate, profile))) { - rT.reason += ", temp " + currenttemp.rate + " ~ req " + basal + "U/hr"; + rT.reason += ", temp " + currenttemp.rate + " ~ req " + round(basal, 2) + "U/hr"; return rT; } else { rT.reason += "; setting current basal of " + round(basal, 2) + " as temp"; @@ -367,10 +367,10 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_ return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); } if (typeof currenttemp.rate !== 'undefined' && (currenttemp.duration > 5 && rate >= currenttemp.rate * 0.8)) { - rT.reason += ", temp " + currenttemp.rate + " ~< req " + rate + "U/hr"; + rT.reason += ", temp " + (currenttemp.rate).toFixed(3) + " ~< req " + round(rate, 2) + "U/hr"; return rT; } else { - rT.reason += ", setting " + rate + "U/hr"; + rT.reason += ", setting " + round(rate, 2) + "U/hr"; return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); } } @@ -476,22 +476,22 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_ var insulinScheduled = currenttemp.duration * (currenttemp.rate - basal) / 60; if (insulinScheduled >= insulinReq * 2) { // if current temp would deliver >2x more than the required insulin, lower the rate - rT.reason += currenttemp.duration + "m@" + (currenttemp.rate - basal).toFixed(3) + " = " + insulinScheduled.toFixed(3) + " > 2 * req " + insulinReq + ". Setting temp basal of " + rate + "U/hr"; + rT.reason += currenttemp.duration + "m@" + (currenttemp.rate - basal).toFixed(3) + " = " + insulinScheduled.toFixed(3) + " > 2 * req " + insulinReq + ". Setting temp basal of " + round(rate, 2) + "U/hr"; return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); } if (typeof currenttemp.duration == 'undefined' || currenttemp.duration == 0) { // no temp is set - rT.reason += "no temp, setting " + rate + "U/hr"; + rT.reason += "no temp, setting " + round(rate, 2) + "U/hr"; return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); } if (currenttemp.duration > 5 && (round_basal(rate, profile) <= round_basal(currenttemp.rate, profile))) { // if required temp <~ existing temp basal - rT.reason += "temp " + currenttemp.rate + " >~ req " + rate + "U/hr"; + rT.reason += "temp " + (currenttemp.rate).toFixed(3) + " >~ req " + round(rate, 2) + "U/hr"; return rT; } // required temp > existing temp basal - rT.reason += "temp " + currenttemp.rate + "<" + rate + "U/hr"; + rT.reason += "temp " + (currenttemp.rate).toFixed(3) + " < " + round(rate, 2) + "U/hr"; return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); } diff --git a/app/src/main/assets/OpenAPSSMB/determine-basal.js b/app/src/main/assets/OpenAPSSMB/determine-basal.js index f7d952f141..f69317bfa6 100644 --- a/app/src/main/assets/OpenAPSSMB/determine-basal.js +++ b/app/src/main/assets/OpenAPSSMB/determine-basal.js @@ -955,7 +955,7 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_ return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); } if (typeof currenttemp.rate !== 'undefined' && (currenttemp.duration > 5 && rate >= currenttemp.rate * 0.8)) { - rT.reason += ", temp " + currenttemp.rate + " ~< req " + rate + "U/hr. "; + rT.reason += ", temp " + currenttemp.rate + " ~< req " + round(rate, 2) + "U/hr. "; return rT; } else { // calculate a long enough zero temp to eventually correct back up to target @@ -976,7 +976,7 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_ return tempBasalFunctions.setTempBasal(rate, durationReq, profile, rT, currenttemp); } } else { - rT.reason += ", setting " + rate + "U/hr. "; + rT.reason += ", setting " + round(rate, 2) + "U/hr. "; } return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); } @@ -1143,22 +1143,22 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_ insulinScheduled = currenttemp.duration * (currenttemp.rate - basal) / 60; if (insulinScheduled >= insulinReq * 2) { // if current temp would deliver >2x more than the required insulin, lower the rate - rT.reason += currenttemp.duration + "m@" + (currenttemp.rate).toFixed(2) + " > 2 * insulinReq. Setting temp basal of " + rate + "U/hr. "; + rT.reason += currenttemp.duration + "m@" + (currenttemp.rate).toFixed(2) + " > 2 * insulinReq. Setting temp basal of " + round(rate, 2) + "U/hr. "; return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); } if (typeof currenttemp.duration === 'undefined' || currenttemp.duration === 0) { // no temp is set - rT.reason += "no temp, setting " + rate + "U/hr. "; + rT.reason += "no temp, setting " + round(rate, 2) + "U/hr. "; return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); } if (currenttemp.duration > 5 && (round_basal(rate, profile) <= round_basal(currenttemp.rate, profile))) { // if required temp <~ existing temp basal - rT.reason += "temp " + currenttemp.rate + " >~ req " + rate + "U/hr. "; + rT.reason += "temp " + (currenttemp.rate).toFixed(2) + " >~ req " + round(rate, 2) + "U/hr. "; return rT; } // required temp > existing temp basal - rT.reason += "temp " + currenttemp.rate + "<" + rate + "U/hr. "; + rT.reason += "temp " + (currenttemp.rate).toFixed(2) + " < " + round(rate, 2) + "U/hr. "; return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); } diff --git a/app/src/main/assets/OpenAPSSMBDynamicISF/determine-basal.js b/app/src/main/assets/OpenAPSSMBDynamicISF/determine-basal.js index adaa126a8c..81b09e4730 100644 --- a/app/src/main/assets/OpenAPSSMBDynamicISF/determine-basal.js +++ b/app/src/main/assets/OpenAPSSMBDynamicISF/determine-basal.js @@ -1085,7 +1085,7 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_ return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); } if (typeof currenttemp.rate !== 'undefined' && (currenttemp.duration > 5 && rate >= currenttemp.rate * 0.8)) { - rT.reason += ", temp " + currenttemp.rate + " ~< req " + rate + "U/hr. "; + rT.reason += ", temp " + currenttemp.rate + " ~< req " + round(rate, 2) + "U/hr. "; return rT; } else { // calculate a long enough zero temp to eventually correct back up to target @@ -1106,7 +1106,7 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_ return tempBasalFunctions.setTempBasal(rate, durationReq, profile, rT, currenttemp); } } else { - rT.reason += ", setting " + rate + "U/hr. "; + rT.reason += ", setting " + round(rate, 2) + "U/hr. "; } return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); } @@ -1273,22 +1273,22 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_ insulinScheduled = currenttemp.duration * (currenttemp.rate - basal) / 60; if (insulinScheduled >= insulinReq * 2) { // if current temp would deliver >2x more than the required insulin, lower the rate - rT.reason += currenttemp.duration + "m@" + (currenttemp.rate).toFixed(2) + " > 2 * insulinReq. Setting temp basal of " + rate + "U/hr. "; + rT.reason += currenttemp.duration + "m@" + (currenttemp.rate).toFixed(2) + " > 2 * insulinReq. Setting temp basal of " + round(rate, 2) + "U/hr. "; return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); } if (typeof currenttemp.duration === 'undefined' || currenttemp.duration === 0) { // no temp is set - rT.reason += "no temp, setting " + rate + "U/hr. "; + rT.reason += "no temp, setting " + round(rate, 2) + "U/hr. "; return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); } if (currenttemp.duration > 5 && (round_basal(rate, profile) <= round_basal(currenttemp.rate, profile))) { // if required temp <~ existing temp basal - rT.reason += "temp " + currenttemp.rate + " >~ req " + rate + "U/hr. "; + rT.reason += "temp " + (currenttemp.rate).toFixed(2) + " >~ req " + round(rate, 2) + "U/hr. "; return rT; } // required temp > existing temp basal - rT.reason += "temp " + currenttemp.rate + "<" + rate + "U/hr. "; + rT.reason += "temp " + (currenttemp.rate).toFixed(2) + " < " + round(rate, 2) + "U/hr. "; return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); } From 62dec454b162ea5956171f0e4d474ed42b2c53b4 Mon Sep 17 00:00:00 2001 From: Philoul Date: Wed, 8 Jun 2022 00:14:39 +0200 Subject: [PATCH 2/5] Fix Crash L137 (I hope) --- .../plugins/general/autotune/AutotuneCore.kt | 6 +-- .../general/autotune/AutotunePlugin.kt | 53 ++++++++++--------- 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotuneCore.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotuneCore.kt index 9bfb851952..d0dc4da9be 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotuneCore.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotuneCore.kt @@ -28,9 +28,9 @@ class AutotuneCore @Inject constructor( //console.error(isf); var carbRatio = previousAutotune.ic //console.error(carbRatio); - var csf = isf / carbRatio - var dia = previousAutotune.dia - var peak = previousAutotune.peak + val csf = isf / carbRatio + val dia = previousAutotune.dia + val peak = previousAutotune.peak val csfGlucose = preppedGlucose.csfGlucoseData val isfGlucose = preppedGlucose.isfGlucoseData val basalGlucose = preppedGlucose.basalGlucoseData diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotunePlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotunePlugin.kt index 320a0d212b..0bc1d3fb05 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotunePlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotunePlugin.kt @@ -115,37 +115,39 @@ class AutotunePlugin @Inject constructor( val from = starttime + i * 24 * 60 * 60 * 1000L // get 24 hours BG values from 4 AM to 4 AM next day val to = from + 24 * 60 * 60 * 1000L log("Tune day " + (i + 1) + " of " + daysBack) - tunedProfile?.let { tunedProfile -> - autotuneIob.initializeData(from, to, tunedProfile) //autotuneIob contains BG and Treatments data from history (<=> query for ns-treatments and ns-entries) + tunedProfile?.let { it -> + autotuneIob.initializeData(from, to, it) //autotuneIob contains BG and Treatments data from history (<=> query for ns-treatments and ns-entries) autotuneFS.exportEntries(autotuneIob) //<=> ns-entries.yyyymmdd.json files exported for results compare with oref0 autotune on virtual machine autotuneFS.exportTreatments(autotuneIob) //<=> ns-treatments.yyyymmdd.json files exported for results compare with oref0 autotune on virtual machine (include treatments ,tempBasal and extended - preppedGlucose = autotunePrep.categorize(tunedProfile) //<=> autotune.yyyymmdd.json files exported for results compare with oref0 autotune on virtual machine + preppedGlucose = autotunePrep.categorize(it) //<=> autotune.yyyymmdd.json files exported for results compare with oref0 autotune on virtual machine + preppedGlucose?.let { preppedGlucose -> + autotuneFS.exportPreppedGlucose(preppedGlucose) + tunedProfile = autotuneCore.tuneAllTheThings(preppedGlucose, it, pumpProfile).also { tunedProfile -> + autotuneFS.exportTunedProfile(tunedProfile) //<=> newprofile.yyyymmdd.json files exported for results compare with oref0 autotune on virtual machine + if (i < daysBack - 1) { + log("Partial result for day ${i + 1}".trimIndent()) + result = rh.gs(R.string.autotune_partial_result, i + 1, daysBack) + rxBus.send(EventAutotuneUpdateGui()) + } + logResult = showResults(tunedProfile, pumpProfile) + if (detailedLog) + autotuneFS.exportLog(lastRun, i + 1) + } + } + ?: { + log("preppedGlucose is null on day ${i + 1}") + tunedProfile = null + } } - - if (preppedGlucose == null || tunedProfile == null) { + if (tunedProfile == null) { result = rh.gs(R.string.autotune_error) - log(result) + log("TunedProfile is null on day ${i + 1}") calculationRunning = false rxBus.send(EventAutotuneUpdateGui()) - tunedProfile = null autotuneFS.exportResult(result) autotuneFS.exportLogAndZip(lastRun) return result } - preppedGlucose?.let { preppedGlucose -> //preppedGlucose and tunedProfile should never be null here - autotuneFS.exportPreppedGlucose(preppedGlucose) - tunedProfile = autotuneCore.tuneAllTheThings(preppedGlucose, tunedProfile!!, pumpProfile) - } - // localInsulin = LocalInsulin("TunedInsulin", tunedProfile!!.peak, tunedProfile!!.dia) // Todo: Add tune Insulin option - autotuneFS.exportTunedProfile(tunedProfile!!) //<=> newprofile.yyyymmdd.json files exported for results compare with oref0 autotune on virtual machine - if (i < daysBack - 1) { - log("Partial result for day ${i + 1}".trimIndent()) - result = rh.gs(R.string.autotune_partial_result, i + 1, daysBack) - rxBus.send(EventAutotuneUpdateGui()) - } - logResult = showResults(tunedProfile, pumpProfile) - if (detailedLog) - autotuneFS.exportLog(lastRun, i + 1) } result = rh.gs(R.string.autotune_result, dateUtil.dateAndTimeString(lastRun)) if (!detailedLog) @@ -187,11 +189,12 @@ class AutotunePlugin @Inject constructor( } } } - lastRunSuccess = true - sp.putLong(R.string.key_autotune_last_run, lastRun) - rxBus.send(EventAutotuneUpdateGui()) - calculationRunning = false + tunedProfile?.let { + lastRunSuccess = true + sp.putLong(R.string.key_autotune_last_run, lastRun) + rxBus.send(EventAutotuneUpdateGui()) + calculationRunning = false return result } return "No Result" // should never occurs From 636bdb0e94a0d2ef72bb3be57061ed333e2d8b22 Mon Sep 17 00:00:00 2001 From: Philoul Date: Wed, 8 Jun 2022 07:42:00 +0200 Subject: [PATCH 3/5] Fix loadLastRun --- .../general/autotune/AutotunePlugin.kt | 51 ++++++++++--------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotunePlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotunePlugin.kt index 948904944c..c46edcbfca 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotunePlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotunePlugin.kt @@ -319,31 +319,34 @@ class AutotunePlugin @Inject constructor( fun loadLastRun() { result = "" lastRunSuccess = false - val json = JSONObject(sp.getString(R.string.key_autotune_last_run, "")) - lastNbDays = JsonHelper.safeGetString(json, "lastNbDays", "") - lastRun = JsonHelper.safeGetLong(json, "lastRun") - val pumpPeak = JsonHelper.safeGetInt(json, "pumpPeak") - val pumpDia = JsonHelper.safeGetDouble(json, "pumpDia") - var localInsulin = LocalInsulin("PumpInsulin", pumpPeak, pumpDia) - selectedProfile = JsonHelper.safeGetString(json, "pumpProfileName", "") - val profile = JsonHelper.safeGetJSONObject(json, "pumpProfile", null)?.let { pureProfileFromJson(it, dateUtil) } - ?:return - pumpProfile = ATProfile(ProfileSealed.Pure(profile), localInsulin, injector).also { it.profilename = selectedProfile } - val tunedPeak = JsonHelper.safeGetInt(json, "tunedPeak") - val tunedDia = JsonHelper.safeGetDouble(json, "tunedDia") - localInsulin = LocalInsulin("PumpInsulin", tunedPeak, tunedDia) - val tunedProfileName = JsonHelper.safeGetString(json, "tunedProfileName", "") - val tuned = JsonHelper.safeGetJSONObject(json, "tunedProfile", null)?.let { pureProfileFromJson(it, dateUtil) } - ?: return - val circadianTuned = JsonHelper.safeGetJSONObject(json, "tunedCircadianProfile", null)?.let { pureProfileFromJson(it, dateUtil) } - ?: return - tunedProfile = ATProfile(ProfileSealed.Pure(tuned), localInsulin, injector).also { atProfile -> - atProfile.profilename = tunedProfileName - atProfile.circadianProfile = ProfileSealed.Pure(circadianTuned) + try { + val json = JSONObject(sp.getString(R.string.key_autotune_last_run, "")) + lastNbDays = JsonHelper.safeGetString(json, "lastNbDays", "") + lastRun = JsonHelper.safeGetLong(json, "lastRun") + val pumpPeak = JsonHelper.safeGetInt(json, "pumpPeak") + val pumpDia = JsonHelper.safeGetDouble(json, "pumpDia") + var localInsulin = LocalInsulin("PumpInsulin", pumpPeak, pumpDia) + selectedProfile = JsonHelper.safeGetString(json, "pumpProfileName", "") + val profile = JsonHelper.safeGetJSONObject(json, "pumpProfile", null)?.let { pureProfileFromJson(it, dateUtil) } + ?: return + pumpProfile = ATProfile(ProfileSealed.Pure(profile), localInsulin, injector).also { it.profilename = selectedProfile } + val tunedPeak = JsonHelper.safeGetInt(json, "tunedPeak") + val tunedDia = JsonHelper.safeGetDouble(json, "tunedDia") + localInsulin = LocalInsulin("PumpInsulin", tunedPeak, tunedDia) + val tunedProfileName = JsonHelper.safeGetString(json, "tunedProfileName", "") + val tuned = JsonHelper.safeGetJSONObject(json, "tunedProfile", null)?.let { pureProfileFromJson(it, dateUtil) } + ?: return + val circadianTuned = JsonHelper.safeGetJSONObject(json, "tunedCircadianProfile", null)?.let { pureProfileFromJson(it, dateUtil) } + ?: return + tunedProfile = ATProfile(ProfileSealed.Pure(tuned), localInsulin, injector).also { atProfile -> + atProfile.profilename = tunedProfileName + atProfile.circadianProfile = ProfileSealed.Pure(circadianTuned) + } + result = JsonHelper.safeGetString(json, "result", "") + updateButtonVisibility = JsonHelper.safeGetInt(json, "updateButtonVisibility") + lastRunSuccess = true + } catch (e: Exception) { } - result = JsonHelper.safeGetString(json, "result", "") - updateButtonVisibility = JsonHelper.safeGetInt(json, "updateButtonVisibility") - lastRunSuccess = true } private fun log(message: String) { From a9b424b2f3b2ec1f065871aba4e5a4ea2ce59df5 Mon Sep 17 00:00:00 2001 From: Philoul Date: Wed, 8 Jun 2022 08:00:01 +0200 Subject: [PATCH 4/5] Autotune fix load result during calculation running --- .../androidaps/plugins/general/autotune/AutotuneFragment.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotuneFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotuneFragment.kt index 52aefc5560..2b467cb500 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotuneFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotuneFragment.kt @@ -257,8 +257,10 @@ class AutotuneFragment : DaggerFragment() { } binding.tuneLastrun.setOnClickListener { - autotunePlugin.loadLastRun() - updateGui() + if (!autotunePlugin.calculationRunning) { + autotunePlugin.loadLastRun() + updateGui() + } } binding.tuneLastrun.paintFlags = binding.tuneLastrun.paintFlags or Paint.UNDERLINE_TEXT_FLAG } From b0891ef2c1a2bb35836541f32e9134c87c2c6138 Mon Sep 17 00:00:00 2001 From: Philoul Date: Wed, 8 Jun 2022 09:03:44 +0200 Subject: [PATCH 5/5] Replace hardcoded text by string --- .../androidaps/plugins/general/autotune/AutotunePlugin.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotunePlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotunePlugin.kt index 69e7ccdecb..b0ec81d2d5 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotunePlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotunePlugin.kt @@ -199,7 +199,7 @@ class AutotunePlugin @Inject constructor( calculationRunning = false return result } - return "No Result" // should never occurs + return rh.gs(R.string.autotune_error) } private fun showResults(tunedProfile: ATProfile?, pumpProfile: ATProfile): String {