Merge pull request #402 from nightscout/adrian/cleanup-glucosestatus

Refactor GlucoseStatusProvider out of GlucoseStatus
This commit is contained in:
Milos Kozak 2021-03-08 20:20:10 +01:00 committed by GitHub
commit 6c072dbe6e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 222 additions and 228 deletions

View file

@ -13,6 +13,7 @@ import info.nightscout.androidaps.databinding.DialogCalibrationBinding
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.utils.HtmlHelper
import info.nightscout.androidaps.utils.XdripCalibrations
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
@ -28,6 +29,7 @@ class CalibrationDialog : DialogFragmentWithDate() {
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var xdripCalibrations: XdripCalibrations
@Inject lateinit var uel: UserEntryLogger
@Inject lateinit var glucoseStatusProvider: GlucoseStatusProvider
private var _binding: DialogCalibrationBinding? = null
@ -51,7 +53,7 @@ class CalibrationDialog : DialogFragmentWithDate() {
super.onViewCreated(view, savedInstanceState)
val units = profileFunction.getUnits()
val bg = Profile.fromMgdlToUnits(GlucoseStatus(injector).glucoseStatusData?.glucose
val bg = Profile.fromMgdlToUnits(glucoseStatusProvider.glucoseStatusData?.glucose
?: 0.0, units)
if (units == Constants.MMOL)
binding.bg.setParams(savedInstanceState?.getDouble("bg")

View file

@ -20,7 +20,7 @@ import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.HtmlHelper
import info.nightscout.androidaps.utils.Translator
@ -41,6 +41,7 @@ class CareDialog : DialogFragmentWithDate() {
@Inject lateinit var translator: Translator
@Inject lateinit var uel: UserEntryLogger
@Inject lateinit var databaseHelper: DatabaseHelperInterface
@Inject lateinit var glucoseStatusProvider: GlucoseStatusProvider
enum class EventType {
BGCHECK,
@ -132,7 +133,7 @@ class CareDialog : DialogFragmentWithDate() {
}
}
val bg = Profile.fromMgdlToUnits(GlucoseStatus(injector).glucoseStatusData?.glucose
val bg = Profile.fromMgdlToUnits(glucoseStatusProvider.glucoseStatusData?.glucose
?: 0.0, profileFunction.getUnits())
val bgTextWatcher: TextWatcher = object : TextWatcher {
override fun afterTextChanged(s: Editable) {}

View file

@ -16,6 +16,7 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy
@ -44,7 +45,8 @@ open class OpenAPSAMAPlugin @Inject constructor(
private val profiler: Profiler,
private val fabricPrivacy: FabricPrivacy,
private val dateUtil: DateUtil,
private val repository: AppRepository
private val repository: AppRepository,
private val glucoseStatusProvider: GlucoseStatusProvider
) : PluginBase(PluginDescription()
.mainType(PluginType.APS)
.fragmentClass(OpenAPSAMAFragment::class.java.name)
@ -81,7 +83,7 @@ open class OpenAPSAMAPlugin @Inject constructor(
aapsLogger.debug(LTag.APS, "invoke from $initiator tempBasalFallback: $tempBasalFallback")
lastAPSResult = null
val determineBasalAdapterAMAJS = DetermineBasalAdapterAMAJS(ScriptReader(context), injector)
val glucoseStatus = GlucoseStatus(injector).glucoseStatusData
val glucoseStatus = glucoseStatusProvider.glucoseStatusData
val profile = profileFunction.getProfile()
val pump = activePlugin.activePump
if (profile == null) {

View file

@ -18,6 +18,7 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.HardLimits
@ -45,7 +46,8 @@ open class OpenAPSSMBPlugin @Inject constructor(
private val profiler: Profiler,
private val sp: SP,
private val dateUtil: DateUtil,
private val repository: AppRepository
private val repository: AppRepository,
private val glucoseStatusProvider: GlucoseStatusProvider
) : PluginBase(PluginDescription()
.mainType(PluginType.APS)
.fragmentClass(OpenAPSSMBFragment::class.java.name)
@ -89,7 +91,7 @@ open class OpenAPSSMBPlugin @Inject constructor(
override fun invoke(initiator: String, tempBasalFallback: Boolean) {
aapsLogger.debug(LTag.APS, "invoke from $initiator tempBasalFallback: $tempBasalFallback")
lastAPSResult = null
val glucoseStatus = GlucoseStatus(injector).glucoseStatusData
val glucoseStatus = glucoseStatusProvider.glucoseStatusData
val profile = profileFunction.getProfile()
val pump = activePlugin.activePump
if (profile == null) {

View file

@ -8,12 +8,12 @@ import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Config
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.IobTotal
import info.nightscout.androidaps.events.Event
import info.nightscout.androidaps.events.EventExtendedBolusChange
import info.nightscout.androidaps.events.EventNewBasalProfile
import info.nightscout.androidaps.events.EventTempBasalChange
import info.nightscout.androidaps.events.EventTreatmentChange
import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.events.*
import info.nightscout.androidaps.interfaces.ActivePluginProvider
import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.PluginDescription
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.aps.events.EventOpenAPSUpdateGui
@ -21,9 +21,8 @@ import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus
import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.events.EventAutosensCalculationFinished
import info.nightscout.androidaps.receivers.ReceiverStatusStore
import info.nightscout.androidaps.services.Intents
import info.nightscout.androidaps.utils.DefaultValueHelper
@ -51,7 +50,7 @@ class DataBroadcastPlugin @Inject constructor(
private val activePlugin: ActivePluginProvider,
private var receiverStatusStore: ReceiverStatusStore,
private val config: Config,
private val databaseHelper: DatabaseHelperInterface
private val glucoseStatusProvider: GlucoseStatusProvider
) : PluginBase(PluginDescription()
.mainType(PluginType.GENERAL)
@ -123,14 +122,14 @@ class DataBroadcastPlugin @Inject constructor(
private fun bgStatus(bundle: Bundle) {
val lastBG = iobCobCalculatorPlugin.lastBg() ?: return
val glucoseStatus = GlucoseStatus(injector).glucoseStatusData ?: return
val glucoseStatus = glucoseStatusProvider.glucoseStatusData ?: return
bundle.putDouble("glucoseMgdl", lastBG.value) // last BG in mgdl
bundle.putLong("glucoseTimeStamp", lastBG.timestamp) // timestamp
bundle.putString("units", profileFunction.getUnits()) // units used in AAPS "mg/dl" or "mmol"
bundle.putString("slopeArrow", lastBG.trendArrow.text) // direction arrow as string
bundle.putDouble("deltaMgdl", glucoseStatus.delta) // bg delta in mgdl
bundle.putDouble("avgDeltaMgdl", glucoseStatus.avgDelta) // average bg delta
bundle.putDouble("avgDeltaMgdl", glucoseStatus.shortAvgDelta) // average bg delta
bundle.putDouble("high", defaultValueHelper.determineHighLine()) // predefined top value of in range (green area)
bundle.putDouble("low", defaultValueHelper.determineLowLine()) // predefined bottom value of in range
}

View file

@ -48,7 +48,7 @@ import info.nightscout.androidaps.plugins.general.overview.activities.QuickWizar
import info.nightscout.androidaps.plugins.general.overview.graphData.GraphData
import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationStore
import info.nightscout.androidaps.plugins.general.wear.events.EventWearInitiateAction
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
@ -117,6 +117,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
@Inject lateinit var databaseHelper: DatabaseHelperInterface
@Inject lateinit var uel: UserEntryLogger
@Inject lateinit var repository: AppRepository
@Inject lateinit var glucoseStatusProvider: GlucoseStatusProvider
private val disposable = CompositeDisposable()
@ -298,14 +299,14 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
if (childFragmentManager.isStateSaved) return
activity?.let { activity ->
when (v.id) {
R.id.treatment_button -> protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, UIRunnable { if (isAdded) TreatmentDialog().show(childFragmentManager, "Overview") })
R.id.wizard_button -> protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, UIRunnable { if (isAdded) WizardDialog().show(childFragmentManager, "Overview") })
R.id.insulin_button -> protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, UIRunnable { if (isAdded) InsulinDialog().show(childFragmentManager, "Overview") })
R.id.treatment_button -> protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, UIRunnable { if (isAdded) TreatmentDialog().show(childFragmentManager, "Overview") })
R.id.wizard_button -> protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, UIRunnable { if (isAdded) WizardDialog().show(childFragmentManager, "Overview") })
R.id.insulin_button -> protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, UIRunnable { if (isAdded) InsulinDialog().show(childFragmentManager, "Overview") })
R.id.quick_wizard_button -> protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, UIRunnable { if (isAdded) onClickQuickWizard() })
R.id.carbs_button -> protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, UIRunnable { if (isAdded) CarbsDialog().show(childFragmentManager, "Overview") })
R.id.temp_target -> protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, UIRunnable { if (isAdded) TempTargetDialog().show(childFragmentManager, "Overview") })
R.id.carbs_button -> protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, UIRunnable { if (isAdded) CarbsDialog().show(childFragmentManager, "Overview") })
R.id.temp_target -> protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, UIRunnable { if (isAdded) TempTargetDialog().show(childFragmentManager, "Overview") })
R.id.active_profile -> {
R.id.active_profile -> {
ProfileViewerDialog().also { pvd ->
pvd.arguments = Bundle().also {
it.putLong("time", DateUtil.now())
@ -314,7 +315,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
}.show(childFragmentManager, "ProfileViewDialog")
}
R.id.cgm_button -> {
R.id.cgm_button -> {
if (xdripPlugin.isEnabled(PluginType.BGSOURCE))
openCgmApp("com.eveningoutpost.dexdrip")
else if (dexcomPlugin.isEnabled(PluginType.BGSOURCE)) {
@ -325,7 +326,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
}
}
R.id.calibration_button -> {
R.id.calibration_button -> {
if (xdripPlugin.isEnabled(PluginType.BGSOURCE)) {
CalibrationDialog().show(childFragmentManager, "CalibrationDialog")
} else if (dexcomPlugin.isEnabled(PluginType.BGSOURCE)) {
@ -340,7 +341,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
}
}
R.id.accept_temp_button -> {
R.id.accept_temp_button -> {
profileFunction.getProfile() ?: return
if (loopPlugin.isEnabled(PluginType.LOOP)) {
val lastRun = loopPlugin.lastRun
@ -360,7 +361,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
}
}
R.id.aps_mode -> {
R.id.aps_mode -> {
protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, UIRunnable {
if (isAdded) LoopDialog().also { dialog ->
dialog.arguments = Bundle().also { it.putInt("showOkCancel", 1) }
@ -392,7 +393,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
return true
}
R.id.aps_mode -> {
R.id.aps_mode -> {
activity?.let { activity ->
protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, UIRunnable {
LoopDialog().also { dialog ->
@ -402,8 +403,8 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
}
}
R.id.temp_target -> v.performClick()
R.id.active_profile -> activity?.let { activity -> protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, UIRunnable { ProfileSwitchDialog().show(childFragmentManager, "Overview") }) }
R.id.temp_target -> v.performClick()
R.id.active_profile -> activity?.let { activity -> protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, UIRunnable { ProfileSwitchDialog().show(childFragmentManager, "Overview") }) }
}
return false
@ -590,7 +591,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
binding.infoLayout.arrow.setImageResource(trendCalculator.getTrendArrow(lastBG).directionToIcon())
binding.infoLayout.arrow.setColorFilter(color)
val glucoseStatus = GlucoseStatus(injector).glucoseStatusData
val glucoseStatus = glucoseStatusProvider.glucoseStatusData
if (glucoseStatus != null) {
binding.infoLayout.deltaLarge.text = Profile.toSignedUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units)
binding.infoLayout.deltaLarge.setTextColor(color)

View file

@ -16,6 +16,7 @@ import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.utils.DecimalFormatter
import info.nightscout.androidaps.utils.FabricPrivacy
@ -42,7 +43,8 @@ class PersistentNotificationPlugin @Inject constructor(
private val context: Context,
private val notificationHolder: NotificationHolderInterface,
private val dummyServiceHelper: DummyServiceHelper,
private val iconsProvider: IconsProvider
private val iconsProvider: IconsProvider,
private val glucoseStatusProvider: GlucoseStatusProvider
) : PluginBase(PluginDescription()
.mainType(PluginType.GENERAL)
.neverVisible(true)
@ -130,13 +132,13 @@ class PersistentNotificationPlugin @Inject constructor(
var line1aa: String
val units = profileFunction.getUnits()
val lastBG = iobCobCalculatorPlugin.lastBg()
val glucoseStatus = GlucoseStatus(injector).glucoseStatusData
val glucoseStatus = glucoseStatusProvider.glucoseStatusData
if (lastBG != null) {
line1aa = lastBG.valueToUnitsString(units)
line1 = line1aa
if (glucoseStatus != null) {
line1 += (" Δ" + Profile.toSignedUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units)
+ " avgΔ" + Profile.toSignedUnitsString(glucoseStatus.avgDelta, glucoseStatus.avgDelta * Constants.MGDL_TO_MMOLL, units))
+ " avgΔ" + Profile.toSignedUnitsString(glucoseStatus.shortAvgDelta, glucoseStatus.shortAvgDelta * Constants.MGDL_TO_MMOLL, units))
line1aa += " " + lastBG.trendArrow.symbol
} else {
line1 += " " +

View file

@ -36,6 +36,7 @@ import info.nightscout.androidaps.plugins.general.overview.notifications.Notific
import info.nightscout.androidaps.plugins.general.smsCommunicator.events.EventSmsCommunicatorUpdateGui
import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePassword
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.receivers.BundleStore
@ -78,6 +79,7 @@ class SmsCommunicatorPlugin @Inject constructor(
private val dateUtil: DateUtil,
private val uel: UserEntryLogger,
private val nsUpload: NSUpload,
private val glucoseStatusProvider: GlucoseStatusProvider,
private val repository: AppRepository
) : PluginBase(PluginDescription()
.mainType(PluginType.GENERAL)
@ -322,7 +324,7 @@ class SmsCommunicatorPlugin @Inject constructor(
val agoMin = (agoMilliseconds / 60.0 / 1000.0).toInt()
reply = resourceHelper.gs(R.string.sms_lastbg) + " " + lastBG.valueToUnitsString(units) + " " + String.format(resourceHelper.gs(R.string.sms_minago), agoMin) + ", "
}
val glucoseStatus = GlucoseStatus(injector).glucoseStatusData
val glucoseStatus = glucoseStatusProvider.glucoseStatusData
if (glucoseStatus != null) reply += resourceHelper.gs(R.string.sms_delta) + " " + Profile.toUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) + " " + units + ", "
activePlugin.activeTreatments.updateTotalIOBTreatments()
val bolusIob = activePlugin.activeTreatments.lastCalculationTreatments.round()

View file

@ -51,6 +51,7 @@ import info.nightscout.androidaps.plugins.general.wear.WearPlugin;
import info.nightscout.androidaps.plugins.general.wear.events.EventWearConfirmAction;
import info.nightscout.androidaps.plugins.general.wear.events.EventWearInitiateAction;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.receivers.ReceiverStatusStore;
@ -62,7 +63,7 @@ import info.nightscout.androidaps.utils.resources.ResourceHelper;
import info.nightscout.androidaps.utils.sharedPreferences.SP;
public class WatchUpdaterService extends WearableListenerService implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
@Inject public HasAndroidInjector injector;
@Inject public GlucoseStatusProvider glucoseStatusProvider;
@Inject public AAPSLogger aapsLogger;
@Inject public WearPlugin wearPlugin;
@Inject public ResourceHelper resourceHelper;
@ -282,7 +283,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
GlucoseValue lastBG = iobCobCalculatorPlugin.lastBg();
// Log.d(TAG, logPrefix + "LastBg=" + lastBG);
if (lastBG != null) {
GlucoseStatus glucoseStatus = new GlucoseStatus(injector).getGlucoseStatusData();
GlucoseStatus glucoseStatus = glucoseStatusProvider.getGlucoseStatusData();
if (googleApiClient != null && !googleApiClient.isConnected() && !googleApiClient.isConnecting()) {
googleApiConnect();
@ -323,7 +324,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
} else {
dataMap.putString("slopeArrow", slopeArrow(glucoseStatus.getDelta()));
dataMap.putString("delta", deltastring(glucoseStatus.getDelta(), glucoseStatus.getDelta() * Constants.MGDL_TO_MMOLL, units));
dataMap.putString("avgDelta", deltastring(glucoseStatus.getAvgDelta(), glucoseStatus.getAvgDelta() * Constants.MGDL_TO_MMOLL, units));
dataMap.putString("avgDelta", deltastring(glucoseStatus.getShortAvgDelta(), glucoseStatus.getShortAvgDelta() * Constants.MGDL_TO_MMOLL, units));
}
dataMap.putLong("sgvLevel", sgvLevel);
dataMap.putDouble("sgvDouble", lastBG.getValue());
@ -386,7 +387,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
if (last_bg == null) return;
List<GlucoseValue> graph_bgs = repository.compatGetBgReadingsDataFromTime(startTime, true).blockingGet();
GlucoseStatus glucoseStatus = new GlucoseStatus(injector).getGlucoseStatusData(true);
GlucoseStatus glucoseStatus = glucoseStatusProvider.getGlucoseStatusData(true);
if (!graph_bgs.isEmpty()) {
DataMap entries = dataMapSingleBG(last_bg, glucoseStatus);

View file

@ -22,6 +22,7 @@ import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.utils.CarbTimer
@ -57,6 +58,7 @@ class BolusWizard @Inject constructor(
@Inject lateinit var config: Config
@Inject lateinit var uel: UserEntryLogger
@Inject lateinit var carbTimer: CarbTimer
@Inject lateinit var glucoseStatusProvider: GlucoseStatusProvider
init {
injector.androidInjector().inject(this)
@ -181,7 +183,7 @@ class BolusWizard @Inject constructor(
}
// Insulin from 15 min trend
glucoseStatus = GlucoseStatus(injector).glucoseStatusData
glucoseStatus = glucoseStatusProvider.glucoseStatusData
glucoseStatus?.let {
if (useTrend) {
trend = it.shortAvgDelta

View file

@ -10,6 +10,7 @@ import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.utils.DateUtil
@ -32,6 +33,7 @@ class QuickWizardEntry @Inject constructor(private val injector: HasAndroidInjec
@Inject lateinit var iobCobCalculatorPlugin: IobCobCalculatorPlugin
@Inject lateinit var repository: AppRepository
@Inject lateinit var dateUtil: DateUtil
@Inject lateinit var glucoseStatusProvider: GlucoseStatusProvider
lateinit var storage: JSONObject
var position: Int = -1
@ -114,7 +116,7 @@ class QuickWizardEntry @Inject constructor(private val injector: HasAndroidInjec
}
if (loopPlugin.isEnabled(loopPlugin.getType()) && loopPlugin.isSuperBolus) superBolus = false
// Trend
val glucoseStatus = GlucoseStatus(injector).glucoseStatusData
val glucoseStatus = glucoseStatusProvider.glucoseStatusData
var trend = false
if (useTrend() == YES) {
trend = true

View file

@ -23,6 +23,7 @@ import info.nightscout.androidaps.plugins.constraints.safety.SafetyPlugin
import info.nightscout.androidaps.plugins.general.maintenance.LoggerUtils
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import info.nightscout.androidaps.plugins.general.nsclient.UploadQueue
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.plugins.pump.combo.ComboPlugin
import info.nightscout.androidaps.plugins.pump.common.bolusInfo.DetailedBolusInfoStorage
@ -138,6 +139,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
`when`(activePlugin.activePump).thenReturn(virtualPumpPlugin)
constraintChecker = ConstraintChecker(activePlugin)
val glucoseStatusProvider = GlucoseStatusProvider(aapsLogger = aapsLogger, iobCobCalculatorPlugin = iobCobCalculatorPlugin)
danaPump = DanaPump(aapsLogger, sp, injector)
hardLimits = HardLimits(aapsLogger, rxBus, sp, resourceHelper, context, nsUpload)
objectivesPlugin = ObjectivesPlugin(injector, aapsLogger, resourceHelper, activePlugin, sp, Config(), uel)
@ -145,8 +149,8 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
danaRPlugin = DanaRPlugin(injector, aapsLogger, aapsSchedulers, rxBus, context, resourceHelper, constraintChecker, activePlugin, sp, commandQueue, danaPump, dateUtil, fabricPrivacy)
danaRSPlugin = DanaRSPlugin(injector, aapsLogger, aapsSchedulers, rxBus, context, resourceHelper, constraintChecker, profileFunction, activePluginProvider, sp, commandQueue, danaPump, detailedBolusInfoStorage, fabricPrivacy, dateUtil)
insightPlugin = LocalInsightPlugin(injector, aapsLogger, rxBus, resourceHelper, treatmentsInterface, sp, commandQueue, profileFunction, nsUpload, context, uploadQueue, Config(), dateUtil, databaseHelper)
openAPSSMBPlugin = OpenAPSSMBPlugin(injector, aapsLogger, rxBus, constraintChecker, resourceHelper, profileFunction, context, activePlugin, treatmentsInterface, iobCobCalculatorPlugin, hardLimits, profiler, sp, dateUtil, repository)
openAPSAMAPlugin = OpenAPSAMAPlugin(injector, aapsLogger, rxBus, constraintChecker, resourceHelper, profileFunction, context, activePlugin, treatmentsInterface, iobCobCalculatorPlugin, hardLimits, profiler, fabricPrivacy, dateUtil, repository)
openAPSSMBPlugin = OpenAPSSMBPlugin(injector, aapsLogger, rxBus, constraintChecker, resourceHelper, profileFunction, context, activePlugin, treatmentsInterface, iobCobCalculatorPlugin, hardLimits, profiler, sp, dateUtil, repository, glucoseStatusProvider)
openAPSAMAPlugin = OpenAPSAMAPlugin(injector, aapsLogger, rxBus, constraintChecker, resourceHelper, profileFunction, context, activePlugin, treatmentsInterface, iobCobCalculatorPlugin, hardLimits, profiler, fabricPrivacy, dateUtil, repository, glucoseStatusProvider)
safetyPlugin = SafetyPlugin(injector, aapsLogger, resourceHelper, sp, rxBus, constraintChecker, openAPSAMAPlugin, openAPSSMBPlugin, sensitivityOref1Plugin, activePlugin, hardLimits, BuildHelper(Config(), loggerUtils), treatmentsInterface, Config())
val constraintsPluginsList = ArrayList<PluginBase>()
constraintsPluginsList.add(safetyPlugin)

View file

@ -27,7 +27,7 @@ import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePassword
import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePasswordValidationResult
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
@ -91,10 +91,6 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
it.resourceHelper = resourceHelper
it.otp = otp
}
if (it is GlucoseStatus) {
it.aapsLogger = aapsLogger
it.iobCobCalculatorPlugin = iobCobCalculatorPlugin
}
}
}
@ -121,8 +117,9 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
repository.runTransactionForResult(anyObject<InsertTemporaryTargetAndCancelCurrentTransaction>())
).thenReturn(Single.just(InsertTemporaryTargetAndCancelCurrentTransaction.TransactionResult().apply {
}))
val glucoseStatusProvider = GlucoseStatusProvider(aapsLogger = aapsLogger, iobCobCalculatorPlugin = iobCobCalculatorPlugin)
smsCommunicatorPlugin = SmsCommunicatorPlugin(injector, aapsLogger, resourceHelper, aapsSchedulers, sp, constraintChecker, rxBus, profileFunction, fabricPrivacy, activePlugin, commandQueue, loopPlugin, iobCobCalculatorPlugin, xdripCalibrations, otp, Config(), DateUtil(context), uel, nsUpload, repository)
smsCommunicatorPlugin = SmsCommunicatorPlugin(injector, aapsLogger, resourceHelper, aapsSchedulers, sp, constraintChecker, rxBus, profileFunction, fabricPrivacy, activePlugin, commandQueue, loopPlugin, iobCobCalculatorPlugin, xdripCalibrations, otp, Config(), DateUtil(context), uel, nsUpload, glucoseStatusProvider, repository)
smsCommunicatorPlugin.setPluginEnabled(PluginType.GENERAL, true)
Mockito.doAnswer { invocation: InvocationOnMock ->
val callback = invocation.getArgument<Callback>(1)

View file

@ -16,6 +16,7 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
@ -59,10 +60,7 @@ class BolusWizardTest : TestBase() {
it.commandQueue = commandQueue
it.loopPlugin = loopPlugin
it.iobCobCalculatorPlugin = iobCobCalculatorPlugin
}
if (it is GlucoseStatus) {
it.aapsLogger = aapsLogger
it.iobCobCalculatorPlugin = iobCobCalculatorPlugin
it.glucoseStatusProvider = GlucoseStatusProvider(aapsLogger = aapsLogger, iobCobCalculatorPlugin = iobCobCalculatorPlugin)
}
}
}

View file

@ -20,6 +20,7 @@ import info.nightscout.androidaps.plugins.general.automation.dialogs.ChooseTrigg
import info.nightscout.androidaps.plugins.general.automation.events.EventTriggerChanged
import info.nightscout.androidaps.plugins.general.automation.events.EventTriggerClone
import info.nightscout.androidaps.plugins.general.automation.events.EventTriggerRemove
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.services.LastLocationDataContainer
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
@ -39,6 +40,7 @@ abstract class Trigger(val injector: HasAndroidInjector) {
@Inject lateinit var treatmentsInterface: TreatmentsInterface
@Inject lateinit var activePlugin: ActivePluginProvider
@Inject lateinit var iobCobCalculatorPlugin: IobCobCalculatorInterface
@Inject lateinit var glucoseStatusProvider: GlucoseStatusProvider
init {
injector.androidInjector().inject(this)

View file

@ -46,7 +46,7 @@ class TriggerBg(injector: HasAndroidInjector) : Trigger(injector) {
}
override fun shouldRun(): Boolean {
val glucoseStatus = GlucoseStatus(injector).glucoseStatusData
val glucoseStatus = glucoseStatusProvider.glucoseStatusData
if (glucoseStatus == null && comparator.value == Comparator.Compare.IS_NOT_AVAILABLE) {
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
return true

View file

@ -64,7 +64,7 @@ class TriggerDelta(injector: HasAndroidInjector) : Trigger(injector) {
}
override fun shouldRun(): Boolean {
val glucoseStatus = GlucoseStatus(injector).glucoseStatusData
val glucoseStatus = glucoseStatusProvider.glucoseStatusData
?: return if (comparator.value == Comparator.Compare.IS_NOT_AVAILABLE) {
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
true

View file

@ -15,6 +15,7 @@ import info.nightscout.androidaps.plugins.general.automation.elements.InputBg
import info.nightscout.androidaps.plugins.general.automation.elements.InputTempTarget
import info.nightscout.androidaps.plugins.general.automation.elements.StaticLabel
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.receivers.ReceiverStatusStore
import info.nightscout.androidaps.services.LastLocationDataContainer
import info.nightscout.androidaps.utils.sharedPreferences.SP
@ -57,6 +58,7 @@ open class TriggerTestBase : TestBaseWithProfile() {
it.treatmentsInterface = treatmentsInterface
it.activePlugin = activePlugin
it.iobCobCalculatorPlugin = iobCobCalculatorPlugin
it.glucoseStatusProvider = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin)
}
if (it is TriggerBg) {
it.profileFunction = profileFunction
@ -83,10 +85,6 @@ open class TriggerTestBase : TestBaseWithProfile() {
if (it is InputTempTarget) {
it.profileFunction = profileFunction
}
if (it is GlucoseStatus) {
it.aapsLogger = aapsLogger
it.iobCobCalculatorPlugin = iobCobCalculatorPlugin
}
if (it is StaticLabel) {
it.resourceHelper = resourceHelper
}

View file

@ -1,147 +1,28 @@
package info.nightscout.androidaps.plugins.iob.iobCobCalculator
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.interfaces.IobCobCalculatorInterface
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.DecimalFormatter
import info.nightscout.androidaps.utils.Round
import java.util.*
import javax.inject.Inject
import kotlin.math.roundToLong
class GlucoseStatus(private val injector: HasAndroidInjector) {
data class GlucoseStatus(
val glucose: Double,
val noise: Double = 0.0,
val delta: Double = 0.0,
val shortAvgDelta: Double = 0.0,
val longAvgDelta: Double = 0.0,
val date: Long = 0L
) {
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var iobCobCalculatorPlugin: IobCobCalculatorInterface
fun log(): String = "Glucose: " + DecimalFormatter.to0Decimal(glucose) + " mg/dl " +
"Noise: " + DecimalFormatter.to0Decimal(noise) + " " +
"Delta: " + DecimalFormatter.to0Decimal(delta) + " mg/dl" +
"Short avg. delta: " + " " + DecimalFormatter.to2Decimal(shortAvgDelta) + " mg/dl " +
"Long avg. delta: " + DecimalFormatter.to2Decimal(longAvgDelta) + " mg/dl"
}
var glucose = 0.0
var noise = 0.0
var delta = 0.0
var avgDelta = 0.0
var shortAvgDelta = 0.0
var longAvgDelta = 0.0
var date = 0L
init {
injector.androidInjector().inject(this)
}
fun log(): String {
return "Glucose: " + DecimalFormatter.to0Decimal(glucose) + " mg/dl " +
"Noise: " + DecimalFormatter.to0Decimal(noise) + " " +
"Delta: " + DecimalFormatter.to0Decimal(delta) + " mg/dl" +
"Short avg. delta: " + " " + DecimalFormatter.to2Decimal(shortAvgDelta) + " mg/dl " +
"Long avg. delta: " + DecimalFormatter.to2Decimal(longAvgDelta) + " mg/dl"
}
fun round(): GlucoseStatus {
glucose = Round.roundTo(glucose, 0.1)
noise = Round.roundTo(noise, 0.01)
delta = Round.roundTo(delta, 0.01)
avgDelta = Round.roundTo(avgDelta, 0.01)
shortAvgDelta = Round.roundTo(shortAvgDelta, 0.01)
longAvgDelta = Round.roundTo(longAvgDelta, 0.01)
return this
}
val glucoseStatusData: GlucoseStatus?
get() = getGlucoseStatusData(false)
fun getGlucoseStatusData(allowOldData: Boolean): GlucoseStatus? {
synchronized(iobCobCalculatorPlugin.dataLock) {
val data = iobCobCalculatorPlugin.bgReadings
val sizeRecords = data.size
if (sizeRecords == 0) {
aapsLogger.debug(LTag.GLUCOSE, "sizeRecords==0")
return null
}
if (data[0].timestamp < DateUtil.now() - 7 * 60 * 1000L && !allowOldData) {
aapsLogger.debug(LTag.GLUCOSE, "oldData")
return null
}
val now = data[0]
val nowDate = now.timestamp
var change: Double
if (sizeRecords == 1) {
val status = GlucoseStatus(injector)
status.glucose = now.value
status.noise = 0.0
status.shortAvgDelta = 0.0
status.delta = 0.0
status.longAvgDelta = 0.0
status.avgDelta = 0.0 // for OpenAPS MA
status.date = nowDate
aapsLogger.debug(LTag.GLUCOSE, "sizeRecords==1")
return status.round()
}
val nowValueList = ArrayList<Double>()
val lastDeltas = ArrayList<Double>()
val shortDeltas = ArrayList<Double>()
val longDeltas = ArrayList<Double>()
// Use the latest sgv value in the now calculations
nowValueList.add(now.value)
for (i in 1 until sizeRecords) {
if (data[i].value > 38) {
val then = data[i]
val thenDate = then.timestamp
val minutesAgo = ((nowDate - thenDate) / (1000.0 * 60)).roundToLong()
// multiply by 5 to get the same units as delta, i.e. mg/dL/5m
change = now.value - then.value
val avgDel = change / minutesAgo * 5
aapsLogger.debug(LTag.GLUCOSE, "$then minutesAgo=$minutesAgo avgDelta=$avgDel")
// use the average of all data points in the last 2.5m for all further "now" calculations
if (0 < minutesAgo && minutesAgo < 2.5) {
// Keep and average all values within the last 2.5 minutes
nowValueList.add(then.value)
now.value = average(nowValueList)
// short_deltas are calculated from everything ~5-15 minutes ago
} else if (2.5 < minutesAgo && minutesAgo < 17.5) {
//console.error(minutesAgo, avgDelta);
shortDeltas.add(avgDel)
// last_deltas are calculated from everything ~5 minutes ago
if (2.5 < minutesAgo && minutesAgo < 7.5) {
lastDeltas.add(avgDel)
}
// long_deltas are calculated from everything ~20-40 minutes ago
} else if (17.5 < minutesAgo && minutesAgo < 42.5) {
longDeltas.add(avgDel)
} else {
// Do not process any more records after >= 42.5 minutes
break
}
}
}
val status = GlucoseStatus(injector)
status.glucose = now.value
status.date = nowDate
status.noise = 0.0 //for now set to nothing as not all CGMs report noise
status.shortAvgDelta = average(shortDeltas)
if (lastDeltas.isEmpty()) {
status.delta = status.shortAvgDelta
} else {
status.delta = average(lastDeltas)
}
status.longAvgDelta = average(longDeltas)
status.avgDelta = status.shortAvgDelta // for OpenAPS MA
aapsLogger.debug(LTag.GLUCOSE, status.log())
return status.round()
}
}
companion object {
fun average(array: ArrayList<Double>): Double {
var sum = 0.0
if (array.size == 0) return 0.0
for (value in array) {
sum += value
}
return sum / array.size
}
}
}
fun GlucoseStatus.asRounded() = copy(
glucose = Round.roundTo(glucose, 0.1),
noise = Round.roundTo(noise, 0.01),
delta = Round.roundTo(delta, 0.01),
shortAvgDelta = Round.roundTo(shortAvgDelta, 0.01),
longAvgDelta = Round.roundTo(longAvgDelta, 0.01)
)

View file

@ -0,0 +1,112 @@
package info.nightscout.androidaps.plugins.iob.iobCobCalculator
import dagger.Reusable
import info.nightscout.androidaps.interfaces.IobCobCalculatorInterface
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.utils.DateUtil
import java.util.*
import javax.inject.Inject
import kotlin.math.roundToLong
@Reusable
class GlucoseStatusProvider @Inject constructor(private val aapsLogger: AAPSLogger, private val iobCobCalculatorPlugin: IobCobCalculatorInterface) {
val glucoseStatusData: GlucoseStatus?
get() = getGlucoseStatusData()
fun getGlucoseStatusData(allowOldData: Boolean = false): GlucoseStatus? {
synchronized(iobCobCalculatorPlugin.dataLock) {
val data = iobCobCalculatorPlugin.bgReadings
val sizeRecords = data.size
if (sizeRecords == 0) {
aapsLogger.debug(LTag.GLUCOSE, "sizeRecords==0")
return null
}
if (data[0].timestamp < DateUtil.now() - 7 * 60 * 1000L && !allowOldData) {
aapsLogger.debug(LTag.GLUCOSE, "oldData")
return null
}
val now = data[0]
val nowDate = now.timestamp
var change: Double
if (sizeRecords == 1) {
aapsLogger.debug(LTag.GLUCOSE, "sizeRecords==1")
return GlucoseStatus(
glucose = now.value,
noise = 0.0,
delta = 0.0,
shortAvgDelta = 0.0,
longAvgDelta = 0.0,
date = nowDate
).asRounded()
}
val nowValueList = ArrayList<Double>()
val lastDeltas = ArrayList<Double>()
val shortDeltas = ArrayList<Double>()
val longDeltas = ArrayList<Double>()
// Use the latest sgv value in the now calculations
nowValueList.add(now.value)
for (i in 1 until sizeRecords) {
if (data[i].value > 38) {
val then = data[i]
val thenDate = then.timestamp
val minutesAgo = ((nowDate - thenDate) / (1000.0 * 60)).roundToLong()
// multiply by 5 to get the same units as delta, i.e. mg/dL/5m
change = now.value - then.value
val avgDel = change / minutesAgo * 5
aapsLogger.debug(LTag.GLUCOSE, "$then minutesAgo=$minutesAgo avgDelta=$avgDel")
// use the average of all data points in the last 2.5m for all further "now" calculations
if (0 < minutesAgo && minutesAgo < 2.5) {
// Keep and average all values within the last 2.5 minutes
nowValueList.add(then.value)
now.value = average(nowValueList)
// short_deltas are calculated from everything ~5-15 minutes ago
} else if (2.5 < minutesAgo && minutesAgo < 17.5) {
//console.error(minutesAgo, avgDelta);
shortDeltas.add(avgDel)
// last_deltas are calculated from everything ~5 minutes ago
if (2.5 < minutesAgo && minutesAgo < 7.5) {
lastDeltas.add(avgDel)
}
// long_deltas are calculated from everything ~20-40 minutes ago
} else if (17.5 < minutesAgo && minutesAgo < 42.5) {
longDeltas.add(avgDel)
} else {
// Do not process any more records after >= 42.5 minutes
break
}
}
}
val shortAverageDelta = average(shortDeltas)
val delta = if (lastDeltas.isEmpty()) {
shortAverageDelta
} else {
average(lastDeltas)
}
return GlucoseStatus(
glucose = now.value,
date = nowDate,
noise = 0.0, //for now set to nothing as not all CGMs report noise
shortAvgDelta = shortAverageDelta,
delta = delta,
longAvgDelta = average(longDeltas),
).also { aapsLogger.debug(LTag.GLUCOSE, it.log()) }.asRounded()
}
}
companion object {
fun average(array: ArrayList<Double>): Double {
var sum = 0.0
if (array.size == 0) return 0.0
for (value in array) {
sum += value
}
return sum / array.size
}
}
}

View file

@ -1,11 +1,11 @@
package info.nightscout.androidaps.plugins.iob.iobCalculator
import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.TestBase
import info.nightscout.androidaps.database.entities.GlucoseValue
import info.nightscout.androidaps.interfaces.IobCobCalculatorInterface
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.asRounded
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.T
import org.junit.Assert
@ -30,88 +30,74 @@ class GlucoseStatusTest : TestBase() {
@Mock lateinit var dateUtil: DateUtil
@Mock lateinit var iobCobCalculatorPlugin: IobCobCalculatorInterface
val injector = HasAndroidInjector {
AndroidInjector {
if (it is GlucoseStatus) {
it.aapsLogger = aapsLogger
it.iobCobCalculatorPlugin = iobCobCalculatorPlugin
}
}
}
@Test fun toStringShouldBeOverloaded() {
val glucoseStatus = GlucoseStatus(injector)
val glucoseStatus = GlucoseStatus(glucose = 0.0, noise = 0.0, delta = 0.0, shortAvgDelta = 0.0, longAvgDelta = 0.0, date = 0)
Assert.assertEquals(true, glucoseStatus.log().contains("Delta"))
}
@Test fun roundTest() {
val glucoseStatus = GlucoseStatus(injector)
glucoseStatus.glucose = 100.11111
Assert.assertEquals(100.1, glucoseStatus.round().glucose, 0.0001)
val glucoseStatus = GlucoseStatus(glucose = 100.11111, noise = 0.0, delta = 0.0, shortAvgDelta = 0.0, longAvgDelta = 0.0, date = 0)
Assert.assertEquals(100.1, glucoseStatus.asRounded().glucose, 0.0001)
}
@Test fun calculateValidGlucoseStatus() {
PowerMockito.`when`(iobCobCalculatorPlugin.bgReadings).thenReturn(generateValidBgData())
val glucoseStatus = GlucoseStatus(injector).glucoseStatusData!!
val glucoseStatus = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin).glucoseStatusData!!
Assert.assertEquals(214.0, glucoseStatus.glucose, 0.001)
Assert.assertEquals(-2.0, glucoseStatus.delta, 0.001)
Assert.assertEquals(-2.5, glucoseStatus.shortAvgDelta, 0.001) // -2 -2.5 -3 deltas are relative to current value
Assert.assertEquals(-2.5, glucoseStatus.avgDelta, 0.001) // the same as short_avgdelta
Assert.assertEquals(-2.0, glucoseStatus.longAvgDelta, 0.001) // -2 -2 -2 -2
Assert.assertEquals(1514766900000L, glucoseStatus.date) // latest date
}
@Test fun calculateMostRecentGlucoseStatus() {
PowerMockito.`when`(iobCobCalculatorPlugin.bgReadings).thenReturn(generateMostRecentBgData())
val glucoseStatus: GlucoseStatus = GlucoseStatus(injector).glucoseStatusData!!
val glucoseStatus: GlucoseStatus = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin).glucoseStatusData!!
Assert.assertEquals(215.0, glucoseStatus.glucose, 0.001) // (214+216) / 2
Assert.assertEquals(-1.0, glucoseStatus.delta, 0.001)
Assert.assertEquals(-1.0, glucoseStatus.shortAvgDelta, 0.001)
Assert.assertEquals(-1.0, glucoseStatus.avgDelta, 0.001)
Assert.assertEquals(0.0, glucoseStatus.longAvgDelta, 0.001)
Assert.assertEquals(1514766900000L, glucoseStatus.date) // latest date, even when averaging
}
@Test fun oneRecordShouldProduceZeroDeltas() {
PowerMockito.`when`(iobCobCalculatorPlugin.bgReadings).thenReturn(generateOneCurrentRecordBgData())
val glucoseStatus: GlucoseStatus = GlucoseStatus(injector).glucoseStatusData!!
val glucoseStatus: GlucoseStatus = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin).glucoseStatusData!!
Assert.assertEquals(214.0, glucoseStatus.glucose, 0.001)
Assert.assertEquals(0.0, glucoseStatus.delta, 0.001)
Assert.assertEquals(0.0, glucoseStatus.shortAvgDelta, 0.001) // -2 -2.5 -3 deltas are relative to current value
Assert.assertEquals(0.0, glucoseStatus.avgDelta, 0.001) // the same as short_avgdelta
Assert.assertEquals(0.0, glucoseStatus.longAvgDelta, 0.001) // -2 -2 -2 -2
Assert.assertEquals(1514766900000L, glucoseStatus.date) // latest date
}
@Test fun insufficientDataShouldReturnNull() {
PowerMockito.`when`(iobCobCalculatorPlugin.bgReadings).thenReturn(generateInsufficientBgData())
val glucoseStatus: GlucoseStatus? = GlucoseStatus(injector).glucoseStatusData
val glucoseStatus: GlucoseStatus? = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin).glucoseStatusData
Assert.assertEquals(null, glucoseStatus)
}
@Test fun oldDataShouldReturnNull() {
PowerMockito.`when`(iobCobCalculatorPlugin.bgReadings).thenReturn(generateOldBgData())
val glucoseStatus: GlucoseStatus? = GlucoseStatus(injector).glucoseStatusData
val glucoseStatus: GlucoseStatus? = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin).glucoseStatusData
Assert.assertEquals(null, glucoseStatus)
}
@Test fun returnOldDataIfAllowed() {
PowerMockito.`when`(iobCobCalculatorPlugin.bgReadings).thenReturn(generateOldBgData())
val glucoseStatus: GlucoseStatus? = GlucoseStatus(injector).getGlucoseStatusData(true)
val glucoseStatus: GlucoseStatus? = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin).getGlucoseStatusData(true)
Assert.assertNotEquals(null, glucoseStatus)
}
@Test fun averageShouldNotFailOnEmptyArray() {
Assert.assertEquals(0.0, GlucoseStatus.average(ArrayList()), 0.001)
Assert.assertEquals(0.0, GlucoseStatusProvider.average(ArrayList()), 0.001)
}
@Test fun calculateGlucoseStatusForLibreTestBgData() {
PowerMockito.`when`(iobCobCalculatorPlugin.bgReadings).thenReturn(generateLibreTestData())
val glucoseStatus: GlucoseStatus = GlucoseStatus(injector).glucoseStatusData!!
val glucoseStatus: GlucoseStatus = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin).glucoseStatusData!!
Assert.assertEquals(100.0, glucoseStatus.glucose, 0.001) //
Assert.assertEquals(-10.0, glucoseStatus.delta, 0.001)
Assert.assertEquals(-10.0, glucoseStatus.shortAvgDelta, 0.001)
Assert.assertEquals(-10.0, glucoseStatus.avgDelta, 0.001)
Assert.assertEquals(-10.0, glucoseStatus.longAvgDelta, 0.001)
Assert.assertEquals(1514766900000L, glucoseStatus.date) // latest date
}