From 4fb8e899c213f744397761379a78dbf0b9967ebc Mon Sep 17 00:00:00 2001 From: Andy Rozman Date: Fri, 4 May 2018 15:48:46 +0100 Subject: [PATCH 001/284] Feature Request/Bug #863 - merged with dev - extended PumpType with new setting in PumpDescription - added Insight pump settings for VirtualPump --- .../interfaces/PumpDescription.java | 11 +-- .../plugins/PumpCommon/defs/DoseStepSize.java | 6 ++ .../PumpCommon/defs/PumpCapability.java | 33 +++++--- .../plugins/PumpCommon/defs/PumpType.java | 77 +++++++++++-------- .../plugins/PumpCommon/utils/PumpUtil.java | 18 +++-- .../PumpVirtual/VirtualPumpFragment.java | 1 + .../PumpVirtual/VirtualPumpPlugin.java | 2 +- app/src/main/res/values/arrays.xml | 3 +- 8 files changed, 94 insertions(+), 57 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/interfaces/PumpDescription.java b/app/src/main/java/info/nightscout/androidaps/interfaces/PumpDescription.java index f3d93b7c65..27fa818528 100644 --- a/app/src/main/java/info/nightscout/androidaps/interfaces/PumpDescription.java +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/PumpDescription.java @@ -58,24 +58,25 @@ public class PumpDescription { isTempBasalCapable = true; tempBasalStyle = PERCENT; - maxTempPercent = 200; tempPercentStep = 10; - maxTempAbsolute = 10; tempAbsoluteStep = 0.05d; - tempDurationStep = 60; tempMaxDuration = 12 * 60; - + tempDurationStep15mAllowed = false; + tempDurationStep30mAllowed = false; isSetBasalProfileCapable = true; basalStep = 0.01d; basalMinimumRate = 0.04d; + is30minBasalRatesCapable = false; isRefillingCapable = false; - storesCarbInfo = true; + supportsTDDs = false; + needsManualTDDLoad = true; + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/defs/DoseStepSize.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/defs/DoseStepSize.java index 84293a0192..69691886e2 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/defs/DoseStepSize.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/defs/DoseStepSize.java @@ -12,6 +12,12 @@ public enum DoseStepSize new DoseStepSizeEntry(1f, 10f, 0.05f), // new DoseStepSizeEntry(10f, Float.MAX_VALUE, 0.1f)), // + InsightBolus( + new DoseStepSizeEntry(0f, 2f, 0.05f), // + new DoseStepSizeEntry(2f, 5f, 0.1f), // + new DoseStepSizeEntry(5f, 10f, 0.2f), // + new DoseStepSizeEntry(10f, Float.MAX_VALUE, 0.5f)), + MedtronicVeoBasal( // new DoseStepSizeEntry(0f, 1f, 0.025f), // new DoseStepSizeEntry(1f, 10f, 0.05f), // diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/defs/PumpCapability.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/defs/PumpCapability.java index 3ee41c67ec..e38df6f4e0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/defs/PumpCapability.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/defs/PumpCapability.java @@ -6,19 +6,30 @@ package info.nightscout.androidaps.plugins.PumpCommon.defs; public enum PumpCapability { - Bolus, // - ExtendedBolus, // - TBR, // - BasalProfileSet, // - Refill, // - StoreCarbInfo, // + Bolus, // isBolusCapable + ExtendedBolus, // isExtendedBolusCapable + TempBasal, // isTempBasalCapable + BasalProfileSet, // isSetBasalProfileCapable + Refill, // isRefillingCapable + StoreCarbInfo, // storesCarbInfo + TDD, // supportsTDDs + ManualTDDLoad, // needsManualTDDLoad + BasalRate30min, // is30minBasalRatesCapable + + // grouped by pump + VirtualPumpCapabilities(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill), // + ComboCapabilities(Bolus, TempBasal, BasalProfileSet, Refill, StoreCarbInfo, TDD, ManualTDDLoad), // + DanaCapabilities(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill, StoreCarbInfo, TDD, ManualTDDLoad), // + InsightCapabilities(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill,TDD,BasalRate30min), // + + + // BasalRates (separately grouped) + BasalRate_Duration15minAllowed, // + BasalRate_Duration30minAllowed, // + BasalRate_Duration15and30minAllowed(BasalRate_Duration15minAllowed, BasalRate_Duration30minAllowed), // + BasalRate_Duration15and30minNotAllowed, // - // grouped - VirtualPump(Bolus, ExtendedBolus, TBR, BasalProfileSet, StoreCarbInfo), // - Bolus_TBR_Basal_Refill_Carb(Bolus, TBR, BasalProfileSet, Refill, StoreCarbInfo), // - Bolus_Extended_TBR_Basal_Carb(Bolus, ExtendedBolus, TBR, BasalProfileSet, StoreCarbInfo), // - Bolus_Extended_TBR_Basal_Refill_Carb(Bolus, ExtendedBolus, TBR, BasalProfileSet, Refill, StoreCarbInfo), // ; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/defs/PumpType.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/defs/PumpType.java index 0c74ef38ab..bc6d3f061e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/defs/PumpType.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/defs/PumpType.java @@ -4,7 +4,6 @@ package info.nightscout.androidaps.plugins.PumpCommon.defs; import java.util.HashMap; import java.util.Map; -import info.nightscout.androidaps.interfaces.PumpDescription; import info.nightscout.androidaps.plugins.PumpCommon.data.DoseSettings; @@ -20,38 +19,43 @@ public enum PumpType { GenericAAPS("Generic AAPS", 0.1f, null, // new DoseSettings(0.05f, 30, 8*60, 0.05f), // PumpTempBasalType.Percent, // - new DoseSettings(10,30, 24*60, 0f, 500f), // - 0.01f, 0.01f, null, PumpCapability.VirtualPump), // + new DoseSettings(10,30, 24*60, 0f, 500f), PumpCapability.BasalRate_Duration15and30minAllowed, // + 0.01f, 0.01f, null, PumpCapability.VirtualPumpCapabilities), // // Cellnovo Cellnovo1("Cellnovo", 0.05f, null, // new DoseSettings(0.05f, 30, 24*60, 1f, null), PumpTempBasalType.Percent, - new DoseSettings(5,30, 24*60, 0f, 200f), // - 0.05f, 0.05f, null, PumpCapability.VirtualPump), // + new DoseSettings(5,30, 24*60, 0f, 200f), PumpCapability.BasalRate_Duration30minAllowed, // + 0.05f, 0.05f, null, PumpCapability.VirtualPumpCapabilities), // // Accu-Chek AccuChekCombo("Accu-Chek Combo", 0.1f, null, // new DoseSettings(0.1f, 15, 12*60, 0.1f), // PumpTempBasalType.Percent, - new DoseSettings(10, 15, 12*60,0f, 500f), // - 0.01f, 0.1f, DoseStepSize.ComboBasal, PumpCapability.Bolus_TBR_Basal_Refill_Carb), // + new DoseSettings(10, 15, 12*60,0f, 500f), PumpCapability.BasalRate_Duration15and30minAllowed, // + 0.01f, 0.1f, DoseStepSize.ComboBasal, PumpCapability.ComboCapabilities), // AccuChekSpirit("Accu-Chek Spirit", 0.1f, null, // new DoseSettings(0.1f, 15, 12*60, 0.1f), // PumpTempBasalType.Percent, - new DoseSettings(10, 15, 12*60,0f, 500f), // - 0.01f, 0.1f, null, PumpCapability.VirtualPump), // + new DoseSettings(10, 15, 12*60,0f, 500f), PumpCapability.BasalRate_Duration15and30minAllowed, // + 0.01f, 0.1f, null, PumpCapability.VirtualPumpCapabilities), // + AccuChekInsight("Accu-Chek Insight", 0.05f, DoseStepSize.InsightBolus, // + new DoseSettings(0.05f, 15, 24*60, 0.05f), // + PumpTempBasalType.Percent, + new DoseSettings(10, 15, 12*60,0f, 250f), PumpCapability.BasalRate_Duration15and30minAllowed, // + 0.02f, 0.1f, null, PumpCapability.InsightCapabilities), // // Animas AnimasVibe("Animas Vibe", 0.05f, null, // AnimasBolus? new DoseSettings(0.05f, 30, 12*60, 0.05f), // PumpTempBasalType.Percent, // - new DoseSettings(10, 30, 24*60, 0f, 200f), // - 0.025f, 5f, 0f, null, PumpCapability.VirtualPump), // + new DoseSettings(10, 30, 24*60, 0f, 200f), PumpCapability.BasalRate_Duration30minAllowed, // + 0.025f, 5f, 0f, null, PumpCapability.VirtualPumpCapabilities), // AnimasPing("Animas Ping", AnimasVibe), @@ -59,32 +63,37 @@ public enum PumpType { DanaR("DanaR", 0.05f, null, // new DoseSettings(0.05f, 30, 8*60, 0.05f), // PumpTempBasalType.Percent, // - new DoseSettings(10f, 60, 24*60, 0f, 200f), // - 0.04f, 0.01f, null, PumpCapability.Bolus_Extended_TBR_Basal_Refill_Carb), + new DoseSettings(10f, 60, 24*60, 0f, 200f), PumpCapability.BasalRate_Duration15and30minNotAllowed, // + 0.04f, 0.01f, null, PumpCapability.DanaCapabilities), DanaRKorean("DanaR Korean", 0.05f, null, // new DoseSettings(0.05f, 30, 8*60, 0.05f), // PumpTempBasalType.Percent, // - new DoseSettings(10f, 60, 24*60, 0f, 200f), // - 0.1f, 0.01f, null, PumpCapability.Bolus_Extended_TBR_Basal_Refill_Carb), + new DoseSettings(10f, 60, 24*60, 0f, 200f), PumpCapability.BasalRate_Duration15and30minNotAllowed, // + 0.1f, 0.01f, null, PumpCapability.DanaCapabilities), - DanaRS("DanaRS", DanaR), - DanaRv2("DanaRv2", DanaR), + DanaRS("DanaRS", 0.05f, null, // + new DoseSettings(0.05f, 30, 8*60, 0.05f), // + PumpTempBasalType.Percent, // + new DoseSettings(10f, 60, 24*60, 0f, 200f), PumpCapability.BasalRate_Duration15and30minAllowed, // + 0.04f, 0.01f, null, PumpCapability.DanaCapabilities), + + DanaRv2("DanaRv2", DanaRS), // Insulet Insulet_Omnipod("Insulet Omnipod", 0.05f, null, // new DoseSettings(0.05f, 30, 8*60, 0.05f), // PumpTempBasalType.Absolute, // - new DoseSettings(0.05f, 30, 12*60, 0f, 5.0f), // cannot exceed max basal rate 30u/hr - 0.05f, 0.05f, null, PumpCapability.VirtualPump), + new DoseSettings(0.05f, 30, 12*60, 0f, 5.0f), PumpCapability.BasalRate_Duration30minAllowed, // cannot exceed max basal rate 30u/hr + 0.05f, 0.05f, null, PumpCapability.VirtualPumpCapabilities), // Medtronic Minimed_512_712("Medtronic 512/712", 0.05f, null, // new DoseSettings(0.05f, 30, 8*60, 0.05f), // PumpTempBasalType.Absolute, // - new DoseSettings(0.05f, 30, 24*60, 0f, 35f), // - 0.05f, 0.05f, null, PumpCapability.VirtualPump), // TODO + new DoseSettings(0.05f, 30, 24*60, 0f, 35f), PumpCapability.BasalRate_Duration30minAllowed, // + 0.05f, 0.05f, null, PumpCapability.VirtualPumpCapabilities), // TODO Minimed_515_715("Medtronic 515/715", Minimed_512_712), Minimed_522_722("Medtronic 522/722", Minimed_512_712), @@ -93,23 +102,23 @@ public enum PumpType { Minimed_553_753_Revel("Medtronic 553/753 (Revel)", 0.05f, null, // new DoseSettings(0.05f, 30, 8*60, 0.05f), // PumpTempBasalType.Absolute, // - new DoseSettings(0.05f, 30, 24*60, 0f, 35f), // - 0.025f, 0.025f, DoseStepSize.MedtronicVeoBasal, PumpCapability.VirtualPump), // + new DoseSettings(0.05f, 30, 24*60, 0f, 35f), PumpCapability.BasalRate_Duration30minAllowed, // + 0.025f, 0.025f, DoseStepSize.MedtronicVeoBasal, PumpCapability.VirtualPumpCapabilities), // Minimed_554_754_Veo("Medtronic 554/754 (Veo)", Minimed_553_753_Revel), // TODO Minimed_640G("Medtronic 640G", 0.025f, null, // new DoseSettings(0.05f, 30, 8*60, 0.05f), // PumpTempBasalType.Absolute, // - new DoseSettings(0.05f, 30, 24*60, 0f, 35f), // - 0.025f, 0.025f, DoseStepSize.MedtronicVeoBasal, PumpCapability.VirtualPump), // + new DoseSettings(0.05f, 30, 24*60, 0f, 35f), PumpCapability.BasalRate_Duration30minAllowed, // + 0.025f, 0.025f, DoseStepSize.MedtronicVeoBasal, PumpCapability.VirtualPumpCapabilities), // // Tandem TandemTSlim("Tandem t:slim", 0.01f, null, // - new DoseSettings(0.01f,15, 8*60, 0.4f) , + new DoseSettings(0.01f,15, 8*60, 0.4f), PumpTempBasalType.Percent, - new DoseSettings(1,15, 8*60, 0f, 250f), // - 0.1f, 0.001f, null, PumpCapability.VirtualPump), + new DoseSettings(1,15, 8*60, 0f, 250f), PumpCapability.BasalRate_Duration15and30minAllowed, // + 0.1f, 0.001f, null, PumpCapability.VirtualPumpCapabilities), TandemTFlex("Tandem t:flex", TandemTSlim), // TandemTSlimG4("Tandem t:slim G4", TandemTSlim), // @@ -122,6 +131,7 @@ public enum PumpType { private DoseSettings extendedBolusSettings; private PumpTempBasalType pumpTempBasalType; private DoseSettings tbrSettings; + private PumpCapability specialBasalDurations; private float baseBasalMinValue; // private Float baseBasalMaxValue; private float baseBasalStep; // @@ -156,15 +166,15 @@ public enum PumpType { PumpType(String description, float bolusSize, DoseStepSize specialBolusSize, // DoseSettings extendedBolusSettings, // - PumpTempBasalType pumpTempBasalType, DoseSettings tbrSettings, // + PumpTempBasalType pumpTempBasalType, DoseSettings tbrSettings, PumpCapability specialBasalDurations, // float baseBasalMinValue, float baseBasalStep, DoseStepSize baseBasalSpecialSteps, PumpCapability pumpCapability) { - this(description, bolusSize, specialBolusSize, extendedBolusSettings, pumpTempBasalType, tbrSettings, baseBasalMinValue, null, baseBasalStep, baseBasalSpecialSteps, pumpCapability); + this(description, bolusSize, specialBolusSize, extendedBolusSettings, pumpTempBasalType, tbrSettings, specialBasalDurations, baseBasalMinValue, null, baseBasalStep, baseBasalSpecialSteps, pumpCapability); } PumpType(String description, float bolusSize, DoseStepSize specialBolusSize, // DoseSettings extendedBolusSettings, // - PumpTempBasalType pumpTempBasalType, DoseSettings tbrSettings, // + PumpTempBasalType pumpTempBasalType, DoseSettings tbrSettings, PumpCapability specialBasalDurations, // float baseBasalMinValue, Float baseBasalMaxValue, float baseBasalStep, DoseStepSize baseBasalSpecialSteps, PumpCapability pumpCapability) { this.description = description; @@ -173,6 +183,7 @@ public enum PumpType { this.extendedBolusSettings = extendedBolusSettings; this.pumpTempBasalType = pumpTempBasalType; this.tbrSettings = tbrSettings; + this.specialBasalDurations = specialBasalDurations; this.baseBasalMinValue = baseBasalMinValue; this.baseBasalMaxValue = baseBasalMaxValue; this.baseBasalStep = baseBasalStep; @@ -299,5 +310,7 @@ public enum PumpType { } - + public PumpCapability getSpecialBasalDurations() { + return specialBasalDurations; + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/utils/PumpUtil.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/utils/PumpUtil.java index a18ff6f7bf..afecccc5e5 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/utils/PumpUtil.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/utils/PumpUtil.java @@ -11,14 +11,10 @@ import info.nightscout.androidaps.plugins.PumpCommon.defs.PumpType; public class PumpUtil { + public static void setPumpDescription(PumpDescription pumpDescription, PumpType pumpType) { - setPumpDescription(pumpDescription, pumpType, false); - } - - public static void setPumpDescription(PumpDescription pumpDescription, PumpType pumpType, boolean isVirtualPump) - { - PumpCapability pumpCapability = isVirtualPump ? PumpCapability.VirtualPump : pumpType.getPumpCapability(); + PumpCapability pumpCapability = pumpType.getPumpCapability(); pumpDescription.isBolusCapable = pumpCapability.hasCapability(PumpCapability.Bolus); pumpDescription.bolusStep = pumpType.getBolusSize(); @@ -28,7 +24,7 @@ public class PumpUtil { pumpDescription.extendedBolusDurationStep = pumpType.getExtendedBolusSettings().getDurationStep(); pumpDescription.extendedBolusMaxDuration = pumpType.getExtendedBolusSettings().getMaxDuration(); - pumpDescription.isTempBasalCapable = pumpCapability.hasCapability(PumpCapability.TBR); + pumpDescription.isTempBasalCapable = pumpCapability.hasCapability(PumpCapability.TempBasal); if (pumpType.getPumpTempBasalType()==PumpTempBasalType.Percent) { @@ -46,6 +42,8 @@ public class PumpUtil { pumpDescription.tempDurationStep = pumpType.getTbrSettings().getDurationStep(); pumpDescription.tempMaxDuration = pumpType.getTbrSettings().getMaxDuration(); + pumpDescription.tempDurationStep15mAllowed = pumpType.getSpecialBasalDurations().hasCapability(PumpCapability.BasalRate_Duration15minAllowed); + pumpDescription.tempDurationStep30mAllowed = pumpType.getSpecialBasalDurations().hasCapability(PumpCapability.BasalRate_Duration30minAllowed); pumpDescription.isSetBasalProfileCapable = pumpCapability.hasCapability(PumpCapability.BasalProfileSet); pumpDescription.basalStep = pumpType.getBaseBasalStep(); @@ -53,6 +51,12 @@ public class PumpUtil { pumpDescription.isRefillingCapable = pumpCapability.hasCapability(PumpCapability.Refill); pumpDescription.storesCarbInfo = pumpCapability.hasCapability(PumpCapability.StoreCarbInfo); + + pumpDescription.supportsTDDs = pumpCapability.hasCapability(PumpCapability.TDD); + pumpDescription.needsManualTDDLoad = pumpCapability.hasCapability(PumpCapability.ManualTDDLoad); + + pumpDescription.is30minBasalRatesCapable = pumpCapability.hasCapability(PumpCapability.BasalRate30min); + } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpFragment.java index 5a42af3811..f01fb0f379 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpFragment.java @@ -15,6 +15,7 @@ import com.squareup.otto.Subscribe; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.db.ExtendedBolus; import info.nightscout.androidaps.db.TemporaryBasal; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPlugin.java index e129786a58..95f27d1707 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPlugin.java @@ -426,7 +426,7 @@ public class VirtualPumpPlugin extends PluginBase implements PumpInterface { // reset pumpDescription.resetSettings(); - PumpUtil.setPumpDescription(pumpDescription, pumpTypeNew, true); + PumpUtil.setPumpDescription(pumpDescription, pumpTypeNew); this.pumpType = pumpTypeNew; diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 30fd658c79..9aea30d324 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -108,11 +108,12 @@ Generic AAPS - Cellnovo Accu-Chek Spirit Accu-Chek Combo + Accu-Chek Insight Animas Ping Animas Vibe + Cellnovo DanaR DanaR Korean DanaRS From 6f19ad1407ff78b30b708dccbdfa30cdcefc5c6c Mon Sep 17 00:00:00 2001 From: Andy Rozman Date: Thu, 10 May 2018 12:40:31 +0100 Subject: [PATCH 002/284] Wrong handling of specialBasalDurations (Duration15 and Duartion30 flags), and added some logging. --- .../androidaps/plugins/PumpCommon/defs/PumpType.java | 11 ++++++++++- .../plugins/PumpVirtual/VirtualPumpPlugin.java | 4 ++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/defs/PumpType.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/defs/PumpType.java index bc6d3f061e..f22c07fa8a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/defs/PumpType.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/defs/PumpType.java @@ -311,6 +311,15 @@ public enum PumpType { public PumpCapability getSpecialBasalDurations() { - return specialBasalDurations; + + if (isParentSet()) + { + return parent.getSpecialBasalDurations(); + } + else + { + return specialBasalDurations == null ? // + PumpCapability.BasalRate_Duration15and30minNotAllowed : specialBasalDurations; + } } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPlugin.java index 4a85b5d462..361f52dd87 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPlugin.java @@ -420,9 +420,13 @@ public class VirtualPumpPlugin extends PluginBase implements PumpInterface { PumpType pumpTypeNew = PumpType.getByDescription(pumptype); + log.debug("Pump in configuration: {}, PumpType object: {}", pumptype, pumpTypeNew); + if (pumpType == pumpTypeNew) return; + log.debug("New pump configuration found ({}), changing from previous ({})", pumpTypeNew, pumpType); + // reset pumpDescription.resetSettings(); From 2600a7009b363ae4f85f72434bb4a4bb19c5ef2b Mon Sep 17 00:00:00 2001 From: Andy Rozman Date: Sun, 13 May 2018 18:40:53 +0100 Subject: [PATCH 003/284] Added UTests for PumpUtil and VirualPlugin (new methods) --- .../PumpCommon/utils/PumpUtilUTest.java | 45 +++++++++++ .../PumpVirtual/VirtualPumpPluginUTest.java | 78 +++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 app/src/test/java/info/nightscout/androidaps/plugins/PumpCommon/utils/PumpUtilUTest.java create mode 100644 app/src/test/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPluginUTest.java diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/PumpCommon/utils/PumpUtilUTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/PumpCommon/utils/PumpUtilUTest.java new file mode 100644 index 0000000000..86b030b801 --- /dev/null +++ b/app/src/test/java/info/nightscout/androidaps/plugins/PumpCommon/utils/PumpUtilUTest.java @@ -0,0 +1,45 @@ +package info.nightscout.androidaps.plugins.PumpCommon.utils; + +import org.junit.Assert; +import org.junit.Test; + +import info.nightscout.androidaps.interfaces.PumpDescription; +import info.nightscout.androidaps.plugins.PumpCommon.defs.PumpCapability; +import info.nightscout.androidaps.plugins.PumpCommon.defs.PumpTempBasalType; +import info.nightscout.androidaps.plugins.PumpCommon.defs.PumpType; + +import static org.junit.Assert.*; + +/** + * Created by andy on 5/13/18. + */ +public class PumpUtilUTest { + + @Test + public void setPumpDescription() throws Exception { + + PumpDescription pumpDescription = new PumpDescription(); + + PumpUtil.setPumpDescription(pumpDescription, PumpType.AccuChekCombo); + + Assert.assertEquals(pumpDescription.bolusStep, PumpType.AccuChekCombo.getBolusSize(), 0.1d); + Assert.assertEquals(pumpDescription.basalMinimumRate, PumpType.AccuChekCombo.getBaseBasalStep(), 0.1d); + Assert.assertEquals(pumpDescription.basalStep, PumpType.AccuChekCombo.getBaseBasalStep(), 0.1d); + Assert.assertEquals(pumpDescription.extendedBolusDurationStep, PumpType.AccuChekCombo.getExtendedBolusSettings().getDurationStep(), 0.1d); + Assert.assertEquals(pumpDescription.extendedBolusMaxDuration, PumpType.AccuChekCombo.getExtendedBolusSettings().getMaxDuration(), 0.1d); + Assert.assertEquals(pumpDescription.extendedBolusStep, PumpType.AccuChekCombo.getExtendedBolusSettings().getStep(), 0.1d); + Assert.assertEquals(pumpDescription.isExtendedBolusCapable, PumpType.AccuChekCombo.getPumpCapability().hasCapability(PumpCapability.ExtendedBolus)); + Assert.assertEquals(pumpDescription.isBolusCapable, PumpType.AccuChekCombo.getPumpCapability().hasCapability(PumpCapability.Bolus)); + Assert.assertEquals(pumpDescription.isRefillingCapable, PumpType.AccuChekCombo.getPumpCapability().hasCapability(PumpCapability.Refill)); + Assert.assertEquals(pumpDescription.isSetBasalProfileCapable, PumpType.AccuChekCombo.getPumpCapability().hasCapability(PumpCapability.BasalProfileSet)); + Assert.assertEquals(pumpDescription.isTempBasalCapable, PumpType.AccuChekCombo.getPumpCapability().hasCapability(PumpCapability.TempBasal)); + Assert.assertEquals(pumpDescription.maxTempPercent, PumpType.AccuChekCombo.getTbrSettings().getMaxDose(), 0.1d); + Assert.assertEquals(pumpDescription.tempPercentStep, PumpType.AccuChekCombo.getTbrSettings().getStep(), 0.1d); + Assert.assertEquals(pumpDescription.tempBasalStyle, PumpType.AccuChekCombo.getPumpTempBasalType()== PumpTempBasalType.Percent ? PumpDescription.PERCENT : PumpDescription.ABSOLUTE); + Assert.assertEquals(pumpDescription.tempDurationStep, PumpType.AccuChekCombo.getTbrSettings().getDurationStep()); + Assert.assertEquals(pumpDescription.tempDurationStep15mAllowed, PumpType.AccuChekCombo.getSpecialBasalDurations().hasCapability(PumpCapability.BasalRate_Duration15minAllowed)); + Assert.assertEquals(pumpDescription.tempDurationStep30mAllowed, PumpType.AccuChekCombo.getSpecialBasalDurations().hasCapability(PumpCapability.BasalRate_Duration30minAllowed)); + + } + +} \ No newline at end of file diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPluginUTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPluginUTest.java new file mode 100644 index 0000000000..4e2da58e06 --- /dev/null +++ b/app/src/test/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPluginUTest.java @@ -0,0 +1,78 @@ +package info.nightscout.androidaps.plugins.PumpVirtual; + +import android.content.Context; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import info.AAPSMocker; +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.PumpCommon.defs.PumpType; +import info.nightscout.androidaps.plugins.PumpInsight.InsightPlugin; +import info.nightscout.utils.SP; +import info.nightscout.utils.ToastUtils; + +import static org.junit.Assert.*; +import static org.powermock.api.mockito.PowerMockito.when; + +/** + * Created by andy on 5/13/18. + */ +@RunWith(PowerMockRunner.class) +@PrepareForTest({MainApp.class, ConfigBuilderPlugin.class, ToastUtils.class, Context.class, SP.class}) +public class VirtualPumpPluginUTest { + + + VirtualPumpPlugin virtualPumpPlugin; + + + + @Before + public void prepareMocks() throws Exception { + AAPSMocker.mockMainApp(); + AAPSMocker.mockConfigBuilder(); + AAPSMocker.mockBus(); + AAPSMocker.mockStrings(); + AAPSMocker.mockCommandQueue(); + AAPSMocker.mockSP(); + + virtualPumpPlugin = VirtualPumpPlugin.getPlugin(); + } + + + @Test + public void getPumpType() throws Exception { + } + + @Test + public void refreshConfiguration() throws Exception { + + when(SP.getString("virtualpump_type", "Generic AAPS")).thenReturn("Accu-Chek Combo"); + + virtualPumpPlugin.refreshConfiguration(); + + Assert.assertEquals(PumpType.AccuChekCombo, virtualPumpPlugin.getPumpType()); + } + + + @Test + public void refreshConfigurationTwice() throws Exception { + + when(SP.getString("virtualpump_type", "Generic AAPS")).thenReturn("Accu-Chek Combo"); + + virtualPumpPlugin.refreshConfiguration(); + + when(SP.getString("virtualpump_type", "Generic AAPS")).thenReturn("Accu-Chek Combo"); + + virtualPumpPlugin.refreshConfiguration(); + + Assert.assertEquals(PumpType.AccuChekCombo, virtualPumpPlugin.getPumpType()); + } + +} \ No newline at end of file From edbeddf8b09e17456682bfda1436adef3eedfb0d Mon Sep 17 00:00:00 2001 From: PoweRGbg Date: Tue, 17 Jul 2018 14:43:34 +0300 Subject: [PATCH 004/284] carbsDialog done also --- .../Overview/Dialogs/NewCarbsDialog.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewCarbsDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewCarbsDialog.java index 0e7390c303..328d7bff44 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewCarbsDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewCarbsDialog.java @@ -165,6 +165,13 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, C setCancelable(true); getDialog().setCanceledOnTouchOutside(false); + + //recovering state if there is something + if (savedInstanceState != null) { + editCarbs.setValue(savedInstanceState.getDouble("editCarbs")); + editTime.setValue(savedInstanceState.getDouble("editTime")); + editDuration.setValue(savedInstanceState.getDouble("editDuration")); + } return view; } @@ -172,6 +179,19 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, C return value > 0 ? "+" + value : String.valueOf(value); } + + @Override + public void onSaveInstanceState(Bundle carbsDialogState) { + carbsDialogState.putBoolean("startActivityTTCheckbox",startActivityTTCheckbox.isChecked()); + carbsDialogState.putBoolean("startEatingSoonTTCheckbox", startEatingSoonTTCheckbox.isChecked()); + carbsDialogState.putBoolean("startHypoTTCheckbox", startHypoTTCheckbox.isChecked()); + carbsDialogState.putDouble("editTime", editTime.getValue()); + carbsDialogState.putDouble("editDuration", editDuration.getValue()); + carbsDialogState.putDouble("editCarbs", editCarbs.getValue()); + super.onSaveInstanceState(carbsDialogState); + } + + @Override public synchronized void onClick(View view) { switch (view.getId()) { @@ -229,6 +249,8 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, C } } + + @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { // Logic to disable a selected radio when pressed. When a checked radio From 141bfda099dea7d0e2eb42590eaee6e614088ac6 Mon Sep 17 00:00:00 2001 From: PoweRGbg Date: Tue, 17 Jul 2018 15:04:07 +0300 Subject: [PATCH 005/284] wizard is ready also --- .../Overview/Dialogs/WizardDialog.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/WizardDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/WizardDialog.java index 303ca10949..6bf9334244 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/WizardDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/WizardDialog.java @@ -147,6 +147,23 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com MainApp.bus().unregister(this); } + @Override + public void onSaveInstanceState(Bundle savedInstanceState) { + savedInstanceState.putBoolean("bgCheckbox", bgCheckbox.isChecked()); + savedInstanceState.putBoolean("ttCheckbox", ttCheckbox.isChecked()); + savedInstanceState.putBoolean("bolusIobCheckbox", bolusIobCheckbox.isChecked()); + savedInstanceState.putBoolean("basalIobCheckbox", basalIobCheckbox.isChecked()); + savedInstanceState.putBoolean("bgtrendCheckbox", bgtrendCheckbox.isChecked()); + savedInstanceState.putBoolean("cobCheckbox", cobCheckbox.isChecked()); + savedInstanceState.putDouble("editBg", editBg.getValue()); + savedInstanceState.putDouble("editCarbs", editCarbs.getValue()); + savedInstanceState.putDouble("editCorr", editCorr.getValue()); + savedInstanceState.putDouble("editCarbTime", editCarbTime.getValue()); + super.onSaveInstanceState(savedInstanceState); + } + + + @Subscribe public void onStatusEvent(final EventNewBG e) { Activity activity = getActivity(); @@ -259,6 +276,13 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com setCancelable(true); getDialog().setCanceledOnTouchOutside(false); + //recovering state if there is something + if (savedInstanceState != null) { + editCarbs.setValue(savedInstanceState.getDouble("editCarbs")); + editBg.setValue(savedInstanceState.getDouble("editBg")); + editCarbTime.setValue(savedInstanceState.getDouble("editCarbTime")); + editCorr.setValue(savedInstanceState.getDouble("editCorr")); + } return view; } From bf22b881232343d59eeb82b2734c13e8fc73565a Mon Sep 17 00:00:00 2001 From: PoweRGbg Date: Wed, 18 Jul 2018 13:52:15 +0300 Subject: [PATCH 006/284] some work for all the CP dialogs --- .../Dialogs/NewNSTreatmentDialog.java | 52 +++++++++++++++++-- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/Dialogs/NewNSTreatmentDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/Dialogs/NewNSTreatmentDialog.java index 46c1e3666d..666a4a27a3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/Dialogs/NewNSTreatmentDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/Dialogs/NewNSTreatmentDialog.java @@ -206,8 +206,11 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick public void onItemSelected(AdapterView parent, View view, int position, long id) { double defaultDuration; double defaultTarget = 0; - if (profile != null) { + if (profile != null && editTemptarget.getValue() == bg) { defaultTarget = bg; + } else { + //prevent changes on screen rotate + defaultTarget = editTemptarget.getValue(); } boolean erase = false; @@ -222,6 +225,8 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick } else if (MainApp.gs(R.string.hypo).equals(reasonList.get(position))) { defaultDuration = helper.determineHypoTTDuration(); defaultTarget = helper.determineHypoTT(units); + } else if (editDuration.getValue() != 0) { + defaultDuration = editDuration.getValue(); } else { defaultDuration = 0; erase = true; @@ -258,7 +263,6 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick if (sensorRadioButton.isChecked()) meterRadioButton.setChecked(true); } }; - editBg = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_bginput); editTemptarget = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_temptarget); if (profile == null) { @@ -271,9 +275,14 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick editBg.setParams(bg, 0d, 500d, 1d, new DecimalFormat("0"), false, bgTextWatcher); editTemptarget.setParams(bg, 0d, 500d, 1d, new DecimalFormat("0"), false); } + sensorRadioButton.setOnCheckedChangeListener((buttonView, isChecked) -> { Double bg1 = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData() != null ? GlucoseStatus.getGlucoseStatusData().glucose : 0d, profile.getUnits()); - editBg.setValue(bg1); + if (savedInstanceState != null && savedInstanceState.getDouble("editBg") != bg1) { + editBg.setValue(savedInstanceState.getDouble("editBg")); + } else { + editBg.setValue(bg1); + } }); Integer maxCarbs = MainApp.getConstraintChecker().getMaxCarbsAllowed().value(); @@ -378,6 +387,25 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick setCancelable(true); getDialog().setCanceledOnTouchOutside(false); + //recovering state if there is something + // only numberPickers and editTexts + if (savedInstanceState != null) { + editBg.setValue(savedInstanceState.getDouble("editBg")); + editTemptarget.setValue(savedInstanceState.getDouble("editTemptarget")); + notesEdit.setText(savedInstanceState.getString("notesEdit")); + editCarbs.setValue(savedInstanceState.getDouble("editCarbs")); + editCarbs.setValue(savedInstanceState.getDouble("editCarbs")); + editInsulin.setValue(savedInstanceState.getDouble("editInsulin")); + editDuration.setValue(savedInstanceState.getDouble("editDuration")); + editPercent.setValue(savedInstanceState.getDouble("editPercent")); + editAbsolute.setValue(savedInstanceState.getDouble("editAbsolute")); + editCarbTime.setValue(savedInstanceState.getDouble("editCarbTime")); + editPercentage.setValue(savedInstanceState.getDouble("editPercentage")); + editTimeshift.setValue(savedInstanceState.getDouble("editTimeshift")); + // time and date + dateButton.setText(savedInstanceState.getString("dateButton")); + timeButton.setText(savedInstanceState.getString("timeButton")); + } return view; } @@ -772,4 +800,22 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick } } + @Override + public void onSaveInstanceState(Bundle savedInstanceState) { + savedInstanceState.putString("notesEdit", notesEdit.getText().toString()); + savedInstanceState.putString("dateButton", dateButton.getText().toString()); + savedInstanceState.putString("timeButton", timeButton.getText().toString()); + savedInstanceState.putDouble("editBg", editBg.getValue()); + savedInstanceState.putDouble("editCarbs", editCarbs.getValue()); + savedInstanceState.putDouble("editInsulin", editInsulin.getValue()); + savedInstanceState.putDouble("editDuration", editDuration.getValue()); + savedInstanceState.putDouble("editPercent", editPercent.getValue()); + savedInstanceState.putDouble("editAbsolute", editAbsolute.getValue()); + savedInstanceState.putDouble("editCarbTime", editCarbTime.getValue()); + savedInstanceState.putDouble("editTemptarget", editTemptarget.getValue()); + savedInstanceState.putDouble("editPercentage", editPercentage.getValue()); + savedInstanceState.putDouble("editTimeshift", editTimeshift.getValue()); + super.onSaveInstanceState(savedInstanceState); + } + } From 0b9fdac9fcf2d268ebb056451963fa5be8e51259 Mon Sep 17 00:00:00 2001 From: pedroll Date: Sun, 22 Jul 2018 19:37:03 +0200 Subject: [PATCH 007/284] Spanish translation RC5 --- app/src/main/res/values-es/strings.xml | 198 +++++++++++++++++++++---- 1 file changed, 172 insertions(+), 26 deletions(-) diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 3a0eb9de6e..4c67a29273 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -11,6 +11,8 @@ DanaR dispositivo Bluetooth Usar siempre valor basal absoluto Por favor reinicia el teléfono o AndroidAPS desde ajustes de sistema, sino AndroidAPS no guardará registros (importantes para trazar y verificar que el algoritmo funcione correctamente) + Objetivo: + Meta: Inicio Verificar Unidades @@ -69,7 +71,7 @@ Objetivos OpenAPS MA Sinopsis - Perfil NS + Perfil NS Perfil simple Basal temporal Tratamientos @@ -81,6 +83,7 @@ APS General días + Duración mínima Restricciones Loop Loop @@ -191,6 +194,7 @@ Conectado Desconectado Ajustes de la bomba DanaR + Nightscout Acuerdo de licencia de usuario final No deben utilizarse para tomar decisiones médicas. NO HAY GARANTÍA PARA EL PROGRAMA, la extensión permitida por la legislación aplicable. Excepto cuando se indique de otra forma por escrito, los tenedores del copyright y / u otras partes proporcionan el programa \"tal cual\" sin garantía de ningún tipo, ya sea expresa o implícita, incluyendo, pero no limitado a, las garantías implícitas de COMERCIALIZACIÓN E IDONEIDAD PARA UN FIN DETERMINADO . TODO EL RIESGO EN CUANTO A LA CALIDAD Y RENDIMIENTO DEL PROGRAMA ES CON USTED. SI EL PROGRAMA TIENE UN ERROR, asume el coste de cualquier servicio, reparación o corrección. Entiendo y acepto @@ -217,7 +221,7 @@ Esperando resultado Números de teléfono permitidos XXXXXXXXXX +; + YYYYYYYYYY - Para entregar bolo %1$.2fU responder con código %2$s + Para entregar bolo %.2fU responder con código %s Bolo falló Bolo %.2fU entregado con éxito Bolo %.2fU enviado correctamente @@ -269,7 +273,7 @@ Configuración de visualización y monitoreo, y el análisis de los basales y ratios Comprobar que los datos de BG están disponibles en Nightscout, y que los datos de la bomba de insulina se están subiendo Empezar con bucle abierto - Ejecutar en modo de Loop abierto durante unos días, y aceptar manualmente las basales temporales. Set up and use temporary and default temporary targets (e.g. for activity or hypo treatment carbs) + Ejecutar en modo de Loop abierto durante unos días, y aceptar manualmente las basales temporales Entender el Loop abierto, incluidas las recomendaciones de basales temporales Sobre la base de esa experiencia, decidir valores de máximo basal, y ajustar la bomba y preferencias Iniciar el bucle cerrado con suspensión con baja glucosa @@ -296,8 +300,8 @@ Asistente Asistente configuración No permitidos ajustes basales remotos - Para iniciar basal %1$.2fU/h responder con código %2$s - Basal temporal %1$.2fU/h para %2$d min iniciada correctamente + Para iniciar basal %.2fU/h responder con código %s + Basal temporal %.2fU/h para %d min iniciada correctamente Fallo inicio basal temporal Para parar basal temporal responder con código %s Basal temporal cancelada @@ -330,12 +334,12 @@ Sueco Max U/h para el perfil base "Max IOB basal OpenAPs puede emitir " - Para enviar calibracion %1$.2f responder con código %2$s + Para enviar calibración %.2f responder con código %s Entregaré %.2fU Duración de acitividad de insulina - %1$.2f limitado a %2$.2f + %.2f limitado a %.2f no permitido el mando remoto - Para cancelar loop por %1$d minutos responde con código %2$s + Para cancelar loop por %d minutos responde con código %s Rellenar/Llenar Llenar/Rellenar cantidad de insulina estándar mg/dl @@ -416,13 +420,13 @@ Usa siempre delta media corto en vez de delta simple Recomendado si los datos de origen no filtrados como xDrip son inestables. Ajustes avancados - Modelo: %1$02X Protocolo: %2$02X Codigo: %3$02X + Modelo: %02X Protocolo: %02X Codigo: %02X Perfiles "Valor por defecte: 3 Esto es valor de seguridad establecido pos OpenAPS. Limita tu base al máximo de x3 de tu base máxima. No necesitas cambiar esto, pero debes tener en cuenta, que esto se esta discutiento sobre „3 x max diario; 4x actual“ pro razones de seguridad. " "Ajuste pro defecto: 4 Esto es la otra mitad de los ajustes de seguridad de OpenAPS y la otra mitad de \"3x max diario, 4x actual\". Esto significa, que tu base no puede ser mas alta que el numero que multiplica tu base. Esto es para evitar que las personas se encuentren en situaciones peligrosas por aumentar mucho la base sin entender el algoritmo del sistema. El ajuste por defecto es x4. La mayoría de las personas nunca tendra que cambiar estos ajustes, si no debe modificar otros ajustes en la terapia. " "Ajuste por defecto: 1.2\nEsto es un multilicador para autosens (y pronto autotune) para poner un 20% limite máximo a la cota de autosens ratio, la que determina cuantos ajustes autosens puede hacer a la base, a cuanto puede ajustar ISF y a cuanto puede bajar el objective de glucosa. " Ajuste pro defecto: 0.7\nEl otro lade de limitaciones de seguridad de autosens, limitando a cuanto puede bajar la base y a cuanto puede subir ISF y BG objectivos. - Ajuste por defecto: true\nEsto se usa para permitir autosens a ajustar objectivos BG ademas de ISF y bases. + Ajuste por defecto: true\nEsto se usa para permitir autosens a ajustar objectivos BG además de ISF y bases. Ajuste por defecto: 2 \nDormir bolo es iniciado después de proveder un bolo para comida, así el loop no interactuará con low temps cuando acabas de comer. El ajuste pro defecto es 2; quiere decir con el DIA de 3 h el bolo será dormido por fases por 1.5 h (3DIA/2). "Ajustes pro defecto: 3.0\nEsto es un ajuste pro defecto para la absorción de carbohidratos pro 5 minutos. Por defecto se espera 3mg/dl/5min. Esto afecta la velocidad de reducción de COB y cuanta absorción se usa para calcular el BG futuro previsto, si la glucosa diminua mas de lo previsto o aumenta mas de lo previsto. " "Atención!\nNormalment no tienes que editar los valores a continuación. Por favor PINCHA AQUI y LEE el texto y PROCURA ENTENDER antes de cambiar alguno de los valores. " @@ -431,6 +435,7 @@ Copiado al clipboard mostrar log Calibración + Calibración Mandar calibración %.1f a xDrip? xDrip+ no instalado Calibración mandada a xDrip @@ -482,6 +487,8 @@ Adulto Por favor elige edad del paciente para emplear limites de seguridad Glimp + Aparato parece no soportar optimización de bateria whitelisting! + Por favor conceda permiso %s necesita optimización de bateria whitelisting para funcionar bien Loop desactivado desactivado (%d m) @@ -510,6 +517,7 @@ Novorapid, Novolog, Humalog Fiasp INS + Insulina acción rápida prolongada activar superbolo en wizard Activar función superbolo en wizard. No lo actives hasta que hayas aprendido lo que realmente hace. PUEDE CAUSAR SOBREDOSIS DE INSULINA usandolo sin precaución! IOB @@ -569,6 +577,8 @@ UPLD BAS EXT + Bloqueo de pantalla + Bloqueo Al activar autosens recuerda editar todos carbohidratos comidos. Si no, sensibilidad será calculada incorrectamente !!! Sensitivity WeightedAverage OK @@ -588,7 +598,7 @@ Free-Peak Oref Rapid-Acting Oref Ultra-Rapid Oref - DIA de %1$f demasiado corto - usando %2$f! + DIA de %f demasiado corto - usando %f! ACTIVAR PERFIL Fecha INVALIDO @@ -682,12 +692,12 @@ Estado Actividad Ninguna conexión por %d min - %1$d%% (%2$d min restan) + %d%% (%d min restan) Apagado por error Apagado por usario Funcionando Cancelando TBR - Poniendo TBR (%1$d%% / %2$d min) + Poniendo TBR (%d%% / %d min) Emitiendo bolo (%.1f U) Actualizando "Acción no disponible en la bomba " @@ -695,11 +705,11 @@ "Uso inseguro: la bomba usa base diferente a la primera. El loop ha sido apagado. Elige primero perfil en la bomba y acualiza. " Un bolo de mismo valor ha sido dado durante el pasado minuto. Para evitar bolos dobles y asegurarse contra bugs esto no es permitido. Ahora - Leiendo historia bomba + Leyendo historia bomba " Activando perfil base " "Nivel del deposito bajo " Bateria casi agotada - La bomba muesta el error E%1$d: %2$s + La bomba muesta el error E%d: %s Bajo Vacio Historial @@ -708,7 +718,9 @@ Alerta TBR cancelada, advertencia acceptada Emisión del bolo fallada. Ningún bolo se ha emitido. Para asegurarse, por favor controle la bomba para evitar bolo doble. Para evitar bugs no se reinician bolos automaticamente. - "Solo %1$.2f U del bolo mandado de %2$.2f U ha sido emitido por causa de un error. Por favorn controla la bomba para confirmar y toma acciones apropiadas. " + "Solo %.2f U del bolo mandado de %.2f U ha sido emitido por causa de un error. Por favorn controla la bomba para confirmar y toma acciones apropiadas. " + "Fallo de emitir bolo y de controlar historical de la bomba.Por favor controla manualmente y crea un record en Careportal si el bolo ha sido emitido. " + Reestablecido conexión fallada. "No hay suficiente insulina en el deposito para emitir bolo. " "Error al emitir bolo prolongado. " Bomba no alcanzable durante [min] @@ -719,7 +731,7 @@ Actualizando estado bomba Rechazando temporal alta ya que el calculo no consideró los cambios recientes en el historial de la bomba El bolus se administró con éxito, pero no se pudo agregar la entrada al tratamiento. Esto puede suceder si se administran dos bolos pequeños del mismo tamaño en los últimos dos minutos. Verifique el historial de la bomba y las entradas de tratamiento y use Careportal para agregar entradas faltantes. Asegúrese de no agregar ninguna entrada para el mismo minuto exacto y la misma cantidad. - El historial de la bomba ha cambiado después de que se realizó el cálculo del bolo. El bolo no fue entregado. Por favor, vuelva a calcular si aún se necesita un bolo. + El historial de la bomba ha cambiado después de que se realizó el cálculo del bolo. El bolo no fue entregado. Por favor, vuelva a calcular si aún se necesita un bolo. Si se requiere la misma cantidad de bolo, espere dos minutos ya que los bolos con la misma cantidad se bloquean cuando se solicita con menos de dos minutos entre ellos por seguridad (independientemente de si se administraron o no). Leyendo perfil basal Inicio TT Hipo Ninguna acción seleccionada, nada sucederá @@ -728,10 +740,11 @@ Insulina activa IOB Desviaciones Sensibilidad + Autorelleno de lecturas perdidas de BG El Bolo solo será anotado Categoría Subcategoría - No administrar Bolo, solo anotar + No administrar Bolo, solo anotar min TT Inicio TT Actividad @@ -763,7 +776,7 @@ Conectar automáticamente cuando se abre AndroidAPS, antes de solicitar ningún comando de bomba, para reducir el retraso de la conexión Estadísticas Estado de Mantener-Activo - %1$ds expira en %2$s + %ds expira en %s Adulto resistente a la insulina Habilitar SMB durante 6 h después de Carbohidratos, incluso con 0 COB. Solo posible con fuente BG con buen filtrado de datos como G5 Habilitar SMB siempre de forma independiente a los Bolos. Solo posible con fuente BG con buen filtrado de datos como G5 @@ -791,10 +804,14 @@ Companion app parece no instalada! ¡La aplicación Companion no parece estar instalada! Permanecer siempre conectado + Usar cancelación Basal Temporal (TBR) real + Actualmente, cancelar una Basal Temporal TBR (crea una alarma de bomba) en su lugar establecer el 90% durante 1 minuto Advertencia W31: Cartucho insulina bajo Advertencia W32: Bateria baja Advertencia W33: Fecha/hora inválida Advertencia W34: Final de garantía + Advertencia W36: Basal Temporal cancelada + Warning W38: Bolo cancelado Warning W39: Adevertencia tiempo de prestamo SMB administrado por bomba Inicializando @@ -839,18 +856,18 @@ Loop cerrado desabilitado en preferencias Autosens desabilitado en preferencias SMB desabilitado en preferencias - limitando max basal rate a %1$.2f U/h debido a %2$s + limitando max basal rate a %.2f U/h debido a %s Limite de la bomba Tiene que ser un valor positivo Multiplicador basal máximo Multiplicador diario basal máximo Un Bolo entregado en los últimos 3 minutos Basal establecida correctamente - Limitando porcentaje máximo de tasa a %1$d%% debido a %2$s - "Limitando el bolo a %1$.1f U debido a %2$s " - Limitando max IOB to %1$.1f U debido a %2$s - Limitando carbs to %1$d g debido a %2$s - Limitando IOB to %1$.1f U debido a %2$s + Limitando porcentaje máximo de tasa a %d%% debido a %s + "Limitando el bolo a %.1f U debido a %s " + Limitando max IOB to %.1f U debido a %s + Limitando carbs to %d g debido a %s + Limitando IOB to %.1f U debido a %s Valor máximo en preferencias Limite estricto uso no seguro @@ -870,7 +887,7 @@ "Tiempo en el que cualquier comida se considera absorbida. Los carbohidratos restantes serán cortados. " Tiempo Mostrar el campo notas en dialogos de tratamientos - Solicitado: %1$.2fU Entregado: %2$.2fU Codigo de error: %3$d + Solicitado: %.2fU Entregado: %.2fU Codigo de error: %d Primer incremento insulina Segundo incremento insulina Tercer incremento insulina @@ -923,4 +940,133 @@ Mostrar configuración Configuración general Rumano + Botones para acceder rápidamente a las funciones comunes + Ingrese entradas de libro de registro avanzadas. + Utilizado para configurar los plugins activos + Programa de aprendizaje + Muestra los ajustes preestablecidos de alimentos definidos en Nightscout + Ajuste de insulina para Humalog y NovoRapid / NovoLog + Ajuste de insulina para Fiasp + Le permite definir el pico de actividad de la insulina y solo debe ser utilizado por usuarios avanzados + Active o desactive la implementación que desencadena el Loop. + Sincroniza sus datos con Nightscout + Estado del algoritmo en 2016 + Estado del algoritmo en 2017 + Algoritmo más reciente para usuarios avanzados + Muestra el estado actual de su Loop y botones para las acciones más comunes + Muestra una notificación ongoing con una breve descripción de lo que está haciendo su Loop + Define un perfil que está disponible fuera de línea. + Proporciona el perfil que ha definido en Nightscout + Define un perfil con solo un bloque de tiempo. + Integración de la bomba para las bombas Comcu-Chek Combo, requiere tener Ruffy instalado + Integración de bomba para bombas DANA Diabecare R + Integración de bomba para bombas domésticas DANA Diabecare R + Integración de bomba para bombas DANA Diabecare R con firmware actualizado + Pump integration for DANA Diabecare RS pumps + Integración de la bomba para las bombas Accu-Chek Insight requiere la instalación de SightRemote + Integración de bomba para personas que realizan múltiples inyecciones diarias (MDI) para su terapia de diabetes + Integración de bomba para bombas que aún no tienen ningún controlador (Open Loop) + " 179/5000 La sensibilidad se calcula de la misma manera que Oref0, pero puede especificar un lapso de tiempo para el pasado. La absorción mínima de carbohidratos se calcula a partir del tiempo máximo de absorción de carbohidratos en las preferencias." + La sensibilidad se calcula a partir de datos de 24 horas en el pasado y los carbohidratos (si no se absorben) se cortan después del tiempo especificado en las preferencias. + La sensibilidad se calcula a partir de datos de 8 h en el pasado y los carbohidratos (si no se absorben) se cortan después del tiempo especificado en las preferencias. El complemento también calcula UAM. + La sensibilidad se calcula como un promedio ponderado de las desviaciones. Las desviaciones más nuevas tienen un mayor peso. La absorción mínima de carbohidratos se calcula a partir del tiempo máximo de absorción de carbohidratos de las preferencias. Este algoritmo es el más rápido en los siguientes cambios de sensibilidad. + Recibe los valores de BG de la aplicación parcheada Dexcom G5. + Recibe los valores de BG de Glimp. + Recibe los valores de BG del 600SeriesAndroidUploader + Descarga los datos de BG de Nightscout + Recibe los valores de BG de xDrip. + Guarda todos los tratamientos que se hicieron + Monitorice y controle AndroidAPS con su reloj WearOS. + Muestra información sobre tu Loop en tu cara de reloj xDrip. + Control remoto de AndroidAPS utilizando comandos de SMS. + Perfil NS + ¿Qué bomba te gustaría usar con AndroidAPS? + ¿Qué complemento debería usarse para el tratamiento? + ¿Qué perfil debería usar AndroidAPS? + ¿Qué algoritmo de APS debería hacer ajustes en la terapia? + Estos son algunos complementos generales que pueden serle útiles. + ¿Qué restricciones se aplican? + Use esto para activar la integración de Loop de AndroidAPS. + ¿De dónde debería obtener AndroidAPS sus datos? + Polski + ¡Debes leer la wiki y subir a maxIOB para que las SMB funcionen bien! Un buen comienzo es maxIOB = mealbolus promedio + 3 x máximo diario basal + Eliminar tratamientos en el futuro + ¿Qué tipo de insulina estás usando? + ¿Qué algoritmo de sensibilidad se debe usar? + Sensibilidad Oref1 + Mantener la pantalla encendida + Evite que Android apague la pantalla. Consumirá mucha energía cuando no esté enchufado a una toma de corriente. + Configuración de carga de Poctech + Valor basal reemplazado por el valor máximo soportado + No administrar solo anotar + Autorelleno de valores BG omitidos. + Siguiente + Anterior + "Asistente de configuración " + TERMINAR + Elige tu idioma + idioma + Irish + Habilitar NSClient + Bienvenido al asistente de configuración. Lo guiará a través del proceso de configuración + Configuración de la bomba + Leer estado + Los cambios deben hacerse en NS + Omitir asistente de configuración + Presione el botón a continuación para permitir que AndroidAPS sugiera / realice cambios basales + Presione el botón de abajo para habilitar Objetivos. Mire en la pestaña Objetivos, después de terminar este asistente, para que AndroidAPS sea completamente funcional. + Activar objetivos + Configurar el plugin APS + Configurar el plugin de sensibilidad + El plugin de sensibilidad se usa para la detección de sensibilidad y el cálculo de COB. Para más información, visite: + NSClient maneja la conexión a Nightscout. Puede omitir esta parte ahora, pero no podrá pasar objetivos hasta que la configure. + Recuerde: los nuevos perfiles de insulina requieren DIA al menos 5 h. DIA 5-6h en el nuevo perfil es igual a DIA 3h en los viejos perfiles de insulina. + Configurar fuente BG + Por favor seleccione la fuente del perfil. Si el paciente es un niño, debe usar el perfil NS. Si no hay nadie que lo siga en Nightscout, probablemente prefiera el perfil Local. Recuerde que solo está seleccionando el origen del perfil. Para usarlo debes activarlo ejecutando el cambio de Perfil + Seleccione uno de los algoritmos disponibles. Se ordenan desde el más antiguo al más nuevo. Algoritmo más nuevo es generalmente más poderoso y más agresivo. Por lo tanto, si eres un looper nuevo, probablemente comiences con AMA y no con el último. No olvide leer la documentación de OpenAPS y configurarla antes de su uso. + Comience su primer objetivo + Permisos + Preguntar por permisos + La aplicación necesita permiso de ubicación para escanear BT + La aplicación necesita permiso de almacenamiento para poder almacenar archivos de registro + "Solicitud " + Configurar el complemento de Insulina + Salir + "Opciones de usuario " + Formato de tiempo mostrado + Botón de desplazamiento + Beep on button press + Alarma + Sonido + Vibrar + Ambos + LCD en tiempo [s] + Luz de fondo a tiempo [h] + Unidades de glucosa + Parada (horas) + Depósito bajo (Unidades) + Guardar las opciones en bomba + Encendido + Apagado + Abrir navegación + Cerrar navegación + Preferencias del plugin + Completado, bien hecho! + Aún no completado + Tiempo transcurrido + %1$d. Objetivo + Recibe valores de BG de la aplicación Poctech + Objetivos temporales Altos (high TT) aumentan la sensibilidad + = 100]]> + Objetivos temporales Bajos (low TT) disminuye la sensibilidad + = 100]]> + La configuración de la bomba no válida, verifique la documentación y verifique que el menú Información rápida se llame \"Quick Info\" utilizando el software de configuración 360. + Personalizar + "Gran diferencia de tiempo " + Gran diferencia de tiempo: El tiempo en la bomba está desfasado en más de 1,5 horas. Ajuste la hora manualmente en la bomba y asegúrese de que la lectura del historial de la bomba no cause un comportamiento inesperado. Si es posible, elimine el historial de la bomba antes de cambiar la hora o deshabilite el ciclo cerrado para un DIA después de la última entrada incorrecta del historial, pero como mínimo un DIA a partir de ahora. + Configuraciones almacenadas encontradas + Atención: si activa y conecta una bomba de hardware, AndroidAPS copiará las configuraciones basales del perfil a la bomba, sobrescribiendo la tasa basal existente almacenada en la bomba. Asegúrate de tener la configuración basal correcta en AndroidAPS. Si no está seguro o no desea sobrescribir la configuración básica de su bomba, presione cancelar y repita el cambio a la bomba más adelante. + Datos de tratamiento incompletos + o se pudo agregar un tratamiento (insulina: %.2f, carbs: %d, en: %s) a los tratamientos. Verifique y añada manualmente un registro según corresponda. + ECarbs generados con cantidad: %1$dg, duración: %2$dh, demora: %3$dm From 90729cffe6c112a80f6174c59fc3047fa751a585 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Mon, 23 Jul 2018 16:17:17 +0200 Subject: [PATCH 008/284] RS disconnect synchronized --- .../androidaps/plugins/PumpDanaRS/services/BLEComm.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/BLEComm.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/BLEComm.java index 9df2ebc0a1..50ecf7527e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/BLEComm.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/BLEComm.java @@ -151,7 +151,7 @@ public class BLEComm { isConnecting = false; } - public void disconnect(String from) { + public synchronized void disconnect(String from) { log.debug("disconnect from: " + from); // cancel previous scheduled disconnection to prevent closing upcomming connection From d7b29db626cc248b5db3c635b3a9762cd2bdf4dc Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Mon, 23 Jul 2018 16:19:11 +0200 Subject: [PATCH 009/284] fix NPE --- .../androidaps/plugins/OpenAPSAMA/OpenAPSAMAPlugin.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/OpenAPSAMAPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/OpenAPSAMAPlugin.java index 74d15cd2a4..f73752faa2 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/OpenAPSAMAPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/OpenAPSAMAPlugin.java @@ -179,6 +179,7 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface { MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.openaps_noasdata))); return; } + lastAutosensResult = autosensData.autosensResult; } else { lastAutosensResult = new AutosensResult(); lastAutosensResult.sensResult = "autosens disabled"; From 130fca4c2a1f0371b49a21908f407beb0beacb65 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Mon, 23 Jul 2018 16:33:51 +0200 Subject: [PATCH 010/284] RS onConnectionStateChangeSynchronized --- .../plugins/PumpDanaRS/services/BLEComm.java | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/BLEComm.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/BLEComm.java index 50ecf7527e..e15f6f23c0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/BLEComm.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/BLEComm.java @@ -187,17 +187,7 @@ public class BLEComm { private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { - log.debug("onConnectionStateChange"); - - if (newState == BluetoothProfile.STATE_CONNECTED) { - mBluetoothGatt.discoverServices(); - } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { - close(); - isConnected = false; - isConnecting = false; - MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTED)); - log.debug("Device was disconnected " + gatt.getDevice().getName());//Device was disconnected - } + onConnectionStateChangeSynchronized(gatt, status, newState); // call it synchronized } public void onServicesDiscovered(BluetoothGatt gatt, int status) { @@ -325,6 +315,20 @@ public class BLEComm { } } + public synchronized void onConnectionStateChangeSynchronized(BluetoothGatt gatt, int status, int newState) { + log.debug("onConnectionStateChange"); + + if (newState == BluetoothProfile.STATE_CONNECTED) { + mBluetoothGatt.discoverServices(); + } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { + close(); + isConnected = false; + isConnecting = false; + MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTED)); + log.debug("Device was disconnected " + gatt.getDevice().getName());//Device was disconnected + } + } + private final byte[] readBuffer = new byte[1024]; private int bufferLength = 0; From fa67aa69d5d3f3881d08ae5a8c4b4da8843c16e7 Mon Sep 17 00:00:00 2001 From: AdrianLxM Date: Mon, 23 Jul 2018 18:43:26 +0200 Subject: [PATCH 011/284] react to HypoTT on first click onClickListener, not OnCheckedListener was set for HypoTT --- .../androidaps/plugins/Overview/Dialogs/NewCarbsDialog.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewCarbsDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewCarbsDialog.java index 26f46081ea..7ab35e69bd 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewCarbsDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewCarbsDialog.java @@ -160,7 +160,7 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, C startHypoTTCheckbox.setOnCheckedChangeListener(null); startHypoTTCheckbox.setChecked(true); } - startHypoTTCheckbox.setOnClickListener(this); + startHypoTTCheckbox.setOnCheckedChangeListener(this); setCancelable(true); getDialog().setCanceledOnTouchOutside(false); From 2090b3c7e1169e942dd78d3940d612e58cc64607 Mon Sep 17 00:00:00 2001 From: "Markus M. May" Date: Mon, 23 Jul 2018 20:58:20 +0200 Subject: [PATCH 012/284] First draft --- .../nightscout/androidaps/MainActivity.java | 15 ++ .../info/nightscout/androidaps/MainApp.java | 8 +- .../info/nightscout/utils/LoggerUtils.java | 171 ++++++++++++++++++ app/src/main/res/menu/menu_main.xml | 4 + app/src/main/res/values/strings.xml | 1 + .../java/info/nightscout/MainAppTest.java | 3 +- .../nightscout/utils/LoggerUtilsTest.java | 40 ++++ .../AndroidAPS.2018-01-01_01-01-00.1.zip | 0 .../AndroidAPS.2018-01-02_01-01-00.1.zip | 0 .../AndroidAPS.2018-01-03_01-01-00.1.zip | 0 app/src/test/res/logger/AndroidAPS.log | 0 11 files changed, 235 insertions(+), 7 deletions(-) create mode 100644 app/src/main/java/info/nightscout/utils/LoggerUtils.java create mode 100644 app/src/test/java/info/nightscout/utils/LoggerUtilsTest.java create mode 100644 app/src/test/res/logger/AndroidAPS.2018-01-01_01-01-00.1.zip create mode 100644 app/src/test/res/logger/AndroidAPS.2018-01-02_01-01-00.1.zip create mode 100644 app/src/test/res/logger/AndroidAPS.2018-01-03_01-01-00.1.zip create mode 100644 app/src/test/res/logger/AndroidAPS.log diff --git a/app/src/main/java/info/nightscout/androidaps/MainActivity.java b/app/src/main/java/info/nightscout/androidaps/MainActivity.java index 8a19a05f4d..e7cc073166 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/MainActivity.java @@ -38,6 +38,9 @@ import com.squareup.otto.Subscribe; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.File; +import java.util.List; + import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.events.EventFeatureRunning; @@ -53,6 +56,7 @@ import info.nightscout.utils.AndroidPermission; import info.nightscout.utils.ImportExportPrefs; import info.nightscout.utils.LocaleHelper; import info.nightscout.utils.LogDialog; +import info.nightscout.utils.LoggerUtils; import info.nightscout.utils.OKDialog; import info.nightscout.utils.PasswordProtection; import info.nightscout.utils.SP; @@ -391,6 +395,17 @@ public class MainActivity extends AppCompatActivity { return true; case R.id.nav_show_logcat: LogDialog.showLogcat(this); + return true; + case R.id.nav_export_log: + String recipient = "mmay@gmx.net"; + + String logDirectory = LoggerUtils.getLogDirectory(); + List logs = LoggerUtils.getLogfiles(logDirectory, 2); + String zipName = LoggerUtils.constructName(); + File zip = LoggerUtils.zipLogs(zipName, logDirectory, logs); + Intent emailIntent = LoggerUtils.sendMail(zip, recipient, "Log Export"); + startActivity(Intent.createChooser(emailIntent , "Send email...")); + return true; case R.id.nav_about: AlertDialog.Builder builder = new AlertDialog.Builder(this); diff --git a/app/src/main/java/info/nightscout/androidaps/MainApp.java b/app/src/main/java/info/nightscout/androidaps/MainApp.java index dbb6ddee8b..de800b8468 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainApp.java +++ b/app/src/main/java/info/nightscout/androidaps/MainApp.java @@ -78,6 +78,7 @@ import info.nightscout.androidaps.receivers.DataReceiver; import info.nightscout.androidaps.receivers.KeepAliveReceiver; import info.nightscout.androidaps.receivers.NSAlarmReceiver; import info.nightscout.utils.FabricPrivacy; +import info.nightscout.utils.LoggerUtils; import info.nightscout.utils.NSUpload; import io.fabric.sdk.android.Fabric; @@ -127,7 +128,7 @@ public class MainApp extends Application { log.info("Version: " + BuildConfig.VERSION_NAME); log.info("BuildVersion: " + BuildConfig.BUILDVERSION); - String extFilesDir = this.getLogDirectory(); + String extFilesDir = LoggerUtils.getLogDirectory(); File engineeringModeSemaphore = new File(extFilesDir, "engineering_mode"); engineeringMode = engineeringModeSemaphore.exists() && engineeringModeSemaphore.isFile(); @@ -388,11 +389,6 @@ public class MainApp extends Application { return devBranch; } - public String getLogDirectory() { - LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); - return lc.getProperty("EXT_FILES_DIR"); - } - @Override public void onTerminate() { super.onTerminate(); diff --git a/app/src/main/java/info/nightscout/utils/LoggerUtils.java b/app/src/main/java/info/nightscout/utils/LoggerUtils.java new file mode 100644 index 0000000000..ec5f927cb4 --- /dev/null +++ b/app/src/main/java/info/nightscout/utils/LoggerUtils.java @@ -0,0 +1,171 @@ +package info.nightscout.utils; + +import android.content.Intent; +import android.net.Uri; + +import org.slf4j.LoggerFactory; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FilenameFilter; +import java.io.IOException; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Date; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import ch.qos.logback.classic.LoggerContext; + +/** + * This class provides serveral methods for log-handling (eg. sending logs as emails). + */ +public class LoggerUtils { + + private static String SUFFIX = ".log.zip"; + + /** + * Returns the directory, in which the logs are stored on the system. This is configured in the + * logback.xml file. + * + * @return + */ + public static String getLogDirectory() { + LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); + return lc.getProperty("EXT_FILES_DIR"); + } + + + /** + * returns a list of log files. The number of returned logs is given via the amount + * parameter. The log files are sorted by the name descending. + * + * @param directory + * @param amount + * @return + */ + public static List getLogfiles(String directory, int amount) { + File logDir = new File(directory); + + File[] files = logDir.listFiles(new FilenameFilter() { + @Override + public boolean accept(File file, String name) { + return name.startsWith("AndroidAPS") + && (name.endsWith(".log") + || (name.endsWith(".zip") && !name.endsWith(SUFFIX))); + } + }); + + Arrays.sort(files, new Comparator() { + public int compare(File f1, File f2) { + return f2.getName().compareTo(f1.getName()); + } + }); + + List result = Arrays.asList(files); + int toIndex = amount++; + + + if (toIndex > result.size()) { + toIndex = result.size(); + } + + return result.subList(0, toIndex); + } + + /** + * Zips the given files in a zipfile which is stored in the given directory using the givven + * name. + * + * @param name + * @param directory + * @param files + * @return + */ + public static File zipLogs(String name, String directory, List files) { + File zip = new File(directory, name); + + try { + zip(zip, files); + } catch (IOException e) { + System.out.print("REmomve this one sooner or later...."); + } + + return zip; + } + + /** + * construct the name of zip file which is used to export logs. + * + * The name is constructed using the following scheme: + * AndroidAPS_LOG_ + Long Time + .log.zip + * + * @return + */ + public static String constructName() { + return "AndroidAPS_LOG_" + String.valueOf(new Date().getTime()) + SUFFIX; + } + + /** + * This method stores all given files inside the given zipFile. + * + * @param zipFile + * @param files + * @throws IOException + */ + public static void zip(File zipFile, List files) throws IOException { + final int BUFFER_SIZE = 2048; + + ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFile))); + + for (File file : files) { + byte data[] = new byte[BUFFER_SIZE]; + + try(FileInputStream fileInputStream = new FileInputStream( file )) { + + try(BufferedInputStream origin = new BufferedInputStream(fileInputStream, BUFFER_SIZE)) { + ZipEntry entry = new ZipEntry(file.getName()); + + out.putNextEntry(entry); + int count; + while ((count = origin.read(data, 0, BUFFER_SIZE)) != -1) { + out.write(data, 0, count); + } + + } + } + } + + out.close(); + } + + /** + * send a mail with the given file to the recipients with the given subject. + * + * the returned intent should be used to really send the mail using + * + * startActivity(Intent.createChooser(emailIntent , "Send email...")); + * + * @param file + * @param recipient + * @param subject + * @return + */ + public static Intent sendMail(File file, String recipient, String subject) { + Intent emailIntent = new Intent(Intent.ACTION_SEND); + + emailIntent .setType("vnd.android.cursor.dir/email"); + emailIntent.putExtra(Intent.EXTRA_EMAIL , new String[]{recipient}); + emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject); + + Uri path = Uri.fromFile(file); + emailIntent .putExtra(Intent.EXTRA_STREAM, path); + + return emailIntent; + } + +} diff --git a/app/src/main/res/menu/menu_main.xml b/app/src/main/res/menu/menu_main.xml index 09bd20a631..9cbaa378cd 100644 --- a/app/src/main/res/menu/menu_main.xml +++ b/app/src/main/res/menu/menu_main.xml @@ -34,6 +34,10 @@ android:id="@+id/nav_show_logcat" app:showAsAction="never" android:title="@string/nav_show_logcat" /> + Copy To Clipboard Copied to clipboard Show log + Export Logs Calibration Send calibration %.1f to xDrip? xDrip+ not installed diff --git a/app/src/test/java/info/nightscout/MainAppTest.java b/app/src/test/java/info/nightscout/MainAppTest.java index 7bb58797be..569d5ded21 100644 --- a/app/src/test/java/info/nightscout/MainAppTest.java +++ b/app/src/test/java/info/nightscout/MainAppTest.java @@ -12,6 +12,7 @@ import info.nightscout.androidaps.R; import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.Overview.OverviewPlugin; +import info.nightscout.utils.LoggerUtils; /** @@ -127,7 +128,7 @@ public class MainAppTest { @Test public void getLogDirectoryTest() { // logger not initialized in Roboelectric - Assert.assertNull(mainApp.getLogDirectory()); + Assert.assertNull(LoggerUtils.getLogDirectory()); } } diff --git a/app/src/test/java/info/nightscout/utils/LoggerUtilsTest.java b/app/src/test/java/info/nightscout/utils/LoggerUtilsTest.java new file mode 100644 index 0000000000..b999c804b7 --- /dev/null +++ b/app/src/test/java/info/nightscout/utils/LoggerUtilsTest.java @@ -0,0 +1,40 @@ +package info.nightscout.utils; + +import org.junit.Test; + +import java.io.File; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class LoggerUtilsTest { + + @Test + public void getLogfilesTest() { + String logDirectory = "src/test/res/logger"; + + List logs = LoggerUtils.getLogfiles(logDirectory, 2); + assertEquals(2, logs.size()); + assertEquals("AndroidAPS.log", logs.get(0).getName()); + assertEquals("AndroidAPS.2018-01-03_01-01-00.1.zip", logs.get(1).getName()); + + logs = LoggerUtils.getLogfiles(logDirectory, 10); + assertEquals(4, logs.size()); + } + + + @Test + public void zipLogsTest() { + String logDirectory = "src/test/res/logger"; + List logs = LoggerUtils.getLogfiles(logDirectory, 2); + + String name = "AndroidAPS.log.zip"; + + File zipFile = LoggerUtils.zipLogs(name, "build", logs); + + assertTrue(zipFile.exists()); + assertTrue(zipFile.isFile()); + } + +} diff --git a/app/src/test/res/logger/AndroidAPS.2018-01-01_01-01-00.1.zip b/app/src/test/res/logger/AndroidAPS.2018-01-01_01-01-00.1.zip new file mode 100644 index 0000000000..e69de29bb2 diff --git a/app/src/test/res/logger/AndroidAPS.2018-01-02_01-01-00.1.zip b/app/src/test/res/logger/AndroidAPS.2018-01-02_01-01-00.1.zip new file mode 100644 index 0000000000..e69de29bb2 diff --git a/app/src/test/res/logger/AndroidAPS.2018-01-03_01-01-00.1.zip b/app/src/test/res/logger/AndroidAPS.2018-01-03_01-01-00.1.zip new file mode 100644 index 0000000000..e69de29bb2 diff --git a/app/src/test/res/logger/AndroidAPS.log b/app/src/test/res/logger/AndroidAPS.log new file mode 100644 index 0000000000..e69de29bb2 From 7e2d3fd8be221483caa26997fae6ef7649f4feb4 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Tue, 24 Jul 2018 00:46:08 +0200 Subject: [PATCH 013/284] historybrowser, rendering optimizations --- .../androidaps/HistoryBrowseActivity.java | 364 ++++++++++-------- .../nightscout/androidaps/MainActivity.java | 1 - .../androidaps/db/DatabaseHelper.java | 17 + .../interfaces/SensitivityInterface.java | 3 +- .../plugins/Actions/ActionsFragment.java | 1 - .../IobCobCalculatorPlugin.java | 57 +-- .../IobCobCalculator/IobCobOref1Thread.java | 18 +- .../IobCobCalculator/IobCobThread.java | 18 +- .../plugins/Overview/OverviewFragment.java | 7 +- .../plugins/Overview/graphData/GraphData.java | 27 +- .../AbstractSensitivityPlugin.java | 12 +- .../Sensitivity/SensitivityAAPSPlugin.java | 10 +- .../Sensitivity/SensitivityOref0Plugin.java | 10 +- .../Sensitivity/SensitivityOref1Plugin.java | 10 +- .../SensitivityWeightedAveragePlugin.java | 10 +- .../res/layout/activity_historybrowse.xml | 16 +- .../AbstractSensitivityPluginTest.java | 4 +- 17 files changed, 319 insertions(+), 266 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/HistoryBrowseActivity.java b/app/src/main/java/info/nightscout/androidaps/HistoryBrowseActivity.java index 636db14086..d106fb9985 100644 --- a/app/src/main/java/info/nightscout/androidaps/HistoryBrowseActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/HistoryBrowseActivity.java @@ -1,7 +1,7 @@ package info.nightscout.androidaps; -import android.app.Activity; import android.os.Bundle; +import android.os.SystemClock; import android.support.v4.content.res.ResourcesCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.PopupMenu; @@ -17,11 +17,13 @@ import android.widget.TextView; import com.jjoe64.graphview.GraphView; import com.squareup.otto.Subscribe; +import com.wdullaer.materialdatetimepicker.date.DatePickerDialog; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Calendar; +import java.util.Date; import butterknife.BindView; import butterknife.ButterKnife; @@ -33,11 +35,12 @@ import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished; +import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventIobCalculationProgress; import info.nightscout.androidaps.plugins.Overview.OverviewFragment; import info.nightscout.androidaps.plugins.Overview.OverviewPlugin; import info.nightscout.androidaps.plugins.Overview.graphData.GraphData; import info.nightscout.utils.DateUtil; -import info.nightscout.utils.SP; +import info.nightscout.utils.T; public class HistoryBrowseActivity extends AppCompatActivity { private static Logger log = LoggerFactory.getLogger(HistoryBrowseActivity.class); @@ -61,9 +64,11 @@ public class HistoryBrowseActivity extends AppCompatActivity { SeekBar seekBar; @BindView(R.id.historybrowse_noprofile) TextView noProfile; + @BindView(R.id.overview_iobcalculationprogess) + TextView iobCalculationProgressView; private int rangeToDisplay = 24; // for graph - private long start; + private long start = 0; IobCobCalculatorPlugin iobCobCalculatorPlugin; @@ -90,7 +95,19 @@ public class HistoryBrowseActivity extends AppCompatActivity { iobGraph.getGridLabelRenderer().setNumVerticalLabels(5); setupChartMenu(); + } + @Override + public void onPause() { + super.onPause(); + MainApp.bus().unregister(this); + iobCobCalculatorPlugin.stopCalculation("onPause"); + } + + @Override + public void onResume() { + super.onResume(); + MainApp.bus().register(this); // set start of current day Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(System.currentTimeMillis()); @@ -99,33 +116,23 @@ public class HistoryBrowseActivity extends AppCompatActivity { calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.HOUR_OF_DAY, 0); start = calendar.getTimeInMillis(); - } - - @Override - protected void onResume() { - super.onResume(); + runCalculation("onResume"); + SystemClock.sleep(1000); updateGUI("onResume"); } - - @OnClick(R.id.historybrowse_start) - void onClickStart() { - } - @OnClick(R.id.historybrowse_left) void onClickLeft() { - start -= rangeToDisplay * 60 * 60 * 1000L; - updateGUI("left"); - iobCobCalculatorPlugin.clearCache(); - iobCobCalculatorPlugin.runCalculation("onClickLeft", start, true, eventCustomCalculationFinished); + start -= T.hours(rangeToDisplay).msecs(); + updateGUI("onClickLeft"); + runCalculation("onClickLeft"); } @OnClick(R.id.historybrowse_right) void onClickRight() { - start += rangeToDisplay * 60 * 60 * 1000L; - updateGUI("right"); - iobCobCalculatorPlugin.clearCache(); - iobCobCalculatorPlugin.runCalculation("onClickRight", start, true, eventCustomCalculationFinished); + start += T.hours(rangeToDisplay).msecs(); + updateGUI("onClickRight"); + runCalculation("onClickRight"); } @OnClick(R.id.historybrowse_end) @@ -137,9 +144,8 @@ public class HistoryBrowseActivity extends AppCompatActivity { calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.HOUR_OF_DAY, 0); start = calendar.getTimeInMillis(); - updateGUI("resetToMidnight"); - iobCobCalculatorPlugin.clearCache(); - iobCobCalculatorPlugin.runCalculation("onClickEnd", start, true, eventCustomCalculationFinished); + updateGUI("onClickEnd"); + runCalculation("onClickEnd"); } @OnClick(R.id.historybrowse_zoom) @@ -159,32 +165,63 @@ public class HistoryBrowseActivity extends AppCompatActivity { calendar.set(Calendar.HOUR_OF_DAY, 0); start = calendar.getTimeInMillis(); updateGUI("resetToMidnight"); - iobCobCalculatorPlugin.clearCache(); - iobCobCalculatorPlugin.runCalculation("onLongClickZoom", start, true, eventCustomCalculationFinished); + runCalculation("onLongClickZoom"); return true; } @OnClick(R.id.historybrowse_date) void onClickDate() { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(new Date(start)); + DatePickerDialog dpd = DatePickerDialog.newInstance( + (view, year, monthOfYear, dayOfMonth) -> { + Date date = new Date(0); + date.setYear(year - 1900); + date.setMonth(monthOfYear); + date.setDate(dayOfMonth); + date.setHours(0); + start = date.getTime(); + updateGUI("onClickDate"); + runCalculation("onClickDate"); + }, + calendar.get(Calendar.YEAR), + calendar.get(Calendar.MONTH), + calendar.get(Calendar.DAY_OF_MONTH) + ); + dpd.setThemeDark(true); + dpd.dismissOnPause(true); + dpd.show(getFragmentManager(), "Datepickerdialog"); + } + + private void runCalculation(String from) { + long end = start + T.hours(rangeToDisplay).msecs(); + iobCobCalculatorPlugin.stopCalculation(from); + iobCobCalculatorPlugin.clearCache(); + iobCobCalculatorPlugin.runCalculation(from, end, true, false, eventCustomCalculationFinished); } @Subscribe public void onStatusEvent(final EventAutosensCalculationFinished e) { - Activity activity = this; - if (activity != null && e.cause == eventCustomCalculationFinished) { + if (e.cause == eventCustomCalculationFinished) { log.debug("EventAutosensCalculationFinished"); - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - synchronized (HistoryBrowseActivity.this) { - updateGUI("EventAutosensCalculationFinished"); - } + runOnUiThread(() -> { + synchronized (HistoryBrowseActivity.this) { + updateGUI("EventAutosensCalculationFinished"); } }); } } + @Subscribe + public void onStatusEvent(final EventIobCalculationProgress e) { + runOnUiThread(() -> { + if (iobCalculationProgressView != null) + iobCalculationProgressView.setText(e.progress); + }); + } + void updateGUI(String from) { + log.debug("updateGUI from: " + from); if (noProfile == null || buttonDate == null || buttonZoom == null || bgGraph == null || iobGraph == null || seekBar == null) return; @@ -200,17 +237,11 @@ public class HistoryBrowseActivity extends AppCompatActivity { } final String units = profile.getUnits(); + final double lowLine = OverviewPlugin.getPlugin().determineLowLine(units); + final double highLine = OverviewPlugin.getPlugin().determineHighLine(units); - double lowLineSetting = SP.getDouble("low_mark", Profile.fromMgdlToUnits(OverviewPlugin.bgTargetLow, units)); - double highLineSetting = SP.getDouble("high_mark", Profile.fromMgdlToUnits(OverviewPlugin.bgTargetHigh, units)); - - if (lowLineSetting < 1) - lowLineSetting = Profile.fromMgdlToUnits(76d, units); - if (highLineSetting < 1) - highLineSetting = Profile.fromMgdlToUnits(180d, units); - - final double lowLine = lowLineSetting; - final double highLine = highLineSetting; + buttonDate.setText(DateUtil.dateAndTimeString(start)); + buttonZoom.setText(String.valueOf(rangeToDisplay)); final boolean showPrediction = false; @@ -226,20 +257,17 @@ public class HistoryBrowseActivity extends AppCompatActivity { //fromTime = toTime - hoursToFetch * 60 * 60 * 1000L; //endTime = toTime + predHours * 60 * 60 * 1000L; //} else { - fromTime = start + 100000; - toTime = start + rangeToDisplay * 60 * 60 * 1000L; + fromTime = start + T.secs(100).msecs(); + toTime = start + T.hours(rangeToDisplay).msecs(); //} - buttonDate.setText(DateUtil.dateAndTimeString(start)); - buttonZoom.setText(String.valueOf(rangeToDisplay)); - log.debug("Period: " + DateUtil.dateAndTimeString(fromTime) + " - " + DateUtil.dateAndTimeString(toTime)); final long pointer = System.currentTimeMillis(); // ------------------ 1st graph - final GraphData graphData = new GraphData(bgGraph, IobCobCalculatorPlugin.getPlugin()); + final GraphData graphData = new GraphData(bgGraph, iobCobCalculatorPlugin); // **** In range Area **** graphData.addInRangeArea(fromTime, toTime, lowLine, highLine); @@ -267,143 +295,137 @@ public class HistoryBrowseActivity extends AppCompatActivity { // ------------------ 2nd graph - final GraphData secondGraphData = new GraphData(iobGraph, iobCobCalculatorPlugin); + new Thread(() -> { + final GraphData secondGraphData = new GraphData(iobGraph, iobCobCalculatorPlugin); - boolean useIobForScale = false; - boolean useCobForScale = false; - boolean useDevForScale = false; - boolean useRatioForScale = false; - boolean useDevSlopeForScale = false; + boolean useIobForScale = false; + boolean useCobForScale = false; + boolean useDevForScale = false; + boolean useRatioForScale = false; + boolean useDSForScale = false; - if (showIob) { - useIobForScale = true; - } else if (showCob) { - useCobForScale = true; - } else if (showDev) { - useDevForScale = true; - } else if (showRat) { - useRatioForScale = true; - } else if (showDevslope) { - useDevSlopeForScale = true; - } + if (showIob) { + useIobForScale = true; + } else if (showCob) { + useCobForScale = true; + } else if (showDev) { + useDevForScale = true; + } else if (showRat) { + useRatioForScale = true; + } else if (showDevslope) { + useDSForScale = true; + } - if (showIob) - secondGraphData.addIob(fromTime, toTime, useIobForScale, 1d); - if (showCob) - secondGraphData.addCob(fromTime, toTime, useCobForScale, useCobForScale ? 1d : 0.5d); - if (showDev) - secondGraphData.addDeviations(fromTime, toTime, useDevForScale, 1d); - if (showRat) - secondGraphData.addRatio(fromTime, toTime, useRatioForScale, 1d); - if (showDevslope) - secondGraphData.addDeviationSlope(fromTime, toTime, useDevSlopeForScale, 1d); + if (showIob) + secondGraphData.addIob(fromTime, toTime, useIobForScale, 1d); + if (showCob) + secondGraphData.addCob(fromTime, toTime, useCobForScale, useCobForScale ? 1d : 0.5d); + if (showDev) + secondGraphData.addDeviations(fromTime, toTime, useDevForScale, 1d); + if (showRat) + secondGraphData.addRatio(fromTime, toTime, useRatioForScale, 1d); + if (showDevslope) + secondGraphData.addDeviationSlope(fromTime, toTime, useDSForScale, 1d); - // **** NOW line **** - // set manual x bounds to have nice steps - secondGraphData.formatAxis(fromTime, toTime); - secondGraphData.addNowLine(pointer); + // **** NOW line **** + // set manual x bounds to have nice steps + secondGraphData.formatAxis(fromTime, toTime); + secondGraphData.addNowLine(pointer); - // do GUI update - if (showIob || showCob || showDev || showRat || showDevslope) { - iobGraph.setVisibility(View.VISIBLE); - } else { - iobGraph.setVisibility(View.GONE); - } - // finally enforce drawing of graphs - graphData.performUpdate(); - secondGraphData.performUpdate(); + // do GUI update + runOnUiThread(() -> { + if (showIob || showCob || showDev || showRat || showDevslope) { + iobGraph.setVisibility(View.VISIBLE); + } else { + iobGraph.setVisibility(View.GONE); + } + // finally enforce drawing of graphs + graphData.performUpdate(); + if (showIob || showCob || showDev || showRat || showDevslope) + secondGraphData.performUpdate(); + }); + }).start(); } private void setupChartMenu() { chartButton = (ImageButton) findViewById(R.id.overview_chartMenuButton); - chartButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - MenuItem item; - CharSequence title; - SpannableString s; - PopupMenu popup = new PopupMenu(v.getContext(), v); + chartButton.setOnClickListener(v -> { + MenuItem item; + CharSequence title; + SpannableString s; + PopupMenu popup = new PopupMenu(v.getContext(), v); - item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.BAS.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_basals)); + item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.BAS.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_basals)); + title = item.getTitle(); + s = new SpannableString(title); + s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.basal, null)), 0, s.length(), 0); + item.setTitle(s); + item.setCheckable(true); + item.setChecked(showBasal); + + item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.IOB.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_iob)); + title = item.getTitle(); + s = new SpannableString(title); + s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.iob, null)), 0, s.length(), 0); + item.setTitle(s); + item.setCheckable(true); + item.setChecked(showIob); + + item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.COB.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_cob)); + title = item.getTitle(); + s = new SpannableString(title); + s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.cob, null)), 0, s.length(), 0); + item.setTitle(s); + item.setCheckable(true); + item.setChecked(showCob); + + item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.DEV.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_deviations)); + title = item.getTitle(); + s = new SpannableString(title); + s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.deviations, null)), 0, s.length(), 0); + item.setTitle(s); + item.setCheckable(true); + item.setChecked(showDev); + + item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.SEN.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_sensitivity)); + title = item.getTitle(); + s = new SpannableString(title); + s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.ratio, null)), 0, s.length(), 0); + item.setTitle(s); + item.setCheckable(true); + item.setChecked(showRat); + + if (MainApp.devBranch) { + item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.DEVSLOPE.ordinal(), Menu.NONE, "Deviation slope"); title = item.getTitle(); s = new SpannableString(title); - s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.basal, null)), 0, s.length(), 0); + s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.devslopepos, null)), 0, s.length(), 0); item.setTitle(s); item.setCheckable(true); - item.setChecked(showBasal); - - item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.IOB.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_iob)); - title = item.getTitle(); - s = new SpannableString(title); - s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.iob, null)), 0, s.length(), 0); - item.setTitle(s); - item.setCheckable(true); - item.setChecked(showIob); - - item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.COB.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_cob)); - title = item.getTitle(); - s = new SpannableString(title); - s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.cob, null)), 0, s.length(), 0); - item.setTitle(s); - item.setCheckable(true); - item.setChecked(showCob); - - item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.DEV.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_deviations)); - title = item.getTitle(); - s = new SpannableString(title); - s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.deviations, null)), 0, s.length(), 0); - item.setTitle(s); - item.setCheckable(true); - item.setChecked(showDev); - - item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.SEN.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_sensitivity)); - title = item.getTitle(); - s = new SpannableString(title); - s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.ratio, null)), 0, s.length(), 0); - item.setTitle(s); - item.setCheckable(true); - item.setChecked(showRat); - - if (MainApp.devBranch) { - item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.DEVSLOPE.ordinal(), Menu.NONE, "Deviation slope"); - title = item.getTitle(); - s = new SpannableString(title); - s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.devslopepos, null)), 0, s.length(), 0); - item.setTitle(s); - item.setCheckable(true); - item.setChecked(showDevslope); - } - - popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - if (item.getItemId() == OverviewFragment.CHARTTYPE.BAS.ordinal()) { - showBasal = !item.isChecked(); - } else if (item.getItemId() == OverviewFragment.CHARTTYPE.IOB.ordinal()) { - showIob = !item.isChecked(); - } else if (item.getItemId() == OverviewFragment.CHARTTYPE.COB.ordinal()) { - showCob = !item.isChecked(); - } else if (item.getItemId() == OverviewFragment.CHARTTYPE.DEV.ordinal()) { - showDev = !item.isChecked(); - } else if (item.getItemId() == OverviewFragment.CHARTTYPE.SEN.ordinal()) { - showRat = !item.isChecked(); - } else if (item.getItemId() == OverviewFragment.CHARTTYPE.DEVSLOPE.ordinal()) { - showDevslope = !item.isChecked(); - } - updateGUI("onGraphCheckboxesCheckedChanged"); - return true; - } - }); - chartButton.setImageResource(R.drawable.ic_arrow_drop_up_white_24dp); - popup.setOnDismissListener(new PopupMenu.OnDismissListener() { - @Override - public void onDismiss(PopupMenu menu) { - chartButton.setImageResource(R.drawable.ic_arrow_drop_down_white_24dp); - } - }); - popup.show(); + item.setChecked(showDevslope); } + + popup.setOnMenuItemClickListener(item1 -> { + if (item1.getItemId() == OverviewFragment.CHARTTYPE.BAS.ordinal()) { + showBasal = !item1.isChecked(); + } else if (item1.getItemId() == OverviewFragment.CHARTTYPE.IOB.ordinal()) { + showIob = !item1.isChecked(); + } else if (item1.getItemId() == OverviewFragment.CHARTTYPE.COB.ordinal()) { + showCob = !item1.isChecked(); + } else if (item1.getItemId() == OverviewFragment.CHARTTYPE.DEV.ordinal()) { + showDev = !item1.isChecked(); + } else if (item1.getItemId() == OverviewFragment.CHARTTYPE.SEN.ordinal()) { + showRat = !item1.isChecked(); + } else if (item1.getItemId() == OverviewFragment.CHARTTYPE.DEVSLOPE.ordinal()) { + showDevslope = !item1.isChecked(); + } + updateGUI("onGraphCheckboxesCheckedChanged"); + return true; + }); + chartButton.setImageResource(R.drawable.ic_arrow_drop_up_white_24dp); + popup.setOnDismissListener(menu -> chartButton.setImageResource(R.drawable.ic_arrow_drop_down_white_24dp)); + popup.show(); }); } diff --git a/app/src/main/java/info/nightscout/androidaps/MainActivity.java b/app/src/main/java/info/nightscout/androidaps/MainActivity.java index 8a19a05f4d..ea8948abdd 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/MainActivity.java @@ -344,7 +344,6 @@ public class MainActivity extends AppCompatActivity { public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_main, menu); pluginPreferencesMenuItem = menu.findItem(R.id.nav_plugin_preferences); - menu.findItem(R.id.nav_historybrowser).setVisible(MainApp.devBranch); checkPluginPreferences(findViewById(R.id.pager)); return true; } diff --git a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java index f869ca36c5..ba6f2e5dd0 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java +++ b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java @@ -431,6 +431,23 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { return new ArrayList(); } + public List getBgreadingsDataFromTime(long start, long end, boolean ascending) { + try { + Dao daoBgreadings = getDaoBgReadings(); + List bgReadings; + QueryBuilder queryBuilder = daoBgreadings.queryBuilder(); + queryBuilder.orderBy("date", ascending); + Where where = queryBuilder.where(); + where.between("date", start, end).and().gt("value", 38).and().eq("isValid", true); + PreparedQuery preparedQuery = queryBuilder.prepare(); + bgReadings = daoBgreadings.query(preparedQuery); + return bgReadings; + } catch (SQLException e) { + log.error("Unhandled exception", e); + } + return new ArrayList(); + } + public List getAllBgreadingsDataFromTime(long mills, boolean ascending) { try { Dao daoBgreadings = getDaoBgReadings(); diff --git a/app/src/main/java/info/nightscout/androidaps/interfaces/SensitivityInterface.java b/app/src/main/java/info/nightscout/androidaps/interfaces/SensitivityInterface.java index 81af28eaa4..f4514ad572 100644 --- a/app/src/main/java/info/nightscout/androidaps/interfaces/SensitivityInterface.java +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/SensitivityInterface.java @@ -1,6 +1,7 @@ package info.nightscout.androidaps.interfaces; import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensResult; +import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; /** * Created by mike on 24.06.2017. @@ -11,6 +12,6 @@ public interface SensitivityInterface { double MIN_HOURS = 1; double MIN_HOURS_FULL_AUTOSENS = 4; - AutosensResult detectSensitivity(long fromTime, long toTime); + AutosensResult detectSensitivity(IobCobCalculatorPlugin plugin, long fromTime, long toTime); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/ActionsFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/ActionsFragment.java index d45fb10b4e..0fb505bda7 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/ActionsFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/ActionsFragment.java @@ -87,7 +87,6 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL tempBasalCancel.setOnClickListener(this); fill.setOnClickListener(this); history.setOnClickListener(this); - history.setVisibility(MainApp.devBranch ? View.VISIBLE : View.GONE); tddStats.setOnClickListener(this); updateGUI(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobCalculatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobCalculatorPlugin.java index 096668b996..d124bfea20 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobCalculatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobCalculatorPlugin.java @@ -1,6 +1,7 @@ package info.nightscout.androidaps.plugins.IobCobCalculator; import android.os.SystemClock; +import android.provider.SyncStateContract; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.util.LongSparseArray; @@ -98,6 +99,10 @@ public class IobCobCalculatorPlugin extends PluginBase { return autosensDataTable; } + public List getBgReadings() { + return bgReadings; + } + public List getBucketedData() { return bucketed_data; } @@ -136,13 +141,10 @@ public class IobCobCalculatorPlugin extends PluginBase { return rounded; } - void loadBgData(long start) { - if (start < oldestDataAvailable()) { - start = oldestDataAvailable(); - log.debug("Limiting BG data to oldest data available: " + DateUtil.dateAndTimeString(start)); - } - bgReadings = MainApp.getDbHelper().getBgreadingsDataFromTime((long) (start - 60 * 60 * 1000L * (24 + dia)), false); - log.debug("BG data loaded. Size: " + bgReadings.size() + " Start date: " + DateUtil.dateAndTimeString(start)); + void loadBgData(long now) { + long start = (long) (now - 60 * 60 * 1000L * (24 + dia)); + bgReadings = MainApp.getDbHelper().getBgreadingsDataFromTime(start, now, false); + log.debug("BG data loaded. Size: " + bgReadings.size() + " Start date: " + DateUtil.dateAndTimeString(start) + " End date: " + DateUtil.dateAndTimeString(now)); } private boolean isAbout5minData() { @@ -294,12 +296,19 @@ public class IobCobCalculatorPlugin extends PluginBase { log.debug("Bucketed data created. Size: " + bucketed_data.size()); } - public long oldestDataAvailable() { - long now = System.currentTimeMillis(); + public long calculateDetectionStart(long from, boolean limitDataToOldestAvailable) { + Profile profile = MainApp.getConfigBuilder().getProfile(from); + double dia = Constants.defaultDIA; + if (profile != null) dia = profile.getDia(); long oldestDataAvailable = TreatmentsPlugin.getPlugin().oldestDataAvailable(); - long getBGDataFrom = Math.max(oldestDataAvailable, (long) (now - T.hours(1).msecs() * (24 + MainApp.getConfigBuilder().getProfile().getDia()))); - log.debug("Limiting data to oldest available temps: " + new Date(oldestDataAvailable).toString()); + long getBGDataFrom; + if (limitDataToOldestAvailable) { + getBGDataFrom = Math.max(oldestDataAvailable, (long) (from - T.hours(1).msecs() * (24 + dia))); + if (getBGDataFrom == oldestDataAvailable) + log.debug("Limiting data to oldest available temps: " + new Date(oldestDataAvailable).toString()); + } else + getBGDataFrom = (long) (from - T.hours(1).msecs() * (24 + dia)); return getBGDataFrom; } @@ -403,7 +412,7 @@ public class IobCobCalculatorPlugin extends PluginBase { @Nullable public AutosensData getLastAutosensDataSynchronized(String reason) { - if (thread != null && thread.isAlive()) { + if (thread != null && thread.isAlive()) { log.debug("AUTOSENSDATA is waiting for calculation thread: " + reason); try { thread.join(5000); @@ -510,7 +519,7 @@ public class IobCobCalculatorPlugin extends PluginBase { public AutosensResult detectSensitivityWithLock(long fromTime, long toTime) { synchronized (dataLock) { - return ConfigBuilderPlugin.getActiveSensitivity().detectSensitivity(fromTime, toTime); + return ConfigBuilderPlugin.getActiveSensitivity().detectSensitivity(this, fromTime, toTime); } } @@ -529,7 +538,7 @@ public class IobCobCalculatorPlugin extends PluginBase { log.debug("Ignoring event for non default instance"); return; } - runCalculation("onEventAppInitialized", System.currentTimeMillis(), true, ev); + runCalculation("onEventAppInitialized", System.currentTimeMillis(), true, true, ev); } @Subscribe @@ -540,10 +549,10 @@ public class IobCobCalculatorPlugin extends PluginBase { return; } stopCalculation("onEventNewBG"); - runCalculation("onEventNewBG", System.currentTimeMillis(), true, ev); + runCalculation("onEventNewBG", System.currentTimeMillis(), true, true, ev); } - private void stopCalculation(String from) { + public void stopCalculation(String from) { if (thread != null && thread.getState() != Thread.State.TERMINATED) { stopCalculationTrigger = true; log.debug("Stopping calculation thread: " + from); @@ -554,13 +563,13 @@ public class IobCobCalculatorPlugin extends PluginBase { } } - public void runCalculation(String from, long start, boolean bgDataReload, Event cause) { - log.debug("Starting calculation thread: " + from); + public void runCalculation(String from, long end, boolean bgDataReload, boolean limitDataToOldestAvailable, Event cause) { + log.debug("Starting calculation thread: " + from + " to " + DateUtil.dateAndTimeString(end)); if (thread == null || thread.getState() == Thread.State.TERMINATED) { if (SensitivityOref1Plugin.getPlugin().isEnabled(PluginType.SENSITIVITY)) - thread = new IobCobOref1Thread(this, from, start, bgDataReload, cause); + thread = new IobCobOref1Thread(this, from, end, bgDataReload, limitDataToOldestAvailable, cause); else - thread = new IobCobThread(this, from, start, bgDataReload, cause); + thread = new IobCobThread(this, from, end, bgDataReload, limitDataToOldestAvailable, cause); thread.start(); } } @@ -586,7 +595,7 @@ public class IobCobCalculatorPlugin extends PluginBase { iobTable = new LongSparseArray<>(); autosensDataTable = new LongSparseArray<>(); } - runCalculation("onNewProfile", System.currentTimeMillis(), false, ev); + runCalculation("onNewProfile", System.currentTimeMillis(), false, true, ev); } @Subscribe @@ -609,7 +618,7 @@ public class IobCobCalculatorPlugin extends PluginBase { iobTable = new LongSparseArray<>(); autosensDataTable = new LongSparseArray<>(); } - runCalculation("onEventPreferenceChange", System.currentTimeMillis(), false, ev); + runCalculation("onEventPreferenceChange", System.currentTimeMillis(), false, true, ev); } } @@ -625,7 +634,7 @@ public class IobCobCalculatorPlugin extends PluginBase { iobTable = new LongSparseArray<>(); autosensDataTable = new LongSparseArray<>(); } - runCalculation("onEventConfigBuilderChange", System.currentTimeMillis(), false, ev); + runCalculation("onEventConfigBuilderChange", System.currentTimeMillis(), false, true, ev); } // When historical data is changed (comming from NS etc) finished calculations after this date must be invalidated @@ -669,7 +678,7 @@ public class IobCobCalculatorPlugin extends PluginBase { } } } - runCalculation("onEventNewHistoryData", System.currentTimeMillis(), false, ev); + runCalculation("onEventNewHistoryData", System.currentTimeMillis(), false, true, ev); //log.debug("Releasing onNewHistoryData"); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobOref1Thread.java b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobOref1Thread.java index d10d0ebe29..1c8c3f925a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobOref1Thread.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobOref1Thread.java @@ -48,19 +48,21 @@ public class IobCobOref1Thread extends Thread { private IobCobCalculatorPlugin iobCobCalculatorPlugin; private boolean bgDataReload; + private boolean limitDataToOldestAvailable; private String from; - private long start; + private long end; private PowerManager.WakeLock mWakeLock; - public IobCobOref1Thread(IobCobCalculatorPlugin plugin, String from, long start, boolean bgDataReload, Event cause) { + public IobCobOref1Thread(IobCobCalculatorPlugin plugin, String from, long end, boolean bgDataReload, boolean limitDataToOldestAvailable, Event cause) { super(); this.iobCobCalculatorPlugin = plugin; this.bgDataReload = bgDataReload; + this.limitDataToOldestAvailable = limitDataToOldestAvailable; this.from = from; this.cause = cause; - this.start = start; + this.end = end; PowerManager powerManager = (PowerManager) MainApp.instance().getApplicationContext().getSystemService(Context.POWER_SERVICE); mWakeLock = powerManager.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "iobCobThread"); @@ -81,15 +83,15 @@ public class IobCobOref1Thread extends Thread { } //log.debug("Locking calculateSensitivityData"); - long oldestTimeWithData = iobCobCalculatorPlugin.oldestDataAvailable(); + long oldestTimeWithData = iobCobCalculatorPlugin.calculateDetectionStart(end, limitDataToOldestAvailable); synchronized (iobCobCalculatorPlugin.dataLock) { if (bgDataReload) { - iobCobCalculatorPlugin.loadBgData(start); + iobCobCalculatorPlugin.loadBgData(end); iobCobCalculatorPlugin.createBucketedData(); } List bucketed_data = iobCobCalculatorPlugin.getBucketedData(); - LongSparseArray autosensDataTable = IobCobCalculatorPlugin.getPlugin().getAutosensDataTable(); + LongSparseArray autosensDataTable = iobCobCalculatorPlugin.getAutosensDataTable(); if (bucketed_data == null || bucketed_data.size() < 3) { log.debug("Aborting calculation thread (No bucketed data available): " + from); @@ -166,7 +168,7 @@ public class IobCobOref1Thread extends Thread { // https://github.com/openaps/oref0/blob/master/lib/determine-basal/cob-autosens.js#L169 if (i < bucketed_data.size() - 16) { // we need 1h of data to calculate minDeviationSlope long hourago = bgTime + 10 * 1000 - 60 * 60 * 1000L; - AutosensData hourAgoData = IobCobCalculatorPlugin.getPlugin().getAutosensData(hourago); + AutosensData hourAgoData = iobCobCalculatorPlugin.getAutosensData(hourago); if (hourAgoData != null) { int initialIndex = autosensDataTable.indexOfKey(hourAgoData.time); if (Config.logAutosensData) @@ -339,7 +341,7 @@ public class IobCobOref1Thread extends Thread { if (bgTime < now()) autosensDataTable.put(bgTime, autosensData); if (Config.logAutosensData) - log.debug("Running detectSensitivity from: " + DateUtil.dateAndTimeString(oldestTimeWithData) + " to: " + DateUtil.dateAndTimeString(bgTime) + " lastDataTime:" + IobCobCalculatorPlugin.getPlugin().lastDataTime()); + log.debug("Running detectSensitivity from: " + DateUtil.dateAndTimeString(oldestTimeWithData) + " to: " + DateUtil.dateAndTimeString(bgTime) + " lastDataTime:" + iobCobCalculatorPlugin.lastDataTime()); AutosensResult sensitivity = iobCobCalculatorPlugin.detectSensitivityWithLock(oldestTimeWithData, bgTime); if (Config.logAutosensData) log.debug("Sensitivity result: " + sensitivity.toString()); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobThread.java b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobThread.java index d60efb5bc6..ebd35b01e3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobThread.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobThread.java @@ -47,19 +47,21 @@ public class IobCobThread extends Thread { private IobCobCalculatorPlugin iobCobCalculatorPlugin; private boolean bgDataReload; + private boolean limitDataToOldestAvailable; private String from; - private long start; + private long end; private PowerManager.WakeLock mWakeLock; - public IobCobThread(IobCobCalculatorPlugin plugin, String from, long start, boolean bgDataReload, Event cause) { + public IobCobThread(IobCobCalculatorPlugin plugin, String from, long end, boolean bgDataReload, boolean limitDataToOldestAvailable, Event cause) { super(); this.iobCobCalculatorPlugin = plugin; this.bgDataReload = bgDataReload; + this.limitDataToOldestAvailable = limitDataToOldestAvailable; this.from = from; this.cause = cause; - this.start = start; + this.end = end; PowerManager powerManager = (PowerManager) MainApp.instance().getApplicationContext().getSystemService(Context.POWER_SERVICE); mWakeLock = powerManager.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "iobCobThread"); @@ -80,15 +82,15 @@ public class IobCobThread extends Thread { } //log.debug("Locking calculateSensitivityData"); - long oldestTimeWithData = iobCobCalculatorPlugin.oldestDataAvailable(); + long oldestTimeWithData = iobCobCalculatorPlugin.calculateDetectionStart(end, limitDataToOldestAvailable); synchronized (iobCobCalculatorPlugin.dataLock) { if (bgDataReload) { - iobCobCalculatorPlugin.loadBgData(start); + iobCobCalculatorPlugin.loadBgData(end); iobCobCalculatorPlugin.createBucketedData(); } List bucketed_data = iobCobCalculatorPlugin.getBucketedData(); - LongSparseArray autosensDataTable = IobCobCalculatorPlugin.getPlugin().getAutosensDataTable(); + LongSparseArray autosensDataTable = iobCobCalculatorPlugin.getAutosensDataTable(); if (bucketed_data == null || bucketed_data.size() < 3) { log.debug("Aborting calculation thread (No bucketed data available): " + from); @@ -165,7 +167,7 @@ public class IobCobThread extends Thread { // https://github.com/openaps/oref0/blob/master/lib/determine-basal/cob-autosens.js#L169 if (i < bucketed_data.size() - 16) { // we need 1h of data to calculate minDeviationSlope long hourago = bgTime + 10 * 1000 - 60 * 60 * 1000L; - AutosensData hourAgoData = IobCobCalculatorPlugin.getPlugin().getAutosensData(hourago); + AutosensData hourAgoData = iobCobCalculatorPlugin.getAutosensData(hourago); if (hourAgoData != null) { int initialIndex = autosensDataTable.indexOfKey(hourAgoData.time); if (Config.logAutosensData) @@ -266,7 +268,7 @@ public class IobCobThread extends Thread { if (bgTime < now()) autosensDataTable.put(bgTime, autosensData); if (Config.logAutosensData) - log.debug("Running detectSensitivity from: " + DateUtil.dateAndTimeString(oldestTimeWithData) + " to: " + DateUtil.dateAndTimeString(bgTime) + " lastDataTime:" + IobCobCalculatorPlugin.getPlugin().lastDataTime()); + log.debug("Running detectSensitivity from: " + DateUtil.dateAndTimeString(oldestTimeWithData) + " to: " + DateUtil.dateAndTimeString(bgTime) + " lastDataTime:" + iobCobCalculatorPlugin.lastDataTime()); AutosensResult sensitivity = iobCobCalculatorPlugin.detectSensitivityWithLock(oldestTimeWithData, bgTime); if (Config.logAutosensData) log.debug("Sensitivity result: " + sensitivity.toString()); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java index 2b4ab247b8..3fb4cd5b4a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java @@ -85,6 +85,7 @@ import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialo import info.nightscout.androidaps.plugins.Careportal.OptionsToShow; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin; +import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensData; import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensResult; import info.nightscout.androidaps.plugins.IobCobCalculator.CobInfo; import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; @@ -1384,9 +1385,9 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, // Sensitivity if (sensitivityView != null) { - AutosensResult lastAutosensResult = IobCobCalculatorPlugin.getPlugin().detectSensitivityWithLock(IobCobCalculatorPlugin.getPlugin().oldestDataAvailable(), System.currentTimeMillis()); - if (lastAutosensResult != null) - sensitivityView.setText(String.format("%.0f%%", lastAutosensResult.ratio * 100)); + AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getLastAutosensDataSynchronized("Overview"); + if (autosensData != null) + sensitivityView.setText(String.format("%.0f%%", autosensData.autosensResult.ratio * 100)); else sensitivityView.setText(""); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphData/GraphData.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphData/GraphData.java index 20feb76124..e551353915 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphData/GraphData.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphData/GraphData.java @@ -11,6 +11,9 @@ import com.jjoe64.graphview.series.DataPoint; import com.jjoe64.graphview.series.LineGraphSeries; import com.jjoe64.graphview.series.Series; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -47,6 +50,7 @@ import info.nightscout.utils.Round; */ public class GraphData { + private static Logger log = LoggerFactory.getLogger(GraphData.class); private GraphView graph; public double maxY = Double.MIN_VALUE; @@ -65,14 +69,17 @@ public class GraphData { public void addBgReadings(long fromTime, long toTime, double lowLine, double highLine, List predictions) { double maxBgValue = Double.MIN_VALUE; - bgReadingsArray = MainApp.getDbHelper().getBgreadingsDataFromTime(fromTime, true); + //bgReadingsArray = MainApp.getDbHelper().getBgreadingsDataFromTime(fromTime, true); + bgReadingsArray = iobCobCalculatorPlugin.getBgReadings(); List bgListArray = new ArrayList<>(); - if (bgReadingsArray.size() == 0) { + if (bgReadingsArray == null || bgReadingsArray.size() == 0) { + log.debug("No BG data."); return; } for (BgReading bg : bgReadingsArray) { + if (bg.date < fromTime || bg.date > toTime) continue; if (bg.value > maxBgValue) maxBgValue = bg.value; bgListArray.add(bg); } @@ -137,7 +144,7 @@ public class GraphData { for (long time = fromTime; time < toTime; time += 60 * 1000L) { Profile profile = MainApp.getConfigBuilder().getProfile(time); if (profile == null) continue; - BasalData basalData = IobCobCalculatorPlugin.getPlugin().getBasalData(profile, time); + BasalData basalData = iobCobCalculatorPlugin.getBasalData(profile, time); double baseBasalValue = basalData.basal; double absoluteLineValue = baseBasalValue; double tempBasalValue = 0; @@ -321,13 +328,13 @@ public class GraphData { } private double getNearestBg(long date) { - for (int r = bgReadingsArray.size() - 1; r >= 0; r--) { + for (int r = 0; r < bgReadingsArray.size(); r++) { BgReading reading = bgReadingsArray.get(r); if (reading.date > date) continue; return Profile.fromMgdlToUnits(reading.value, units); } return bgReadingsArray.size() > 0 - ? Profile.fromMgdlToUnits(bgReadingsArray.get(0).value, units) : 0; + ? Profile.fromMgdlToUnits(bgReadingsArray.get(0).value, units) : Profile.fromMgdlToUnits(100, units); } // scale in % of vertical size (like 0.3) @@ -342,7 +349,7 @@ public class GraphData { Profile profile = MainApp.getConfigBuilder().getProfile(time); double iob = 0d; if (profile != null) - iob = IobCobCalculatorPlugin.getPlugin().calculateFromTreatmentsAndTempsSynchronized(time, profile).iob; + iob = iobCobCalculatorPlugin.calculateFromTreatmentsAndTempsSynchronized(time, profile).iob; if (Math.abs(lastIob - iob) > 0.02) { if (Math.abs(lastIob - iob) > 0.2) iobArray.add(new ScaledDataPoint(time, lastIob, iobScale)); @@ -380,7 +387,7 @@ public class GraphData { Scale cobScale = new Scale(); for (long time = fromTime; time <= toTime; time += 5 * 60 * 1000L) { - AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getAutosensData(time); + AutosensData autosensData = iobCobCalculatorPlugin.getAutosensData(time); if (autosensData != null) { int cob = (int) autosensData.cob; if (cob != lastCob) { @@ -438,7 +445,7 @@ public class GraphData { Scale devScale = new Scale(); for (long time = fromTime; time <= toTime; time += 5 * 60 * 1000L) { - AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getAutosensData(time); + AutosensData autosensData = iobCobCalculatorPlugin.getAutosensData(time); if (autosensData != null) { int color = MainApp.gc(R.color.deviationblack); // "=" if (autosensData.type.equals("") || autosensData.type.equals("non-meal")) { @@ -488,7 +495,7 @@ public class GraphData { Scale ratioScale = new Scale(); for (long time = fromTime; time <= toTime; time += 5 * 60 * 1000L) { - AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getAutosensData(time); + AutosensData autosensData = iobCobCalculatorPlugin.getAutosensData(time); if (autosensData != null) { ratioArray.add(new ScaledDataPoint(time, autosensData.autosensResult.ratio - 1, ratioScale)); maxRatioValueFound = Math.max(maxRatioValueFound, autosensData.autosensResult.ratio - 1); @@ -525,7 +532,7 @@ public class GraphData { Scale dsMinScale = new Scale(); for (long time = fromTime; time <= toTime; time += 5 * 60 * 1000L) { - AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getAutosensData(time); + AutosensData autosensData = iobCobCalculatorPlugin.getAutosensData(time); if (autosensData != null) { dsMaxArray.add(new ScaledDataPoint(time, autosensData.slopeFromMaxDeviation, dsMaxScale)); dsMinArray.add(new ScaledDataPoint(time, autosensData.slopeFromMinDeviation, dsMinScale)); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/AbstractSensitivityPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/AbstractSensitivityPlugin.java index 1d96eeff6b..c91e1a4379 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/AbstractSensitivityPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/AbstractSensitivityPlugin.java @@ -8,6 +8,7 @@ import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.SensitivityInterface; import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensResult; +import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.utils.Round; import info.nightscout.utils.SP; import info.nightscout.utils.SafeParse; @@ -21,10 +22,10 @@ public abstract class AbstractSensitivityPlugin extends PluginBase implements Se } @Override - public abstract AutosensResult detectSensitivity(long fromTime, long toTime); + public abstract AutosensResult detectSensitivity(IobCobCalculatorPlugin plugin, long fromTime, long toTime); - public AutosensResult fillResult(double ratio, double carbsAbsorbed, String pastSensitivity, - String ratioLimit, String sensResult, int deviationsArraySize) { + AutosensResult fillResult(double ratio, double carbsAbsorbed, String pastSensitivity, + String ratioLimit, String sensResult, int deviationsArraySize) { return this.fillResult(ratio, carbsAbsorbed, pastSensitivity, ratioLimit, sensResult, deviationsArraySize, SafeParse.stringToDouble(SP.getString(R.string.key_openapsama_autosens_min, "0.7")), @@ -32,8 +33,8 @@ public abstract class AbstractSensitivityPlugin extends PluginBase implements Se } public AutosensResult fillResult(double ratio, double carbsAbsorbed, String pastSensitivity, - String ratioLimit, String sensResult, int deviationsArraySize, - double ratioMin, double ratioMax) { + String ratioLimit, String sensResult, int deviationsArraySize, + double ratioMin, double ratioMax) { double rawRatio = ratio; ratio = Math.max(ratio, ratioMin); ratio = Math.min(ratio, ratioMax); @@ -64,5 +65,4 @@ public abstract class AbstractSensitivityPlugin extends PluginBase implements Se } - } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/SensitivityAAPSPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/SensitivityAAPSPlugin.java index e5ca522a51..c90c1948d1 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/SensitivityAAPSPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/SensitivityAAPSPlugin.java @@ -49,8 +49,8 @@ public class SensitivityAAPSPlugin extends AbstractSensitivityPlugin { } @Override - public AutosensResult detectSensitivity(long fromTime, long toTime) { - LongSparseArray autosensDataTable = IobCobCalculatorPlugin.getPlugin().getAutosensDataTable(); + public AutosensResult detectSensitivity(IobCobCalculatorPlugin iobCobCalculatorPlugin, long fromTime, long toTime) { + LongSparseArray autosensDataTable = iobCobCalculatorPlugin.getAutosensDataTable(); String age = SP.getString(R.string.key_age, ""); int defaultHours = 24; @@ -67,13 +67,13 @@ public class SensitivityAAPSPlugin extends AbstractSensitivityPlugin { } if (autosensDataTable == null || autosensDataTable.size() < 4) { - log.debug("No autosens data available. lastDataTime=" + IobCobCalculatorPlugin.getPlugin().lastDataTime()); + log.debug("No autosens data available. lastDataTime=" + iobCobCalculatorPlugin.lastDataTime()); return new AutosensResult(); } - AutosensData current = IobCobCalculatorPlugin.getPlugin().getAutosensData(toTime); // this is running inside lock already + AutosensData current = iobCobCalculatorPlugin.getAutosensData(toTime); // this is running inside lock already if (current == null) { - log.debug("No autosens data available. toTime: " + DateUtil.dateAndTimeString(toTime) + " lastDataTime: " + IobCobCalculatorPlugin.getPlugin().lastDataTime()); + log.debug("No autosens data available. toTime: " + DateUtil.dateAndTimeString(toTime) + " lastDataTime: " + iobCobCalculatorPlugin.lastDataTime()); return new AutosensResult(); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/SensitivityOref0Plugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/SensitivityOref0Plugin.java index c9086dbfbd..81ceca968b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/SensitivityOref0Plugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/SensitivityOref0Plugin.java @@ -48,8 +48,8 @@ public class SensitivityOref0Plugin extends AbstractSensitivityPlugin { } @Override - public AutosensResult detectSensitivity(long fromTime, long toTime) { - LongSparseArray autosensDataTable = IobCobCalculatorPlugin.getPlugin().getAutosensDataTable(); + public AutosensResult detectSensitivity(IobCobCalculatorPlugin iobCobCalculatorPlugin, long fromTime, long toTime) { + LongSparseArray autosensDataTable = iobCobCalculatorPlugin.getAutosensDataTable(); int hoursForDetection = 24; @@ -62,13 +62,13 @@ public class SensitivityOref0Plugin extends AbstractSensitivityPlugin { } if (autosensDataTable == null || autosensDataTable.size() < 4) { - log.debug("No autosens data available. lastDataTime=" + IobCobCalculatorPlugin.getPlugin().lastDataTime()); + log.debug("No autosens data available. lastDataTime=" + iobCobCalculatorPlugin.lastDataTime()); return new AutosensResult(); } - AutosensData current = IobCobCalculatorPlugin.getPlugin().getAutosensData(toTime); // this is running inside lock already + AutosensData current = iobCobCalculatorPlugin.getAutosensData(toTime); // this is running inside lock already if (current == null) { - log.debug("No autosens data available. toTime: " + DateUtil.dateAndTimeString(toTime) + " lastDataTime: " + IobCobCalculatorPlugin.getPlugin().lastDataTime()); + log.debug("No autosens data available. toTime: " + DateUtil.dateAndTimeString(toTime) + " lastDataTime: " + iobCobCalculatorPlugin.lastDataTime()); return new AutosensResult(); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/SensitivityOref1Plugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/SensitivityOref1Plugin.java index 214c82db9b..d6370c03a4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/SensitivityOref1Plugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/SensitivityOref1Plugin.java @@ -48,10 +48,10 @@ public class SensitivityOref1Plugin extends AbstractSensitivityPlugin { } @Override - public AutosensResult detectSensitivity(long fromTime, long toTime) { + public AutosensResult detectSensitivity(IobCobCalculatorPlugin iobCobCalculatorPlugin, long fromTime, long toTime) { // todo this method is called from the IobCobCalculatorPlugin, which leads to a circular // dependency, this should be avoided - LongSparseArray autosensDataTable = IobCobCalculatorPlugin.getPlugin().getAutosensDataTable(); + LongSparseArray autosensDataTable = iobCobCalculatorPlugin.getAutosensDataTable(); Profile profile = MainApp.getConfigBuilder().getProfile(); @@ -61,14 +61,14 @@ public class SensitivityOref1Plugin extends AbstractSensitivityPlugin { } if (autosensDataTable == null || autosensDataTable.size() < 4) { - log.debug("No autosens data available. lastDataTime=" + IobCobCalculatorPlugin.getPlugin().lastDataTime()); + log.debug("No autosens data available. lastDataTime=" + iobCobCalculatorPlugin.lastDataTime()); return new AutosensResult(); } // the current - AutosensData current = IobCobCalculatorPlugin.getPlugin().getAutosensData(toTime); // this is running inside lock already + AutosensData current = iobCobCalculatorPlugin.getAutosensData(toTime); // this is running inside lock already if (current == null) { - log.debug("No autosens data available. toTime: " + DateUtil.dateAndTimeString(toTime) + " lastDataTime: " + IobCobCalculatorPlugin.getPlugin().lastDataTime()); + log.debug("No autosens data available. toTime: " + DateUtil.dateAndTimeString(toTime) + " lastDataTime: " + iobCobCalculatorPlugin.lastDataTime()); return new AutosensResult(); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/SensitivityWeightedAveragePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/SensitivityWeightedAveragePlugin.java index 0200838d39..d4b9f58ab5 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/SensitivityWeightedAveragePlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/SensitivityWeightedAveragePlugin.java @@ -47,8 +47,8 @@ public class SensitivityWeightedAveragePlugin extends AbstractSensitivityPlugin } @Override - public AutosensResult detectSensitivity(long fromTime, long toTime) { - LongSparseArray autosensDataTable = IobCobCalculatorPlugin.getPlugin().getAutosensDataTable(); + public AutosensResult detectSensitivity(IobCobCalculatorPlugin iobCobCalculatorPlugin, long fromTime, long toTime) { + LongSparseArray autosensDataTable = iobCobCalculatorPlugin.getAutosensDataTable(); String age = SP.getString(R.string.key_age, ""); int defaultHours = 24; @@ -58,14 +58,14 @@ public class SensitivityWeightedAveragePlugin extends AbstractSensitivityPlugin int hoursForDetection = SP.getInt(R.string.key_openapsama_autosens_period, defaultHours); if (autosensDataTable == null || autosensDataTable.size() < 4) { - log.debug("No autosens data available. lastDataTime=" + IobCobCalculatorPlugin.getPlugin().lastDataTime()); + log.debug("No autosens data available. lastDataTime=" + iobCobCalculatorPlugin.lastDataTime()); return new AutosensResult(); } - AutosensData current = IobCobCalculatorPlugin.getPlugin().getAutosensData(toTime); // this is running inside lock already + AutosensData current = iobCobCalculatorPlugin.getAutosensData(toTime); // this is running inside lock already if (current == null) { if (Config.logAutosensData) - log.debug("No autosens data available. toTime: " + DateUtil.dateAndTimeString(toTime) + " lastDataTime: " + IobCobCalculatorPlugin.getPlugin().lastDataTime()); + log.debug("No autosens data available. toTime: " + DateUtil.dateAndTimeString(toTime) + " lastDataTime: " + iobCobCalculatorPlugin.lastDataTime()); return new AutosensResult(); } diff --git a/app/src/main/res/layout/activity_historybrowse.xml b/app/src/main/res/layout/activity_historybrowse.xml index f05672e765..6f29d671c4 100644 --- a/app/src/main/res/layout/activity_historybrowse.xml +++ b/app/src/main/res/layout/activity_historybrowse.xml @@ -27,41 +27,35 @@ android:layout_height="wrap_content" android:orientation="horizontal"> - -